2010-01-29 63 views
7

我已经添加了一个keylistener到我的JTextArea字段,但它不像我预期的那样工作。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(""); 
    } 
    } 
    } 
    } 
} 
}); 

我想这一点: - 如果返回按钮被击中并移下来:添加一个新行。 - 如果返回按钮被击中并且换档按钮没有停止:不需要换行,但是提交。

现在它的行为如下: - 如果我按下了返回按钮并且换档停机:没有添加任何行。什么都没发生。 - 如果我点击返回按钮并且换档没有关闭:提交,但是如果我再次开始输入,则以新行开始。

有人知道如何去做我想要的吗?

编辑:

我尝试了一些其他的代码来检测,如果Shift键是向下:

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

这并不工作,以及

回答

21

您可以使用JTextAreaInputMapActionMap的击键映射到操作:

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 - “插断” - 用于shift ENTER

+0

谢谢!这是我需要的解决方案! – dododedodonl 2010-01-29 21:48:28

+0

+1为我在网上找到的最不起眼的答案+1。 – sethro 2012-11-16 20:54:43

1

尝试使用和的keyTyped没有在keyPressed。我相信keyPressed为你提供了一个换班和输入的事件,而keyTyped给你一个带修饰符的组合事件。

+0

这并不能解决我的问题。它们是相同的。 – dododedodonl 2010-01-29 13:56:27

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

} 

在我看来,这里看到的问题是由于应用程序定义的操作和内部操作不被正确排序,从而导致重新绘制文本已经被修改之前发生的事情。

+0

我试过这个。我保持相同的结果。 现在我看到JTextArea在JScrollPane中。这可以产生效果吗? – dododedodonl 2010-01-29 14:29:42