webForumDet fria alternativet

getGraphics på JPanel

1 svar · 345 visningar · startad av pettsson

pettssonMedlem sedan jan. 20021 122 inlägg
#1

Försöker rita på en JPanel mha Graphics.drawLine, men får NullPointerEx när jag kör getGraphics, vilket verkar konstigt. Enl. dokumentationen ska alla komponenter returnera sin GraphicContext om de är synliga, vilket den är. Några konstigheter jag inte tänker på? Alt., finns det någon bättre komponent att rita på?

LimeMedlem sedan sep. 2001961 inlägg
#2

pettsson skrev:

Försöker rita på en JPanel mha Graphics.drawLine, men får NullPointerEx när jag kör getGraphics, vilket verkar konstigt. Enl. dokumentationen ska alla komponenter returnera sin GraphicContext om de är synliga, vilket den är. Några konstigheter jag inte tänker på? Alt., finns det någon bättre komponent att rita på?

Kika lite på http://java.sun.com/developer/onlineTraining/new2java/javaworkbook/gui/Drawing/solution.html

Du kan inte rita direkt på graphics-objektet eftersom JPanel försöker rita om sig själv hela tiden. Detta görs i metoden paint som får ett Graphics-objektet.

Detta funkar alltså inte eftersom JPanel ännu inte fått Graphics-objektet eftersom den inte är ritad ännu...

import java.awt.BorderLayout;
import java.awt.Graphics;

import javax.swing.JPanel;
import javax.swing.JFrame;

public class MainFrame extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;

	/**
	 * This is the default constructor
	 */
	public MainFrame() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(300, 200);
		this.setContentPane(getJContentPane());
		this.setTitle("JFrame");
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			Graphics gr = jContentPane.getGraphics();
			gr.drawLine(1,1,100,100);
		}
		return jContentPane;
	}

	
	public static void main(String[] args) {
		MainFrame mf = new MainFrame();
		mf.setVisible(true);
	}
}

Det du kan göra är överlagra paint-metoden, såhär:

import java.awt.BorderLayout;
import java.awt.Graphics;

import javax.swing.JPanel;
import javax.swing.JFrame;

public class MainFrame extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;

	/**
	 * This is the default constructor
	 */
	public MainFrame() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(300, 200);
		this.setContentPane(getJContentPane());
		this.setTitle("JFrame");
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
		}
		return jContentPane;
	}

[B]	public void paint(Graphics g) {
		super.paint(g);
		g.drawLine(1, 1, 100, 100);
	}[/B]
	
	public static void main(String[] args) {
		MainFrame mf = new MainFrame();
		mf.setVisible(true);
	}
}

eller ännu bättre, om man vill rita på själva JPanel (två klasser):

Ändring i MainFrame:

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = [B]new LinePanel();[/B]
			jContentPane.setLayout(new BorderLayout());
		}
		return jContentPane;
	}

Klassen LinePanel

import java.awt.Graphics;

import javax.swing.JPanel;

public class LinePanel extends JPanel {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public void paint(Graphics g) {
		super.paint(g);
		g.drawLine(1, 1, 100, 100);
	}

}

Med andra ord, rita i komponenten och inte utanför...

246 ms totalt · 3 externa anrop · v20260731065814-full.2b84b982
126 ms — hämta forumlista (db)
119 ms — hämta statistik (db)
125 ms — hämta tråd, inlägg och bilagor (db)