javaswinggraphicspaintcomponent

Is there a way to make a 2nd click change the result?


I'm trying to make it when you click the cameraButton, the graphics show, but when clicked again, it closes.

@Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        int camButtonWidth = 500;
        int camButtonHeight = 33;
        int camButtonX = (width - camButtonWidth) / 2;
        int camButtonY = (height - camButtonHeight) - 5;

        int camWidth = width - 50;
        int camHeight = (height - (camButtonHeight * 2)) - 10;
        int camX = (width - camWidth) / 2;
        int camY = ((height - camHeight) - camButtonHeight) / 2;


        Graphics2D g1 = (Graphics2D) g;
        Graphics2D g2 = (Graphics2D) g;
        Graphics2D g3 = (Graphics2D) g;


        RoundRectangle2D camButton = new RoundRectangle2D.Double(camButtonX, camButtonY, camButtonWidth, camButtonHeight, 25, 25);
        RoundRectangle2D cameras = new RoundRectangle2D.Double(camX, camY, camWidth, camHeight, 25, 25);

        // Background
        g1.setColor(Color.BLACK);
        g1.fillRect(0, 0, width, height);

        addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (camButton.contains(e.getPoint())) {
                    camUp = !camUp;
                    repaint();
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {

            }

            @Override
            public void mouseReleased(MouseEvent e) {

            }

            @Override
            public void mouseEntered(MouseEvent e) {

            }

            @Override
            public void mouseExited(MouseEvent e) {

            }
        });

        // Camera Button
        g2.setColor(camColor);
        g2.fill(camButton);


        paintCameras = camUp;


        // Cameras
        g3.setColor(camColor);
        if (paintCameras) {
            g3.fill(cameras);
        }


        repaint();
    }

Try to change make it when you click the camera button, a graphics object shows, but when clicked again, it closes.


Solution

  • To get this sort of program to work you should:

    1. Create your MouseListener in code that is only called once, such as within a constructor
    2. Create an instance field in the class to represent the camera button, such as a Rectangle or RoundRectangle2D and give it a viable object reference
    3. In the mouse listener, toggle the state of a boolean variable if a click occurs within the shape that represents the camera button, e.g., camUp = !camUp; as you're doing
    4. And then call repaint().
    5. In the paintComponent method, check the state of the boolearn variable with an if statement, and if true, draw the image inside the if statement.
    6. Keep the mouse listener and the painting code separate and in separate methods (or constructor).
    7. Never call repaint() within a painting method as that will cause an uncontrolled animation. If you need a Swing animation, then use a Swing Timer so that you can fully control it. I don't see the need for it here.

    For example:

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.*;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class GraphicsExample extends JPanel {
        private static final int IMG_WIDTH = 400;
        private static final int PREF_W = (3 * IMG_WIDTH) / 2;
        private static final int PREF_H = PREF_W;
        private static final Color BTN_COLOR = Color.RED;
        private static final Color HOVER_COLOR = new Color(255, 100, 100);
        private static final Color BTN_CLK_COLOR = new Color(180, 0, 0);
        private static final int IMG_X = IMG_WIDTH / 2;
        private static final int IMG_Y = IMG_X;
        private double camX = 10;
        private double camY = camX;
        private double camWidth = 200;
        private double camHeight = 80;
        private Color buttonColor = Color.RED;
        private RoundRectangle2D cameraButton = new RoundRectangle2D.Double(camX, camY, camWidth, camHeight, 25, 25);
        private Image img;
        private boolean showImage = false;
        private JCheckBox toggleModeChkBox = new JCheckBox("Toggle Mode");
        // private boolean toggleMode = true;
    
        public GraphicsExample() {
            add(toggleModeChkBox);
            setPreferredSize(new Dimension(PREF_W, PREF_H));
            img = createMyImage();
            MouseAdapt mouseAdapt = new MouseAdapt();
            addMouseListener(mouseAdapt);
            addMouseMotionListener(mouseAdapt);
        }
    
        private Image createMyImage() {
            BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_WIDTH, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2 = img.createGraphics();
            g2.setPaint(new GradientPaint(0, 0, Color.RED, 100, 100, Color.BLUE, true));
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            int gap = 10;
            g2.fillOval(gap, gap, IMG_WIDTH - 2 * gap, IMG_WIDTH - 2 * gap);
            g2.dispose();
            return img;
        }
    
        private class MouseAdapt extends MouseAdapter {
            @Override
            public void mousePressed(MouseEvent e) {
                if (cameraButton.contains(e.getPoint())) {
                    buttonColor = BTN_CLK_COLOR;
                    if (toggleModeChkBox.isSelected()) {
                        showImage = !showImage;
                    } else {
                        showImage = true;
                    }
                } else {
                    buttonColor = BTN_COLOR;
                }
                repaint();
            }
    
            @Override
            public void mouseReleased(MouseEvent e) {
                if (cameraButton.contains(e.getPoint())) {
                    buttonColor = HOVER_COLOR;
                } else {
                    buttonColor = Color.RED;
                }
                
                if (!toggleModeChkBox.isSelected()) {
                    showImage = false;
                }
                repaint();
            }
    
            @Override
            public void mouseMoved(MouseEvent e) {
                if (cameraButton.contains(e.getPoint())) {
                    buttonColor = HOVER_COLOR;
                } else {
                    buttonColor = Color.RED;
                }
                if (!toggleModeChkBox.isSelected()) {
                    showImage = false;
                }
                repaint();
            }
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
    
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setColor(buttonColor);
            g2.fill(cameraButton);
            
            if (showImage) {
                int x = (getWidth() - IMG_WIDTH) / 2;
                int y = (getHeight() - IMG_WIDTH) / 2;
                g2.drawImage(img, x, y, this);
            }
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> {
                GraphicsExample mainPanel = new GraphicsExample();
    
                JFrame frame = new JFrame("GUI");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(mainPanel);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            });
        }
    
    }