Размещение JButton внутри JPanel внутри JFrame с переменными результатами - PullRequest
0 голосов
/ 20 апреля 2020

У меня чрезвычайно сложная проблема с простой (?) Концепцией. Я пытаюсь изучить основы JFrame, JPanel, et c, и сейчас пытаюсь реализовать простую задачу. Я хочу, чтобы большой JFrame назывался canvas и находился внутри 2 JPanel рядом, без полей или чего-либо еще. Внутри этих двух JPanels у меня есть кнопка, покрывающая цветной прямоугольник. Когда вы нажимаете на кнопку, кнопка должна исчезнуть и показать цвет. У меня много проблем.

Код, похоже, живет своей жизнью. Даже использование сообщения get внутри оператора print приведет к изменению вывода. Что касается самого вывода, то на первый взгляд он выглядит хорошо, две кнопки рядом названы правильно.

Однако, когда вы нажимаете кнопку 1, обе кнопки исчезают, и в правом верхнем углу появляется третья кнопка с именем «кнопка два». Когда вы нажимаете новую кнопку, она отключается, но не исчезает.

Иногда, когда вы нажимаете кнопку 1, третья кнопка 2 также появляется, но исходная кнопка 2 только отключает, но не скрывает. Кроме того, весь фон синий, а не красный и синий, как должно быть. Совершенно новый набор событий происходит, когда вы нажимаете кнопку2, но, надеюсь, этого может быть достаточно, чтобы помочь вам.

Большое спасибо!

import java.awt.*;
import javax.swing.*;
public class testbig {
    public static void main(String[] args) {
        JFrame canvas = new JFrame("canvas");
        canvas.setSize(400,400);
        canvas.setVisible(true);
        canvas.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        canvas.setLayout(null);

        testinner temp = new testinner("1",Color.blue);
        temp.setBounds(0,0,200,400);
        canvas.getContentPane().add(temp);

        testinner temp2=new testinner("2",Color.red);
        temp2.setBounds(200,0,200,400);
        canvas.getContentPane().add(temp2);
    }
}
public class testinner extends JPanel implements ActionListener{
    private JButton button;

    private Color color2;
    public testinner(String title,Color color) {
        super();
        color2=color;
        setSize(200,400);
        setBackground(color);
        setLayout(new FlowLayout());
        button=new JButton(title);
        button.setBounds(getX(), getY(), getWidth(), getHeight());
        button.setVisible(true);
        button.addActionListener(this);
        //panel.add(label);
        add(button);
    }
    public void paintComponent(Graphics gr) {
        gr.setColor(color2);
        gr.fillRect(getX(), getY(), getWidth(), getHeight());

    }
    public void actionPerformed( ActionEvent evt){
        button.setEnabled(false);
        button.setVisible(false);
        //System.out.println(this);
        //shown.setVisible(true);
    }
}

1 Ответ

2 голосов
/ 20 апреля 2020

Давайте посмотрим, что вы сделали. Вы создали JFrame с нулевым макетом. Так что это означает, что он не управляет размером или положением своих детей. (Некоторые могут сказать, что это нерадивый родитель.)

Это означает, что оба ваших JPanels должны запомнить setBounds звонок, который вы им сделали. Который устанавливает и их размер и положение. Таким образом, ваш setSize вызов избыточен.

Вы установили в JPanels менеджер flowLayout. Это означает, что они пытаются управлять размером и положением своих детей. Это не всегда сразу.

Вы вызываете setBounds для своих кнопок. Теперь они действительно запутались. Во-первых, у них есть свои границы и размеры. Не вызывать setBound для не пользовательских компонентов . На самом деле, лучше вообще его не использовать.

Первая панель в порядке. Вы устанавливаете границы вашей кнопки равными (0, 0, 200, 400). Это внутри JPanel, на котором он предназначен для рисования.

Вторая панель не в порядке. Границы вашей кнопки (200, 0, 200, 400) имеют ширину вашего компонента 200, поэтому вы даете кнопке пространство вне панели для рисования. Затем ваш компонент рисования также заполняет прямоугольник за пределами вашей jpanel .

Таким образом, ваши кнопки имеют размер и положение, которые будут изменены при первом обращении к диспетчеру компоновки.

Следующий код управляет тем, что я предполагаю, что вы пытаетесь делать. Есть две цветные панели, каждая из которых показывает JButton. Когда вы нажимаете на нее, она уходит. Это в основном то, что у вас есть с некоторыми лишними битами.

import java.awt.*;
import javax.swing.*;
public class TestBig {
    public static void main(String[] args) {
        JFrame canvas = new JFrame("canvas");
        canvas.setSize(400,400);

        canvas.setLayout(null);

        JPanel leftPanel = new JPanel( new FlowLayout(0, 0, 0) );
        leftPanel.setOpaque(true);
        leftPanel.setBackground(Color.BLUE);

        JPanel rightPanel = new JPanel();
        rightPanel.setOpaque(true);
        rightPanel.setBackground(Color.RED);

        BufferedImage img = new BufferedImage(200, 400, BufferedImage.TYPE_INT_ARGB);
        Graphics g = img.getGraphics();
        g.setColor(Color.YELLOW);
        g.fillRect(0, 0, 200, 400);
        g.dispose();

        JButton left = new JButton(new ImageIcon(img));
        left.setBorder(null);
        left.addActionListener( evt->{
            left.setVisible(false);
        });

        JButton right = new JButton("right");
        right.addActionListener( evt -> {
            right.setVisible(false);
        });

        leftPanel.add(left);
        rightPanel.add(right);

        canvas.add(leftPanel);
        canvas.add(rightPanel);

        leftPanel.setBounds( 0, 0, 200, 400);
        rightPanel.setBounds(200, 0, 200, 400);

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