JButton отвечает в JFrame, но не в JPanel - PullRequest
0 голосов
/ 19 мая 2018

Я новичок в Java, и я пытаюсь понять, как работают слушатели действий и кнопки.Я обнаружил, что могу получить работающий JButton, если я помещу его прямо в мой объект JFrame.Но если я помещу его в JPanel в этого JFrame, он не будет отвечать.Почему это так?

Main.java

public class Main {
    private static Frame f = new Frame();
    public static void main(String[] args) {}
}

Frame.java

public class Frame extends JFrame {
    private final int WIDTH = 640, HEIGHT = 480;
    private Panel p = new Panel();

    Frame() {
        super("Java Program");   
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(WIDTH, HEIGHT);
        this.setLayout(null);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    public void paint(Graphics g) {
        super.paint(g);
        p.paintComponent(g);
    }
}

Панель.java

public class Panel extends JPanel {
    JButton b = new JButton("Button");

    Panel() {
        b.setBounds(0,  0, 200, 100);
        add(b);
        b.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                b.setText("Pressed");
            }
        });
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        b.paint(g);
    }
}

1 Ответ

0 голосов
/ 19 мая 2018

Я не эксперт по Swing, поэтому не могу объяснить, почему это не работает.Похоже, что неотзывчивая кнопка нарисована поверх вашей кнопки.Я немного подправил его, и вот несколько модификаций, чтобы заставить его работать:

  • Добавьте панель в рамку: add(p);
  • Удалите строку this.setLayout(null);, этокажется, что портит фрейм
  • Чтобы установить размер фрейма, используйте setPreferredSize: this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
  • Вам также нужно вызвать pack() в конце вашего конструктора Frame.
  • И вам нужно удалить b.paint(g) из вашего Panel.paintComponent(), похоже, это то, что рисует кнопку «не отвечает» (см. Изображение в конце ответа).

  • При желании вы можете удалить краску () из фрейма, она не делает ничего, кроме JFrame

Вот модифицированная рабочая версия:

class Frame extends JFrame {
    private final int WIDTH = 640, HEIGHT = 480;
    private Panel p = new Panel();

    Frame() {
        super("Java Program");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
        this.setLocationRelativeTo(null);
        this.setVisible(true);

        // add the panel to the frame
        add(p);

        pack();
    }

}

class Panel extends JPanel {
    JButton b = new JButton("Button");

    Panel() {
        b.setBounds(0,  0, 200, 100);
        add(b);
        b.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                b.setText("Pressed");
            }
        });
    }


    // You can also get rid of this method, 
    // I just leave it here to show that I removed the b.paint(g) line
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    }
}

Вот то, что показывает тот же код, если вы оставите b.paint(g) в Panel.paintComponent(), как вы можете видеть, есть 2 кнопки, одна в углу не работает.

enter image description here

...