Java Кнопка из JPanel ActionsListener не работает - PullRequest
0 голосов
/ 18 января 2020

У меня следующая проблема: у меня небольшое приложение с очень простым пользовательским интерфейсом и прослушивателями реализованных действий в другом классе, вот код

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);

    }
}

Панель

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 = new Panel();
    public Controller(Panel panel) {
         this.panel=panel;
         panel.btn.addActionListener(this);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        //not working
    }
}

Не знаю, почему не работает

Ответы [ 2 ]

1 голос
/ 18 января 2020

Это не имеет никакого отношения к вашему вопросу, но я должен отметить, что это плохой стиль и совершенно ненужный. Не создавайте класс для этого. Просто создайте метод.

class Panel extends JPanel{

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

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

Сделайте это вместо этого. Если вы не используете какие-либо поля экземпляра, вы можете даже сделать это 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;
}

То же самое верно для вашего Frame класса. Вы должны стремиться избегать наследования в этих случаях и go для композиции (используя простой экземпляр). Это особенно верно с JFrame. Для более сложных экземпляров используйте методы, облегчающие их создание.

1 голос
/ 18 января 2020

Вы создали 3 объекта Panel, один из которых добавлен в JFrame и который является видимым, и отдельный , который вы отправляете контроллеру, который не видимый и третий созданный внутри контроллера (посмотрите, сколько раз вы звоните new Panel()). Не делай этого. Создайте один объект Panel, который добавляется к видимому GUI и подключается к контроллеру.

Например,

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");
    }
}

Примечание:

Лучше не открывать свои поля миру через публичные c поля, а вместо этого делать их приватными, выставляя только то, что нужно раскрыть. В этой ситуации рассмотрите возможность создания метода publi c, чтобы контроллер мог добавить прослушиватель. Например:

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");
    }
}
...