action listener in another class - java

66,498

Solution 1

Not only it is possible to separate these two, it's also recommended (see MVC pattern - it's very much about separating screen controls like buttons, and the logics of your program)

The easiest way that comes to my mind is to do write a named class that implements ActionListener interface, something like this:

public class SomeActionListener implements ActionListener{

    private JTextField textField1;
    private JComboBox combo1;
    private JTextField textField2;
    //...

    public SomeActionListener(JTextField textField1, JComboBox combo1, 
                                          JTextField textField2){
        this.textField1=textField1;
        this.combo1=combo1;
        this.textField2=textField2;
        //...
    }

    public void actionPerformed(ActionEvent e) {
        //cmd
    }

}

And then add it to your buttons:

ActionListener actionListener = new SomeActionListener(textField1, combo1, textField2);
someButton.addActionListener(actionListener);

Solution 2

To answer: "my problem is that action listener have many variables of swing like buttons for example,so, when i change to another class, i have problems with that"

Your action listener class could have a constructor that takes a parameter of the type of the view class:

public class Listener implements ActionListener {
  private final MyViewClass mView;
  public Listener(MyViewClass pView) {
    mView = pView;
  }

  public void actionPerformed(ActionEvent e) {
    // can use mView to get access to your components.
    mView.get...().doStuff...
  }
}

Then in your view:

Listener l = new Listener(this);
button.addActionListener(l);

Solution 3

you can do it easily by using nested classes, but i think the best way is pass the parent object as a parameter to the construct of object and using it as an action handler;

//**parent class - Calculator **//

public class Calculator extends JFrame implements ActionListener{

    private DPanel dPanel;
    private JTextField resultText;

    public Calculator(){
        // set calc layout
        this.setLayout(new BorderLayout(1,1));
        dPanel = new DPanel(this); // here is the trick ;)
    }
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        resultText.setText(command);
        // **** your code ****/
    }    
}



//**inner class - DPanel**//

public class DPanel extends JPanel{

    private JButton digitsButton[];
    private JButton dotButton,eqButton;

    public DPanel(Calculator parent){
        //layout
        this.setLayout(new GridLayout(4,3,1,1));

        // digits buttons
        digitsButton = new JButton[10];
        for (int i=9;i>=0;i--){
            digitsButton[i] = new JButton(i+"");
            digitsButton[i].addActionListener(parent); // using parent as action handler ;)
            this.add(digitsButton[i]);
        }
     }
}

Solution 4

It's a bit off topic but you should definately not use the == operator to compare Strings as you appear to be doing on this line:

if (player[j].getCard(i).getSuit() == Suit.HEARTS.toString()

This is because Strings are pointers, not actual values, and you may get unexpected behaviour using the == operator. Use the someString.equals(otherString) method instead. And also

"String to compare".equals(stringVariable)

is alot better than the other way around

stringVariable.equals("String to compare to")

because in the first example you avoid getting a NullPointerException if stringVariable is null. It just returns false.

Solution 5

Yes, it can be done. It's very simple; in one class you have your buttons, in the other class you just need to implement an ActionListener and just make your //cmd to separate that button's function. To do this, you need to use e.getActionCommand().equals(buttonActionCommand). Sample code:

public class Click implements ActionListener{

    public Click(
     //input params if needed
     ){

    }

     public void actionPerformed(ActionEvent e) {
     if( e.getActionCommand().equals(buttonActionCommand){
     //cmd
     }
     } 

}

To add that listener on your button just do:

buttonTest.addActionListener(new Click());
Share:
66,498

Related videos on Youtube

user455318
Author by

user455318

Updated on July 09, 2022

Comments

  • user455318
    user455318 almost 2 years

    it is possible to have two class, and in one something like

    arrayButtons[i][j].addActionListener(actionListner);
    

    and in another

    ActionListener actionListner = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
    
                for (int j = 0; j < arrayButtons.length; j++) {
                    for (int i = 0; i < arrayButtons[j].length; i++) {
                        if (arrayButtons[j][i] == e.getSource()) {
    
                            if ((gameNumber == 2) && (playHand.getNumberOfCards() == 0)) {
                                if (player[j].getCard(i).getSuit() == Suit.HEARTS.toString() && player[j].hasSuitBesideHearts())
                                    //second game
                                    messageOnTable("xxx");
    
                                else{
                                    arrayButtons[j][i].setVisible(false);
                                    test[j].setIcon(player[j].getCard(i).getImage());
                                    pnCardNumber[j].setText(Integer.toString(player[j].getCard(i).getNumber()));
                                    pnCardName[j].setText(player[j].getCard(i).toString());
                                    pnCardSuit[j].setText(player[j].getCard(i).getSuit());
    
                                    playHand.addCard(player[j].getCard(i), j);
    
                                    player[j].removeCard(i);
    
                                }
    
                            }
    
    }
    

    //and more the reason of that is because i need to separate the button (swing) to the action listener

    how i can do ?

    thanks

    • Hovercraft Full Of Eels
      Hovercraft Full Of Eels over 13 years
      Yes you can use ActionListeners from other classes or have a separate class implement the ActionListener interface, but the devil's in the details. We can more easily advise you on how to do this if we know more details about your program.
  • user455318
    user455318 over 13 years
    my problem is that action listener have many variables of swing like buttons for example,so, when i change to another class, i have problems with that
  • Goran Jovic
    Goran Jovic over 13 years
    @user: That is tricky. See my updated answer for one possible solution. The other thing you could do is have getter methods for all the components on the JFrame and then pass only jFrame instance to the listener.
  • Hovercraft Full Of Eels
    Hovercraft Full Of Eels over 13 years
    @user: again, the more details you can provide by editing your original post above, the more informative answers we can provide.
  • user455318
    user455318 over 13 years
    it is much more complicated, because involve many arrays and loops of buttons (52- game of cards)
  • Goran Jovic
    Goran Jovic over 13 years
    @user: Not really. Just pass entire arrays and loop in the listener. An array may have many elements but it's still a single reference.
  • user455318
    user455318 over 13 years
    but for example who i can to do reference for arrayButtons[j][i] ?
  • Ian Campbell
    Ian Campbell about 11 years
    This is very helpful and straightforward, especially after spending many many hours trying to understand MVC and CardLayout (I still want to learn that stuff too, though).
  • Benjamin R
    Benjamin R almost 10 years
    It's not exactly decoupled, but it's a solution! YOINK!
  • skubski
    skubski over 8 years
    This solution gets very messy when dealing with complex GUI's and equally complex handlers. Works fine for the amount of code you provide but it certainly isn't a maintainable solution when files grow large. -1
  • Fareed Alnamrouti
    Fareed Alnamrouti over 8 years
    @skubski actually from my long experience with Java, languages like java didn't approve it's efficiency for UI anyway :P, and i think this was the reason scripting languages like "javascript" and "Actionscript" is used for UI, anyway using clear and straight forward solution is always winning over standards, please watch the video when Facebook introduce "React Framework" and you will know how MVC was sucks for a complex UI that i am sure you never face in your career