JFrame 在 Thread.sleep(int) 期间处于非活动状态
JFrame is inactive during Thread.sleep(int)
我有一些 Java 类 可以模拟一台旧计算机。其中之一是 JFrame,名为 GUI,带有 JTabbedPane。计算过程需要一些时间,所以我包含了 Thread.sleep(int)。问题是当计算功能工作时,无法选择我的 GUI 中 JTabbedPane 的选项卡。
这是一些代码:
import java.util.*;
import java.awt.*;
public class Engine
{
private GUI gui;
private Store store;
private Mill mill;
public static void main(String[] args) {
Engine e = new Engine();
}
public Engine() {
gui = new GUI(this);
mill = new Mill(this);
store = new Store(this);
store.draw(); // affects GUI elements
}
public void read(String operations) {
clearStatus(); // affects GUI elements
try {
String[] op = operations.split("\n");
for (int i = 0; i < op.length; i++) {
setStatus(op[i]); // affects GUI elements
if (op[i].length() == 0) { // empty line
continue;
}
int number = Integer.parseInt(op[i]);
store.addNumber(number);
Thread.sleep(200);
}
store.draw(); // affects GUI elements
} catch(Exception e) {
System.out.println(e);
}
}
public void clearStatus() {
gui.statusLabel.setText("");
}
public void setStatus(String msg) {
gui.statusLabel.setText(msg);
}
}
这是我的 GUI(这是一个简短版本):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI extends JFrame
{
private Engine engine;
// Swing
JTabbedPane tabs;
JPanel mill;
JTextArea input, store;
JLabel statusLabel;
JButton sendInput;
public GUI(Engine e)
{
engine = e;
input = new JTextArea();
sendInput = new JButton("Run");
sendInput.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
pressInputButton(evt);
}
});
JPanel inputPanel = new JPanel();
inputPanel.add(input, BorderLayout.CENTER);
inputPanel.add(sendInput, BorderLayout.SOUTH);
mill = new JPanel();
statusLabel = new JLabel();
mill.add(statusLabel);
store = new JTextArea();
JTextPane helpPane = new JTextPane();
helpPane.setText("[...]");
tabs = new JTabbedPane();
tabs.addTab("Input", inputPanel);
tabs.addTab("Mill", mill);
tabs.addTab("Store", new JScrollPane(store));
tabs.addTab("Help", helpPanel);
add(tabs, BorderLayout.CENTER);
setVisible(true);
pack();
}
public void pressInputButton(ActionEvent evt) {
engine.read(input.getText());
}
}
@sorifiend 的意思是,从 事件处理程序 调用 sleep()
将 "lock up" 您的应用程序的 事件调度线程 .在事件处理函数 returns.
之前,应用程序不会响应任何其他用户输入
如果您希望应用程序在计算器 "working" 时响应,那么您需要做的是:
- 记录计算器状态为"working"
- 在计算器处于 "working" 时禁用您不希望用户按下的任何按钮,--或者-- 更改这些按钮的处理程序以执行不同的操作(模拟干扰机器?)如果它们在 "working" 状态下被按下。
- 在不久的将来提交一个定时器事件(无论计算需要多长时间。)
- 在计时器事件的处理程序中,显示计算结果,重新启用禁用的按钮,并将状态从 "working" 更改回 "idle"(或其他)。
我有一些 Java 类 可以模拟一台旧计算机。其中之一是 JFrame,名为 GUI,带有 JTabbedPane。计算过程需要一些时间,所以我包含了 Thread.sleep(int)。问题是当计算功能工作时,无法选择我的 GUI 中 JTabbedPane 的选项卡。
这是一些代码:
import java.util.*;
import java.awt.*;
public class Engine
{
private GUI gui;
private Store store;
private Mill mill;
public static void main(String[] args) {
Engine e = new Engine();
}
public Engine() {
gui = new GUI(this);
mill = new Mill(this);
store = new Store(this);
store.draw(); // affects GUI elements
}
public void read(String operations) {
clearStatus(); // affects GUI elements
try {
String[] op = operations.split("\n");
for (int i = 0; i < op.length; i++) {
setStatus(op[i]); // affects GUI elements
if (op[i].length() == 0) { // empty line
continue;
}
int number = Integer.parseInt(op[i]);
store.addNumber(number);
Thread.sleep(200);
}
store.draw(); // affects GUI elements
} catch(Exception e) {
System.out.println(e);
}
}
public void clearStatus() {
gui.statusLabel.setText("");
}
public void setStatus(String msg) {
gui.statusLabel.setText(msg);
}
}
这是我的 GUI(这是一个简短版本):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI extends JFrame
{
private Engine engine;
// Swing
JTabbedPane tabs;
JPanel mill;
JTextArea input, store;
JLabel statusLabel;
JButton sendInput;
public GUI(Engine e)
{
engine = e;
input = new JTextArea();
sendInput = new JButton("Run");
sendInput.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
pressInputButton(evt);
}
});
JPanel inputPanel = new JPanel();
inputPanel.add(input, BorderLayout.CENTER);
inputPanel.add(sendInput, BorderLayout.SOUTH);
mill = new JPanel();
statusLabel = new JLabel();
mill.add(statusLabel);
store = new JTextArea();
JTextPane helpPane = new JTextPane();
helpPane.setText("[...]");
tabs = new JTabbedPane();
tabs.addTab("Input", inputPanel);
tabs.addTab("Mill", mill);
tabs.addTab("Store", new JScrollPane(store));
tabs.addTab("Help", helpPanel);
add(tabs, BorderLayout.CENTER);
setVisible(true);
pack();
}
public void pressInputButton(ActionEvent evt) {
engine.read(input.getText());
}
}
@sorifiend 的意思是,从 事件处理程序 调用 sleep()
将 "lock up" 您的应用程序的 事件调度线程 .在事件处理函数 returns.
如果您希望应用程序在计算器 "working" 时响应,那么您需要做的是:
- 记录计算器状态为"working"
- 在计算器处于 "working" 时禁用您不希望用户按下的任何按钮,--或者-- 更改这些按钮的处理程序以执行不同的操作(模拟干扰机器?)如果它们在 "working" 状态下被按下。
- 在不久的将来提交一个定时器事件(无论计算需要多长时间。)
- 在计时器事件的处理程序中,显示计算结果,重新启用禁用的按钮,并将状态从 "working" 更改回 "idle"(或其他)。