I am coding one applet that will show the number of mouse clicks on a button, and another that will show the coordinates of a mouse click and change the background color to a random color.
In both cases, I encountered the "is not abstract and does not override abstract method" error in BlueJ, and I need help understanding what I am doing wrong. I'm very new to this, so any tips/proofreadings are welcome as well :)
here's the first applet:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Option1 extends Frame implements ActionListener {
public void main (String[] args) {
int click = 0;
JFrame base = new JFrame ("Button Click Counter");
base.getContentPane().setLayout(null);
base.setSize(500,500);
base.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Click Me!");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed (ActionEvent e) {
click++; }
});
JTextField count = new JTextField(click);
this.add(button);
this.add(count);
}}
and the coordinates one:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Random;
public class Option2 extends Frame implements MouseListener {
double x;
double y;
public void init() {
addMouseListener(this);
JFrame base = new JFrame("Mouse Coordinates");
base.getContentPane().setLayout(null);
base.setSize(500,500);
base.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextField answer = new JTextField(x + "," + y);
}
public void mouseClicked( MouseEvent e ) {
x = e.getX();
y = e.getY();
this.setBackground(new Color((int)(Math.random() * 0x1000000)));
}}
Thanks in advance!
Option1 declares to implement the ActionListener interface:
public class Option1 extends Frame implements ActionListener {
If a class does so, it must be either abstract (which Option1 is not) or it must implement the methods declared in the interface. When you take a look at the API for ActionListener, you'll find one method there:
void actionPerformed(ActionEvent e)
You need to implement this method in Option1, e.g.
#Override
public void actionPerformed(ActionEvent e) {
click++;
}
and then register Option1 as ActionListener:
button.addActionListener(this);
The thing you tried is to implement the ClickListener in an anonymous inner class, which is also ok, but in this case Option1 must not implement ActionListener.
Your main method in Option1 is not declared properly, a main method usually is
public static void main(String[] args)
But the initialization you do in the main method should be done in the constructor or (as with Option2) in a separate method
public class Option1 extends Frame implements ActionListener {
private int click = 0;
public Option1() {
JFrame base = new JFrame("Button Click Counter");
base.getContentPane().setLayout(null);
base.setSize(500, 500);
base.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Click Me!");
button.addActionListener(this);
JTextField count = new JTextField(click);
this.add(button);
this.add(count);
}
#Override
public void actionPerformed(ActionEvent e) {
click++;
}
}
The problem with Option2 is that you only implement the method mouseClicked from the interface MouseListener. There are a couple others that need to be implemented:
void mouseEntered(MouseEvent e)
void mouseExited(MouseEvent e)
void mousePressed(MouseEvent e)
void mouseReleased(MouseEvent e)
Even if you do not want to handle these events, you need to have the empty methods.
A final tip: I don't know your IDE, but many IDEs (Eclipse, Netbeans, IntelliJ) have an option to generate the required methods for an interface for you, which saves a lot of typing ;)
you're implementing an interface...
at least you pronouce you do it when you write
public class Option1 extends Frame implements ActionListener
but you don't keep your contract! if you say you implement ActionListener, then you guaranteed that you have this method
public void actionPerformed(ActionEvent e) {
}
but your code lacks this method - and that's your error message...
Related
I am trying to develop a main menu for a game in java, but my JMenuItems wouldn't listen to the KeyEvents and I don't understand why. Note that I don't want to set any JMenuBars nor JMenus as this program is intended to be a game used with screen readers, so I don't want accessibility roles to be read. Furthermore, adding a menu complicates the access to the elements with the keyboard and I want the focus to start in the first option.
This is my code:
import java.util.Set;
import java.util.HashSet;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
public class Screen {
public Screen() {
// Accept arrow keys as focus traversal keys
Set<AWTKeyStroke> set = new HashSet<AWTKeyStroke>(KeyboardFocusManager.getCurrentKeyboardFocusManager().getDefaultFocusTrave rsalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
set.add(KeyStroke.getKeyStroke("DOWN"));
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,set);
set = new HashSet<AWTKeyStroke>(KeyboardFocusManager.getCurrentKeyboardFocusManager().getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
set.add(KeyStroke.getKeyStroke("UP"));
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,set);
// definition of Menu Items
JMenuItem mi=new JMenuItem("play");
JMenuItem mi2=new JMenuItem("exit");
mi.setFocusable(true);
mi2.setFocusable(true);
// Attempt with MenuKeyListener
mi.addMenuKeyListener(new MenuKeyListener() {
public void menuKeyReleased(MenuKeyEvent e) {
System.out.println("Play released");
}
public void menuKeyTyped(MenuKeyEvent e) {}
public void menuKeyPressed(MenuKeyEvent e) {}
});
// Attempt with ActionListener
mi2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
mi.setVisible(true);
mi2.setVisible(true);
JPanel mp = new JPanel();
JFrame mf = new JFrame("Game");
mf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mp.add(mi);
mp.add(mi2);
mf.add(mp);
mf.setVisible(true);
}
public static void main(String args[]) {
new Screen();
}
}
I've tried with both ActionListener and MenuKeyListener, with and without the JPanel, changing visibilities... I also tried to use KeyEventDispatcher but I didn't know how to send a KeyEvent to the component that returns KeyboardFocusManager.getFocusOwner().
Please help.
There's a lot to help with in this case. For starters,
public static void main(String args[]) {
new Screen();
}
is wrong. It is not appropriate to perform any operation that alters the Swing layout or presentation on the main thread. Instead do
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Screen();
}
});
}
if you decide that you want to put swing calls into an object's constructor in this way.
Ideally your Screen would be a JFrame but one that is customized to meet your needs. That means you might want to create a new class GamePanel that extends JPanel
public class Screen extends JFrame {
public Screen() {
super("Game"); // to remind us that the JFrame is created
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(new GamePanel());
pack();
setVisible(true);
}
}
public class GamePanel extends JPanel {
public GamePanel() {
super();
}
}
Now, if you want that panel to listen to keys, you need to add a KeyListener interface. This only gives it the capability to listen, it doesn't make it listen.
public class GamePanel extends JPanel implements KeyListener {
...
public void keyTyped(KeyEvent e) {
System.out.println("KEY TYPED: " + e);
}
public void keyPressed(KeyEvent e) {
System.out.println("KEY PRESSED: " + e);
}
public void keyReleased(KeyEvent e) {
System.out.println("KEY RELEASED: " + e);
}
}
Now you can add your key listener to the Screen or to the GamePanel (it will listen to itself). Whenever the focus is in one of these items, and a key is pressed, the even will be routed to the listener.
public class GamePanel extends JPanel implements KeyListener {
public GamePanel() {
super();
addKeyListener(this);
}
...
}
Ideally, you might want to not combine your key listener with the panel itself, but make it a "Command Processor" of some sort. In that case, remove the KeyListener code from the JPanel and make a completely new CommmandHandler object that implements KeyListener.
As far as Actions go, they are convenience items that pre-configure menu entries with lots of things (icons, acceleration keys, text, callback functions). If you are avoiding menus for whatever reason, you will find that much of their utility in setting up menus is misdirected for your purpose. Effectively, they are configuration entries that configure the MenuItem objects to handle a key (through the KeyListener interface and then dispatch a swing Event object. This provide "better than key" tracking of items through an application as it converts a keyboard letter k to a class ActionEvent which is passed to the registered "action handler" typically a subclass of AbstractAction.
An example of an Action would be
public class MoveLeft extends AbstractAction { // which extends ActionListener
private final GameState gameState;
public MoveLeft(GameState gameState) {
super("move left", new ImageIcon(MoveLeft.class.getResource("/images/moveleft.png"));
putValue("SHORT_DESCRIPTION", "left");
putValue("MNEMONIC_KEY", "l");
this.gameState = gameState;
}
public void actionPerformed(ActionEvent e) {
gamestate.getSelected().moveLeft();
}
}
Assuming you wanted this convenience, you would initialize your CommandHandler with Actions, maybe like so:
public CommandHandler implements KeyListener {
private int actionId;
...
public void addAction(Action action) {
handlers.put(action.getValue("MNEMONIC_KEY")., action);
}
public void keyTyped(KeyEvent e) {
Action action = handlers.get(String.valueOf(e.getKeyChar());
ActionEvent event = new ActionEvent(this, id, action.getValue("NAME"));
action.actionPerformed( event );
}
}
As you can see, the added convenience of having Actions defined for the actions within your game is a balanced by making your components that use them be configured by them (and using them in the KeyListener implementations).
For large projects, the simplicity of having all your actions listed generally makes creating Actions well worth the effort; but, for smaller projects that are mostly using custom components, the added one-time-cost of making the KeyListener components use actions might outweigh the benefits.
Don't use JMenuItem this way, that's not how it's intended to be used
Instead, I'd start with JButton. The following makes use of your focus transversal code, the Action API and the key bindings API
import java.awt.AWTKeyStroke;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
Set<AWTKeyStroke> set = new HashSet<AWTKeyStroke>(KeyboardFocusManager.getCurrentKeyboardFocusManager().getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
set.add(KeyStroke.getKeyStroke("DOWN"));
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, set);
set = new HashSet<AWTKeyStroke>(KeyboardFocusManager.getCurrentKeyboardFocusManager().getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
set.add(KeyStroke.getKeyStroke("UP"));
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, set);
Action playAction = new AbstractAction("Play") {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("play");
}
};
playAction.putValue(Action.MNEMONIC_KEY, (int)'P');
Action exitAction = new AbstractAction("Exit") {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("exit");
}
};
exitAction.putValue(Action.MNEMONIC_KEY, (int)'x');
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0), "play");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, 0), "exit");
am.put("play", playAction);
am.put("exit", exitAction);
JButton playButton = new JButton(playAction);
JButton exitButton = new JButton(exitAction);
add(playButton, gbc);
add(exitButton, gbc);
}
}
}
Now, you could do something similar with JLabel, but, JLabel isn't focusable by default, nor does it render any kind of focus indication. Instead, I might be tempted to just strip down a JButton so it didn't paint its border or content/background instead
I was trying to change the text "Java" to "Love Java" by using MouseAdapter. The text "Java" comes out when mouseEntered and "Love Java" comes out when mouseExited. So I created class MyMouse extends MouseAdapter and trying to use the methods.
But there is the error message "The method getSource() is undefined for the type MouseEvent". When I searched it, this code is nothing wrong with it but I don't know why I'm getting this error message, and also of course the result is not working.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MouseEvent extends JFrame{
MouseEvent(){
setTitle("Practicing mouse event");
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lb = new JLabel("Java");
MyMouse mym = new MyMouse();
lb.addMouseListener(mym);
lb.setSize(300,100);
add(lb);
setSize(400,200);
setVisible(true);
}
public static void main(String[] args) {
new MouseEvent();
}
}
class MyMouse extends MouseAdapter{
public void mouseEntered(MouseEvent e) {
JLabel lb = (JLabel)e.getSource();
lb.setText("Love Java");
}
public void mouseExited(MouseEvent e) {
JLabel lb = (JLabel)e.getSource();
lb.setText("Java");
}
}
The MouseEvent object e you are using inside public void mouseEntered(MouseEvent e) or public void mouseExited(MouseEvent e) should be from java.awt.event.MouseEvent.
But, as you have named your main class also as MouseEvent, in that case the MouseEvent object e inside mouseEntered() and mouseExited() methods are actually the object of your main class. That's why it was searching for getSource() method in your main class and failed.
Please change your main class name to something other than MouseEvent. For example:
public class MyMouseEvent extends JFrame {
MyMouseEvent() {
...
...
public static void main(String[] args) {
new MyMouseEvent();
...
The problem can be solved through these changes to the code:
Rename the main class of the program so that its name does not conflict with that of the class (java.awt.event.MouseEvent) imported from Java library.
Add #Override annotations to mouseEntered and mouseExited methods to avoid compiler warnings
Call setVisible(true) on the frame to display after instantiation
Here is the working example with the above mentioned changes:
// File name: Demo.java
// This name was chosen to avoid conflict with java.awt.event.MouseEvent
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class MyMouse extends MouseAdapter{
// Add #Override annotation to overridden methods
#Override
public void mouseEntered(MouseEvent e) {
JLabel lb = (JLabel)e.getSource();
lb.setText("Love Java");
}
// Add #Override annotation to overridden methods
#Override
public void mouseExited(MouseEvent e) {
JLabel lb = (JLabel)e.getSource();
lb.setText("Java");
}
}
public class Demo extends JFrame{
Demo() {
setTitle("Practicing mouse event");
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lb = new JLabel("Java");
MyMouse mym = new MyMouse();
lb.addMouseListener(mym);
lb.setSize(300,100);
add(lb);
setSize(400,200);
}
public static void main(String[] args) {
Demo demo = new Demo();
// Display the frame
demo.setVisible(true);
}
}
Output:
> javac Demo.java
> java Demo
my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Events1 extends JFrame {
private JLabel label;
private JButton button;
public Events1() {
setLayout(new FlowLayout());
label = new JLabel("");
button = new JButton("Click for text");
add(button);
add(label);
event e = new event();
button.addActionListener(e);
}
public class event implements ActionListener {
public void actionPerfomed(ActionEvent e) {
label.setText("See motherfucker it does do stuff");
}
}
public static void main(String[] args) {
Events1 window = new Events1();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(500, 500); //.pack();
window.setVisible(true);
window.setTitle("Attempt 2");
}
}
Basically I'm new to GUI's and get the error message when I try to compile the above code:
Events1.java:25: error: Events1.event is not abstract and does not override abstract method actionPerformed(ActionEvent) in ActionListener
public class event implements ActionListener {
^
1 error
I basically made this code based on the information on the Oracle Docs and and pretty confused of why this doesn't work/how to fix it.
Any help is greatly appreciated thanks.
You have a typo in overriden method
public void actionPerformed(ActionEvent e)
That's why you should use #Override annotation for overriden methods and IDE support for this kind of operations.
I have been coding for a card game and cannot get my method to wait for a button to be pressed.
The general code goes like this. When I run the code, doTask() has a segment where it needs to wait for a button to be pressed. However, the method does not wait for the button and just loops through.
I am currently thinking to have a while loop with a boolean (buttonIsPressed) which will be triggered true in actionPerformed(e). However, is there a simpler way to do this?
Any help would be appreciated.
Thank you.
public class Test {
public Test()
{
// all vars instantiated
while (!(taskLeft==0))
{
doTask();
taskLeft--;
}
}
private class Handler implements ActionListener
{
public void actionPerformed(ActionEvent arg0) {
// update information in doTask()
}
}
}
Yours is a classic XY Problem where you ask how to solve a specific code problem when the best solution is to use a completely different approach. You're thinking of how do I code this event-driven GUI program to work as a linear console program, and that's not how you should approach this. Instead look at changing object state and basing response of the object to events based on its state.
So get rid of the while loop, and instead do your task when the button is pushed based on the state of the GUI. The details of any solution will depend on the details of your problem, something you may wish to share with us.
So for instance, here taskLeft represents a "state" of the TaskEx object, and your Handler's response will depend on the state of this variable.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class TaskEx extends JPanel {
private int taskLeft = 10;
public void doTask() {
//
}
private class Handler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (taskLeft > 0) {
doTask();
taskLeft--;
}
}
}
}
An actually functioning example:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class TaskEx extends JPanel {
private int taskLeft = 10;
private JLabel taskCountLabel = new JLabel(String.valueOf(taskLeft));
public TaskEx() {
JPanel northPanel = new JPanel();
northPanel.add(new JLabel("Tasks Left:"));
northPanel.add(taskCountLabel);
JPanel centerPanel = new JPanel();
centerPanel.add(new JButton(new Handler("Push Me")));
setLayout(new BorderLayout());
add(northPanel, BorderLayout.PAGE_START);
add(centerPanel, BorderLayout.CENTER);
}
public void doTask() {
taskCountLabel.setText(String.valueOf(taskLeft));
}
private static void createAndShowGui() {
TaskEx mainPanel = new TaskEx();
JFrame frame = new JFrame("Task Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
private class Handler extends AbstractAction {
public Handler(String name) {
super(name);
putValue(MNEMONIC_KEY, (int) name.charAt(0));
}
#Override
public void actionPerformed(ActionEvent e) {
if (taskLeft > 0) {
taskLeft--;
doTask();
}
}
}
}
I'm doing some very basic coding, just trying to learn the basic concepts behind keybinding. It all seems very straightforward but there's something wrong with my logic or structure that is keeping my code from executing the way I want it to.
Here is my code
public class Board {
ButtonListener buttonlistener;
EnterAction enterAction;
public Board(){
JFrame skeleton = new JFrame();
skeleton.setDefaultCloseOperation(EXIT_ON_CLOSE);
skeleton.setVisible(true);
skeleton.setSize(400, 400);
buttonlistener = new ButtonListener();
enterAction = new EnterAction();
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
JButton button = new JButton("button");
button.addActionListener(buttonlistener);
panel.add(button);
skeleton.add(panel);
panel.getInputMap().put(KeyStroke.getKeyStroke("s"), "doEnterAction");
panel.getActionMap().put("doEnterAction", enterAction);
}
public class ButtonListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("button pressed");
}
}
public class EnterAction extends AbstractAction{
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("enter pressed");
}
}
public static void main(String[] args){
new Board();
}
So, it should be pretty simple. As you can see I'm just trying to make it print out "enter pressed" whenever you press enter, but it isn't printing out anything (unless you click the button also shown in the code above). Also, in eclipse, the EnterAction class is underlined in yellow, I think it may not be being called right, but I don't know why it wouldn't be.
Any help is appreciated, thanks.
Change
panel.getInputMap().put(KeyStroke.getKeyStroke("s"), "doEnterAction");
To
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "doEnterAction");
Also
skeleton.setDefaultCloseOperation(EXIT_ON_CLOSE);
the parameter must be JFrame.EXIT_ON_CLOSE or just put number 3.
The immediate issue I can see is with the following statement
panel.getInputMap().put(KeyStroke.getKeyStroke("s"), "doEnterAction");
KeyStroke.getKeyStroke("s") is going to return null. The requirements for the String passed to this method are very particular and not well documented (IMHO).
You could use KeyStroke.getKeyStroke("S") instead, but I prefer to use KeyStroke.getKeyStroke(KeyEvent.VK_S, 0) as there is no chance of ambiguity in the statement.
I would also recommend that you define the focus boundaries as well for the input map...
Instead of panel.getInputMap(), try using panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) to ensure that the key event will be triggered if the window is focused
Take a look at JComponent#getInputMap for more details.
If you haven't already done so, you should also take a look at How to use Key Bindings
I think Azad and MadProgrammer are correct, I only had to make one more simple change in addition to what they recommended to get the program running. I have numbered the three items for you as a comment in the code: (copy and paste and you are good to go).
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Board {
ButtonListener buttonlistener;
EnterAction enterAction;
public Board() {
JFrame skeleton = new JFrame();
//Change #1 below
skeleton.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
skeleton.setVisible(true);
skeleton.setSize(400, 400);
buttonlistener = new ButtonListener();
enterAction = new EnterAction();
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
JButton button = new JButton("button");
button.addActionListener(buttonlistener);
panel.add(button);
skeleton.add(panel);
//Change #2 below
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke("S"), "doEnterAction");
panel.getActionMap().put("doEnterAction", (Action) enterAction);
}
public class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("button pressed");
}
}
public class EnterAction extends AbstractAction {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("enter pressed");
}
}
public static void main(String[] args) {
new Board();
}
//Change #3 below
}
here is the screenshot: