Initialisierung von Zeichenpanel

beastofchaos

Bekanntes Mitglied
Hallo Leute,
Ich arbeite im Moment an einem Zeichenprogramm. Leider hänge ich an einer Sache ein bisschen.
Mein Problem ist, dass mein Zeichenpanel (PaintPanel) zu langsam lädt. Denn es soll bei der Initialisierung schon ein weißes Bild drauflegen, auf das dann gemalt wird. Aber in diesm Moment (wo das erste/zweite Mal paintComponent() zur Initialisierung aufgerufen wird) ist das Panel noch nicht ganz geladen. Dabei hab ich aber eingestellt, dass das Bild die Größe des Panels nehmen soll. Aber das unvollständige Panel besitzt in dem Momment die Größe 0-0 oder ein bisschen größer, da es beim Laden ist. Ich zeig euch am besten mal den relevanten Quelltext:

Der Aufruf des PaintPanels:
Java:
public final class Main extends JFrame{   
    
    public PaintPanel paintPanel = new PaintPanel(this);
    ...
    
    static public void main(String [] args) {
    	try {
    	    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
	    Main frame = new Main();
	    ...
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }

paintComponent() von PaintPanel:
Java:
if (paints == null){
			SwingUtilities.invokeLater(new Runnable() {
				@Override
				public void run() {
					paints = new ImageDesign();
					paints.setObserver(PaintPanel.this);
					paints.setImage(new BufferedImage(PaintPanel.this.getWidth() - 3,PaintPanel.this.getHeight() - 3, BufferedImage.TYPE_INT_RGB));
					paints.setSize(new Point(paints.getImage().getWidth(paints.getObserver()), paints.getImage().getHeight(paints.getObserver())));
					Graphics tempGC = paints.getImage().getGraphics();
					tempGC.setColor(Color.white);
					tempGC.fillRect(0, 0, PaintPanel.this.getWidth(), PaintPanel.this.getHeight());
					inited = true;
				}
			});
		}
		else{
			draw(g);
		}


ImageDesign() - benötigte Methoden:
Java:
public class ImageDesign extends Design {
	private Image image;
	private PaintPanel observer;

	public ImageDesign() {
		super();
		this.image = null;
	}

	public void setObserver(PaintPanel anObserver) {
		observer = anObserver;
	}
	public PaintPanel getObserver(){
		return this.observer;
	}
	
	public void setImage(Image anImage) {
		if (anImage == null){
			this.image = anImage;
			JOptionPane.showConfirmDialog(null, "Die Ablage enthält kein Bild!", "Bild einfügen - Fehlermeldung", JOptionPane.DEFAULT_OPTION);
		}
		else {
			this.image = anImage;
			setSize(new Point(anImage.getWidth(observer), anImage.getHeight(observer)));
		}
	}
	public Image getImage(){
		return this.image;
	}
	
	public void addImage(BufferedImage anImage){
		Graphics g = getImage().getGraphics();
		g.drawImage(anImage, 0, 0, observer);
	}
	
	public void add(Design des){
		try {
			des.draw(getImage().getGraphics());
		}
		catch (NullPointerException e){ }
	}
	
	@Override
	public void draw(Graphics g) {
		g.drawImage(image, getLocation().x, getLocation().y, observer);
	}

Die Oberklasse Design enthält nur relevante Methoden wie setSize(), womit dann später gezeichnet wird. Das brauche ich aber nicht auch noch vorhalten 😉

Wie ihr sehen könnt, benutzte ich bisher für diese Problem ein SwingUtilities.invokeLater(), was leider auch nicht 100%ig funktioniert. Ich schätze mal jedes 10./15. Mal kommt eine graue Oberfläsche - sprich kein geladenes Bild. Wenn ich dann zeihcne, wird das automatisch neu gemacht, aber unter sowas stelle ich mir kein schönes Zeichenprogrmam vor 😀
Dadurch wird brigens ncoh ein weiterer Fehler produziert, der jedesmal auftaucht. Und zwar benuzte ich für die Farbauswahl ein JColorChosser, welches per JSplitPane an das PaintPanel gekoppelt ist. Zwar wird das nach dem Konstruktor für das PaintPanel aufgerufen, aber trotzdem sieht man am Anfang für einen Moment, dass die ColorChooser-Seite des SplitPanes fast alles einnimmt. Erst wenn nach ca. einer viertel/halben das PaintPanel geladen ist und seine totale Größe erreicht hat, verschiebt sich auch das SplitPane entsprechend. Wisst ihr vll. eine bessere Lösung, mit der erst alles angezeigt wird, wenn wirklich alles geladen ist?
Dazu hätte ich nur die Idee, ein Timer in ders tatischen main-Methode einzubauen, der das Frame solange unsichtbar hält, bis das PaintPanel seine volle Größe hat. Das würde zumindest das SplitPane-Problem lösen, wenn auch meiner Meinung anch unsschön... :/

Gruß, Thomas
 
ich hatte letztens genau das gleiche Problem, bei mir war es allerdings so, dass ich einen extra Thread laufen hatte, welcher die Zeichnung jeweils aktualisiert hat (alle 30ms ca.).

Diesen hatte ich dann gestartet nachdem alle Initialisierungen fertig waren.

Weiterhin solltest du noch wie folgt in der main-Methode dein Fenster erstellen (ebenfalls im EDT):
Java:
SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        Main frame = new Main();
        frame.setVisible(true);
    }
});

Bei mir hatte ich dann danach die Zeichnung angeworfen, und es ging. Vielleicht kannst du etwas ähnliches realisieren.
 
Darauf hätt ich auch mal kommen müssen 😛 Hab das invokeLater nun auch beim Alles-erstellen eingebaut und das Problem "SplitPane" ist behoben. Das andere ist seit längerem nciht mehr aufgetaucht 😀

Dankeschön,
vll. wäre dafür wirklich ein Timer nicht schlecht. Im Moment schaltet sich nur einer ein, wenn ich in den Auswählmodus gehe, wo er eine gestrichelte Linie über einen Bereich legt und die Linie andauernd bewegt. Das repaint(), was darin aufgerufen wird, kann sich mit dem in mouseDragged überschneiden und unnötige Ressourcen verwenden xD Ich werd mcih mal ranhocken.
Und am Ende kriegt ihr alle das Programm von mir hier gepostet und könnt mir Tipps für Verbesserungen geben 😉

Gruß und Dankeschön, Thomas
 
Hatte jetzt das Problem mit dem unvollständigen Laden 2mal wieder, also lass ich jetzt am Anfang per Timer 5 Mal neu zeichnen, damit es wirklich funktioniert
 

Neue Themen


Zurück
Oben