[英]Swing GUI doesn't wait for user input
我是Swing的新手,我創建了一個帶有按鈕和文本字段的簡單GUI類。 這個類中有一個方法, String createAndShowUI()
,我希望它返回文本字段的文本。 我創建了另一個調用此方法的主類,並期望返回文本字段的文本。 但是我的問題是這個方法不等待用戶輸入文本字段並單擊按鈕; 一旦調用GUI就會返回。 我希望它等待按鈕點擊。
// TestSwing.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TestSwing extends JPanel implements ActionListener {
JButton submit;
JTextField t1;
String msg = "No Msg";
public TestSwing() {
submit = new JButton("Submit");
t1 = new JTextField(10);
submit.addActionListener(this);
setLayout(new FlowLayout());
add(t1);
add(submit);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == submit) {
msg = t1.getText();
}
}
public String createAndShowUI() {
JFrame f = new JFrame("Sample frame");
f.add(new TestSwing());
f.pack();
f.setVisible(true);
return msg;
}
}
//Main.java
public class Main {
public static void main(String[] arg) {
System.out.println(new TestSwing().createAndShowUI());
}
}
你在用戶有機會改變它之前得到你的msg字符串,原因是你正在以程序的方式思考,這對Swing不起作用。 事實上,你必須改變你的整個思維方式,以便編寫像Swing這樣的事件驅動編程。 因此,在創建類之后不會顯示msg,但僅在用戶啟動事件之后才會顯示 - 這里按下一個按鈕,提示ActionListener調用其actionPerformed方法。 例如(使用//!!
注釋突出顯示的更改):
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
// Significant changes noted with the //!! comment
public class TestSwing extends JPanel implements ActionListener {
JButton submit;
JTextField t1;
String msg = "No Msg";
public TestSwing() {
submit = new JButton("Submit");
t1 = new JTextField(10);
submit.addActionListener(this);
setLayout(new FlowLayout());
add(t1);
add(submit);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == submit) {
msg = t1.getText();
//!! Display msg only **after** the user has pressed enter.
System.out.println(msg);
}
}
public void createAndShowUI() { //!! Don't have method return anything
JFrame f = new JFrame("Sample frame");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //!! close GUI
f.add(new TestSwing());
f.pack();
f.setLocationRelativeTo(null); // center GUI
f.setVisible(true);
//!! return msg; // get rid of
}
public static void main(String[] arg) {
new TestSwing().createAndShowUI();
}
}
編輯2
您提到要將msg文本放入main方法,或者除了TestSwing類之外的其他位置。 一種方法是使用Observer設計模式,允許其他類“觀察”TestSwing類 - 這是“可觀察的”。 有幾種方法可以做到,包括:
addActionListener(ActionListener al)
的公共void方法,並在方法體中添加傳入提交按鈕的偵聽器。 這樣,外部類可以將ActionListener直接添加到該按鈕並響應其事件。 最新版本的TestSwing:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
@SuppressWarnings("serial")
public class TestSwing extends JPanel {
public static final String MESSAGE = "Message";
private JButton submit;
private JTextField mainTextField;
private String message = "No Msg";
private PropertyChangeSupport propSupport = new PropertyChangeSupport(this);
public TestSwing() {
submit = new JButton("Submit");
mainTextField = new JTextField(10);
submit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
submitActionPerformed(e);
}
});
setLayout(new FlowLayout());
add(mainTextField);
add(submit);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propSupport.removePropertyChangeListener(listener);
}
public void setMessage(String newValue) {
String oldValue = message;
this.message = newValue;
PropertyChangeEvent event = new PropertyChangeEvent(this, MESSAGE, oldValue, newValue);
propSupport.firePropertyChange(event);
}
private void submitActionPerformed(ActionEvent e) {
if (e.getSource() == submit) {
setMessage(mainTextField.getText());
}
}
public static void createAndShowUI() {
TestSwing testSwing = new TestSwing();
testSwing.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(TestSwing.MESSAGE)) {
System.out.println("message = " + evt.getNewValue());
}
}
});
JFrame f = new JFrame("Sample frame");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(testSwing);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] arg) {
createAndShowUI();
}
}
請閱讀觀察器設計模式以獲取更多信息。
Swing是事件驅動的。 不管你想要使用 msg
,應稱為被稱為動作監聽的結果 。
或者,您可以使用JOptionPane
一個現成解決方案
String userInput = JOptionPane.showInputDialog("Please enter ...");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.