Java “绘制”面板渲染不正确

Java “绘制”面板渲染不正确,java,swing,graphics,jpanel,paintcomponent,Java,Swing,Graphics,Jpanel,Paintcomponent,下面是正在发生的事情: 我想制作一个非常基本的绘画程序来练习使用绘画方法,处理图形,使用工具栏等等。我已经读了很多关于如何做这些事情的书,我确信我遗漏了一行重要的代码,因为paintpanel本身正在呈现一个不应该存在的JMenu。我用actionListeners设置了一个JMenu,但是呈现为extra的JMenu不起任何作用,无法与之交互。这是一张照片: 如下图所示,我可以在菜单上画画,但它仍然没有任何反应。另外,这一次你可以看到一个radom按钮,从程序中的前一个窗口是出于某种原因添加的

下面是正在发生的事情:

我想制作一个非常基本的绘画程序来练习使用绘画方法,处理图形,使用工具栏等等。我已经读了很多关于如何做这些事情的书,我确信我遗漏了一行重要的代码,因为paintpanel本身正在呈现一个不应该存在的JMenu。我用actionListeners设置了一个JMenu,但是呈现为extra的JMenu不起任何作用,无法与之交互。这是一张照片:

如下图所示,我可以在菜单上画画,但它仍然没有任何反应。另外,这一次你可以看到一个radom按钮,从程序中的前一个窗口是出于某种原因添加的

这是按钮的来源:

我不知道如何解决这个问题,下面是相关类的代码:

这是画这幅画的面板。 包装油漆工

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;
    }
}
这是添加到PaintPanel、菜单和稍后的其他按钮等中的主类

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);
    }
}
这两个类应该是与当前问题相关的唯一类,但是如果需要其他类,请告诉我。我只是不想在帖子里塞满无用的信息

下面是我已经尝试过的:

正如您在PaintPanel类中看到的,我添加了一个super.paintComponent(g);方法调用。然而,虽然这完全解决了我的问题,但它一次只绘制一个黑色正方形。我可以想象,因为它会用一个paint调用覆盖面板,然后每次调用repoint时都会绘制正方形

这是一张添加了super.paintComponent(g)的照片:

我不确定这是否重要,但我使用的是Windows10


感谢您提供的任何帮助。

我认为您需要调用
.repaint()
以减少UI的故障。

您不是在调用super.paintComponent方法,而是在注释它——这是危险的代码,不应该这样做。如果希望图像保持不变,请将点放入ArrayList中,然后在paintComponent中绘制点的ArrayList。或者绘制一个BuffereImage,然后在paintComponent方法中绘制它。并始终调用super的paintComponent方法。有一些工作示例,向您展示了如何通过使用上面建议的
列表
缓冲图像
来持久绘制。@HovercraftFullOfEels我在测试时注释掉了super.paintComponent(g)。我的代码中实际上有。如果我从不调用repaint(),它就不会绘制任何东西。至少它不在您给出的代码中,除了在单击处理程序中。您应该在更改UI后调用它。