Java Swing:使用 Action 事件激活动画

问题描述 投票:0回答:1

我正在尝试在 java.switch 中编写一个简单的 GUI,当按下按钮时它会激活动画。当我删除按钮并让动画直接运行时,动画可以工作,但是当我将动画代码放在按下按钮时运行的 ActionListener 类中时,它就不再工作了。这是什么原因呢?

代码,无按钮的工作动画:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.TimeUnit;

class SimpleGUI {
    
    private JFrame frame;
    private JPanel panel;
    private int xPos = 70;
    private int yPos = 70;

    class DrawPanel extends JPanel {
    public void paintComponent(Graphics g) {
        g.setColor(Color.white);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());
        g.setColor(Color.green);
        g.fillOval(xPos, yPos, 40, 40);
    }
    }

    public void go() {
    frame = new JFrame();
    panel = new DrawPanel();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(BorderLayout.CENTER, panel);
    //frame.getContentPane().add(BorderLayout.SOUTH, button);
    frame.setSize(300,300);
    frame.setVisible(true);
    for(int i = 0; i < 100; i++) {
        xPos++;
        yPos++;
        panel.repaint();
        try {
        TimeUnit.MILLISECONDS.sleep(50);
        } catch(Exception e) {
        e.printStackTrace();
        }
    }
    }
}

class GUITest {
    public static void main(String[] args) {
    SimpleGUI gui = new SimpleGUI();
    gui.go();
    }
}

代码,带有按钮的破损动画:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.TimeUnit;

class SimpleGUI {
    
    private JFrame frame;
    private JPanel panel;
    private int xPos = 70;
    private int yPos = 70;

    class DrawPanel extends JPanel {
    public void paintComponent(Graphics g) {
        g.setColor(Color.white);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());
        g.setColor(Color.green);
        g.fillOval(xPos, yPos, 40, 40);
    }
    }

     class AnimationListener implements ActionListener {
    public void actionPerformed(ActionEvent event) {
        for(int i = 0; i < 100; i++) {
        xPos++;
        yPos++;
        panel.repaint();
            try {
            TimeUnit.MILLISECONDS.sleep(50);
        } catch(Exception e) {
            e.printStackTrace();
        }
        }
    }
     }

    public void go() {
    frame = new JFrame();
    panel = new DrawPanel();
    JButton button = new JButton("Start Animation");
    button.addActionListener(event -> button.setText("Animation starts"));
    button.addActionListener(new AnimationListener());
    
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(BorderLayout.CENTER, panel);
    frame.getContentPane().add(BorderLayout.SOUTH, button);
    frame.setSize(300,300);
    frame.setVisible(true);
    }
}



class GUITest {
    public static void main(String[] args) {
    SimpleGUI gui = new SimpleGUI();
    gui.go();
    }
}

我期望按下按钮时 ActionListener 类中的代码会完全执行。我还尝试删除 ActionListener 类中的 for 循环,以便每当按下按钮时圆圈都会移动一步。这可行,我可以通过重复按下按钮将圆圈移动 100 步。

java swing actionlistener
1个回答
0
投票

您遇到了线程问题。

工作: 您在主线程上启动应用程序。它创建 UI,并生成事件调度线程来更新 UI。同时,您的应用程序在主线程上运行 go(),并且它似乎可以工作。虽然还是有设计缺陷。

不工作: go() 方法从按下按钮开始,该方法本身在事件调度线程上调用。由于 go() 方法不会退出,因此线程保持忙碌状态,没有时间更新 UI。

© www.soinside.com 2019 - 2024. All rights reserved.