等待不允许 JFrame 更新
Wait doesn't allow the JFrame to update
在我的程序中,我需要等待用户从 JFrame 输入。当用户完成第一个输入时,他们按下 JButton。这会为我创建的 Class 调用一个构造函数:HumanTrainer。在构造函数中,我需要用户有更多的输入。我做了两个等待和通知的功能。但是当代码开始等待时,一切都冻结了,并且 JFrame 没有更新到它应该的状态。
这是第一个按钮预制的动作
startingButton.addActionListener((e)->{
Trainer[]t=new Trainer[2];//HumanTrainer extends Trainer
String[]names=new String[2];
for(int a=0;a<2;a++)
names[a]=((JTextField)(startingInputs[2][1+a])).getText();
grid.removeAll();//The JPanel that the Frame has
Frame.repaint();//The JFrame
Frame.validate();
if(isHuman[0])
t[0]=new HumanTrainer(names[0],grid,Frame);//The constructor
if(isHuman[1])
t[1]=new HumanTrainer(names[1],grid,Frame);
});
以及 HumanTrainer 的构造函数
HumanTrainer(String name,JPanel grid,JFrame Frame){
super(name);
GridBagConstraints manager=new GridBagConstraints();
manager.gridx=0;
manager.gridy=0;
manager.gridheight=1;
manager.gridwidth=1;
manager.fill=GridBagConstraints.HORIZONTAL;
Font Format=new Font("Courier New",Font.PLAIN,14);
JButton cont=new JButton("Continue");//This is the button that when clicked should run the function that notifies
grid.add(cont,manager);
grid.repaint();//One of these four things SHOULD change the view of the frame
grid.validate();
Frame.repaint();
Frame.validate();
System.out.print("TEST");//This prints
cont.addActionListener((e)->{
made();//This is a function contained in HumanTrainer that only calls notify();
});
make();//This is a function contained in HumanTrainer that only calls wait(); With the proper try and catch
}
但是当按下 starterButton 时,屏幕会冻结并且不会更新,因此可以继续按下。
首先,您可能想用 {}
关闭 for 循环,这样它就不会将整个代码循环两次。此外,您应该通过在没有 java awt 的情况下单独测试 wait()
和 notify()
来检查它们是否正常工作。
先看看 Concurrency in Swing。 Swing 使用单个线程来调度它的事件,如果您从 EDT 中执行任何长 运行 或阻塞操作(例如调用 wait
),那么它会冻结您的程序并且用户将不得不终止它。
您有两个基本选择。您可以使用模态对话框从用户那里收集信息,请参阅 How to Make Dialogs,这将在代码显示时阻止代码的执行,而不会阻止整个 EDT 或使用观察者模式,它可以生成通知用户已提供您所期望的信息。
老实说,模态对话框通常更容易,并且有助于防止意外的副作用
这个...
make();//This is a function contained in HumanTrainer that only calls wait(); With the proper try and catch
似乎是你问题的核心,但如果没有更多信息和你正在尝试做的事情的背景,就不可能真正建议你应该做什么,但是我建议你看看 model-view-controller 并将您的代码分成更合适的层
在我的程序中,我需要等待用户从 JFrame 输入。当用户完成第一个输入时,他们按下 JButton。这会为我创建的 Class 调用一个构造函数:HumanTrainer。在构造函数中,我需要用户有更多的输入。我做了两个等待和通知的功能。但是当代码开始等待时,一切都冻结了,并且 JFrame 没有更新到它应该的状态。
这是第一个按钮预制的动作
startingButton.addActionListener((e)->{
Trainer[]t=new Trainer[2];//HumanTrainer extends Trainer
String[]names=new String[2];
for(int a=0;a<2;a++)
names[a]=((JTextField)(startingInputs[2][1+a])).getText();
grid.removeAll();//The JPanel that the Frame has
Frame.repaint();//The JFrame
Frame.validate();
if(isHuman[0])
t[0]=new HumanTrainer(names[0],grid,Frame);//The constructor
if(isHuman[1])
t[1]=new HumanTrainer(names[1],grid,Frame);
});
以及 HumanTrainer 的构造函数
HumanTrainer(String name,JPanel grid,JFrame Frame){
super(name);
GridBagConstraints manager=new GridBagConstraints();
manager.gridx=0;
manager.gridy=0;
manager.gridheight=1;
manager.gridwidth=1;
manager.fill=GridBagConstraints.HORIZONTAL;
Font Format=new Font("Courier New",Font.PLAIN,14);
JButton cont=new JButton("Continue");//This is the button that when clicked should run the function that notifies
grid.add(cont,manager);
grid.repaint();//One of these four things SHOULD change the view of the frame
grid.validate();
Frame.repaint();
Frame.validate();
System.out.print("TEST");//This prints
cont.addActionListener((e)->{
made();//This is a function contained in HumanTrainer that only calls notify();
});
make();//This is a function contained in HumanTrainer that only calls wait(); With the proper try and catch
}
但是当按下 starterButton 时,屏幕会冻结并且不会更新,因此可以继续按下。
首先,您可能想用 {}
关闭 for 循环,这样它就不会将整个代码循环两次。此外,您应该通过在没有 java awt 的情况下单独测试 wait()
和 notify()
来检查它们是否正常工作。
先看看 Concurrency in Swing。 Swing 使用单个线程来调度它的事件,如果您从 EDT 中执行任何长 运行 或阻塞操作(例如调用 wait
),那么它会冻结您的程序并且用户将不得不终止它。
您有两个基本选择。您可以使用模态对话框从用户那里收集信息,请参阅 How to Make Dialogs,这将在代码显示时阻止代码的执行,而不会阻止整个 EDT 或使用观察者模式,它可以生成通知用户已提供您所期望的信息。
老实说,模态对话框通常更容易,并且有助于防止意外的副作用
这个...
make();//This is a function contained in HumanTrainer that only calls wait(); With the proper try and catch
似乎是你问题的核心,但如果没有更多信息和你正在尝试做的事情的背景,就不可能真正建议你应该做什么,但是我建议你看看 model-view-controller 并将您的代码分成更合适的层