Darstellungsproblem mehrerer Komponenten

  • Themenstarter Themenstarter Gast
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
G

Gast

Gast
Hallo Experten,

ich bin neu, was den Bereich Swing und Grafik generell angeht. Deswegen befürchte ich auch, dass ich bei meinem momentanen Problem etwas grundlegendes falsch mache. Ich finde aber um's verrecken alleine nicht raus was.

Ich versuche derzeit in einem JFrame mit GridLayout von 10mal10 Felder insgesamt 100 kleine JPanels darzustellen, in denen ich etwas zeichnen möchte.

Das Problem ist jetzt, dass ich genau ein FieldPanel oben links im JFrame angezeigt bekomme. Der Rest ist nur zu sehen, wenn ich das Window resize. Was stimmt in meinem Ablauf nicht?

Code:
public class MapPanel extends JFrame {
	static final long serialVersionUID = 123456476596534500l;
	
	private FieldPanel[][] map;
	
	  public MapPanel(){
		  super();
		  map = new FieldPanel[10][10];
		  this.setSize(500, 500);
		  this.setLayout(new GridLayout(10,10));
		  for (int i=0;i<10;i++){
			  for (int j=0;j<10;j++){
				  map[i][j]=new FieldPanel();
				  this.add(map[i][j]);
			  }
		  }
	  }
}

Code:
public class FieldPanel extends JPanel {
        static final long serialVersionUID = 1234564645645700l;	
        private Ellipse2D.Double circle =
            new Ellipse2D.Double(0, 0, 60, 30);
        private Rectangle2D.Double square =
            new Rectangle2D.Double(0, 0, 60, 30);

  public FieldPanel(){
	  this.setPreferredSize(new Dimension(60,30));
  }
  @Override
  public void paintComponent(Graphics g) {
	  super.paintComponent(g);
          Graphics2D g2d = (Graphics2D)g;
          g2d.draw(circle);
          g2d.draw(square);
          this.setBounds(0,0,60,30);
          this.setBackground(Color.blue);
  }
}

MapPanel war ursprünglich ein JPanel, das in einem JFrame dargestellt werden soll, aber ich habe erstmal eine Stufe rausgenommen. (hat aber nix genutzt 🙂 )

Code:
public static JFrame openInJFrame(JFrame frame,
                                    int width,
                                    int height,
                                    String title,
                                    Color bgColor) {
      frame.setBackground(bgColor);
      frame.setSize(width, height);
      frame.addWindowListener(new ExitListener());
      frame.setResizable(true);
      //frame.pack();
      frame.setVisible(true);
      return(frame);
  }

Gruß
Torsten
 
hmmm wenn es nur angezeigt wird wenn du es resized dann fehlt wahrscheinlich nen repaint bzw validate();

einfach mal als letztes nen frame. repaint oder frame.validate mit reinschreiben wenns net geht guck ich nochmal in den code 🙂
 
So, ich habe mich spontan erstmal registriert. Jetzt ist das auch etwas weniger anonym 🙂

Also repaint() und validate() haben nichts gebracht. Ich habe sie direkt vor frame.setVisible() ausgeführt.
 
so hab erstmal nen eigenständig laufendes prog draus gemacht...

also im mom wird ja nur openInJFrame aufgerufen
du willst auf das frame ja sicher noch deine mappanels drauf packen wie sieht n da deine funktion aus?


Code:
package testapp;

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;


public class testframe {

	public class MapPanel extends JFrame { 
		static final long serialVersionUID = 123456476596534500l; 
		
		private FieldPanel[][] map; 
		
		public MapPanel(){ 
			super(); 
			map = new FieldPanel[10][10]; 
			this.setSize(500, 500); 
			this.setLayout(new GridLayout(10,10)); 
			for (int i=0;i<10;i++){ 
				for (int j=0;j<10;j++){ 
					map[i][j]=new FieldPanel(); 
					this.add(map[i][j]); 
				} 
			} 
		} 
	}
	
	public class FieldPanel extends JPanel { 
        static final long serialVersionUID = 1234564645645700l;    
        private Ellipse2D.Double circle = new Ellipse2D.Double(0, 0, 60, 30); 
        private Rectangle2D.Double square = new Rectangle2D.Double(0, 0, 60, 30); 

        public FieldPanel(){ 
        	this.setPreferredSize(new Dimension(60,30)); 
        } 
        @Override 
        public void paintComponent(Graphics g) { 
        	super.paintComponent(g); 
        	Graphics2D g2d = (Graphics2D)g; 
        	g2d.draw(circle); 
        	g2d.draw(square); 
        	this.setBounds(0,0,60,30); 
        	this.setBackground(Color.blue); 
        } 
	}
	
	public static JFrame openInJFrame(JFrame frame, int width, int height, String title, Color bgColor) { 
		frame.setBackground(bgColor); 
		frame.setSize(width, height); 
		frame.setResizable(true);
		frame.setVisible(true); 
		return(frame); 
	}

	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JFrame frame = new JFrame();
		openInJFrame(frame, 150, 150, "test",  Color.red);
	}

}
 
Die Main() sieht für das Beispiel so aus:

Code:
public static void main(String[] args) {
	TestFrame tf = new TestFrame(); 
	TestFrame.MapPanel map = tf.new MapPanel();
	openInJFrame(map, 150, 150, "test",  Color.red);
}

Ich schachtel die MapPanel nicht nochmal in einem JFrame. Ursprünglich war die Idee, dass MapPanel ein JPanel ist, dass ich dann dem JFrame hinzufüge. (über setConentPane() ) Aber zur Vereinfachung habe ich die Stufe rausgenommen. (Ist momentan nicht wichtig, ob mir die Titelleiste beim zeichnen im Weg ist oder nicht...)
 
Ok, hier ist die Lösung: Benutze nie die selben Werte für alle Elemente beim Aufruf von setBounds()!!! :lol: (siehe Zeile 46). Dadurch wurden alle FieldPanels übereinander geschoben. Seltsam und irritierend ist nur, dass sie beim Vergrößern oder Verkleinern des Fensters korrekt sichtbar waren....
 
Bei einem resize wird die falsche Angabe der Bounds vom LayoutManager korrigiert. Allerdings ist es doch ein bißchen "Zufall", dass es funktioniert, weil man in der paintComponent auf keinen Fall(!) so etwas wie setBounds oder setBackground aufrufen sollte. paintComponent ist zum painten da. Ansonsten hieße sie nicht paintComponent, sondern paintComponentAndDoSomeOtherThingsOfWhichIDontKnowWhereToDoThem
 
Hm, dass das da nicht hingehört mag sein. Aber wie gesagt, ich fang ja erst an. 🙂 Im Übrigen wäre eine paintComponentAndDoSomeOtherThingsOfWhichIDontKnowWhereToDoThem-Methode vielleicht gar nicht schlecht....wobei der Name ist ziemlich lang, oder? :lol:
 
Das grenzt dann schon an diese berühmt-berüchtigte Klasse
sun.java.special.secret.DoClass
die eine Methode
public Object doWhatIWant(String whatIWant);
anbieten soll, und nach der hier so häufig (wenn auch nur indirekt) gefragt wird :wink:
 
Hm, Sun könnte ja wenigstens mal ein entsprechendes Interface zur Verfügung stellen....vielleicht implementiert es ja wer... :lol:
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben