Reputation: 3
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
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
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