无法找出 ActionListener 的错误
Can't figure out error with ActionListener
以下是我的程序。目标是在用户输入数字并按下回车键后,将罗马数字转换为阿拉伯数字。
这是一项家庭作业,我们被迫使用 JTextAreas
代替 JTextFields
。
我的错误存在于行:enterRomanNumber.addActionListener(handler)
;
错误内容为:
"The method addActionListener(ArabicToRomanGUI.HandlerForTextArea) is
undefined for the type 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
要获得更好的答案,请参阅@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
s 从来都不是与文本组件一起使用的合适解决方案,如果你想在文本组件更改时得到通知,你可以使用 DocumentListener
,如果你想 change/filter 什么可以输入到文本组件中,你使用DocumentFilter
,如果你需要更改一个特殊的键,比如Enter,你应该使用一个键绑定[=22] =]
有关详细信息,请参阅 How to Use Key Bindings。
使用 KeyListener
可能遇到的一个问题是不知道文本组件何时处理击键,在您的情况下,这可能不是主要问题,但它可能会改变方式该程序适用于不同的平台。
相反,您可以覆盖 JTextArea
对 Enter 键(名为 insert-break
)的键绑定。这为您提供了实际更改击键行为的能力,或者,在您的情况下,管理您处理事件的方式。例如,这将替换文本区域的 Enter 键的 Action
,但保留 previous/default 行为...
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);
}
}
}
}
以下是我的程序。目标是在用户输入数字并按下回车键后,将罗马数字转换为阿拉伯数字。
这是一项家庭作业,我们被迫使用 JTextAreas
代替 JTextFields
。
我的错误存在于行:enterRomanNumber.addActionListener(handler)
;
错误内容为:
"The method addActionListener(ArabicToRomanGUI.HandlerForTextArea) is undefined for the type 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
要获得更好的答案,请参阅@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
s 从来都不是与文本组件一起使用的合适解决方案,如果你想在文本组件更改时得到通知,你可以使用 DocumentListener
,如果你想 change/filter 什么可以输入到文本组件中,你使用DocumentFilter
,如果你需要更改一个特殊的键,比如Enter,你应该使用一个键绑定[=22] =]
有关详细信息,请参阅 How to Use Key Bindings。
使用 KeyListener
可能遇到的一个问题是不知道文本组件何时处理击键,在您的情况下,这可能不是主要问题,但它可能会改变方式该程序适用于不同的平台。
相反,您可以覆盖 JTextArea
对 Enter 键(名为 insert-break
)的键绑定。这为您提供了实际更改击键行为的能力,或者,在您的情况下,管理您处理事件的方式。例如,这将替换文本区域的 Enter 键的 Action
,但保留 previous/default 行为...
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);
}
}
}
}