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:
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.
Here's where that button came from:
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:
I'm not sure if it matters, but I am using Windows 10.
Thanks for any help that can be provided.
I think you need to call
.repaint()
to make your UI less glitchy.