无法用ActionListener弄清楚错误

时间:2015-10-12 01:08:42

标签: java swing actionlistener jtextarea

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

这是一项家庭作业,我们被迫用JTextAreas代替JTextFields

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

  

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

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

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

2 个答案:

答案 0 :(得分:2)

要获得更好的答案,请参阅 @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
    }
}

答案 1 :(得分:2)

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

有关详细信息,请参阅How to Use Key Bindings

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

    }

}

现在,您甚至可以创建自己的JTextArea支持ActionPerformed ...

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

}