Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java sleep()使我的GUI崩溃_Java_User Interface - Fatal编程技术网

Java sleep()使我的GUI崩溃

Java sleep()使我的GUI崩溃,java,user-interface,Java,User Interface,ButtonListener类中的Thread.sleep(rand.nextInt(delay))命令使GUI崩溃。有什么想法吗?程序应该将人添加到ArrayList中,然后随机选择他们,并在0和timeText JTextField之间的随机时间显示他们,直到我添加sleep命令为止。任何帮助都将不胜感激,谢谢 import javax.swing.*; import java.awt.event.*; import java.util.*; import java.awt.*; impor

ButtonListener类中的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");

   }
}
import javax.swing.*;
导入java.awt.event.*;
导入java.util.*;
导入java.awt.*;
导入javax.swing.Timer;
公共类MyProgram扩展了AppClass{
受保护的整数x、y、宽度、高度;
保护色;
private ArrayList people=new ArrayList();
私家侦探;
私人定时器;
私有按钮侦听器;
private Random rand=new Random();
私人JLabel-addPeople;
私人JTextField newPerson;
私有JTextField timeText;
私有字体font1=新字体(“Arial”,1,17);
私有字体font2=新字体(“Arial”,1,65);
公共MyProgram(){
设置首选尺寸(新尺寸(1000800));
添加(“我”);
添加(“约翰”);
添加(“greg”);
JPanel面板=新的JPanel();
面板。设置首选尺寸(新尺寸(600400));
panel.setLayout(新的BoxLayout(panel,BoxLayout.Y_轴));
newPerson=newjtextfield(2);
newPerson.setFont(font1);
addPeople=newjlabel(“addPeople:”);
addPeople.setFont(font1);
person=新JLabel();
person.setFont(font2);
JButton addButton=新JButton(“添加”);
addButton.setFont(font1);
JButton startButton=新JButton(“开始”);
setFont(font1);
timeText=新的JTextField(2);
timeText.setFont(font1);
JLabel时间=新的JLabel(“绘制之间的最大时间:”);
time.setFont(font1);
listener=新按钮listener();
addButton.addActionListener(listener);
addActionListener(listener);
panel.add(addPeople);
面板。添加(newPerson);
panel.add(添加按钮);
面板。添加(时间);
面板。添加(时间文本);
面板。添加(开始按钮);
小组.增加(人);
添加(面板);
}
私有类ButtonListener实现ActionListener{
已执行的公共无效行动(行动事件ae){
JButton button=(JButton)ae.getSource();
if(button.getText().equals(“Add”)){
添加(newPerson.getText());
System.out.println(newPerson.getText());
System.out.println(“也工作”);
}else if(button.getText().equals(“Start”)){
int delay=Integer.parseInt(timeText.getText());
对于(;;){
person.setText(people.get(rand.nextInt(people.size()));
试一试{
Thread.sleep(rand.nextInt(delay));//问题
}捕获(异常错误){
System.out.println(“错误”);
}
}
}
}
}
}
导入javax.swing.*;
导入java.awt.event.*;
导入java.util.*;
导入java.awt.*;
导入javax.swing.Timer;
公共类AppClass扩展了JPanel{
公共静态void main(字符串[]args){
JFrame=新JFrame();
frame.getContentPane().add(new Get());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
frame.setTitle(“我的程序”);
}
}

实际上,您是在同一个线程中执行gui,当您使用
线程时。睡眠(延迟)
您也是在睡眠gui。因此,您必须使用新线程进行其他处理

Thread t = new Thread(new Runnable(){
    @Override
    public void run() {
    }
});

只有一个线程修改UI。这是出于设计,因为这意味着,即使UI可以接收到许多事件源,并发错误也不可能破坏UI状态


只有一个线程修改UI。这包括:

  • 接收鼠标事件
  • 接收键盘事件
  • 处理重新绘制的请求
  • 处理UI计时器
在许多其他方面

如果您在修改UI的代码中,那么您必须在UI线程上(否则,您就有一个bug)。如果您在UI线程上并调用
Sleep()
,则UI线程将停止执行操作

它将停止响应重新绘制的请求。它将停止响应键盘事件、鼠标事件等

相反,您必须使用窗体计时器来执行动画。当有人单击“开始”按钮时,您将设置第一个值,保存其余的值,然后启动计时器,然后让UI线程继续处理

每次计时器启动时,您都会推进状态-使用下一个要显示的值更新UI。继续此操作,直到显示所有值,然后停止计时器并释放告诉您在动画中的位置的状态

是的,您只是在某些组件上设置文本,但这仍然属于动画模式


但要小心-如果在动画计时器仍在运行时关闭了UI,则将尝试修改已关闭的UI。因此,现在您的UI代码必须小心停止动画计时器,如果它在UI关闭时仍在运行。

您正在使GUI与睡眠相关:(顺便说一句,您已经导入了
javax.swing.timer
,为什么不使用它…)没有其他线程可以解决此问题;需要使用UI计时器。引入其他线程只会导致UI并发错误,因为您将违反只有一个线程读取或写入整个UI的限制。如何实现计时器?感谢您在处理程序中的帮助,当单击开始按钮时,解析延迟,然后使用该延迟启动swing计时器。当swing计时器启动时,修改UI:随机选择一个人并调用
person.setText()
。当UI开始关闭时,如果计时器尚未禁用,请确保计时器已禁用。