我的ButtonListener类中的My Thread.sleep(rand.nextInt(delay))命令崩溃了我的GUI。有任何想法吗?该程序应该将人们添加到ArrayList,然后随机选择它们并在0和timeText JTextField之间的随机时间显示它们,直到我添加sleep命令。任何帮助将不胜感激!
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import java.awt.*;
import javax.swing.Timer;
public class MyProgram extends AppClass{
protected int x,y,width,height;
protected Color color;
private ArrayList<String> people = new ArrayList<String>();
private static JLabel person;
private Timer timer;
private ButtonListener listener;
private Random rand = new Random();
private JLabel addPeople;
private JTextField newPerson;
private JTextField timeText;
private Font font1 = new Font("Arial",1,17);
private Font font2 = new Font("Arial",1,65);
public MyProgram(){
setPreferredSize(new Dimension(1000,800));
people.add("me");
people.add("john");
people.add("greg");
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(600,400));
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
newPerson = new JTextField(2);
newPerson.setFont(font1);
addPeople = new JLabel("Add people:");
addPeople.setFont(font1);
person = new JLabel();
person.setFont(font2);
JButton addButton = new JButton("Add");
addButton.setFont(font1);
JButton startButton = new JButton("Start");
startButton.setFont(font1);
timeText = new JTextField(2);
timeText.setFont(font1);
JLabel time = new JLabel("Maximum time between draws:");
time.setFont(font1);
listener = new ButtonListener();
addButton.addActionListener(listener);
startButton.addActionListener(listener);
panel.add(addPeople);
panel.add(newPerson);
panel.add(addButton);
panel.add(time);
panel.add(timeText);
panel.add(startButton);
panel.add(person);
add(panel);
}
private class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent ae){
JButton button = (JButton) ae.getSource();
if(button.getText().equals("Add")){
people.add(newPerson.getText());
System.out.println(newPerson.getText());
System.out.println("also worked");
}else if(button.getText().equals("Start")){
int delay = Integer.parseInt(timeText.getText());
for(;;){
person.setText(people.get(rand.nextInt(people.size())));
try{
Thread.sleep(rand.nextInt(delay)); // the problem
}catch(Exception error){
System.out.println("Error");
}
}
}
}
}
}
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import java.awt.*;
import javax.swing.Timer;
public class AppClass extends JPanel{
public static void main(String [] args){
JFrame frame = new JFrame();
frame.getContentPane().add(new Get());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
frame.setTitle("My Program");
}
}
答案 0 :(得分:0)
只有一个线程可以修改UI。这是设计使然,因为它意味着,即使UI可以接收许多事件源,并发错误也不可能破坏UI状态。
只有一个线程可以修改UI。这包括:
其他许多人。
如果你在修改UI的代码中,那么你必须在UI线程上(否则,你有一个bug)。如果您在UI线程上并且调用Sleep()
,那么UI线程将停止执行操作。
它会停止响应重绘请求。它将停止响应键盘事件,鼠标事件等。
相反,您必须使用表单计时器来执行动画。当有人点击您的&#34;开始&#34;按钮,你将设置第一个值,保存其余的值,然后启动你的计时器,然后让UI线程继续处理。
每次计时器触发时,都会提前状态 - 您使用要显示的下一个值更新UI。你继续这个直到你显示了所有的值,然后停止计时器并释放你的状态,告诉你你在动画中的位置。
是的,您只是在某个组件上设置文本,但这仍属于动画模式。
但请注意 - 如果您的UI在动画计时器仍在运行时关闭,您将尝试修改已消失的UI。所以现在你的UI代码必须小心停止动画计时器,如果它在UI关闭时仍在运行。
答案 1 :(得分:-1)
实际上,你是在同一个线程中执行你的gui,当你使用Thread.sleep(delay)
时,你也会睡觉。所以你必须使用新线程进行其他处理。
Thread t = new Thread(new Runnable(){
@Override
public void run() {
}
});