Swing paint() von JPanel wird nicht aufgerufen

Hatschi

Aktives Mitglied
Folgendes Problem: Die paint(java.awt.Graphics g)-Methode von der inneren Klasse Grid wird nicht aufgerufen. Warum?
Wenn ich die Klasse statt von JPanel von Canvas erben lassen, dann geht es komischer weise...

Java:
public class Field extends toolkit.gui.DBPlotter implements java.awt.event.MouseListener, java.awt.event.ActionListener {
	private final Dimension SCREEN_SIZE = new Dimension(400, 400);
	
	private Color background;
	private JPopupMenu popupMenu;
	private Grid grid;
	private int size;
	private boolean isGrid, gridPossible;
	
	
	public Field(int size, Color background) {
		this.size = size;
		this.background = background;
		
		init();
	}

...

	private void addGrid() {
		int step = SCREEN_SIZE.width / size;
		grid = new Grid(size, step);
		grid.setSize(SCREEN_SIZE);
		add(grid);
	}

...

	private class Grid extends javax.swing.JPanel {
		private int size, step;
		
		
		public Grid(int size, int step) {
			this.size = size;
			this.step = step;
		}
		
		
		@Override
		public void paint(java.awt.Graphics g) {
			g.setColor(Color.BLACK);
			for(int i=1; i<size; i++) {
				g.fillRect(i*step-1, 0, 2, step*size);
				g.fillRect(0, i*step-1, step*size, 2);
			}
		}
	}
}
 
überschreib mal paintComponent statt paint .. vielleicht wirkt das schon wunder 🙂 .. bin mir aber net ganz sicher, ist aber der bevorzugte weg
 
Mach doch am Besten mal ein kurzes Beispiel welches man ausführen kann!
So kann man doch jetzt nur raten...wird die Methode addGrid() überhaupt aufgerufen? Ist der Frame sichtbar indem das Panel "hinzugefügt" wird? Woher weisst du dass paint/paintCOmponent nicht aufgerufen wird? Was ist step? SIZE ? usw....
 
Ein extra Test ist eigentlich überflüssig. Lass ich Grid von java.awt.Canvas erben funktioniert alles (nur will ich nicht awt und swing vermischen). Dennoch:
Java:
public class Test extends javax.swing.JFrame {
	public static void main(String[] args) {
		new Test().setVisible(true);
	}
	
	
	public Test() {
		setLayout(null);
		Grid grid = new Grid();
		add(grid);
	}
	
	
	private class Grid extends javax.swing.JPanel {
		public void paint(java.awt.Graphics g) {
			System.out.println("paint");
		}
		
		public void paintComponent(java.awt.Graphics g) {
			System.out.println("paintComponent");
		}
	}
}
selbes Problem, nur das hier auch das Canvas nicht geht...

Ich poste einfach mal den kompletten Code... (die Variabeln sollten ja eigentlich nichts damit zu tun haben, oder doch???)
Java:
package predator.mainWnd;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;


public class Field extends toolkit.gui.DBPlotter implements java.awt.event.MouseListener, java.awt.event.ActionListener {
	private final Dimension SCREEN_SIZE = new Dimension(400, 400);
	
	private Color background;
	private JPopupMenu popupMenu;
	private Grid grid;
	private int size;
	private boolean isGrid, gridPossible;
	
	
	public Field(int size, Color background) {
		this.size = size;
		this.background = background;
		
		init();
	}
	
	
	private void init() {
		setLayout(null);
		
		if(size<50) {
			isGrid = true;
			addGrid();
		}
		else if(size==50) {
			isGrid = false;
			gridPossible = true;
		}
		else {
			isGrid = false;
			gridPossible = false;
		}
		
		addPopupMenu();
	}
	
	
	private void addGrid() {
		int step = SCREEN_SIZE.width / size;
		grid = new Grid(size, step);
		grid.setSize(SCREEN_SIZE);
		add(grid);
	}
	
	
	private void removeGrid() {
		isGrid = false;
		remove(grid);
	}
	
	
	private void addPopupMenu() {
		popupMenu = new JPopupMenu();
		JMenuItem item;
		
		item = new JMenuItem("Vollbild");
		item.setActionCommand("fullScreen");
		item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.ALT_MASK));
		item.addActionListener(this);
		popupMenu.add(item);
		
		item = new JMenuItem("Raster " + (isGrid ? "verbergen" : "anzeigen"));
		if(!gridPossible) item.setEnabled(false);
		item.setActionCommand("grid");
		item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.ALT_MASK));
		item.addActionListener(this);
		popupMenu.add(item);
				
		addMouseListener(this);
		setComponentPopupMenu(popupMenu);
	}
	
	
	private void show(MouseEvent e) {
		if(e.isPopupTrigger()) popupMenu.show(e.getComponent(), e.getX(), e.getY());
	}
	
	
	@Override
	public void paint(java.awt.Graphics g) {
		g.setColor(background);
		g.fillRect(0, 0, getWidth(), getHeight());
	}
	
	
	@Override
	public Dimension getPreferredSize() {
		return SCREEN_SIZE;
	}
	

	@Override
	public void mouseClicked(MouseEvent e) {}


	@Override
	public void mouseEntered(MouseEvent e) {}


	@Override
	public void mouseExited(MouseEvent e) {}
	

	@Override
	public void mousePressed(MouseEvent e) {
		show(e);
	}


	@Override
	public void mouseReleased(MouseEvent e) {
		show(e);
	}


	@Override
	public void actionPerformed(ActionEvent e) {
		String ac = e.getActionCommand();
		
		if(ac.equals("grid")) {
			 if(isGrid) removeGrid();
			 else addGrid();
		}
	}
	
	
	private class Grid extends javax.swing.JPanel {
		private int size, step;
		
		
		public Grid(int size, int step) {
			this.size = size;
			this.step = step;
		}
		
		
		@Override
		public void paint(java.awt.Graphics g) {
			g.setColor(Color.BLACK);
			for(int i=1; i<size; i++) {
				g.fillRect(i*step-1, 0, 2, step*size);
				g.fillRect(0, i*step-1, step*size, 2);
			}
		}
	}
}
 
Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 16.10 Alles Auslegungssache: die Layoutmanager

Das Argument null bei setLayout() setzt keinen Layoutmanager, und die Komponenten müssen absolut positioniert werden. Zum Setzen der Position und Maße bietet jede Component die Methode setBounds(int x, int y, int width, int height). Ein üblicher Layoutmanager wird mit genau dieser Methode die Größen zuweisen.

Das Setzen vom Null-Layout sollte nicht die Regel sein, da Änderungen an der Zeichensatzgröße hässliche Effekte nach sich ziehen. Eine Oma mit Sehschwierigkeiten, die die Fontgröße auf 40 stellt, sieht dann in einer Schaltfläche vielleicht nur eine halbe, abgeschnittene Zeichenkette.
 
wenn ich dich richtig verstanden habe, soll ich also "Field" ein Layout zuweisen? Das habe ich mal ausprobiert (auch wenn ich nicht verstehe warum dann paint aufgerufen werden soll...), funktioniert aber trotzdem nicht...
 
Also nochmal: Ich beziehe mich jetzt mal auf deinen ersten Code:
Java:
public class Test extends javax.swing.JFrame {
    public static void main(String[] args) {
        new Test().setVisible(true);
    }
    
    
    public Test() {
        setLayout(null);
        Grid grid = new Grid();
        add(grid);
    }
    
    
    private class Grid extends javax.swing.JPanel {
        public void paint(java.awt.Graphics g) {
            System.out.println("paint");
        }
        
        public void paintComponent(java.awt.Graphics g) {
            System.out.println("paintComponent");
        }
    }
}

Durch das null-Layout, hat deine Komponente Grid die Größe 0x0 ! Daher wird auch nicht paintComponent/paint aufgerufen, macht ja eh keinen Sinn!
Du musst also, so wie oben beschrieben deine Komponente selbst positionieren und ihr eine Größe geben(weil du eben keinen Layoutmanager verwendest - wahrscheinlich reicht es auch aus nur setSize aufzurufen, aber positionieren willst du ja meist auch, daher bietet sich setBounds an)
Auf dein Code oben, würde dies also ungefähr folgendes bedeuten:
Java:
	public Test() {
		setLayout(null);
		Grid grid = new Grid();
		grid.setBounds(0, 0, 500, 500);
		add(grid);
		setSize(500, 500);
	}

Dann wird auch paintComponent aufgerufen !

Ansonsten kann es bestimmt auch nicht schaden, sich wirklich mal mit den Layoutmanagern zu beschäftigen !!
 
Zuletzt bearbeitet:
Java:
public class Test extends javax.swing.JFrame {
	public static void main(String[] args) {
		new Test().setVisible(true);
	}
	
	
	public Test() {
		setLayout(null);
		setSize(500, 500);
		
		Grid grid = new Grid();
		grid.setBounds(0, 0, 500, 500);
						
		Grid2 grid2 = new Grid2();
		grid2.setBounds(0, 0, 500, 500);
				
		grid.add(grid2);
		add(grid);
		
	}
	
	
	private class Grid extends javax.swing.JPanel {
		public void paint(java.awt.Graphics g) {
			System.out.println("0::paint");
		}
		
		public void paintComponent(java.awt.Graphics g) {
			System.out.println("0::paintComponent");
		}
	}
	
	
	private class Grid2 extends javax.swing.JPanel {
		public void paint(java.awt.Graphics g) {
			System.out.println("1::paint");
		}
		
		public void paintComponent(java.awt.Graphics g) {
			System.out.println("1::paintComponent");
		}
	}
}

Ich weiß ich nerve, aber so gehts nicht... auch nicht wenn ich dem n Layout gebe...
 
Schreib mal in deine Paint methoden folgendes mit rein:

Java:
super.paint(g);

Danach werden die anderen Methoden auch aufgerufen, also alle paint und alle paintComponent methoden
 
es ist zum heulen... jetzt wird zwar die paint aufgerufen, aber man sieht trotzdem kein Bild... ich verzweifele...
Vielleicht bin ich ja auf dem völlig falschen Dampfer. Ich will einfach nur eine Animation laufen lassen und darüber die Möglichkeit haben ein Gitter ein bzw. ausblenden zu können, sollte man das vielleicht anders lösen?
 

Neue Themen


Zurück
Oben