0

I have a JLabel that has keybinded actions on it. I have defined some code for some of the Actions but, alas, there are other JLabels, a JPanel, and other things within the method (this is in main()) that I want my Actions to fool with.

I tried to change the Actions into taking parameters, but was not successful, how can I get my actions to take in parameters to manipulate? Is there any way? I have looked about but this is pretty specific and I see few good examples.

Here is a nice slab of my code:

    /*Bunch of stuff I want my actions to interact with above - another JLabel, a JPanel*/
    ImageIcon cursor = new ImageIcon("cursor.gif");
    JLabel cursorlbl = new JLabel("", cursor, JLabel.CENTER);
    Action goRight = new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            System.out.println("lol");

        }
    };

    Action goLeft = new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            System.out.println("lol2");
        }
    };

    Action goUp = new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent arg0) {


        }
    };

    Action goDown = new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            System.out.println("lol2");

        }
    };


    cursorlbl.setFocusable(true);
    cursorlbl.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"),
            "pressed right");
    cursorlbl.getInputMap().put(KeyStroke.getKeyStroke("LEFT"),
            "pressed left");
    cursorlbl.getActionMap().put("pressed right", goRight);
    cursorlbl.getActionMap().put("pressed left", goLeft);
Barett
  • 5,826
  • 6
  • 51
  • 55
PinkElephantsOnParade
  • 6,452
  • 12
  • 53
  • 91

3 Answers3

2

You can declare each action as a subclass (this starts to separate MVC anyways), and each item you want to manipulate a field in the parent class. Example:

// Parent Class
public class ParentClass{
//Field you want to mess with in your action
   JLabel cursorlbl = new JLabel("");

    // Action that does things
    public class MoveAction extends AbstractAction{
        char direction;

        //Constructor for action
        public MoveAction(char direction){
            this.direction = direction;
        }

        @Override
        public void actionPerformed(ActionEvent arg0) {
            int change = 0;

            // Figure out how you'll be changing the variable
            if(direction == 'u' || direction == 'r'){
                change = 1;
            } else{
                change = -1;
            }

            // Apply the change to the correct variable
            if(direction == 'u' || direction =='d'){
                cursy += change;
            } else{
                cursx += change;
            }

            //Example how you can access the parent class's fields
            cursorlbl.setLocation(cursx, cursy);
        }       
    }
}

Then to set your actions, you just create instances of your subclass:

    contentArea.getActionMap().put("pressed right", new MoveAction('r'));
    contentArea.getActionMap().put("pressed left", new MoveAction('l'));
Nick Rippe
  • 6,465
  • 14
  • 30
0

Declare other components you wish to see in your actions as final. That will make actions see them.

More info here

ioreskovic
  • 5,531
  • 5
  • 39
  • 70
0

You should be able to pass them in like this:

// note that the JLabel is now final
final JLabel cursorlbl = new JLabel("", cursor, JLabel.CENTER);
Action goRight = new AbstractAction() {

    @Override
    public void actionPerformed(ActionEvent arg0) {
        System.out.println(cursorlbl.getText()); // has access to JLabel because it's scoped to the method/class

    }
};

Note that doing this can cause some maintenance issues and you should try to document things that might be unclear for future developers (and yourself two weeks from now!)

corsiKa
  • 81,495
  • 25
  • 153
  • 204