Why, when I change the size of the window, do the drawn components disappear?

2

I built an application using the windowbuilder of eclipse. In it, when clicking with the mouse, a figure is drawn according to the last button selected.

However, when I change the size of the window, all the drawings disappear.

After reading this question , that tutorial , and this article ; I suppose I should override the paint(Graphics g) method and add fields to a class that stores the drawings.

But it is not clear to me where I would do this. Because I really do not understand what's going on behind the scenes of the code.

Class created with windowbuilder

public class PintarFiguras {

    private JFrame frame;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    PintarFiguras window = new PintarFiguras();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public PintarFiguras() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBackground(Color.GRAY);
        frame.getContentPane().setBackground(Color.GRAY);
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel canvas = new JPanel();
        canvas.setBackground(Color.WHITE);
        canvas.setForeground(Color.BLACK);
        canvas.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                // pegar coordenadas
                int x = e.getX();
                int y = e.getY();

                Graphics g = canvas.getGraphics(); 

                Artista.desenhar(g,x,y);
            }
        });
        frame.getContentPane().add(canvas, BorderLayout.CENTER);
        canvas.setLayout(new CardLayout(0, 0));

        JToolBar toolBar = new JToolBar();
        frame.getContentPane().add(toolBar, BorderLayout.NORTH);

        JButton btnQuadrado = new JButton("quadrado");
        btnQuadrado.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Artista.setModo(MODOS.QUADRADO);
            }
        });
        toolBar.add(btnQuadrado);

        Component horizontalStrut = Box.createHorizontalStrut(20);
        toolBar.add(horizontalStrut);

        JButton btnCirculo = new JButton("circulo");
        btnCirculo.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Artista.setModo(MODOS.CIRCULO);
            }
        });
        toolBar.add(btnCirculo);

        Component horizontalStrut_1 = Box.createHorizontalStrut(20);
        toolBar.add(horizontalStrut_1);

        JButton btnNada = new JButton("nada");
        btnNada.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Artista.setModo(MODOS.NADA);
            }
        });
        toolBar.add(btnNada);

        Component horizontalStrut_2 = Box.createHorizontalStrut(20);
        toolBar.add(horizontalStrut_2);

        JButton btnLimpar = new JButton("limpar");
        btnLimpar.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Graphics g = canvas.getGraphics();
                g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
                frame.setBackground(Color.WHITE);
            }
        });
        toolBar.add(btnLimpar);
    }

}

Enum of the figures to draw

public enum MODOS {
QUADRADO, CIRCULO, NADA}

Class artist, who does the drawings

public abstract class Artista {
    private static MODOS modo = MODOS.NADA;

    public static MODOS getModo() {
        return modo;
    }

    public static void setModo(MODOS modo) {
        Artista.modo = modo;
    }

    /**
     * pinta um objeto de acordo com o modo
     * https://docs.oracle.com/javase/tutorial/2d/basic2d/index.html
     */
    public static void desenhar(Graphics g, int x, int y) {     
        switch(modo){   

        case QUADRADO:
            pintarQuadrado(g,x,y);
            break;

        case CIRCULO:
            pintarCirculo(g,x,y);
            break;

        case NADA:
            break;
        }       
    }

    private static void pintarQuadrado(Graphics g, int x, int y) {
        g.fillRect(x, y, 20, 10);
    }

    private static void pintarCirculo(Graphics g, int x, int y) {
        g.drawOval(x, y, 20, 20);
    }

}
    
asked by anonymous 12.07.2016 / 14:30

1 answer

4

The components are disappearing as they are only being added and painted once in the JPanel , but there is no callback of the paint(Graphics g) method, which is always called when it is necessary to paint the screen again, as in your case in a resize. So when you change the size of the screen, the objects will only appear again when you, from what I saw in the method, click somewhere on the screen.

Virtually Java does all the dirty work through the paint method and it makes sure that the objects will be drawn after some changes to the panel.

One solution would be to make your class PintarFiguras extend from JPanel and thus override the paint method and put the desenhar(Graphics g, int x, int y) method inside.

So, in MouseListener in mouseClicked just call repaint .

For JPanel reference, you do not need to create a new object, just call this (in class scope, of course)

Now, the variables x and y that were created within mouseClicked , just make them in the scope of the class and assign the values normally.

The class PintarFiguras would look like this:

public class PintarFiguras extends JPanel {

private int x, y;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                new PintarFiguras();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public PintarFiguras() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {

    final JFrame frame = new JFrame();
    frame.setBackground(Color.GRAY);
    frame.getContentPane().setBackground(Color.GRAY);
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    this.setBackground(Color.WHITE);
    this.setForeground(Color.BLACK);
    this.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            // pegar coordenadas
            PintarFiguras.this.x = e.getX();
            PintarFiguras.this.y = e.getY();

            repaint();
        }
    });
    frame.getContentPane().add(this, BorderLayout.CENTER);
    this.setLayout(new CardLayout(0, 0));

    JToolBar toolBar = new JToolBar();
    frame.getContentPane().add(toolBar, BorderLayout.NORTH);

    JButton btnQuadrado = new JButton("quadrado");
    btnQuadrado.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Artista.setModo(MODOS.QUADRADO);
        }
    });
    toolBar.add(btnQuadrado);

    Component horizontalStrut = Box.createHorizontalStrut(20);
    toolBar.add(horizontalStrut);

    JButton btnCirculo = new JButton("circulo");
    btnCirculo.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Artista.setModo(MODOS.CIRCULO);
        }
    });
    toolBar.add(btnCirculo);

    Component horizontalStrut_1 = Box.createHorizontalStrut(20);
    toolBar.add(horizontalStrut_1);

    JButton btnNada = new JButton("nada");
    btnNada.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Artista.setModo(MODOS.NADA);
        }
    });
    toolBar.add(btnNada);

    Component horizontalStrut_2 = Box.createHorizontalStrut(20);
    toolBar.add(horizontalStrut_2);

    JButton btnLimpar = new JButton("limpar");
    btnLimpar.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            limparTela();
        }
    });
    toolBar.add(btnLimpar);

    frame.setVisible(true);
}

public void paint(Graphics g){
    super.paint(g);
    Artista.desenhar(g, this.x, this.y);
}

public void limparTela(){
    Graphics g = this.getGraphics();
    g.setColor(Color.white);
    g.fillRect(0, 0, getWidth(), getHeight());
}

EDIT: As @diegofm indicated, I declared JFrame as the end within the scope of the method, so that it can be called normally within anonymous classes, as used by the OP.

    
12.07.2016 / 15:23