我是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());
}
}
答案 0 :(得分:6)
你在用户有机会改变之前得到了你的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();
}
}
请阅读Observer Design Pattern了解详情。
答案 1 :(得分:4)
Swing是事件驱动的。您想要使用 msg
的任何地方都应该被调用为被调用的动作侦听器的结果。
或者,您可以使用JOptionPane
中的一个现成解决方案,例如
String userInput = JOptionPane.showInputDialog("Please enter ...");