我是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());
    }

}

最佳答案

您在用户没有机会更改它之前就获取了味精字符串,原因是您以一种程序性的方式进行思考,而这不适用于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类以外的其他地方。一种方法是使用观察者设计模式,其中允许其他类“观察” TestSwing类,即“可观察”类。有几种方法可以完成此操作,包括:
  • 提供TestSwing一个名为addActionListener(ActionListener al)之类的公共void方法,并在方法主体中将传入的侦听器添加到“提交”按钮中。这样,外部类可以将ActionListener直接添加到该按钮并响应其事件。
  • 为TestSwing提供一种接受ChangeListener的方法,并通知它们是否已在ActionListener或
  • 中按下按钮
  • 通过为它提供PropertyChangeSupport变量以及公共添加和删除PropertyChangelistener方法,使TestSwing能够使用PropertyChangeListener。这类似于ChangeListener的想法,但是由于PCL可以侦听多个状态更改,所以它提供了更大的灵活性和功能,因此,这是我目前所希望的。例如:

  • 最新版本的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以获得更多信息。

    09-25 22:05