我的方法必须在用户按下按钮后返回。经过一些研究,我认为这会起作用:

方法本身:

public Aluno getAlunoFromUser() throws InterruptedException
{
    //Wait to be notified from ActionListener
    synchronized(this)
    {
        this.wait();
    }

    //return
    return null;
}


ActionListener:

Button.addActionListener(
            new ActionListener()
            {
                public void actionPerformed(ActionEvent event)
                {
                    this.notify();
                }
            });


但是程序冻结了。我想知道该如何解决。

最佳答案

由于您冻结了Swing事件线程,因此无法使用。一种解决方案是使用后台线程进行等待。另一个方法是让您的方法更改模型的状态,然后在按下按钮时再次更改模型的状态并更新视图,基于这些状态的GUI也会更改。我更喜欢后者,除非您的代码运行一个长时间运行的过程并且无论如何都将需要一个后台线程。

有关更详细的答案,您可能希望告诉我们有关您的问题的更多详细信息,包括您要具体实现的行为。



在评论中注明您的状态:


  好。 getAlunoFromUser()打开一个新窗口(可以认为是一个对话框),用户必须在某些JTextField中放置一些值。当按下Button时,我将使用这些值并使用它们创建一个Aluno对象,然后将此Aluno对象返回到主窗口,以便进行存储。 (在原始代码中,getAlunoFromUser具有更多方法,但我删除了它们以使其更直观地显示)


为此,为什么不简单地使用模式JDialog或JOptionPane(实际上只不过是预制的模式JDialog)呢?这样,您可以在用户按下创建Aluno按钮时关闭对话框,然后调用代码可以在基于对话框的代码中查询Aluno对象。



编辑2例如:

import java.awt.event.ActionEvent;
import javax.swing.*;

public class AlunoExample {
   private static void createAndShowGui() {
      MainPanel mainPanel = new MainPanel();

      JFrame frame = new JFrame("AlunoExample");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class MainPanel extends JPanel {
   private JTextField field = new JTextField(20);
   private DialogPanel dialogPanel = new DialogPanel();

   public MainPanel() {
      field.setEditable(false);
      field.setFocusable(false);

      add(new JLabel("Aluno:"));
      add(field);
      add(new JButton(new AbstractAction("Create Aluno") {

         @Override
         public void actionPerformed(ActionEvent e) {
            int result = JOptionPane.showConfirmDialog(MainPanel.this,
                  dialogPanel, "Dialog", JOptionPane.OK_CANCEL_OPTION,
                  JOptionPane.PLAIN_MESSAGE);
            if (result == JOptionPane.OK_OPTION) {
               String name = dialogPanel.getNameText();
               int value = dialogPanel.getValue();
               Aluno aluno = new Aluno(name, value);
               field.setText(aluno.toString());
            }

         }
      }));
   }
}

class DialogPanel extends JPanel {
   private JTextField nameField = new JTextField(5);
   private JSpinner spinner = new JSpinner(
         new SpinnerNumberModel(50, 0, 100, 1));

   public DialogPanel() {
      add(new JLabel("Name:"));
      add(nameField);
      add(new JLabel("Value:"));
      add(spinner);
   }

   public String getNameText() {
      return nameField.getText();
   }

   public int getValue() {
      return ((Integer) spinner.getValue()).intValue();
   }
}

class Aluno {
   private String name;
   private int value;

   public Aluno(String name, int value) {
      this.name = name;
      this.value = value;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public int getValue() {
      return value;
   }

   public void setValue(int value) {
      this.value = value;
   }

   @Override
   public String toString() {
      return "Aluno [name=" + name + ", value=" + value + "]";
   }

}

09-12 18:09