Java Blink JButton в течение 2 секунд

Я хочу, чтобы программа ждала 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().

1 ответ

Используйте таймер, который вам уже нужен, чтобы помочь вам определить, когда прошло 2 секунды, и вы можете сделать это, посчитав внутри своего таймера, сколько раз вызывается метод actionPerformed. Когда он вызывается 4 раза (2 секунды), остановите таймер. Это просто:

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 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();
         }
      });
   }
}
Другие вопросы по тегам