Java 无继承地绘制到JPanel

Java 无继承地绘制到JPanel,java,swing,jpanel,Java,Swing,Jpanel,现在我正在开发一个程序,它抛出一堆单独的(在运行时生成的)图像,每个图像都在自己的窗口中。为此,我尝试了以下方法: public void display(){ JFrame window = new JFrame("NetPart"); JPanel canvas = new JPanel(); window.getContentPane().add(canvas); Graphics g = canvas.getGraphics(); Dimensio

现在我正在开发一个程序,它抛出一堆单独的(在运行时生成的)图像,每个图像都在自己的窗口中。为此,我尝试了以下方法:

public void display(){
    JFrame window = new JFrame("NetPart");
    JPanel canvas = new JPanel();
    window.getContentPane().add(canvas);
    Graphics g = canvas.getGraphics();
    Dimension d = getSize();
    System.out.println(d);
    draw(g,new Point(d.minX*50,d.maxY*50), 50);
    window.setSize(d.size(50));
    window.setResizable(false);
    window.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
    window.setVisible(true);
}

public void draw(Graphics g, Point startLoc, int scale){
    // generate and draw the image
}

public Dimension getSize(){
    //returns my own dimensions class
}

但是,这会在draw中抛出NullPointerException,声称图形为null。是否有任何方法可以从外部绘制到JPanel(而不是从JPanel继承并覆盖PaintComponent)?任何帮助都将不胜感激

您会发现
getGraphics()
不会以这种方式工作,因为在渲染组件之前获得的图形对象为null,即使它不为null,它也不稳定,并且在每次重画时都会失效。可能的选择包括:

  • 从每个图像创建ImageIcon,将图标放置在JLabel中并显示JLabel
  • 咬紧牙关,扩展JPanel或其他JComponent(您不会说为什么要避免这种情况),并在JPanel的paintComponent方法中显示图像
  • 执行上述操作,但首先创建一个BuffereImage,显示在
    paintComponent(…)
    方法中。然后,如果需要更改显示、添加新图像等,可以在程序运行期间修改BuffereImage

如果在运行时绘制图像,则应使用BuffereImage

创建一个BuffereImage,调用其上的getGraphics()以获取其图形对象,使用Graphics(2D)api绘制它,然后调用Graphics.dispose()(不是严格必需的,但这是一个好习惯),如前一张海报所建议的,使用它创建一个ImageIcon并使用setIcon()放入一个JLabel或者子类JPanel/JComponent并在paintComponent中绘制它

a program that throws up a bunch of separate (generated at runtime) images, 
each in their own window
  • 不要这样做,不要创建大量
    JFrames
    ,这些
    Object
    会留在内存中,直到当前JVM实例存在,这个概念的结果可能是
    OutOfMemory异常

  • 不要创建大量的
    JFrame
    ,只创建一个
    JFrame
    ,其余的
    容器可以是
    JDialog
    JWindow

  • 不要在运行时创建新的
    JFrames
    JDialogs
    JWindows
    ,请重新使用现有的
    容器

  • 把这些图片放在地图上,或者最好看一看


  • 我使用的图像是在运行时生成的,所以我(据我所知)无法制作图像图标。我不想扩展JPanel的原因是,我的代码实际上是用于生成图像背后的结构,而显示它们主要只是一个有用的工具(在此之前,我使用了一个复杂的toString,但它达到了我无法理解的程度,所以我创建了这个。如何创建一个BuffereImage来显示?@g.rocket:您关于在运行时不能生成ImageIcon的假设是错误的,这应该是有意义的,因为为什么运行中的应用程序会阻止类显示正在创建?我看到“已接受”的答案与上面我的第三个要点相同。我知道你可以从图像文件(位于硬盘上)创建图像图标在运行时,但据我所知,我无法对ImageIcon进行自定义绘制,这正是我试图做的。是的,基本上是一样的,但它解释了更多的方法,我没有这样做understand@g.rocket:同样,我不确定您所说的“您不能将自定义图形设置为图像图标”是什么意思。当然可以--可以进行任何类型的自定义绘图。图像图标基于图像。如果“在运行时”绘制到BuffereImage,您可以随时从该图像创建ImageIcon。但是,我如何将BuffereImage绘制到JPanel?要在JPanel上绘制BuffereImage,您需要对JPanel进行子类化,并在paintComponent方法中调用g.drawImage(MyBuffereImage,x,y,…)