2

我需要一些关于我的程序的帮助。我的主线程中有一个阻塞功能等待用户单击“Enter”。然后,当用户按下回车键时,应该触发 keypressed 事件,这将解除阻塞功能。但是,当程序遇到阻塞功能时,它只是冻结并且不注册按键事件。

所以,我的问题是,一个事件是否是可运行的,只要用户点击进入,它就会被添加到线程中?如果是这样,我的代码应该可以工作,对吧?如果不是这种情况,并且每个事件都不是一个单独的线程,那么任何人都可以告诉我如何在这里解决我的问题吗?我的阻塞功能:

public String getInput() {
    synchronized(waitObject) {
        try {
            System.out.println("waiting");
            waitObject.wait(); // throws exception, cba to add it here
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    return(myString);
}

我的按键监听器代码:

public void keyPressed(KeyEvent e) {
    System.out.println("key pressed");
    char c = e.getKeyChar();
    if (c == e.VK_ENTER) {
        System.out.println("Enter pressed");
        synchronized(waitObject) {
            waitObject.notifyAll();
        }
    }
}

以及获取输入的函数:

private String getCommand() {
    System.out.println("getting command");
    CommandField command = new CommandField((JFrame)(this));
    command.setPreferredSize(new Dimension(getWidth(), 30));
    m_panel.add(command, BorderLayout.NORTH);
    validate();
    command.requestFocus();
    System.out.println(command.getInput());

    return null;
}

这个函数是从另一个 keylistener 调用的:

public class Listener implements KeyListener {
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_F2) {
            System.out.println(getCommand());
        }

    }
    public void keyReleased(KeyEvent e) {

    }
    public void keyTyped(KeyEvent e) {

    }
}
4

2 回答 2

2

好的,getCommand()在事件线程上调用,然后getInput()在同一个线程上调用,然后Object#wait()在事件线程上调用,所以是的,你正在绑定事件线程并有效地冻结你的程序。

这些都不是必需的,如果您使用事件驱动编程的概念进行编码,则可以进行更简单的修复。您不想wait()在 Swing GUI 中调用并且在您的情况下不需要调用它,而是希望更改程序根据其状态响应输入的方式。如果您告诉我们更多关于您试图引起的确切行为的信息,我们可能会帮助您找到更好的解决方案。

编辑
考虑使用 JOptionPane 或模态 JDialog 来显示“阻塞”窗口,该窗口会停止主程序,直到对话框被处理。

于 2012-08-08T14:12:44.360 回答
2

从 开始ImageApp,我在构造函数中添加了以下键绑定。按键时会show()弹出菜单Enter。您可以更改任意位置以适合您的使用。

this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "showPopup");
this.getActionMap().put("showPopup", new AbstractAction("showPopup") {

    @Override
    public void actionPerformed(ActionEvent e) {
        popup.show(ImageApp.this, 42, 42);
    }
});

附录:调出模态输入对话框,如下所示:

this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "dialog");
this.getActionMap().put("dialog", new AbstractAction("dialog") {

    @Override
    public void actionPerformed(ActionEvent e) {
        String value = JOptionPane.showInputDialog("What?");
        System.out.println(value);
    }
});
于 2012-08-08T21:06:42.173 回答