所以我对java比较陌生(自学成才,所以我会喜欢你能给出的任何建议/批评)作为练习我决定使用Jbuttons作为Dice创建一个掷骰子滚动程序。为了模拟骰子的滚动,我想在呈现结果之前将Jbutton的文本随机地改变为不同的数字几秒钟。
我写这样做的方法似乎有效,直到我试图从ActionPerformed方法中调用。当我这样做时,程序将冻结直到方法结束,然后将按钮文本更改为最终结果。
我很好奇是否有人可以解释为什么会发生这种情况,或者教我正确的做法。谢谢你的帮助。
Bellow是同一问题的一个简单例子
package experiments.changingtext;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class ChangingText extends JFrame implements ActionListener{
JButton button = new JButton("Change Me");
public ChangingText(){
this.setSize(200,200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel pane = new JPanel();
button.addActionListener(this);
pane.add(button);
this.add(pane);
this.setVisible(true);
try{Thread.sleep(500);}catch(Exception ex){}
//Works as expected
this.changeButtonText();
}
@Override
public void actionPerformed(ActionEvent e) {
//when run program freezes and presents the final text "change to 5"
if(e.getSource() == button){
button.setText("change to 1");
try{Thread.sleep(500);}catch(Exception ex){}
button.setText("change to 2");
try{Thread.sleep(500);}catch(Exception ex){}
button.setText("change to 3");
try{Thread.sleep(500);}catch(Exception ex){}
button.setText("change to 4");
try{Thread.sleep(500);}catch(Exception ex){}
button.setText("change to 5");
}
}
public void changeButtonText(){
button.setText("change to 1");
try{Thread.sleep(500);}catch(Exception ex){}
button.setText("change to 2");
try{Thread.sleep(500);}catch(Exception ex){}
button.setText("change to 3");
try{Thread.sleep(500);}catch(Exception ex){}
button.setText("change to 4");
try{Thread.sleep(500);}catch(Exception ex){}
button.setText("change to 5");
}
}
答案 0 :(得分:3)
不需要直接使用后台线程。而是使用Swing Timer为您进行后台计数,最重要的是,允许在Swing事件线程上进行所有间歇性调用。有关如何使用这个非常有用的工具的更多信息,请查看Swing Timer Tutorial。简而言之,您在JButton的ActionListener中创建一个新的Timer,为Timer提供自己的ActionListener,它保存重复调用的代码,直到完成。
例如:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.EnumMap;
import java.util.Map;
import java.util.Random;
import javax.swing.*;
public class ChangingText2 extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private static final float PTS = 24f;
public static final int TIMER_DELAY = 200;
public static final int MAX_TIME = 2000;
private JButton button = new JButton("1");
public ChangingText2() {
button.setFont(button.getFont().deriveFont(Font.BOLD, PTS));
button.addActionListener(new ButtonListener());
setLayout(new GridBagLayout());
add(button);
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class ButtonListener implements ActionListener {
private Timer timer;
@Override
public void actionPerformed(ActionEvent e) {
if (timer != null && timer.isRunning()) {
return;
}
timer = new Timer(TIMER_DELAY, new ActionListener() {
private int count = 0;
@Override
public void actionPerformed(ActionEvent e2) {
if (count * TIMER_DELAY > MAX_TIME) {
((Timer) e2.getSource()).stop();
return;
}
count++;
Die die = Die.getRandomDie();
((AbstractButton) e.getSource()).setText("" + die.getValue());
}
});
timer.start();
}
}
private static void createAndShowGui() {
ChangingText2 mainPanel = new ChangingText2();
JFrame frame = new JFrame("ChangingText2");
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();
}
});
}
}
enum Die {
ONE(1), TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6);
private int value;
private static Random random = new Random();
private Die(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static Die getRandomDie() {
int index = random.nextInt(Die.values().length);
return Die.values()[index];
}
}