从GUI代码外部请求用户输入,在这种情况下,我是否需要事件或动作来与GUI通信?

时间:2012-01-18 20:15:30

标签: java swing events actionlistener

我正在编写2D多边形和物理编辑器,其中一项功能是设置关节的旋转限制。

要使用此功能,用户点击并拖动需要接收限制的关节点之间的一条线。

确定选择是否有效的逻辑发生在GUI代码之外。

如果找到了一个选择,我想弹出一个JOptionPane.showInputDialog用户可以输入限制。

事情是,如果我直接这样做,程序会变得没有反应,我认为这是因为线程化。

我有一种方法来定义GUI可以使用的事件监听器,它不需要实际的GUI组件吗?

我想发送一个事件,该事件还包含对该组件的目标对象的引用,然后告诉它已经进行了有效的选择并且需要用户输入,然后通过目标的方法将值发回对象

我对Swing非常缺乏经验。 我的预感是我可能能够在主窗口中添加ActionListener,但我不知道如何具体地解决该听众的问题。 在中,我如何定义仅由特定侦听器处理的Action? 如果那实际上是可能的,那么。

到目前为止,我只使用了监听器让GUI与逻辑对话,而不是相反......

编辑: 程序对我所说的动作没有反应  result = JOptionPane.showInputDialog(this,"Enter Limit.");

那就是打破它。甚至无法在文本框中输入任何内容,也不能将其关闭等等。

我认为这是因为它产生了一个暂停某个线程的模态对话框,并且从非GUI代码的内容中调用它并不是我应该做的事情,但是我太缺乏经验而不知道另一种方式.. 。

EDIT2: 我应该补充说,如果我生成它,我可以使用JOptionPane.showInputDialog而不会出现任何问题,例如,在单击按钮或选择弹出菜单选项之后。 事实上,这就是我重命名我正在使用的项目的方式。

但是我假设在那时,对话框是在GUI线程或者事件调度程序队列事件中产生的。

但问题在于,这需要触发该事件的可见的交互式GUI组件。 然而,我想要的是某种组件,它会像点击按钮或上下文菜单一样产生JOptionPane.showInputDialog,但不需要与用户交互,而是由代码交互。 我想我可以使用隐形按钮并模拟鼠标点击事件,但这非常hacky ......

另外,我尝试生成Threads和Runnables,它们产生了JOptionPane.showInputDialog,但这也没有帮助。 除非我从GUI源生成JOptionPane,否则一切都会停止,对话框将无效。

3 个答案:

答案 0 :(得分:2)

发布者将拥有一个公共添加/删除侦听器,订阅者将在其中添加或通过其他频道添加到发布者的EventListenerList。

您可以创建自己的侦听器接口,扩展EventListener和一个用于拍摄事件的函数。以下是一个例子:

import java.util.EventListener;

public interface MyEventListener extends EventListener {
   public void myEventOccurred(MyEvent event);
}

然后,您可以在上面的示例中创建自定义事件类“MyEvent”,如:

import java.util.EventObject;

public class MyEvent extends EventObject {
  // customer fields and methods here
  public MyEvent(Object source) //more possible args here {
    super(source);
    //other things here to do what you want
  }
}

现在,您可以让订阅者实现MyEventListener并覆盖myEventOccurred(..)方法。

答案 1 :(得分:2)

另一种方法是使用SwingWorker类在不阻塞GUI调度线程的情况下执行确定专用线程中的选择的逻辑,并使用其回调方法执行GUI操作(打开输入对话框)。

请参阅:http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html

(这个页面对概念的解释比我写的要好。)

答案 2 :(得分:1)

您的后台线程应该可以使用invokeAndWait()生成对话框:

final double[] result = new double[1];
SwingUtilities.invokeAndWait(new Runnable() {
   public void run() {
      try {
         result[0] = Double.parseDouble(
            JOptionPane.showInputDialog("Enter value:"));
      } catch(NumberFormatException e) { 
         result[0] = -1;
      }
   }
}
// ... do something with result[0]

在这里,我使result成为一个数组,以便它可以是最终的(匿名类可访问)并且也是可变的。