Odd graphical bug: a copy of component A is painted on component B. HELP! (java)
I have made a simple paint program in which you can use a brush-tool to paint some different colors and era开发者_如何学编程se (simply paint in white).
It works fine, but I have a very strange graphical bug which causes the toolpanel and the last mouseovered color/tool-icon to be painted on top of the drawpanel.
Implementation: The frame holds two extentions of JPanel: a ToolPanel and a DrawPanel. ToolPanel holds two JPanels which hold the color- and toolbuttons. The Buttons are extensions of JComponent.
link to screenshot (I'm not allowed to post images appearently):
note: The buttons in the second "fake" toolpanel are not actual buttons that can be clicked and I can paint on top of it. If I paint on the "fake" color button in the left corner it will be repainted again when I mouseover a new color and enter the drawpanel with the mouse.
note 2: I used to have a JMenuBar which was also painted in the drawpanel. It was repainted each time the drawpanel is mouseovered after the window (not just the panel) lost focus once.
Some code: (I know the tool selection implementation isn't the best :P)
DrawPanel's paintComponent method:
public void paintComponent(Graphics g) {
if(isMousePressed) {
if(tool == "BRUSH") {
g.setColor(color);
g.fillOval(currentEvent.getX(), currentEvent.getY(), 30, 30);
} else if(tool == "ERASER") {
g.setColor(getBackground());
g.fillOval(currentEvent.getX(), currentEvent.getY(), 30, 30);
}
}
}
Let me know if there is any relevant information or code that I left out.
Hypothesis: I didn't call super.paintComponent in DrawPanels paintComponent-method, maybe that causes some problems? The reason that I didn't is that if I do, it will repaint the background all the time so only the dot I painted last will be visible. Not sure if the supercall actually solves the problem or if the fake-panel is just covered by the background as well. Maybe I need to work around that some other way? Or is it something else?
Thanks!
It's been a long time since I worked with Swing but your basic problem is the fact the background is not being repainted. This does mean a proper working component should paint the entire area every single time, so you will have to save and repaint any previous drawing.
You could try setting your component to transparent (check for a setTransparent or setOpaque method) but as it's been several years I'm not sure what the exact result will be.
It sounds like you're probably altering the Graphics object instead of creating new ones (g.create()
) and therefore doing stuff like setting bounds or clip regions that might alter paint positions.
If you can post a bit more detail (such as all the places you paint) or even a full SSCCE, then I will update this answer to be more specific. Until then, that's impossible.
It is good practise to always create a new Graphics
object to work with.
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (isMousePressed) {
// create the new Graphics context which
// we can work with/modify independently
g2 = g.create();
// use "str".equals() for String comparisons
if ("BRUSH".equals(tool)) {
g2.setColor(color);
g2.fillOval(currentEvent.getX(), currentEvent.getY(), 30, 30);
} else if ("ERASER".equals(tool)) {
g2.setColor(getBackground());
g2.fillOval(currentEvent.getX(), currentEvent.getY(), 30, 30);
}
// you should always dispose() of a Graphics
g2.dispose();
}
}
精彩评论