我认为您遇到的问题是如何根据输入到 GUI 中的内容更改按钮的功能。请记住,使用 GUI,用户可以随时以任何顺序与任何启用的 GUI 组件进行交互。关键是在按钮的 ActionListener 中检查 GUI 的状态,然后根据此 GUI 的状态更改此方法的行为。例如,如果您的 GUI 有三个 JTextField,field1、field2 和 sumField 以及一个 JButton addButton:
private JTextField field1 = new JTextField(5);
private JTextField field2 = new JTextField(5);
private JTextField sumField = new JTextField(5);
private JButton addButton = new JButton("Add");
并且您希望 addButton 将 field1 和 field2 中的数字相加并将结果放入 sumField 中,如果任一字段留空,您显然不想进行任何加法,因此您在 JButton 中对其进行测试动作监听器:
addButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String text1 = field1.getText().trim();
String text2 = field2.getText().trim();
if (text1.isEmpty() || text2.isEmpty()) {
// data not entered... so return the method and do nothing
return;
}
// if we've reached this point, the user has entered in text and so we handle it
这是整个事情:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class WaitForInput extends JPanel {
private JTextField field1 = new JTextField(5);
private JTextField field2 = new JTextField(5);
private JTextField sumField = new JTextField(5);
private JButton addButton = new JButton("Add");
public WaitForInput() {
addButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String text1 = field1.getText().trim();
String text2 = field2.getText().trim();
if (text1.isEmpty() || text2.isEmpty()) {
// data not entered... so return the method and do nothing
return;
}
try {
int number1 = Integer.parseInt(field1.getText());
int number2 = Integer.parseInt(field2.getText());
int sum = number1 + number2;
sumField.setText("" + sum);
} catch (NumberFormatException e1) {
// TODO: use JOptionPane to send error message
// clear the fields
field1.setText("");
field2.setText("");
}
}
});
add(field1);
add(new JLabel("+"));
add(field2);
add(new JLabel("="));
add(sumField);
add(addButton);
}
private static void createAndShowUI() {
JFrame frame = new JFrame("WaitForInput");
frame.getContentPane().add(new WaitForInput());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
编辑 1
否则,如果您绝对必须使用循环,那么是的,在 Runnable 中执行它并在后台线程中执行此操作。记住在循环内调用 Thread.sleep(...) 哪怕只是一小段时间,这样它就不会占用 CPU。例如
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class HaltingProblem extends JPanel {
private static final int PANEL_HEIGHT = 400;
private static final int PANEL_WIDTH = 600;
private static final long SLEEP_DELAY = 100;
private Color[] colors = {Color.red, Color.orange, Color.yellow,
Color.green, Color.blue, Color.cyan};
private boolean halt = false;
private JButton haltButton = new JButton("Halt");
private int colorIndex = 0;
public HaltingProblem() {
setBackground(colors[colorIndex]);
haltButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
halt = !halt; // toggle it!
}
});
add(haltButton);
new Thread(new Runnable() {
public void run() {
while (true) {
keepDoingThis();
}
}
}).start();
}
private void keepDoingThis() {
try {
Thread.sleep(SLEEP_DELAY);
} catch (InterruptedException e) {}
if (halt) {
return;
}
colorIndex++;
colorIndex %= colors.length;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
setBackground(colors[colorIndex]);
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PANEL_WIDTH, PANEL_HEIGHT);
}
private static void createAndShowUI() {
JFrame frame = new JFrame("HaltingProblem");
frame.getContentPane().add(new HaltingProblem());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}