'Here is a simple drawing pad. Why do the buttons appear in the corner when the UpdateUI() is called during a mouseevent? How do I fix it?

If I push the buttons pen/eraser in the When I call repaint(), it creates an image of the button in the top corner. Why is this happening? How can I prevent these button images from appearing?

I have attempted to layer the frames and many other things but I can't seem to figure it out.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Main extends JPanel implements MouseListener, MouseMotionListener {
    private int lineThickness = 10;
    private int xMousePos, yMousePos;
    private boolean isPressed = true;
    private static JLayeredPane layered;
    private static JToolBar toolBar;
    private static JToggleButton pen, eraser, color;
    private static Main screen;
    private static JFrame app, toolWindow;
    private static Color drawColor;
    private static int i=0;
    public Main() {
        addMouseListener(this);
        addMouseMotionListener(this);
    }

    @Override
    public void paintComponent(Graphics g) {
        g.setColor(drawColor);
        g.fillRect(xMousePos, yMousePos, lineThickness, lineThickness);
    }

    public static void main(String[] args) {
        screen = new Main();
        screen.setBounds(0, 0, 20, 20);
        app = new JFrame("Drawing-Pad");
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(2, 1));
        panel.setFocusable(false);
        panel.setBounds(0, 0, 600, 60);
        panel.setBackground(Color.RED);

        app.setBackground(Color.WHITE);
        app.add(panel);
        app.add(screen);
        app.setVisible(true);
        app.setBounds(0, 0, 600, 400);


        pen = new JToggleButton("Pen");
        eraser = new JToggleButton("Eraser");
        toolBar = new JToolBar();
        toolBar.add(pen);
        toolBar.add(eraser);
        panel.add(toolBar);

        pen.addActionListener(e->{
            ++i;
            eraser.setSelected(false);
            drawColor = Color.BLACK;
        });

        eraser.addActionListener(e->{
            ++i;
            pen.setSelected(false);
            drawColor = Color.WHITE;
        });
    }



    @Override
    public void mouseClicked(MouseEvent e) {
        //isPressed = false;
    }

    @Override
    public void mousePressed(MouseEvent e) {
        xMousePos = e.getX();
        yMousePos = e.getY();
        if(e.getY()>60 && i == 0) updateUI();
        i=0;
    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    @Override
    public void mouseDragged(MouseEvent e) {
        xMousePos = e.getX();
        yMousePos = e.getY();
        if(e.getY()>60 && i == 0) updateUI();
        i=0;
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        xMousePos = e.getX();
        yMousePos = e.getY();
    }
}

I don't know why this is happening please help.



Solution 1:[1]

Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section.

I reworked your code and created the following GUI.

Drawing Pad

I replaced your two JToggleButtons with one JToggleButton. That way, the state is either to draw or to erase.

I created a drawing JPanel. In Swing, the drawing JPanel is completely erased each and every time the JPanel is repainted. That means you have to redraw the entire image each time you call for a JPanel repaint.

I broke up your monolithic main method into several methods and classes. This helps to keep the code organized and makes the code simpler to read, understand, and more importantly, debug.

The first line of any Swing application is a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.

I used Swing layout managers to create the GUI. The JFrame uses a default BorderLayout. The drawing JPanel has a preferred size.

I created an application model to hold all of the drawing points. I kept a java.util.List of these drawing points so I could redraw the entire image each and every time I repainted the drawing JPanel.

I used a MouseAdapter so I only had to code the MouseListener and MouseMotionListener methods I actually needed.

Here's the complete runnable code. I made the additional classes inner classes so I could post the code as one block.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;

public class SimpleDrawingPad implements Runnable {
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SimpleDrawingPad());
    }
    
    private final DrawingPanel drawingPanel;
    
    private final SimpleDrawingModel model;
    
    public SimpleDrawingPad() {
        this.model = new SimpleDrawingModel();
        this.drawingPanel = new DrawingPanel(this, model);
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Drawing Pad");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createToolBar(), BorderLayout.NORTH);
        frame.add(drawingPanel, BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JToolBar createToolBar() {
        JToolBar toolBar = new JToolBar();
        toolBar.setRollover(true);
        
        JToggleButton button = new JToggleButton(" Draw ");
        button.addActionListener(event -> {
            if (button.isSelected()) {
                button.setText("Erase");
                model.setDrawingColor(Color.WHITE);
            } else {
                button.setText(" Draw ");
                model.setDrawingColor(Color.BLACK);
            }
        });
        toolBar.add(button);
        
        return toolBar;
    }
    
    public void repaint() {
        drawingPanel.repaint();
    }
    
    public class DrawingPanel extends JPanel {

        private static final long serialVersionUID = 1L;
        
        private final SimpleDrawingModel model;
        
        public DrawingPanel(SimpleDrawingPad view, SimpleDrawingModel model) {
            this.model = model;
            this.setBackground(Color.WHITE);
            this.setPreferredSize(new Dimension(640, 480));
            
            DrawingListener listener = new DrawingListener(view, model);
            this.addMouseListener(listener);
            this.addMouseMotionListener(listener);
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            
            for (DrawingPoint drawingPoint : model.getDrawingPoints()) {
                g.setColor(drawingPoint.getDrawingColor());
                Point point = drawingPoint.getDrawingPoint();
                int lineThickness = drawingPoint.getLineThickness();
                g.fillRect(point.x, point.y, lineThickness, lineThickness);
            }
        }
        
    }
    
    public class DrawingListener extends MouseAdapter {
        
        private final SimpleDrawingPad view;
        
        private final SimpleDrawingModel model;
        
        public DrawingListener(SimpleDrawingPad view,
                SimpleDrawingModel model) {
            this.view = view;
            this.model = model;
        }

        @Override
        public void mousePressed(MouseEvent event) {
            DrawingPoint drawingPoint = new DrawingPoint(event.getPoint(), 
                    model.getDrawingColor(), model.getLineThickness());
            model.addDrawingPoint(drawingPoint);
            view.repaint();
        }
        
        @Override
        public void mouseDragged(MouseEvent event) {
            DrawingPoint drawingPoint = new DrawingPoint(event.getPoint(), 
                    model.getDrawingColor(), model.getLineThickness());
            model.addDrawingPoint(drawingPoint);
            view.repaint();
        }
        
    }
    
    public class SimpleDrawingModel {
        
        private int lineThickness;
        
        private Color drawingColor;
        
        private List<DrawingPoint> drawingPoints;
        
        public SimpleDrawingModel() {
            this.lineThickness = 10;
            this.drawingColor = Color.BLACK;
            this.drawingPoints = new ArrayList<>();
        }

        public int getLineThickness() {
            return lineThickness;
        }

        public void setLineThickness(int lineThickness) {
            this.lineThickness = lineThickness;
        }

        public Color getDrawingColor() {
            return drawingColor;
        }

        public void setDrawingColor(Color drawingColor) {
            this.drawingColor = drawingColor;
        }

        public List<DrawingPoint> getDrawingPoints() {
            return drawingPoints;
        }

        public void addDrawingPoint(DrawingPoint drawingPoint) {
            this.drawingPoints.add(drawingPoint);
        }
        
    }
    
    public class DrawingPoint {
        
        private final int lineThickness;
        
        private final Color drawingColor;
        
        private final Point drawingPoint;

        public DrawingPoint(Point drawingPoint, Color drawingColor,
                int lineThickness) {
            this.drawingPoint = drawingPoint;
            this.drawingColor = drawingColor;
            this.lineThickness = lineThickness;
        }

        public int getLineThickness() {
            return lineThickness;
        }

        public Color getDrawingColor() {
            return drawingColor;
        }

        public Point getDrawingPoint() {
            return drawingPoint;
        }
        
    }
    
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Gilbert Le Blanc