【问题标题】:Java Blink JButton during 2 secondsJava 在 2 秒内闪烁 JButton
【发布时间】:2015-05-16 04:28:52
【问题描述】:

我希望程序在闪烁按钮时等待 2 秒。 我有这个闪烁按钮的代码:

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

public class a
{
    static JFrame frame = new JFrame();
    static JButton button = new JButton("Hello");

    public static void main(String[] args) {
        frame.add(button);
        frame.pack();
        frame.setVisible(true);
        blinking();   //this is the blinking part
        //this is where the waiting 2 seconds should be
        JOptionPane.showMessageDialog(null,"Popup message", "Title", JOptionPane.PLAIN_MESSAGE);
        //rest of the code of my program
    }

    private void blinking() {
        button.setOpaque(true);
        Timer blinkTimer = new Timer(500, new ActionListener() {
            boolean on=false;
            public void actionPerformed(ActionEvent e) {
                // blink the button background on and off
                button.setBackground( on ? Color.YELLOW : null);
                on = !on;
            }
        });
        blinkTimer.start();
    }
}

我希望程序在 2 秒内闪烁,然后打开 JOptionPane。它所做的是打开JOptionPane 而不等待2 秒。 我曾尝试使用Thread.sleep(2000) 进行等待,但它似乎不起作用,在这 2000 毫秒的等待时间内按钮不会闪烁。
有什么建议?

注意: 我无法将 JOptionPane 移出 main()。

【问题讨论】:

    标签: java swing jbutton background-color blink


    【解决方案1】:

    使用您已经拥有的 Timer 来帮助您确定 2 秒结束的时间,您可以通过在 Timer 内部计算调用 actionPerformed 方法的次数来做到这一点。当它被调用 4 次(2 秒)时,停止 Timer。很简单:

    Timer blinkTimer = new Timer(500, new ActionListener() {
        private int count = 0;
        private int maxCount = 4;
        private boolean on = false;
    
        public void actionPerformed(ActionEvent e) {
            if (count >= maxCount) {
                button.setBackground(null);
                ((Timer) e.getSource()).stop();
            } else {
                button.setBackground( on ? Color.YELLOW : null);
                on = !on;
                count++;
            }
        }
    });
    blinkTimer.start();
    

    您还告诉我,您希望在此闪烁期间以某种方式暂停某些程序的执行,为此我建议您创建一个方法,例如 enableExecution(boolean) 为您执行此操作,您调用在启动 Timer 之前并在 Timer 完成后再次调用,例如:

    Timer blinkTimer = new Timer(500, new ActionListener() {
        private int count = 0;
        private int maxCount = 4;
        private boolean on = false;
    
        public void actionPerformed(ActionEvent e) {
            if (count >= maxCount) {
                button.setBackground(null);
                ((Timer) e.getSource()).stop();
                enableExecution(true);   //  ***** re-enable execution of whatever *****
    
            } else {
                button.setBackground( on ? Color.YELLOW : null);
                on = !on;
                count++;
            }
        }
    });
    
    enableExecution(false);   //  ***** disable execution of whatever *****
    blinkTimer.start();
    

    编辑
    关于您编辑的代码,我仍然认为最好的解决方案是再次调用从计时器中显示对话框的代码。如果您的问题是调用计时器的类没有在对话框中适当显示所需的信息,请考虑将此信息传递给该类。例如:

    import java.awt.Color;
    import java.awt.Window;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.*;
    
    public class BetterA extends JPanel {
       private static final int TIMER_DELAY = 500;
       private JButton button = new JButton("Hello");
    
       // information needed by the dialog:
       private String message;
       private String title;
    
       public BetterA(String message, String title) {
          add(button);
          blinking();
    
          // set the dialog information
          this.message = message;
          this.title = title;
       }
    
       private void blinking() {
          button.setOpaque(true);
          Timer blinkTimer = new Timer(TIMER_DELAY, new ActionListener() {
             private int count = 0;
             private int maxTime = 2000;
             private boolean on = false;
    
             public void actionPerformed(ActionEvent e) {
                if (count * TIMER_DELAY >= maxTime) {
                   button.setBackground(null);
                   ((Timer) e.getSource()).stop();
                   Window win = SwingUtilities.getWindowAncestor(BetterA.this);
                   JOptionPane.showMessageDialog(win, message, title,
                         JOptionPane.PLAIN_MESSAGE);
                } else {
                   button.setBackground(on ? Color.YELLOW : null);
                   on = !on;
                   count++;
                }
             }
          });
          blinkTimer.start();
       }
    
       private static void createAndShowGui() {
          String myMessage = "Popup message";
          String myTitle = "Some Title";
    
          BetterA mainPanel = new BetterA(myMessage, myTitle);
    
          JFrame frame = new JFrame("BetterA");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          frame.getContentPane().add(mainPanel);
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    

    编辑 2

    另一种选择是使用 Swing 固有的 PropertyChangeListener 支持。例如:

    import java.awt.Color;
    import java.awt.Window;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    
    import javax.swing.*;
    
    public class BetterA2 extends JPanel {
       private static final int TIMER_DELAY = 500;
       private static final int MAX_TIME = 2000;
       private static final String READY = "ready";
       private JButton button = new JButton("Hello");
    
       public BetterA2() {
          add(button);
          blinking();
       }
    
       private void blinking() {
          button.setOpaque(true);
          Timer blinkTimer = new Timer(TIMER_DELAY, new ActionListener() {
             private int count = 0;
             private boolean on = false;
    
             public void actionPerformed(ActionEvent e) {
                if (count * TIMER_DELAY >= MAX_TIME) {
                   button.setBackground(null);
                   ((Timer) e.getSource()).stop();
    
                   // !!!
                   firePropertyChange(READY, READY, null);
                } else {
                   button.setBackground(on ? Color.YELLOW : null);
                   on = !on;
                   count++;
                }
             }
          });
          blinkTimer.start();
       }
    
       private static void createAndShowGui() {
          final BetterA2 mainPanel = new BetterA2();
          mainPanel.addPropertyChangeListener(BetterA2.READY,
                new PropertyChangeListener() {
    
                   @Override
                   public void propertyChange(PropertyChangeEvent evt) {
                      JOptionPane.showMessageDialog(mainPanel, "Popup message",
                            "Title", JOptionPane.PLAIN_MESSAGE);
                   }
                });
    
          JFrame frame = new JFrame("BetterA");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          frame.getContentPane().add(mainPanel);
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    

    【讨论】:

    • 谢谢,它确实停止了。但我想要的是程序在这 2 秒内什么都不做(只是眨眼),然后继续执行
    • @dan_san_1:你上面的陈述对我来说有点模棱两可。请编辑您的问题并准确告诉我们您所说的"... for the program to do nothing ..." 是什么意思。在编辑中,请考虑确切地告诉我们程序当前正在做什么而您不希望它执行。我们越能理解您的问题,就越能提供帮助。另外,请考虑创建并发布minimal example program or MCVE
    • @dan_san_1:见编辑回答。请注意,enableExecution(...) 方法的详细信息都将取决于您的代码和问题的详细信息。
    • 我不希望它在闪烁期间暂停,我希望程序在这 2 秒内只是闪烁。只需等待 2 秒
    • @dan_san_1:再次"...then continue with the execution." 是什么意思。 什么的执行?请通过提供这些详细信息来帮助您回答问题。如果我们能理解您的问题,我们可以为您提供帮助。
    猜你喜欢
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多