覆盖绘制(图形g)Java

覆盖绘制(图形g)Java,java,swing,paint,paintcomponent,undo,Java,Swing,Paint,Paintcomponent,Undo,我在NetBeans中的GUI有点问题。当用户在JPanel中的鼠标点击位置点击时,我会绘制图像(点)。这部分很好用。我将每个图像位置存储在两个不同的ArrayList中,其中包含X位置和Y位置。现在,我想做的是在单击按钮后删除面板中绘制的最新图像。因此,我所做的是删除两个ArrayList的最后一个索引,然后调用repaint()从X和Y ArrayList中的位置绘制所有图像(下面的代码) 奇怪的是,我需要调整GUI的大小(将其置于全屏或仅更改其大小),以便在JPanel中再次显示绘制的图像

我在NetBeans中的GUI有点问题。当用户在JPanel中的鼠标点击位置点击时,我会绘制图像(点)。这部分很好用。我将每个图像位置存储在两个不同的ArrayList中,其中包含X位置和Y位置。现在,我想做的是在单击按钮后删除面板中绘制的最新图像。因此,我所做的是删除两个ArrayList的最后一个索引,然后调用repaint()从X和Y ArrayList中的位置绘制所有图像(下面的代码)

奇怪的是,我需要调整GUI的大小(将其置于全屏或仅更改其大小),以便在JPanel中再次显示绘制的图像,否则面板将保持为空

以下是受影响的代码部分:

public void paint(Graphics g) {

    super.paint(g);
    for(int i=0;i<=listePointsX.size()-1;i++) {
        try{
            BufferedImage icon = ImageIO.read(getClass().getResourceAsStream("/myimage.png"));
            Graphics graphe = jPanel1.getGraphics();
            graphe.setColor(Color.BLACK);
            graphe.drawImage(icon, this.listePointsX.get(i),this.listePointsY.get(i), rootPane);
        }catch(Exception e1){

        }
    }

private void jButtonUndoActionPerformed(java.awt.event.ActionEvent evt) {                                            
    if(listePointsX.size()>0){
        int lastObject= listePointsX.size();
        listePointsX.remove(lastObject-1);
        listePointsY.remove(lastObject-1);
        jPanel1.repaint();         
    }
    else{

    }


}   
public void绘制(图形g){
超级油漆(g);
对于(int i=0;i0){
int lastObject=listpointsx.size();
listpointsx.remove(lastObject-1);
listpointsy.remove(lastObject-1);
jPanel1.repaint();
}
否则{
}
}   

你知道我需要做些什么来“刷新”整件事吗?我做错什么了吗?我试着搜索,但没有找到任何东西

Graphics graph=jPanel1.getGraphics()不是绘制的工作方式,相反,您应该覆盖面板的
paintComponent
方法并在中绘制点

有关如何在Swing中进行绘制的更多详细信息,请参见和

相反,您的面板应该完成所有工作,管理
ArrayList
中的点并绘制它们。如果满足您的设计要求,您的父组件“可能”有能力添加或删除点,但核心责任仍在面板上


避免在
paint
方法中执行任何长时间运行或块操作,它们应尽可能快地运行。由于映像从不更改,因此您只需加载一次(无论是在构建类时还是在您第一次需要映像时),并继续使用相同的引用。

Graphics graph=jPanel1.getGraphics()不是绘制的工作方式,相反,您应该覆盖面板的
paintComponent
方法并在中绘制点

有关如何在Swing中进行绘制的更多详细信息,请参见和

相反,您的面板应该完成所有工作,管理
ArrayList
中的点并绘制它们。如果满足您的设计要求,您的父组件“可能”有能力添加或删除点,但核心责任仍在面板上


避免在
paint
方法中执行任何长时间运行或块操作,它们应尽可能快地运行。由于图像永远不会更改,因此您只需加载一次(无论是在构建类时还是在您第一次需要图像时),并继续使用相同的引用。

好的,现在它工作得很好。我必须按照你告诉我的方式来做。我创建了一个扩展jPanel的新类(如下)。然后在我的主窗体中,必须创建这个类的对象。每当用户单击时,它都会调用此图形类对象并将一个项目添加到ArrayList(此对象管理有关创建点的所有内容…如下所示:

public class MyDrawingClass extends JPanel {
ArrayList<Integer> arrayListPointX = new ArrayList<>();
ArrayList<Integer> arrayListPointY = new ArrayList<>();

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    try{
    BufferedImage icon = ImageIO.read(getClass().getResourceAsStream("/images/dot.png"));
    g.setColor(Color.BLACK);
    if(arrayListPointX.size()<=0){
        ...
    }
    else{
        for(int i=0;i<listePointsX.size();i++){
                g.setColor(Color.BLACK);
                g.drawImage(icon, listePointsX.get(i), listePointsY.get(i), rootPane);
        }
    }
    }catch(Exception e){
        ...
    }
}
公共类MyDrawingClass扩展了JPanel{
ArrayList arrayListPointX=新的ArrayList();
ArrayList arrayListPointY=新的ArrayList();
@凌驾
公共组件(图形g){
超级组件(g);
试一试{
BuffereImage icon=ImageIO.read(getClass().getResourceAsStream(“/images/dot.png”);
g、 设置颜色(颜色为黑色);

如果(arrayListPointX.size()好的话,它现在工作得很好。我必须按照你在这里告诉我的方式来做。我创建了一个扩展jPanel的新类(如下)。然后在我的主窗体中,必须创建这个类的对象。每当用户单击时,它都会调用这个绘图类对象并向ArrayList添加一个项(此对象管理有关创建点的所有内容…它看起来如下所示:

public class MyDrawingClass extends JPanel {
ArrayList<Integer> arrayListPointX = new ArrayList<>();
ArrayList<Integer> arrayListPointY = new ArrayList<>();

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    try{
    BufferedImage icon = ImageIO.read(getClass().getResourceAsStream("/images/dot.png"));
    g.setColor(Color.BLACK);
    if(arrayListPointX.size()<=0){
        ...
    }
    else{
        for(int i=0;i<listePointsX.size();i++){
                g.setColor(Color.BLACK);
                g.drawImage(icon, listePointsX.get(i), listePointsY.get(i), rootPane);
        }
    }
    }catch(Exception e){
        ...
    }
}
公共类MyDrawingClass扩展了JPanel{
ArrayList arrayListPointX=新的ArrayList();
ArrayList arrayListPointY=新的ArrayList();
@凌驾
公共组件(图形g){
超级组件(g);
试一试{
BuffereImage icon=ImageIO.read(getClass().getResourceAsStream(“/images/dot.png”);
g、 设置颜色(颜色为黑色);

if(arrayListPointX.size()天哪,你在一个绘画方法中多次重复读取图像文件,这个方法需要非常快。不要这样做一次,更不要说多次。接下来,你不应该覆盖绘画,而应该覆盖绘画组件,你不应该有空的捕捉块……这里有太多错误。请停止,阅读教程首先是als,因为你只是在猜测,并且做出了很多错误的猜测。是的,气垫船说了什么。移动图像IO.read()在for循环外调用,以便只执行一次。@Parapa:图像读取不仅应该在循环外,还应该在所有绘制方法之外。绘制方法的速度是GUI程序感知响应的主要决定因素,决不能像上面的代码中那样被文件I/O减慢。@Hover克拉夫特:我知道Catch块是空的,我只是还没有这样做,但我肯定不会让它空的,哈哈。对于ImageIO.read(),就像你说的,它不会改变,所以我不会把它留在循环中…在paint方法中也不会,它只是一个静态类变量。上帝啊,你在一个paint方法中多次重复读取图像文件,一个需要非常快的方法。永远不要这样做一次,更不用说多次了。接下来,你不应该这样做不要覆盖绘画,而应该覆盖绘画组件,你不应该有空的捕捉块,…这里有很多错误。请停止,先阅读教程,因为你是j