2

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

方法本身:

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

    //return
    return null;
}

动作监听器:

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

但该程序正在冻结。我想知道如何解决这个问题。

4

1 回答 1

5

当您冻结 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 + "]";
   }

}
于 2013-06-15T21:59:05.570 回答