getWidth(); getHeight(); außerhalb von paintComponent

Status
Nicht offen für weitere Antworten.

MrGe

Mitglied
Um paintComponent schlank zu halten, sollen die zu zeichnenden Komponenten außerhalb erzeugt werden.
Wie aber komme ich außerhalb von paintComponent an die Maße der Zeichenfläche heran?
Oder
Wie baut man getWidth() und getHeight() sauber ein?

Vielen Dank für die Tipps!

(Und vielen Dank an Wildcard für das Tutorial!!!)

Java:
//Bspl. nach "Zeichnen in Swing Tutorial"
public class SimpleRectangle {
	private NaivePaintingComponent paintingComponent = new NaivePaintingComponent();
	public SimpleRectangle() {
		JFrame frame = new JFrame("");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                paintingComponent.setPreferredSize(new Dimension(300,300));
                frame.add(paintingComponent);
                frame.pack();
                frame.setVisible(true);
                frame.setLocationRelativeTo(null);

           	Rectangle2D.Float rect = new Rectangle2D.Float(10f,10f,100f,100f);
    	       paintingComponent.setShape(rect);
           	paintingComponent.setColor(Color.BLACK);
           	paintingComponent.repaint();
           }
           public static void main(String[] args){new SimpleRectangle();}
}//class SimpleRectangle
 
class NaivePaintingComponent extends JComponent{
    private Shape shape;
    private Color c;
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if(shape!=null && c!=null){
            Graphics2D g2d = (Graphics2D)g;
            g2d.setColor(c);
            g2d.draw(shape);
        }
    }
    public void setColor(Color c) {this.c = c;}
    public void setShape(Shape shape) {this.shape = shape;}
}//class NaivePaintingComponent
 

KrokoDiehl

Top Contributor
Ich verstehe offenbar das Problem nicht...
Code:
getX()
,
Code:
getY()
,
Code:
getWidth()
und
Code:
getHeight()
von JComponent liefern doch stets die Größe, bzw. den Bereich in dem man zeichnen kann.
 
S

SlaterB

Gast
erst wenn die Komponente zu sehen ist, das Layout gesetzt wurde,
wenn paintComponent aufgerufen wird ist das garantiert schon der Fall gewesen,

außerhalb hat man die Gefahr, dass man zu früh getWidth() & Co. aufruft, z.B. bevor das initiale
setVisible(true);
noch nicht ausgeführt oder eine neue Komponente noch nicht ins GesamtLayout eingegliedert wurde
 

Ebenius

Top Contributor
Ich würde es so einbauen:
Java:
public class A extends JComponent {
  public A() {
    enableEvents(AWTEvent.COMPONENT_EVENT_MASK);
  }

  protected void processComponentEvent(ComponentEvent e) {
    super.processComponentEvent(e);
    if ((e.getID() & ComponentEvent.COMPONENT_RESIZED) != 0) {
      rebuildDrawnObjects(); // <== oder so ähnlich
    }
  }
}
Ebenius
 

MrGe

Mitglied
Vielen Dank für den Tipp !!

Aber wie bekomme ich die veränderten Werte dahin, wo die Figuren erzeugt werden?

Ich habe mal eine Lösung mit einem selbstgestrickten "Observer" gebastelt.

Ist das so OK, oder gibt es elegantere Lösungen?

Vielen Dank für Tipps.

Java:
package draw_resizing_figures;

import java.awt.Dimension;

import javax.swing.JFrame;

public class MainGUI extends JFrame{

	public NaivePaintingComponent paintingComponent = new NaivePaintingComponent();
	
	public MainGUI() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		new RectangleCreator(paintingComponent);
		new CircleCreator(paintingComponent);
		paintingComponent.setPreferredSize(new Dimension(300,300));
		add(paintingComponent);
		pack();
		setVisible(true);
		setLocationRelativeTo(null);
	}//MainGUI
	
	public static void main(String[] args){new MainGUI();}
}

Die Klassen, die Figuren erzeugen, implementieren dieses Interface.
Java:
package draw_resizing_figures;

public interface XY_Observer {
	public void updateXY(int x, int y);
}

Diese Klasse stellt die Zeichenfläche bereit, sie kann eine Größenveränderung erkennen.
Klassen, die Figuren erstellen, bekommen eine Referenz auf diese Klasse und
können so ihre Figuren übergeben.

Klassen, die Figuren erstellen, können sich in eine ArrayList in dieser Klasse
eintragen.
Bei einer Größenveränderung werden sie darüber informiert und erstellen dann
angepasste Figuren.

Java:
package draw_resizing_figures;

import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.ComponentEvent;
import java.util.ArrayList;

import javax.swing.JComponent;

public class NaivePaintingComponent extends JComponent{
	
	/**die arraylist speichert alle zu zeichnenden figuren*/
	private ArrayList<Shape> al_shape = new ArrayList<Shape>();
	
	/**die arraylist speichert alle beobachter*/
	private ArrayList<XY_Observer> xy_observer= new ArrayList<XY_Observer>(); 

	public NaivePaintingComponent() {
		enableEvents(AWTEvent.COMPONENT_EVENT_MASK);
	}
	
	/**reagiert auf veraenderung der groesse*/
	public void processComponentEvent(ComponentEvent e){
		super.processComponentEvent(e);
		//if(e.getID() != 0 && ComponentEvent.COMPONENT_RESIZED!= 0){
		//so gehts eleganter:
		if((e.getID() & ComponentEvent.COMPONENT_RESIZED) != 0){	
			System.out.println("new width/height = "+getWidth()+" / "+getHeight());
			//die vorhandenen figuren werden geloescht
			//die neuen werden spaeter angeliefert
			al_shape.clear();
			//die beobachter werden informiert
			informObservers(getWidth(), getHeight());
		}
	}

	public void addShape(Shape sh){
		al_shape.add(sh);
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		if(al_shape.size()>0){
			Graphics2D g2d = (Graphics2D)g.create();
			g2d.setColor(Color.BLACK);
			//alle figuren werden gezeichnet
			for(int i = 0; i<al_shape.size(); i++){
				g2d.draw(al_shape.get(i));
			}
		}
	}

	/**beobachter hinzufuegen*/
	public void addCuriousComponent(XY_Observer nc) {
		xy_observer.add(nc);
	}

	/**beobachter loeschen*/
	public void removeCuriousComponent(XY_Observer b) {
		int i = xy_observer.indexOf(b);
		if (i >= 0){xy_observer.remove(i);}
	}
	
	/**beobachter informieren*/
	public void informObservers(int x, int y) {
		if(xy_observer.size()>0){
			for (int i = 0; i < xy_observer.size(); i++){
				XY_Observer b = xy_observer.get(i);
				b.updateXY(x, y);
			}
		}
	}
}


Diese Klasse erstellt Kreise.

Java:
package draw_resizing_figures;

import java.awt.geom.Ellipse2D;

public class CircleCreator implements XY_Observer {

	private NaivePaintingComponent npc;
	
	public CircleCreator(NaivePaintingComponent n){
		System.out.println("CircleCreator");
		this.npc = n;
		//anmelden als beobachter
		npc.addCuriousComponent(this);
	}
		
	@Override
	public void updateXY(int x, int y) {
		System.out.println("CircleCreator updateXY");
		Ellipse2D.Float circle = new Ellipse2D.Float(10, 10, x-20, y-20);
		npc.addShape(circle);
	}
}

Diese Klasse erstellt Rechtecke.

Java:
package draw_resizing_figures;

import java.awt.geom.Rectangle2D;

public class RectangleCreator implements XY_Observer{
	
	private NaivePaintingComponent npc;
	
	public RectangleCreator (NaivePaintingComponent n){
		System.out.println("RectangleCreator");
		this.npc = n;
		//anmelden als beobachter
		npc.addCuriousComponent(this);
	}

	@Override
	public void updateXY(int x, int y) {
		System.out.println("RectangleCreator updateXY");
		Rectangle2D.Float rect = new Rectangle2D.Float(10,10,x-20,y-20);
		npc.addShape(rect);
	}
}
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Rechtecke mittels getWidth AWT, Swing, JavaFX & SWT 1
F JavaFX label.getWidth() AWT, Swing, JavaFX & SWT 2
H img.getWidth AWT, Swing, JavaFX & SWT 3
M Image - getHeight ist -1 AWT, Swing, JavaFX & SWT 6
volcanos SpringLayout mit zusätzlichen Buttons außerhalb des SpringLayout AWT, Swing, JavaFX & SWT 33
CptK Fokus auf geöffnetes Zweit-Fenster setzen und Eingaben außerhalb blocken AWT, Swing, JavaFX & SWT 2
M JavaFX - Bild in Jar einbinden, sodass es auch außerhalb der IDE geladen wird. AWT, Swing, JavaFX & SWT 2
Q GUI außerhalb GUI-Thread updaten - GUI friert ein AWT, Swing, JavaFX & SWT 18
B Event Handling Mausbewegung auch außerhalb eines JFrames registrieren AWT, Swing, JavaFX & SWT 2
F Canvas Objekt außerhalb des Frames zeichnen AWT, Swing, JavaFX & SWT 3
N Swing außerhalb des Hauptframe Komponente/Frame öffnen AWT, Swing, JavaFX & SWT 2
E 2D-Grafik Zeichnen außerhalb der "paintComponent"-Methode? AWT, Swing, JavaFX & SWT 5
T MouseMotionListener außerhalb von Frame AWT, Swing, JavaFX & SWT 3
thE_29 Swing JTabbedPane Focus von Komponenten außerhalb AWT, Swing, JavaFX & SWT 10
J getFontMetrics außerhalb von paint(Graphics g) AWT, Swing, JavaFX & SWT 8
J JTextArea wird nicht aktualisiert bei Zugriff von außerhalb AWT, Swing, JavaFX & SWT 2
T Variable Menge an Bildern außerhalb paint() zeichnen? AWT, Swing, JavaFX & SWT 2
H JWindow schließen bei einem Klick außerhalb der Anwendung? AWT, Swing, JavaFX & SWT 19
T erkennen ob innerhalb oder außerhalb von canvas gezeichnet AWT, Swing, JavaFX & SWT 2
conan2 getFontMetrics() außerhalb des Components AWT, Swing, JavaFX & SWT 7

Ähnliche Java Themen

Neue Themen


Oben