【问题标题】:java animation, making an object change color every 'x' secondsjava动画,使对象每'x'秒改变一次颜色
【发布时间】:2015-03-30 02:38:14
【问题描述】:

嗨,我只是想知道是否有人可以帮助我或给我一些有关计时器的建议,我遇到的问题是我需要一个对象在单击按钮“flash”时每 x 秒更改一次颜色并保持单击“稳定”按钮时的单色到目前为止,我的按钮已经开始工作,我似乎无法让对象“闪烁”(自行更改颜色)。我的代码在下面并且没有问题。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


/**
 * Created by joe on 26/03/15.
 */

    class Beacon extends JPanel {
    private boolean lightOn = true;

    private int x = 150;
    private int y = 90;
    private int ballSize = 55;

        public void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D) g;
                if (lightOn){
                    g2.setColor(Color.BLACK);
                    g2.fillRect(172, 140, 12, 30);
                    g2.drawRect(172, 170, 11, 30);
                    g2.fillRect(172, 200, 12, 30);
                    g2.drawRect(172, 230, 11, 30);
                    g2.fillRect(172, 260, 12, 30);
                    g2.drawRect(172, 290, 11, 30);
                    g2.fillRect(172, 320, 12, 30);
                    g2.drawRect(172, 350, 11, 30);
                    g2.setColor(Color.ORANGE);
                    g2.fillOval(x, y, ballSize, ballSize);
                }
            else{
        g2.setColor(Color.BLACK);
        g2.fillRect(172, 140, 12, 30);
        g2.drawRect(172, 170, 11, 30);
        g2.fillRect(172, 200, 12, 30);
        g2.drawRect(172, 230, 11, 30);
        g2.fillRect(172, 260, 12, 30);
        g2.drawRect(172, 290, 11, 30);
        g2.fillRect(172, 320, 12, 30);
        g2.drawRect(172, 350, 11, 30);
        g2.setColor(Color.GRAY);
        g2.fillOval(x, y, ballSize, ballSize);
    }   }
    public void lightOn() { lightOn = true; }
    public void lightOff() { lightOn = false; }
}

    public class BeaconViewer extends JFrame
    {
        JButton Flash = new JButton("Flash");
        JButton Steady = new JButton("Steady");
        JPanel bPanel = new JPanel();
        Beacon bbPanel = new Beacon();



    public BeaconViewer()
    {
        bPanel.add(Flash);
        this.add(bPanel, BorderLayout.SOUTH);
        bPanel.add(Steady);
        this.add(bbPanel, BorderLayout.CENTER);
        Flash.addActionListener(new FlashListener());
        Steady.addActionListener(new SteadyListener());
    }

        class FlashListener implements ActionListener {

            public void actionPerformed(ActionEvent e) {
                bbPanel.lightOff();
                repaint();

            }

        }

        class SteadyListener implements ActionListener {

            public void actionPerformed(ActionEvent a) {
                bbPanel.lightOn();
                repaint();
            }

        }

        public static void main(String[] args) {
        JFrame scFrame = new BeaconViewer();
        scFrame.setTitle("Belish Beacon");
        scFrame.setSize(300, 500);
        scFrame.setDefaultCloseOperation((JFrame.EXIT_ON_CLOSE));
        scFrame.setVisible(true); }}

【问题讨论】:

  • 不要创建两个方法(lightOn() 和 lightOff)。通常,要管理类中的属性,您将拥有一个“getter”和一个“setter”方法。所以在你的情况下,因为你调用你的变量名是lightOn,我建议你创建两个方法isLightOn()setLightOn(boolean lightOn)。然后在setLightOn(...) 方法中调用repaint(),这样您的属性的新状态就可以反映在GUI 上。

标签: java swing flash animation timer


【解决方案1】:

先看看How to use Swing Timers

首先你需要知道Beacon是打开还是关闭,我们通过添加来实现这一点

public boolean isLighOff() {
    return !lightOn;
}

Beacon 类。

接下来,我们需要一个javax.swing.Timer的实例

public class BeaconViewer extends JFrame {
    //...
    private Timer flashTimer;

    public BeaconViewer() {
        //...
        flashTimer = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (bbPanel.isLighOff()) {
                    bbPanel.lightOn();
                } else {
                    bbPanel.lightOff();
                }
                repaint();
            }
        });
        flashTimer.setInitialDelay(0);
    }

这用于在指定的持续时间(1 秒)安排定期回调,确定 Beacon 的当前状态并切换状态...使用 Swing Timer 的原因是这样的,除了简单来说,是因为在分配的 ActionListener 中修改 UI 组件是安全的

接下来,我们需要相应地启动和置顶Timer...

class FlashListener implements ActionListener {

    public void actionPerformed(ActionEvent e) {
        flashTimer.start();
    }

}

class SteadyListener implements ActionListener {

    public void actionPerformed(ActionEvent a) {
        if (flashTimer.isRunning()) {
            flashTimer.stop();
        }
        bbPanel.lightOn();
        repaint();
    }

}

【讨论】:

  • 感谢您的帮助,正是我正在寻找的东西
【解决方案2】:

您想要做的是使用摆动计时器并将其注册为AbstractActionActionListener,它将根据您传递的延迟参数触发。

例如,我可能有...

...
Timer timer = new Timer(FRAME_DELAY, myActionListener);
timer.start();
...

其中FRAME_DELAY 是事件触发之间的毫秒数,myActionListener 接收到执行操作的通知。

一旦有了计时器,您就可以调整延迟、停止和重新启动等等。请参阅Timer 了解更多信息。

【讨论】:

    【解决方案3】:

    这很容易实现,你需要做的就是使用System.currentTimeMillis()这样的东西

    start = System.currentTimeMillis()
    //stuff
    finish = System.currentTimeMillis()
    elapsed = finish - start
    

    如果结果大于 1,000,则已经过了一秒。您可能希望将此计时器放在单独的线程中,具体取决于您希望如何在程序中实现它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-10
      • 2014-12-31
      • 1970-01-01
      • 2020-11-05
      • 2017-11-20
      • 2018-12-15
      • 1970-01-01
      • 2021-06-17
      相关资源
      最近更新 更多