当前位置: 首页 > 知识库问答 >
问题:

repaint()不调用PaintComponent来使用Graphics2D

万俟宜修
2023-03-14

我已经花了几天时间试图让Graphics2D类在我的代码中工作。我把它的结构化为这样一种方式,即当注册了一个单击事件时,调用reaint()就完成了,但是当它到达调用repaint()的阶段时,这只会产生一个空指针异常。

调试时,这一切都在按预期工作,而不是从油漆组件方法中调用,但是当试图使用油漆组件和reaint()正确调用代码以允许Graphics2D类显示每个点的行时,它不起作用。

我已经包含了代码中我在工作中遇到困难的部分。任何帮助都将非常感激。提前谢谢你。

下面是包含我的mouseListener的GUI类。

public class GUI extends JPanel implements MouseListener {

private JLabel label;

    public BufferedImage getImg() {
    return img;
    }

    public void mouseClicked(java.awt.event.MouseEvent e) {
    // TODO Auto-generated method stub
    label = new JLabel();

    //set point equal to the location of the mouse click on the image label
    Point b = e.getPoint();

    //place we are going to print the dots
    segmentation.x = b.x; //gets the x coordinate 
    segmentation.y = b.y; //gets the y coordinate

    System.out.println("x = " + segmentation.x);
    System.out.println("y = " + segmentation.y);        

    //set the global img in the segmentation class equal to that of the one in the current tab
    segmentation.setImg(tabbedPane.getSelectedIndex(), getImg());
    segmentation.paintUpdate();
    label = segmentation.getLabel();

    //if i run this line of code the existing label I already have with simply vanish because of the paintComponent method not being called upon properly.
    //tabbedPane.setComponentAt(tabbedPane.getSelectedIndex(), label);
}

这是一个Segmentation类,它包含paintComponent方法,我在正确调用该方法时遇到了问题。

public class Segmentation extends JLabel {

public int[] xpoints = new int[50];
public int[] ypoints = new int[50];
private int npoints = 0;
public int x;
public int y;
GeneralPath polyline;
Graphics2D g2;
JLabel label;
BufferedImage img;
ImageIcon icon;

public void paintUpdate() {
    repaint();
}

public void setImg(int tabNum, BufferedImage img) {
    this.img = img;
}

public GeneralPath createPath() {

    //      if (npoints > 0) {
    polyline.moveTo(xpoints[0], ypoints[0]);

    for(int i = 1; i < xpoints.length; i++) {
        //add the position of the point to the respective x and y arrays
        polyline.lineTo(xpoints[i], ypoints[i]);        
    }
    //      }
    return polyline;
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);

    System.out.println("we're in the paint component method");

    //set up for the new jlabel
    label = new JLabel();
    label.setIcon(new javax.swing.ImageIcon(img));
    label.setHorizontalAlignment(JLabel.LEFT);
    label.setVerticalAlignment(JLabel.TOP);

    //add the position of the point to the respective x and y arrays
    xpoints[npoints] = x;
    ypoints[npoints] = y;

    if (npoints == 0) {
        JOptionPane.showMessageDialog(null, "Your first point has been added successfully");
    }
    else {
        JOptionPane.showMessageDialog(null, "Your " + npoints + " rd/th" + " point has been added successfully");
    }

    polyline = createPath();

    // Draws the buffered image to the screen.
    g2.drawImage(img, 0, 0, this);

    g2.draw(polyline);

    npoints++;
}

共有1个答案

钱毅
2023-03-14

您的Segmentation类有两个JLabel,一个是类本身的对象,它有一个paintComponent覆盖,可能从未使用过:

public class Segmentation extends JLabel {

另一个是一个名为label的JLabel,由类中的composition持有,该类没有方法重写,实际上使用了该方法重写,并且似乎“隐藏”了该类的实例:

JLabel label

如果希望调用paintComponent,则需要使用事实上覆盖该方法的label对象。

此外,您似乎正在油漆组件(...)方法(??)中创建组件。永远不要这样做,也不要在这个方法中使用程序逻辑。

编辑:
要在图像上绘制,我通常会重写油漆组件,并使用它的图形/图形2D对象绘制。例如:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.*;

public class DrawOnLabel extends JLabel {
   public static final String GIRAFFE_IMG_URL = "http://upload.wikimedia.org/wikipedia/commons/thumb" +
        "/9/9e/Giraffe_Mikumi_National_Park.jpg/474px-Giraffe_Mikumi_National_Park.jpg";
   private static final Color LINES_COLOR = Color.red;
   private static final Color CURRENT_LINE_COLOR = new Color(255, 200, 200);
   private List<Line2D> lineList = new ArrayList<Line2D>();
   private Line2D currentLine = null;

   public DrawOnLabel() throws IOException {
      URL giraffeUrl = new URL(GIRAFFE_IMG_URL);
      BufferedImage img = ImageIO.read(giraffeUrl);
      ImageIcon icon = new ImageIcon(img);
      setIcon(icon);

      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      addMouseListener(myMouseAdapter);
      addMouseMotionListener(myMouseAdapter);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

      g2.setColor(LINES_COLOR);
      for (Line2D line : lineList) {
         g2.draw(line);
      }
      if (currentLine != null) {
         g2.setColor(CURRENT_LINE_COLOR);
         g2.draw(currentLine);
      }
   }

   private class MyMouseAdapter extends MouseAdapter {
      Point p1 = null;

      @Override
      public void mousePressed(MouseEvent e) {
         p1 = e.getPoint();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         if (currentLine != null) {
            currentLine = new Line2D.Double(p1, e.getPoint());
            lineList.add(currentLine);
            currentLine = null;
            p1 = null;
            repaint();
         }
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         if (p1 != null) {
            currentLine = new Line2D.Double(p1, e.getPoint());
            repaint();
         }

      }
   }

   private static void createAndShowGui() {
      DrawOnLabel mainPanel = null;
      try {
         mainPanel = new DrawOnLabel();
      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }

      JFrame frame = new JFrame("DrawOnLabel");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.setResizable(false);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
 类似资料:
  • 在试图制作一个非常简单的子弹地狱游戏来学习java时,我遇到了一个障碍: repaint()没有调用油漆组件()。 这是整个程序,目前只需将我每秒创建50次的图像绘制到JFrame上的JPanel上。 在使用断点和println方法进行了一些调试之后,我可以确认正在读取正确的图像,gameTimerAction中的计时器每秒被调用50次,并且repaint()根本没有调用paintComponen

  • 对于我的程序,我目前希望使用open按钮打开JFileChooser并选择一个图像,然后在applet左侧的JPanel上绘制它,我知道该文件正在被检索,但当我重新绘制图形上下文时,什么也没有发生。提前谢了。

  • 首先,请不要因为创建一个问题而将我置于火刑柱上,而其他具有类似名称和内容的人却存在。我把它们都看了一遍,但没有找到解决办法。 调用repaint()绝对不会调用paintComponent(),不管我似乎尝试了什么。下面是与问题相关的所有代码: 按照预期,“创建的级别面板和设置的内容窗格”被打印到控制台。 从不打印“油漆组件级油漆”。“计时器重新绘制”每2秒打印一次,正如预期的那样。

  • 这里我的程序旨在创建一个GUI,允许用户通过在JPanel上单击和释放鼠标来绘制图形。其他选项包括更改颜色和是否填充形状。一旦绘制了形状,其他选项应该使用任何新的修饰符重新绘制相同的形状。例如,如果我画一个红色矩形,如果我选择蓝色,矩形应该只是改变颜色。到目前为止,我只实现了“矩形”选项。

  • 基本上,我有一个接口形状,它具有和方法。绘制形状的每个类都实现了这一点。还有一个类包含这些形状类的。然后有一个单独的类包含我的JFrame。我有一个“动画”按钮,它调用中的所有方法。

  • 我想做一个象棋游戏,我想在游戏循环中的一个jFrame上调用方法。这个特殊的JFrame显示了每个玩家的总击杀数。我很确定确实调用了repaint(),但由于某种原因,它似乎没有正确更新我的jlabel,jlabel应该保存每个玩家的击杀数值。 这是我为自定义JFrame扩展类编写的代码,该类包含代表kill的JLabel。 然后我只是在不同类的main方法中调用这个框架的repaint(): 非