hey people,

I've been experimenting with some new (for me) java techniques, like keybindings. i've got a small app, where the bindings work fine, untill i press a JButton with actionListener.
the actionListener doesn't do anything at all, but keybindings fail after i press one of them.

here's my code (the keybindings are in a seperate file, but i know they work anyway)

package hokjesmain;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class HokjesMain extends JFrame{

    private static Color background = Constants.applicationBackground;
    private static int width = Constants.applicationWidth, height = Constants.applicationHeight;

    public static void main(String[] args) {
        JFrame frame = new HokjesMain();
        frame.setBackground(background);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(width, height);
        frame.setContentPane(new Pane());
        frame.setVisible(true);
    }

}
class Pane extends JPanel{
    private Player player, player2;
    private Grid grid;
    private JButton newGame,help, exit;

    public Pane(){
        try{
            this.setLayout(null);

            this.player2 = new Player(Constants.defaultPlayerOneStartCell, Constants.defaultPlayerOneStartRow, Constants.defaultPlayerStartingCredits, Constants.defaultPlayer1Color, Constants.defaultPlayerOneImageLocation);
            this.player = new Player(Constants.defaultPlayerTwoStartCell, Constants.defaultPlayerTwoStartRow, Constants.defaultPlayerStartingCredits, Constants.defaultPlayer2Color, Constants.defaultPlayerTwoImageLocation);
            this.grid = new Grid(Constants.defaultGridColls, Constants.defaultGridRows);

            this.newGame = new JButton("restart");
            this.help = new JButton("help");
            this.exit = new JButton("exit");

            MovementHandler movement = new MovementHandler(player, player2, grid, this);  
            PlayerActionHandler pa = new PlayerActionHandler(player, player2, grid, this);

            this.newGame.setBounds(Constants.buttonLeftX, Constants.buttonTopY, Constants.buttonWidth, Constants.buttonHeight);
            this.help.setBounds(Constants.buttonRightX, Constants.buttonTopY, Constants.buttonWidth, Constants.buttonHeight);
            this.exit.setBounds(Constants.buttonLeftX, Constants.buttonRow2Y, Constants.buttonWidth, Constants.buttonHeight);

            this.newGame.addActionListener(new startNewGame());
            this.help.addActionListener(new help());
            this.exit.addActionListener(new exit());

            add(this.newGame);
            add(this.help);
            add(this.exit);

            validate();

        }
        catch(Error e){
            System.out.println(e.getMessage());
        }

        catch(IOException e){
            System.out.println(Constants.IOError + e.getCause());
        }
    }

    class startNewGame implements ActionListener{
        @Override public void actionPerformed(ActionEvent e){

        }
    }
    class help implements ActionListener{
        @Override public void actionPerformed(ActionEvent e){
            System.out.println("not yet implemented");
            repaint();
        }
    }
    class exit implements ActionListener{
        @Override public void actionPerformed(ActionEvent e){
            System.exit(0);
        }
    }

    @Override public void paintComponent(Graphics g){
        try{
            grid.drawGrid(g);
            g.setFont(new Font(Constants.fontForPlayerText, Constants.fontForPlayerTextStyle, Constants.fontForPlayerTextSize));
            g.setColor(Constants.defaultTextDrawingColor);
            g.drawImage(player.getPlayer(), player.getPositionCellForDrawing(), player.getPositionRowForDrawing(), null);
            g.drawImage(player2.getPlayer(), player2.getPositionCellForDrawing(), player2.getPositionRowForDrawing(), null);
            g.drawString(Constants.playerDataText1, Constants.drawDistanceXForPlayer1Data, (grid.getAmountOfRows() * Constants.defaultCellHeightPx) + Constants.distanceBetweenGridAndData);
            g.setColor(player.getPlayerColor());
            g.fillRect(Constants.drawDistanceXForPlayer1Data + Constants.distanceBetweenTextAndData, ((grid.getAmountOfRows() * Constants.defaultCellHeightPx) + Constants.distanceBetweenGridAndData -  Constants.defaultExampleCellHeight), Constants.defaultExampleCellWidth, Constants.defaultExampleCellHeight);
            g.setColor(player2.getPlayerColor());
            g.fillRect(Constants.drawDistanceXForPlayer2Data + Constants.distanceBetweenTextAndData, ((grid.getAmountOfRows() * Constants.defaultCellHeightPx) + Constants.distanceBetweenGridAndData -  Constants.defaultExampleCellHeight), Constants.defaultExampleCellWidth, Constants.defaultExampleCellHeight);
            g.setColor(Constants.defaultTextDrawingColor);
            g.drawString(Constants.playerDataText2, Constants.drawDistanceXForPlayer1Data, (grid.getAmountOfRows() * Constants.defaultCellHeightPx) + Constants.distanceBetweenGridAndData + Constants.fontForPlayerTextSize + Constants.DistanceBetweenDataRules);
            g.setColor(Constants.applicationBackground);
            g.fillRect(Constants.drawDistanceXForPlayer1Data + Constants.distanceBetweenTextAndData, ((grid.getAmountOfRows() * Constants.defaultCellHeightPx) + Constants.distanceBetweenGridAndData -  Constants.defaultExampleCellHeight) + Constants.defaultExampleCellHeight + Constants.DistanceBetweenDataRules, (Constants.fontForPlayerTextSize * 2), Constants.defaultExampleCellHeight);
            g.fillRect(Constants.drawDistanceXForPlayer2Data + Constants.distanceBetweenTextAndData, ((grid.getAmountOfRows() * Constants.defaultCellHeightPx) + Constants.distanceBetweenGridAndData -  Constants.defaultExampleCellHeight) + Constants.defaultExampleCellHeight + Constants.DistanceBetweenDataRules, (Constants.fontForPlayerTextSize * 2), Constants.defaultExampleCellHeight);
            g.setColor(Constants.defaultTextDrawingColor);
            g.drawString(""+player.getCredits(), Constants.drawDistanceXForPlayer1Data + Constants.distanceBetweenTextAndData, ((grid.getAmountOfRows() * Constants.defaultCellHeightPx) + Constants.distanceBetweenGridAndData) + Constants.defaultExampleCellHeight + Constants.DistanceBetweenDataRules);
            g.drawString(""+player2.getCredits(), Constants.drawDistanceXForPlayer2Data + Constants.distanceBetweenTextAndData, ((grid.getAmountOfRows() * Constants.defaultCellHeightPx) + Constants.distanceBetweenGridAndData) + Constants.defaultExampleCellHeight + Constants.DistanceBetweenDataRules);

        }
        catch(Error e){
            System.out.println(e.getMessage());
        }
    }
}

You don't say which action listener you are talking about - the empty one or the not implemented one. And what exactly does "keybindings fail" mean?
ps Don't use System.out.println(e.getMessage()); , use e.printStackTrace(); instead so you can see where the error happened as well as what it was

you're right, i've been too hastely typping my post, sorry about that.
all of the actionListeners are causing this issue; they do work themselves, but once they are done, none of the keybindings are working anymore. they don't post my test texts either.
the quit button works fine though.

and yes, i had a seperate class for error handling to do that, but it bugged so i had this one as a quick replacement. i wanted to work on the error class after this issue, and i knew that no problems were thrown anyway, but still thanks :)

Can you post a small, complete program that compiles, executes and shows the problem for testing?

Its really hard to guess without the code, but maybe your ActionListeners (new game, help) are opening new windows which capture the keyboard focus, and you don't have key bindings that include the new windows?

Ok, the full source code is in the file, i've also written this small file that has the same issue.

When you press a, it should say "pressed A" in the console, but if you push the button, and then press A, nothing happens. the actionhandler for the button doesn't do anything.

package kbal.experiment;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/**
 * Experiment to test an actionListener/keybinding combination
 * @author phoenix
 */
public class KbalExperiment extends JFrame{
    public static void main(String[] args) {
        JFrame frame = new KbalExperiment();
        Panel paneel = new Panel();
        frame.setSize(100, 100);
        frame.setContentPane(paneel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

class Panel extends JPanel{
    private JButton button;

    public Panel(){

        this.getInputMap().put(KeyStroke.getKeyStroke((Character) 'a'), "a");
        this.getActionMap().put("a", printA);

        this.button = new JButton("test");
        this.button.addActionListener(new doNothing());

        add(this.button);
    }

    Action printA = new AbstractAction() {
        @Override public void actionPerformed(ActionEvent e){
            System.out.println("pressed a!");
        }
    };  
}
class doNothing implements ActionListener{
    @Override public void actionPerformed(ActionEvent e){

    }
}
Attachments

That demo program was worth every minute you spent on it! I was able to run it and reproduce your problem.
If you don't add the ActionListener ast all, so the button has none of your code attached to it in any way, then you still have the problem. So it's nothing to do with the ActionListener. My guess is that it's a focus problem - clicking the button moves the focus.

You are using the default input map, which is the "when focussed" map. Try adding your binding to the WHEN_IN_FOCUSED_WINDOW input map - that fixed it for me.

Edited 4 Years Ago by JamesCherrill

This question has already been answered. Start a new discussion instead.