2013-10-24 2 views
2

Я разрабатываю приложение чата, и когда я нажимаю кнопку ввода при фокусировке JTextArea, я хочу, чтобы она перестала добавлять ненужную новую строку текста, поэтому, например, я смогу определить когда пользователь нажал кнопку ввода и не набрал ничего внутри JTextArea. Я использую KeyListener для средств обнаружения, когда пользователь выпустил ключ ввода, а затем отправил сообщение. Сначала я попытался заменить новую строку текста пустой строкой message.replaceAll ("[\ n]", ""), а также обрезать сообщение, однако оно не сработало. Есть ли что-то, что я делаю неправильно с моим подходом, или было бы любое другое решение, которое я мог бы приспособить?JTextArea нажатие enter добавляет ненужную новую строку

+0

Вместо этого используйте JTextField. –

ответ

4
  • Не используйте для этого JTextArea, но вместо этого используйте JTextField.
  • Затем вы можете легко прослушать ввод, нажав JTextField на ActionListener.
  • Большинство приложений чата Swing, которые я видел, используют для этого два текстовых компонента: JTextArea для отображения входящего текста и отправленного текста и JTextField, чтобы разрешить ввод текста отправляемого текста.
  • Обычно один находится прямо поверх другого с помощью BorderLayout.


  • Если вы абсолютно необходимо использовать JTextArea, то вы, вероятно, хотите использовать Key Binding, чтобы захватить клавишу ввода и борьбы с ним. Проверьте How to use Key Bindings Tutorial.


Например:

Пример Key Bindings Решение:

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class CaptureTextAreaEnter extends JPanel { 
    private static final int COLS = 30; 
    private static final int VIEW_ROWS = 12; 
    private static final int ENTER_ROWS = 4; 
    private JTextArea chatViewArea = new JTextArea(VIEW_ROWS, COLS); 
    private JTextArea chatEnterArea = new JTextArea(ENTER_ROWS, COLS); 

    public CaptureTextAreaEnter() { 
     setLayout(new BorderLayout()); 
     add(new JScrollPane(chatViewArea), BorderLayout.CENTER); 
     add(new JScrollPane(chatEnterArea), BorderLayout.SOUTH); 

     chatViewArea.setFocusable(false); 

     chatViewArea.setWrapStyleWord(true); 
     chatEnterArea.setWrapStyleWord(true); 
     chatViewArea.setLineWrap(true); 
     chatEnterArea.setLineWrap(true); 

     // start our set up of key bindings 

     // to get the correct InputMap 
     int condition = WHEN_FOCUSED; 
     // get our maps for binding from the chatEnterArea JTextArea 
     InputMap inputMap = chatEnterArea.getInputMap(condition); 
     ActionMap actionMap = chatEnterArea.getActionMap(); 

     // the key stroke we want to capture 
     KeyStroke enterStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); 

     // tell input map that we are handling the enter key 
     inputMap.put(enterStroke, enterStroke.toString()); 

     // tell action map just how we want to handle the enter key 
     actionMap.put(enterStroke.toString(), new AbstractAction() { 

     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      String text = chatEnterArea.getText(); 
      chatEnterArea.setText(""); 
      chatViewArea.append(text + "\n"); 

      // *** you will want to send text to your 
      // *** PrintStream to the chat server here 
     } 
     }); 
    } 

    private static void createAndShowGui() { 
     CaptureTextAreaEnter mainPanel = new CaptureTextAreaEnter(); 

     JFrame frame = new JFrame("CaptureTextAreaEnter"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
+0

Хорошо, спасибо за ваш ответ, однако я уже заметил, что JTextField не разрешает перенос строк, как бы вернуть эту функциональность в текстовое поле? – Adrian

+0

Мне бы очень хотелось, чтобы свиток был вертикальным + завернутым, иначе, если это невозможно, я мог бы найти решение для JTextArea – Adrian

+0

@Adrian: см. Edit для ответа. –

-1

Чтобы заменить стандартное поведение "введите" ключ, который вы должны использовать Input/Действие карты ваша текстовая область

См. метод registerKeyboardAction(ActionListener anAction,String aCommand,KeyStroke aKeyStroke,int aCondition). В качестве слушателя действий вы должны принять действие с вашей кнопки «отправить», команда - это строка, выбранная вами, клавиша-ход - KeyStroke.getKeyStroke(KeyEvent.VK_ENTER), а условие - JComponent.WHEN_FOCUSED.

+0

I не согласны с вашей рекомендацией, чтобы увидеть метод registerKeyboardAction. В [API JComponent] (http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html): «Этот метод устарел, используйте комбинацию getActionMap() и getInputMap() для аналогичного поведения. "« Лучше снова использовать стандартные привязки клавиш в соответствии с моим ответом. –

+0

Почему? Этот метод использует внутреннюю карту ввода/действия. –

+0

Метод, вероятно, на пути к устареванию. Что до этого, я понятия не имею. Вы захотите обсудить это с разработчиками и разработчиками Java и Swing. Это люди, которые помещают этот комментарий в API Java, а не я. –

Смежные вопросы