Gavin S. Yancey
Gavin S. Yancey

Reputation: 1276

drawing to a JPanel without inheritance

Right now I'm working on a program that throws up a bunch of separate (generated at runtime) images, each in their own window. To do this i've tried this approach:

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
}

However, this throws a NullPointerException in draw, claiming that the graphics is null. is there any way to externally draw to a JPanel from outside it (not inherit from JPanel and override PaintComponent)? Any help would be appreciated.

Upvotes: 2

Views: 755

Answers (3)

mKorbel
mKorbel

Reputation: 109815

a program that throws up a bunch of separate (generated at runtime) images, 
each in their own window
  1. don't do it that this way, don't create a lots of JFrames, these Object stays in the memory, until current JVM instance exists, result from this concept pretty could be OutOfMemory exceptions

  2. don't create lots of JFrames, create only one JFrame, rest of Containers could be JDialog or JWindow

  3. don't create a new JFrames, JDialogs or JWindows on the runtime, re_use the existing Containers

  4. put these images as Icons to the JList or maybe better would be look at CardLayout

Upvotes: 2

ControlAltDel
ControlAltDel

Reputation: 35011

If you are drawing your images at runtime you should use BufferedImage.

Create a BufferedImage, call getGraphics() on it to get its Graphics object, draw to it using the Graphics(2D) api, then call Graphics.dispose() (not strictly necessary but a good habit) and as the previous poster suggested either create an ImageIcon with it and put in a JLabel using setIcon() or subclass JPanel / JComponent and draw it in paintComponent

Upvotes: 4

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

You're finding out that getGraphics() won't work in this way since the Graphics object obtained is null prior to the component being rendered, and even when it is not null, it is not stable and becomes invalid with each redraw. Possible options include:

  • Creating ImageIcon from each Image, placing the icon in a JLabel and displaying the JLabel.
  • Biting the bullet and extending JPanel or other JComponent (you don't say why you're trying to avoid this) and displaying the image in the JPanel's paintComponent method.
  • Doing the above, but first creating a BufferedImage which is displayed in the paintComponent(...) method. Then you can modify the BufferedImage during the program's run if you need to change the display, add new images,...

Upvotes: 4

Related Questions