Reputation: 113
I'm trying to clear a JTextArea of 2 rows after pressing enter.
I set a KeyListener that triggers when the pressed key is enter; I use setText("")
and it clears it but my problem is that it goes to the next line and the text into the area remain made by 2 lines but I want only one line. I also tried to set the caret but it doesn't work, it places the caret at the beginning of the second line.
Here's the listener code, I think it's enough because this does all the work, in case you need more code let me know.
private class AscoltatoreKey implements KeyListener{
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){ //viene azionato quando viene premuto invio
String espressione = input.getText().trim(); //prendo il testo dall'area di input
valutatore.addEspressione(espressione); //aggiungo l'espressione al valutatore
numeroEspressioni++;
areaEquazioni.append(numeroEspressioni + ") " + espressione +"\n"); //scrivo l'espressione nella lista delle espressioni
try{
areaSoluzioni.append(numeroEspressioni + ") " + valutatore.risolvi() + "\n"); //scrivo l'espressione nella lista delle soluzioni
}catch (Exception exc){
areaSoluzioni.append(numeroEspressioni + ") " + "Espressione malformata!" + "\n");
}
input.setText(""); //svuoto l'area di input per prepararmi a ricevere la nuova espressione
input.setCaretPosition(0);
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
Upvotes: 0
Views: 985
Reputation: 285403
Never add a KeyListener to a JTextComponent such as a JTextArea as this can ruin the underlying function of the text component. Instead use what the Swing library uses when it wants to trap key strokes on a component: use Key Bindings.
For example if you bound the enter key stroke to an Action that cleared the JTextArea, your code would work. In the code below we get the InputMap for the JTextArea for when it has focus:
int condition = JComponent.WHEN_FOCUSED;
InputMap inputMap = textArea.getInputMap(condition);
and also get the JTextArea's ActionMap
ActionMap actionMap = textArea.getActionMap();
then we tie the two maps together, we bind them using the same String constant, here I use the .toString()
for my KeyStroke, but any unique (one not also used in the current InputMap) String will do. The action simply clears the JTextArea that caused the action to occur (the source of the Action):
KeyStroke enterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
inputMap.put(enterKey, enterKey.toString());
actionMap.put(enterKey.toString(), new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
JTextArea txtArea = (JTextArea) e.getSource();
txtArea.setText("");
}
});
My full MCVE example of the above in action:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class ClearTextAreaEg extends JPanel {
private JTextArea textArea = new JTextArea(10, 20);
public ClearTextAreaEg() {
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
int condition = JComponent.WHEN_FOCUSED;
InputMap inputMap = textArea.getInputMap(condition);
ActionMap actionMap = textArea.getActionMap();
KeyStroke enterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
inputMap.put(enterKey, enterKey.toString());
actionMap.put(enterKey.toString(), new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
JTextArea txtArea = (JTextArea) e.getSource();
txtArea.setText("");
}
});
setLayout(new BorderLayout());
add(new JScrollPane(textArea));
}
private static void createAndShowGui() {
ClearTextAreaEg mainPanel = new ClearTextAreaEg();
JFrame frame = new JFrame("ClearTextAreaEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
Upvotes: 1