按下方法等待按钮

时间:2013-06-15 21:57:16

标签: java swing concurrency wait

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

方法本身:

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

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

1 个答案:

答案 0 :(得分: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 + "]";
   }

}