2

ここで私のプログラムについて少し助けが必要です。ユーザーが「Enter」をクリックするのをメインスレッドで待機しているブロック機能があります。次に、ユーザーが 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;
}

そして、この関数は別のキーリスナーから呼び出されます:

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

OK、getCommand()イベントスレッドで呼び出さgetInput()れ、同じスレッドで呼び出さObject#wait()れ、イベントスレッドで呼び出されるため、イベントスレッドを結び付けてプログラムを効果的にフリーズしています。

これは必要ありません。イベント駆動型プログラミングの概念を使用してコーディングすると、はるかに簡単に修正できます。Swing GUI を呼び出すwait()必要はなく、自分の状況ではそれを呼び出す必要もありませんが、状態に基づいてプログラムが入力に応答する方法を変更したい場合。誘発しようとしている正確な動作について詳しく教えていただければ、より良い解決策を見つけるお手伝いができるでしょう。

編集
ダイアログが処理されるまでメインプログラムを停止する「ブロッキング」ウィンドウを表示するために、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 に答える