Paint Panel Incorrect Rendering

106 views Asked by At

Here is what is going on:

I wanted to make a very basic paint program to practice using the paint method, working with graphics, using toolbars, et cetera. I've been doing a lot of reading on how to do these things, and I'm sure I'm missing an important line of code somewhere because the paintpanel itself is rendering a JMenu that isn't supposed to be there. I have a JMenu set up with actionListeners, but the one that is rendered as extra doesn't do anything and cannot be interacted with. Here's a picture: enter image description here

As you can see in the following image, I can paint over the menu and it still does not react at all. Plus, this time you can see a radom button from a previous window in the program is added for some reason. enter image description here

Here's where that button came from: enter image description here

I am at a loss as to how to fix this, so here is the code for the relevant classes:

This is the panel that does the painting. package painter;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;

import javax.swing.JPanel;
import javax.swing.event.MouseInputListener;

@SuppressWarnings("serial")
public class PaintPanel extends JPanel implements MouseInputListener
{
    //These two values will be used to determine where the mouse is and thus where to paint...stuff...
    public int xCoordinate, yCoordinate = -10;

    static Color currentColor = Color.black;

    public PaintPanel()
    {
        //These two methods simply attaches the mouse listener methods listed below to the actual panel.
        addMouseListener(this);
        addMouseMotionListener(this);
    }
    //This method is an overwritten version of the default paint method.  It's job is to render custom graphics
    //objects on the screen.  The Graphics g argument is the item responsible for doing the actual rendering.
    @Override
    public void paintComponent(Graphics g)
    {
        // super.paintComponent(g);
         g.setColor(currentColor);
         g.fillRect(xCoordinate, yCoordinate, 10, 10);
    }

    @Override
    //This method, added because of the MouseInputListener implementation, is used when a user clicks the left mouse button.
    public void mouseClicked(MouseEvent e) 
    {
        xCoordinate = e.getX();
        yCoordinate = e.getY();
        repaint();
    }
    @Override
    public void mouseEntered(MouseEvent arg0) 
    {
        // TODO Auto-generated method stub

    }
    @Override
    public void mouseExited(MouseEvent arg0)
    {
        // TODO Auto-generated method stub

    }

    @Override
    public void mousePressed(MouseEvent arg0) 
    {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseReleased(MouseEvent arg0) 
    {
        // TODO Auto-generated method stub

    }

    @Override
    //This method, added because of the MouseInputListener implementation, is used when a user presses and holds the
    //left mouse button while moving the mouse.
    public void mouseDragged(MouseEvent e) 
    {   
        xCoordinate = e.getX();
        yCoordinate = e.getY();
        repaint();
    }

    @Override
    public void mouseMoved(MouseEvent arg0) 
    {
        // TODO Auto-generated method stub

    }
    public static void changeColor(Color color)
    {
        currentColor = color;
    }
}

This is the main class that adds in the PaintPanel, the menu, and later other buttons and such.

package painter;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;

import painter.menu.FileMenu;
import painter.menu.ToolsMenu;

@SuppressWarnings("serial")
//This class will do the job of bringing together all the various sub-classes and rendering everything.
public class MainPainterGUI extends JFrame
{
    private JPanel menuPanel;

    private JMenuBar menuBar;

    //These values are going to be used to set an initial window size.
    private final short WINDOW_HEIGHT = 1000;
    private final short WINDOW_WIDTH = 1000;

    //This constructor will do the actual creation of the window.
    public MainPainterGUI()
    {
        //This does the same thing that setTitle does.
        super("Painter");
        //setTitle("Painter");

        //This method will set what the window is supposed to do when the red x is clicked.
        //Technically, the value passed is an integer.
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        //Obviously this method sets the initial size of the window.  It can be changed by the user however.
        setSize(WINDOW_WIDTH,WINDOW_HEIGHT);

        //This method sets the center of the window relative to whatever is passed.  In this case, null makes
        //the window appear in the center of the desktop regardless of the size.
        setLocationRelativeTo(null);

        menuPanel = new JPanel();

        menuBar = new JMenuBar();

        menuBar.add(new FileMenu());
        menuBar.add(new ToolsMenu());

        menuPanel.add(menuBar);

        //The add method simply attaches a component to whatever is calling, like a frame or another panel.
        //The BorderLayout is needed to use the draggable toolbar.
        add(new PaintPanel(), BorderLayout.CENTER);
        add(menuPanel, BorderLayout.NORTH);

        //This will allow the window to be seen.  Make sure this method is last, as if 
        //a component is created afterwards it may not be visible.
        setVisible(true);
    }
}

Those two classes should be the only ones relevant to the current problem, however let me know if other classes are needed. I just didn't want to clutter the post with useless information.

Now, here is what I have tried already:

As you can see in the PaintPanel class, I had added a super.paintComponent(g); method call. However, while this completely fixes my problem, it only paints a single black square at a time. I would imagine because it's overwriting the panel with a paint call, then painting the square each time repaint is called.

Here's a photo with super.paintComponent(g) added: enter image description here

I'm not sure if it matters, but I am using Windows 10.

Thanks for any help that can be provided.

1

There are 1 answers

2
Joonazan On

I think you need to call .repaint() to make your UI less glitchy.