如何通过按回车键清除 JTextArea 并保持在同一行

How to clear a JTextArea by pressing enter and remain on the same line

我正在尝试在按回车键后清除 2 行的 JTextArea。 我设置了一个 KeyListener,它在输入按下的键时触发;我使用 setText("") 并清除它,但我的问题是它转到下一行并且该区域中的文本仍然由 2 行组成,但我只想要一行。我也尝试设置插入符号,但它不起作用,它将插入符号放在第二行的开头。 这是侦听器代码,我认为这已经足够了,因为它完成了所有工作,如果您需要更多代码,请告诉我。

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

切勿将 KeyListener 添加到 JTextComponent(例如 JTextArea),因为这会破坏文本组件的基础功能。而是使用 Swing 库在想要捕获组件上的击键时使用的内容:使用 Key Bindings.

例如,如果您将回车键绑定到清除 JTextArea 的操作,您的代码就可以工作。在下面的代码中,我们获得了 JTextArea 的 InputMap,因为它具有焦点:

int condition = JComponent.WHEN_FOCUSED;
InputMap inputMap = textArea.getInputMap(condition);

同时获取 JTextArea 的 ActionMap

ActionMap actionMap = textArea.getActionMap();

然后我们将两个映射绑定在一起,我们使用相同的字符串常量绑定它们,这里我使用 .toString() 作为我的 KeyStroke,但是任何唯一的(当前 InputMap 中未使用的)字符串将做。该操作只是清除导致操作发生的 JTextArea(操作的来源):

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

我上面的完整 MCVE 示例:

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