无法用ActionListener弄清楚错误

以下是我的计划。 目标是在用户键入数字并按下回车键后,将罗马数字转换为阿拉伯数字。

这是一项家庭作业,我们不得不使用JTextAreas代替JTextFields

我的错误存在于该行: enterRomanNumber.addActionListener(handler) ; 错误如下:

“未定义类型JTextArea的方法addActionListener(ArabicToRomanGUI.HandlerForTextArea)”

我似乎无法弄清楚为什么我会收到此错误或如何纠正错误,有人可以提出建议。

 import java.awt.FlowLayout; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.ActionEvent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTextField; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextArea; public class ArabicToRomanGUI extends JFrame { private static final long serialVersionUID = 1L; private JTextArea enterRomanNumber = new JTextArea(); JLabel label = new JLabel(); JPanel panel = new JPanel(); JFrame frame = new JFrame(); //TestArea contructor adds jtextArea to jframe public ArabicToRomanGUI() { super("Convert a Roman Numeral"); setLayout(new FlowLayout()); //Text field to enter a roman numeral enterRomanNumber = new JTextArea(1,25); enterRomanNumber.setText("Delete this text and Enter a Roman Numerial Here!"); //enterRomanNumber.setAlignmentX(0); //enterRomanNumber.setAlignmentY(0); add(enterRomanNumber); HandlerForTextArea handler = new HandlerForTextArea(); enterRomanNumber.addActionListener(handler); } private class HandlerForTextArea implements ActionListener { //used to process textArea events @Override public void actionPerformed(ActionEvent e) { String userInput = ""; userInput = enterRomanNumber.getText(); userInput = userInput.toUpperCase(); ConversionLogic.ConvertFromRomanToArabic(userInput); //converts user string of Roman numerals to an int in arabic String arabicNumberAsString = ConversionLogic.getConvertedRomanNumeral(); enterRomanNumber.setText(arabicNumberAsString); //user pressed enter in JTextField enterNumberField if(e.getSource() == enterRomanNumber) { //enterRomanNumber.setText(arabicNumberAsString); if (ConversionLogic.getCheckFail() == true) { JOptionPane.showMessageDialog(frame, "The Roman Numeral entered is Invalid", "Error", JOptionPane.ERROR_MESSAGE); } else { JOptionPane.showMessageDialog(frame, "The arabic equivalent is " + arabicNumberAsString + "." , "Conversion Successful", JOptionPane.PLAIN_MESSAGE); } } } } }//end inner class TextAreaHandler 

有关更好的答案,请参阅 @MadProgrammer 的答案。

我的解决方案

JTextArea没有ActionListener。

所以只需使用KeyListener

 HandlerForTextArea handler = new HandlerForTextArea(); enterRomanNumber.addKeyListener(handler); 

实现KeyListener

 private class HandlerForTextArea implements KeyListener { @Override public void keyPressed(KeyEvent arg0) { // TODO Auto-generated method stub } @Override public void keyReleased(KeyEvent arg0) { // TODO Auto-generated method stub if (arg0.getKeyCode() == VK_ENTER){ // TODO Your bussiness } } @Override public void keyTyped(KeyEvent arg0) { // TODO Auto-generated method stub } } 

KeyListener是永远不适合用于文本组件的解决方案,如果您希望在文本组件发生更改时收到通知,则使用DocumentListener ,如果要更改/过滤可以输入文本组件的内容,则使用DocumentFilter ,如果您需要更改特殊键,例如Enter ,则应使用键绑定

有关更多详细信息,请参见如何使用键绑定 。

KeyListener可能遇到的一个问题是不知道文本组件何时处理了键击,在您的情况下,它可能不是一个主要问题,但它可能会改变程序在不同平台上的工作方式。

相反,您可以为Enter键覆盖JTextArea的键绑定(名为insert-break )。 这使您能够实际更改击键的行为,或者在您的情况下,管理您处理事件的方式。 例如,这将替换文本区域的Enter键的Action ,但保留以前/默认的行为…

 import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class KeyBindingsTest { public static void main(String[] args) { new KeyBindingsTest(); } public KeyBindingsTest() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private JTextArea ta; public TestPane() { ta = new JTextArea(10, 20); ActionMap am = ta.getActionMap(); Action proxy = am.get("insert-break"); am.put("insert-break", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { // You can process the event through the original action BEFORE // you do your own processing //proxy.actionPerformed(e); System.out.println("You pressed the enter key, you can have candy"); // Or you can process the event through the original action AFTER // you do your own processing, you have now gained control proxy.actionPerformed(e); } }); setLayout(new BorderLayout()); add(ta); } } } 

现在,您甚至可以创建自己支持ActionPerformedJTextArea

 public class ActionableTextArea extends JTextArea { private String actionCommand; public ActionableTextArea() { installKeyBindings(); } public ActionableTextArea(String text) { super(text); installKeyBindings(); } public ActionableTextArea(int rows, int columns) { super(rows, columns); installKeyBindings(); } public ActionableTextArea(String text, int rows, int columns) { super(text, rows, columns); installKeyBindings(); } public ActionableTextArea(Document doc) { super(doc); installKeyBindings(); } public ActionableTextArea(Document doc, String text, int rows, int columns) { super(doc, text, rows, columns); installKeyBindings(); } protected void installKeyBindings() { ActionMap am = getActionMap(); Action proxy = am.get("insert-break"); am.put("insert-break", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { // You can process the event through the original action BEFORE // you do your own processing //proxy.actionPerformed(e); fireActionPerformed(); // Or you can process the event through the original action AFTER // you do your own processing, you have now gained control proxy.actionPerformed(e); } }); } public void addActionListener(ActionListener listener) { listenerList.add(ActionListener.class, listener); } public void removeActionListener(ActionListener listener) { listenerList.remove(ActionListener.class, listener); } public void setActionCommand(String actionCommand) { this.actionCommand = actionCommand; } public String getActionCommand() { return actionCommand; } protected void fireActionPerformed() { ActionListener[] listeners = listenerList.getListeners(ActionListener.class); if (listeners.length > 0) { ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, getActionCommand()); for (ActionListener listener : listeners) { listener.actionPerformed(evt); } } } }