2010-01-29 2 views
7

Я добавил ключевое слово в поле JTextArea, но он не ведет себя так, как я ожидал.JTextArea new line on shift + enter

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

Я хочу это: - Если кнопка возврата подбит и сдвиг вниз: добавить новую строку. - Если кнопка возврата нажата, а кнопка переключения не опускается: нет новой строки, но отправьте.

Теперь он ведет себя следующим образом: - Если я нажму кнопку возврата и сдвиг вниз: ни одна строка не добавлена. Ничего не произошло. - Если я нажму кнопку возврата, а смена не будет: отправлена, но если я начну печатать снова, она начнется на новой строке.

Кто-нибудь знает, как делать то, что я хочу?

EDIT:

Я попробовал некоторые другие код для обнаружения, если кнопка переключения вниз:

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

Это не работает, а

ответ

21

Вы можете использовать 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 - «вставить-брейк» - используется для shift ENTER.

+0

Спасибо! Это необходимое мне решение! – dododedodonl

+0

+1 за наименее хакерский ответ, который я нашел в Интернете. – sethro

1

Попробуйте использовать keyTyped и не Keypressed. I beleive keyPressed дает вам событие для смены и для ввода, тогда как keyTyped дает вам одно комбинированное событие с модификатором.

+0

Это не решает проблемы. Они вызывают то же самое. – dododedodonl

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