8

JTextArea フィールドにキーリスナーを追加しましたが、期待どおりに動作しません。

inputTextArea.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent k) {
  //If the return button is hit, only set to a new line if shift is also down.
  if(k.getKeyChar() == KeyEvent.VK_ENTER) {
   if(k.isShiftDown()) {
    inputTextArea.append(" \n");
   } else {
    //Send The Message...
    boolean cleanTextField = false;
    try {
     sendMessage(inputTextArea.getText());
     cleanTextField = true;
     msgScrollPane.setAutoscrolls(true);

     JScrollBar vbar = msgScrollPane.getVerticalScrollBar();
     if ((vbar.getValue() + vbar.getVisibleAmount()) == vbar.getMaximum()) {
      msgPane.setCaretPosition(msgDoc.getLength());
     }
    } catch (Exception ex) {
     ex.printStackTrace();
     cleanTextField = false;
    } finally {
     if(cleanTextField) {
      inputTextArea.setText("");
     }
    }
   }
  }
 }
});

これが欲しい: - 戻るボタンが押されてシフトが押された場合:新しい行を追加します。- 戻るボタンが押され、シフト ボタンが押されていない場合: 改行せずに送信します。

今では次のように動作します: - 戻るボタンを押してシフトを押した場合: 行は追加されません。何も起こりません。- 戻るボタンを押してシフトが押されていない場合: 送信されますが、もう一度入力を開始すると新しい行で始まります。

誰かが私がやりたいことをする方法を知っていますか?

編集:

シフトボタンが押されているかどうかを検出するために、他のコードを試しました:

                    if((k.getModifiersEx() == KeyEvent.SHIFT_DOWN_MASK) || 
                            (k.getModifiers() == KeyEvent.SHIFT_DOWN_MASK)) {

これもうまくいかない

4

3 に答える 3

22

InputMapのとActionMapを使用してJTextArea、キー ストロークをアクションにマッピング できます。

private static final String TEXT_SUBMIT = "text-submit";
private static final String INSERT_BREAK = "insert-break";
...
private void initialize() {
    InputMap input = inputTextArea.getInputMap();
    KeyStroke enter = KeyStroke.getKeyStroke("ENTER");
    KeyStroke shiftEnter = KeyStroke.getKeyStroke("shift ENTER");
    input.put(shiftEnter, INSERT_BREAK);  // input.get(enter)) = "insert-break"
    input.put(enter, TEXT_SUBMIT);

    ActionMap actions = inputTextArea.getActionMap();
    actions.put(TEXT_SUBMIT, new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            submitText();
        }
    });
}
...
private void submitText() {
    // TODO
}  

の元のアクションENTER- "insert-break" - が に使用されshift ENTERます。

于 2010-01-29T15:36:28.157 に答える
1

keyPressedではなくkeyTypedを使用してみてください。keyPressedは、shiftとenterのイベントを提供しますが、keyTypedは、修飾子を含む1つの結合されたイベントを提供します。

于 2010-01-29T13:43:13.063 に答える
0

イベントを受信するとすぐにアクションを実行する代わりに、SwingUtilities.invokeLater()を使用してアクションを投稿することにより、後でそれらをシーケンスします。コードは次のようになります。

if(k.isShiftDown()) {
   SwingUtilities.invokeLater(new Runnable() {
      public void run() {
         inputTextArea.append(" \n");
      }
   });
} else {
   SwingUtilities.invokeLater(new Runnable() {
      public void run() {
          //rest of the else body here
      }
   });

}

私の意見では、ここで見られる問題は、アプリケーション定義のアクションと内部アクションが適切に順序付けられておらず、テキストが変更される前に再描画が発生するためです。

于 2010-01-29T14:17:08.943 に答える