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();
}
});
}
}