Возникли проблемы при отрисовке прямоугольника при нажатии кнопки - PullRequest
1 голос
/ 08 октября 2019

Я пытаюсь добавить Rectangle в панель нажатием кнопки и удалить его другим. Это должно работать, но ничего не делает, и я абсолютно не знаю почему.

Может кто-нибудь объяснить, что я делаю неправильно, и дать мне несколько полезных советов, которые я могу улучшить с помощью своего кода?

public class GUI extends JPanel {

    public static boolean isRecVisible = false;

    public static void main(String[] args) {
        createGui();
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        super.paintComponent(g);
        g2d.drawRect(10, 10, 200, 200);
    }

    public static void createGui() {

        int frameWidth = 550;
        int frameHeight = 400;

        int buttonWidth1 = 250;
        int buttonHeight1 = 30;

        int buttonWidth2 = 500;
        int buttonHeight2 = 30;

        int displayWidth = frameWidth - 20;
        int displayHeight = frameHeight - 105;

        GUI drawRec = new GUI();

        JFrame f = new JFrame("Rectangle");
        JPanel p = new JPanel();
        JPanel display = new JPanel();
        JButton addRec = new JButton("Add Rectangle");
        JButton removeRec = new JButton("Remove Rectangle");
        JButton colorRec = new JButton("Color Rectangle");

        f.add(p);
        p.add(addRec);
        p.add(removeRec);
        p.add(colorRec);
        p.add(display);

        display.setBackground(Color.LIGHT_GRAY);

        f.setSize(frameWidth, frameHeight);
        f.setLocationRelativeTo(null);
        f.setResizable(false);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);

        display.setBounds(frameWidth / 2 - displayWidth / 2, 10, displayWidth, displayHeight);
        addRec.setBounds(frameWidth / 2 - buttonWidth1 / 2 - 250 / 2, frameHeight - 85, buttonWidth1, buttonHeight1);
        removeRec.setBounds(frameWidth / 2 - buttonWidth1 / 2 + 250 / 2, frameHeight - 85, buttonWidth1, buttonHeight1);
        colorRec.setBounds(frameWidth / 2 - buttonWidth2 / 2, frameHeight - 60, buttonWidth2, buttonHeight2);

        addRec.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (isRecVisible == false) {
                    isRecVisible = true;
                    display.add(drawRec);
                    display.repaint();
                    System.out.println("Rectangle has been drawn!");

                } else {
                    System.out.println("Rectangle has already been drawn!");
                    return;
                }
            }
        });

        removeRec.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (isRecVisible == true) {
                    isRecVisible = false;
                    System.out.println("Rectangle has been removed!");

                } else {
                    System.out.println("Rectangle has already been removed");
                    return;
                }
            }
        });
    }
}

Ответы [ 2 ]

1 голос
/ 08 октября 2019

Вместо того, чтобы добавлять или удалять компоненты, здесь было бы более целесообразно добавить настраиваемую окрашенную панель в конструкцию и использовать логическое значение isRecVisible в качестве флага для проверки рисования прямоугольника.

Что-то вродепоказано здесь:

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

public class GUI extends JPanel {

    public static boolean isRecVisible = false;

    public static void main(String[] args) {
        createGui();
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        super.paintComponent(g);
        if (isRecVisible) {
            g2d.drawRect(10, 10, 200, 200);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(600,400);
    }

    public static void createGui() {
        int frameWidth = 550;
        int frameHeight = 400;

        GUI drawRec = new GUI();
        drawRec.setBackground(Color.LIGHT_GRAY);

        JFrame f = new JFrame("Rectangle");
        JPanel p = new JPanel();
        JButton addRec = new JButton("Add Rectangle");
        JButton removeRec = new JButton("Remove Rectangle");
        JButton colorRec = new JButton("Color Rectangle");

        f.add(p, BorderLayout.PAGE_START);
        p.add(addRec);
        p.add(removeRec);
        p.add(colorRec);
        f.add(drawRec);

        f.setSize(frameWidth, frameHeight);
        f.setLocationRelativeTo(null);
        f.setResizable(false);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);

        addRec.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                isRecVisible = true;
                drawRec.repaint();
            }
        });

        removeRec.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                isRecVisible = false;
                drawRec.repaint();
            }
        });
    }
}
1 голос
/ 08 октября 2019
display.add(drawRec);
display.repaint();

Когда вы добавляете (или удаляете) компоненты к видимому фрейму, тогда основная логика такова:

display.add(...);
display.revalidate();
display.repaint(); // sometimes needed

revalidate() - это ключевой метод, потому что он вызывает менеджер компоновки, поэтому размер/ расположение компонента может быть задано.

Однако это все равно не решит проблему, потому что ваша пользовательская панель не имеет предпочтительного размера, поэтому нечего рисовать для вашего компонента.

Вам необходимо переопределить метод getPreferredSize() вашей пользовательской панели, чтобы вернуть предпочтительный размер вашего пользовательского компонента. Так что в вашем случае вы можете установить предпочтительный размер (220, 220), чтобы прямоугольник центрировался на панели.

Прочтите раздел из учебника по Swing на Custom Painting , чтобы узнать большеинформация и полные рабочие примеры.

Примечание: пример учебника также покажет вам, как лучше структурировать ваш код, чтобы убедиться, что GUI создан в потоке диспетчеризации событий.

...