saturn07
saturn07

Reputation: 3

Java Button from JPanel ActionsListener not working

I have a following problem: I have a small application with a very simple UI and Implemented Action Listeners in another class, here is the code

public class PruebaEvento {

    public static void main(String[] args) {
        Frame frame = new Frame();
        Panel panel = new Panel();
        Controller c = new Controller(panel);

        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Frame

class Frame extends JFrame{

    public Frame() {
        setBounds(600, 250, 600, 300);
        Panel mipanel = new Panel();
        add(mipanel);

    }
}

Panel

class Panel extends JPanel{

    public javax.swing.JButton btn = new javax.swing.JButton("Subir archivo");

    public Panel() {
        add(btn);
    }

}

Controller

class Controller implements ActionListener{

    Panel panel = new Panel();
    public Controller(Panel panel) {
         this.panel=panel;
         panel.btn.addActionListener(this);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        //not working
    }
}

I don't know why isn't working

Upvotes: 0

Views: 33

Answers (2)

WJS
WJS

Reputation: 40062

This has nothing to do with your question but I need to point out this is bad style and totally unnecessary. Don't create a class to do this. Just create a method.

class Panel extends JPanel{

    public javax.swing.JButton btn = new javax.swing.JButton("Subir archivo");

    public Panel() {
        add(btn);
    }
}

Do this instead. If you're not using any instance fields, you can even make it static.

public JPanel createPanel(String text, ActionListener al) {
    JPanel panel = new JPanel()
    JButton button = new JButton(text);
    button.addActionListener(al);
    panel.add(button);
    return panel;
}

The same is true for your Frame class. You should strive to avoid inheritance in these cases and go for composition (using a simple instance). This is especially true with JFrame. For more complex instances, use methods to facilitate their creation.

Upvotes: 1

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

You have created 3 Panel objects, one added to the JFrame and which is visible, and a separate one that you send to the controller which is not visible and a third created inside the controller (look at how many times you call new Panel()). Don't do this. Create one single Panel object that is both added to the visible GUI and that is hooked up to the controller.

e.g.,

import java.awt.event.*;
import javax.swing.*;

public class PruebaEvento {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            Frame frame = new Frame();
            Panel panel = new Panel();
            frame.add(panel);
            Controller c = new Controller(panel);

            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        });
    }
}
class Frame extends JFrame {

    public Frame() {
        setBounds(600, 250, 600, 300);

        // ****** don't create a new Panel here *****
        // Panel mipanel = new Panel();
        // add(mipanel);

    }
}
class Panel extends JPanel {

    public javax.swing.JButton btn = new javax.swing.JButton("Subir archivo");

    public Panel() {
        add(btn);
    }

}
class Controller implements ActionListener {

    Panel panel;

    public Controller(Panel panel) {
        this.panel = panel;
        panel.btn.addActionListener(this);
    }

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

Side note:

It's best not to directly expose your fields to the world via public fields, and instead make them private, exposing only that which needs to be exposed. In this situation, consider creating a public method to allow the controller to add the listener. For example:

class Panel extends JPanel {

    private javax.swing.JButton btn = new javax.swing.JButton("Subir archivo");

    public Panel() {
        add(btn);
    }

    public void addBtnListener(ActionListener l) {
        btn.addActionListener(l);  // !!
    }

}
class Controller implements ActionListener {

    Panel panel;

    public Controller(Panel panel) {
        this.panel = panel;
        // panel.btn.addActionListener(this);
        panel.addBtnListener(this); // !! 
    }

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

Upvotes: 1

Related Questions