Java 奇怪的图形错误:组件a的副本绘制在组件B上。帮助!(爪哇)

Java 奇怪的图形错误:组件a的副本绘制在组件B上。帮助!(爪哇),java,swing,graphics,paintcomponent,Java,Swing,Graphics,Paintcomponent,我已经做了一个简单的画图程序,你可以使用画笔工具画一些不同的颜色和擦除(简单地画成白色) 它工作正常,但我有一个非常奇怪的图形错误,导致toolpanel和最后一个鼠标覆盖的颜色/工具图标被绘制在drawpanel的顶部 实现:框架包含JPanel的两个扩展:ToolPanel和DrawPanel。ToolPanel包含两个JPanel,其中包含颜色和工具按钮。这些按钮是JComponent的扩展 链接到屏幕截图(我不允许在表面上发布图像): 注意:第二个“假”工具面板中的按钮不是可以单击的实

我已经做了一个简单的画图程序,你可以使用画笔工具画一些不同的颜色和擦除(简单地画成白色)

它工作正常,但我有一个非常奇怪的图形错误,导致toolpanel和最后一个鼠标覆盖的颜色/工具图标被绘制在drawpanel的顶部

实现:框架包含JPanel的两个扩展:ToolPanel和DrawPanel。ToolPanel包含两个JPanel,其中包含颜色和工具按钮。这些按钮是JComponent的扩展

链接到屏幕截图(我不允许在表面上发布图像):

注意:第二个“假”工具面板中的按钮不是可以单击的实际按钮,我可以在上面绘制。如果我在左角的“假”颜色按钮上画画,当我将鼠标移到新颜色上并用鼠标进入绘图面板时,它将再次重新画画

注2:我曾经有一个JMenuBar,它也被画在绘图板上。在窗口(而不仅仅是面板)失去焦点一次后,每次鼠标悬停drawpanel时都会重新绘制

一些代码: (我知道工具选择实现不是最好的:P)

DrawPanel的paintComponent方法:

    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);

        }
    }
}
如果我遗漏了任何相关信息或代码,请告诉我

假设: 我没有在DrawPanels paintComponent方法中调用super.paintComponent,这可能会导致一些问题?我没有这样做的原因是,如果我这样做,它会一直重新绘制背景,因此只有我最后绘制的点才可见。不确定超级球是否真的解决了问题,或者假面板是否也被背景覆盖了。也许我需要用别的方法来解决这个问题?还是别的什么


谢谢

听起来您可能是在更改图形对象,而不是创建新的图形对象(
g.create()
),因此需要设置边界或剪辑区域,以改变绘制位置

如果你可以发布更多的细节(比如你画的所有地方),甚至是完整的,那么我会更新这个答案,让它更具体。在那之前,这是不可能的

始终创建一个新的
图形
对象进行处理是一个很好的做法

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();
    }
}

我已经很久没有使用Swing了,但是你的基本问题是背景没有被重新绘制。这意味着正确的工作组件每次都应该绘制整个区域,因此您必须保存并重新绘制任何以前的图形


您可以尝试将组件设置为透明(检查setTransparent或setOpaque方法),但由于已经过了几年,我不确定确切的结果是什么。

+1“WTF”屏幕截图:DDon不使用“==”来比较字符串。使用equals(…)方法。您是否解决过此问题,或者是否可以创建一个?1+用于“disporing”图形2D副本:谢谢你的回复!我已经根据您的评论更新了paintComponent方法,除了super调用,因为如果我这样做的话,我绘制的最后一个点将是可见的(如果DrawPanel失去焦点,甚至那个点也会消失)。编辑:在我完成之前发布><但是在这种情况下,创建新的图形对象似乎没有帮助。除了DrawPanel,我只画了按钮。而且我不会在任何地方弄乱剪辑。当我画按钮时,我基本上只画一个矩形或一个图标,如果它被鼠标覆盖/按下,它会有一点不同。我们需要从你那里得到更多@tobes,即一个完整的工作示例。谢谢你的回复!我也考虑过类似的事情(一直在重新绘制图纸)。你知道如何实现吗?在你做任何其他事情之前(即最上面的组件)只需打电话。1。听从查尔斯的建议。2.当一个组件绘制时,它需要绘制整个组件。因此,如果你想保留用户以前的画,你必须以某种方式将其存储在内存中,这样你才能复制它。一种方法是存储他们所做的一切,并每次都完成每个步骤,但这可能会变得非常麻烦。另一种方法可能是将其存储为内存中的图像,并在每次添加用户编辑之前绘制它。实际上,这正是您可以做的。对一个图像进行所有绘制,然后在图形上绘制图像。