GUI: RectangleDrawer - zu viele Elemente im Vector für die paint-Methode

Status
Nicht offen für weitere Antworten.

Hutmacher

Bekanntes Mitglied
Okay, der Titel hört sich komisch an; ich habe ein Fenster, RectangleDrawer, auf das ich mit der Maus mehrere Rechtecke zeichnen kann. Da beim Painten alle gezogenen Fenster erscheinen sollen und nicht nur das letzte, habe ich einen Vector paintList, in den ich alle Elemente hineinstecke. Links oben wird immer angezeigt, wie viele Elemente (Rectangles) der Vector besitzt.

Das Programm funktioniert - aber während des Draggens, also des Ziehens mit der Maus soll das Rechteck ja auch schon agezeigt werden. Deswegen muss bei jedem Aufruf der mouseDragged-Methode also an den Vector ein weiteres Rectangle angehängt werden.

[Die Aufrufreihenfolge der Methoden ist also mousePressed - der Klick, öfters mouseDragged - das Ziehen und am Ende mouseReleased - das Loslassen.]

Es funktioniert zwar alles gut, aber ich habe schon nach ein paar mal Zeichnen extrem viele Elemente im Vector.
1h517pxl.png


So sieht der Code aus:
Java:
package test.gui;

import java.awt.*;
import java.awt.event.*;
import java.util.*;

/*         RectangleDrawer
 * Erlaubt es, dass auf einem Frame mit der Maus 
 * Rechtecke gezogen werden können.
 */
class RectangleDrawer extends Frame 
{
	private static Color backColor = new Color(240, 240, 240);//Hintergrundfensterfarbe
	private Vector<Rectangle> paintList; //damit paint alles erneut zeichnen kann und nicht nur das letzte
	private Rectangle curRect; //das aktuell zu zeichnende Viereck
	
	public static void main(String[] args) 
	{
		RectangleDrawer mainWnd = new RectangleDrawer();
		mainWnd.curRect = new Rectangle(0, 0, 0, 0); //Init.
		mainWnd.paintList = new Vector<Rectangle>(); //Init.
		
	}

	//Konstruktor
	public RectangleDrawer()
	{
		super("Rectangle Drawer!");
		setBackground(backColor);
		setSize(350, 250);
		setResizable(false);
		addMouseListener(new MyMouseListener());
		addMouseMotionListener(new MyMouseDragListener());
		setVisible(true);
	}
	
	public void paint(Graphics g)
	{
		g.drawString(String.valueOf(paintList.size()), getInsets().left+ 3, getInsets().top +10); //Schreibt Elemente
		
		if (!paintList.isEmpty())
		{
			// Zeichnet jedes Rechteck aus der Liste auf das Fenster
			for (Iterator<Rectangle> it = paintList.iterator(); it.hasNext();)
			{
				Rectangle rect = it.next();
				g.drawRect(rect.x, rect.y, rect.width, rect.height);	
			}
		}
	}
	
	class MyMouseListener
	 extends MouseAdapter
	 {
		//Beim ersten Klick gettet es die Klick-Koordinaten, also die Stelle,
        //an der das Rechteck beginnt.
		@Override 
		public void mousePressed(MouseEvent event)
		{
			setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
			curRect = new Rectangle(event.getX(), event.getY(), 0, 0);
		}
		
		
		//Ergibt beim Loslassen der Maustatse das letztendlich Rechteck
		@Override
		public void mouseReleased(MouseEvent event)
		{
			setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
			paintList.add(curRect);
			
			repaint();
		}
	 }
	
	class MyMouseDragListener
	 extends MouseMotionAdapter
	{
		//Berechnet, wie lang das Rechteck sein muss und lässt es zeichnen
		// - während des Ziehens
		@Override
		public void mouseDragged(MouseEvent event)
		{
			curRect.width = event.getX() - curRect.x;
			curRect.height = event.getY() - curRect.y;
			
			paintList.add(curRect);
			
			repaint();
		}
	}
}

Gibt es eine bessere, performantere Alternative, bei der die paintList nicht so voll ist?

Am besten ist vielleicht, ihr kopiert euch den Code in Eclipse o.ä. und probiert ihn einmal aus.
Danke im Voraus, und besonders, wenn ihr euch meinen langen Code durchlest ^^'
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Grob sowas wie
Code:
mouseReleased(...)
{
    ...
    if (curRect != null)
    {
        paintList.add(curRect); // NUR hier!!!
    }
    curRect = null; // Wichtich!!!
}


void paint(...)
{
    maleAlleAusPaintList();
    if (curRect != null) maleAuch(curRect); 
}
 

Schandro

Top Contributor
warum addest du "curRect" zur paintList? Eigentlich soll curRect doch ne Membervariable sein, wo immer das aktuell gezogene Rechteck drin zwischengespeichert wird. Also würde sowas reichen:

Java:
public void mouseDragged(MouseEvent event){
   curRect = new Rectangle(event.getX(), event.ge/* usw... */);
   repaint();
}
public void mouseReleased(MouseEvent event){
   curRect = null;
}
und in der paint-Methode entsprechend ne Kontrolle ob curRect null ist, wenn nicht wirds gemalt.

@Hutmacher
weiß nicht ob dus bereits wusstest und dich bewusst dagegen entschieden hast, oder ob du es noch nicht weißt:
AWT ist veraltert, benutz doch z.b. Swing stattdessen
"ArrayList" ist von der Performance her schneller als "Vector", dafür aber nicht Threadsicher.
 
Zuletzt bearbeitet:

Hutmacher

Bekanntes Mitglied
Die beiden Lösungen haben nicht funktioniert. Ich habe in der jetzigen Version Schandros Code, aber so geht das überhaupt nicht. Wenn ich ziehe, bekomme ich nichts angezeigt und nach Release am Ende nur ein sehr kleines Rechteck. Dazu werden auch die alten Rechtecke nicht mehr gezeichnet, wenn ich neue zeichne.

An Schandro angepasster Code
Java:
package test.gui;

import java.awt.*;
import java.awt.event.*;
import java.util.*;

/*         RectangleDrawer
 * Erlaubt es, dass auf einem Frame mit der Maus 
 * Rechtecke gezogen werden können.
 */
class RectangleDrawer extends Frame 
{
	private static Color backColor = new Color(240, 240, 240);//Hintergrundfensterfarbe
	private Vector<Rectangle> paintList; //damit paint alles erneut zeichnen kann und nicht nur das letzte
	private Rectangle curRect; //das aktuell zu zeichnende Viereck
	
	public static void main(String[] args) 
	{
		RectangleDrawer mainWnd = new RectangleDrawer();
		mainWnd.curRect = new Rectangle(0, 0, 0, 0); //Init.
		mainWnd.paintList = new Vector<Rectangle>(); //Init.
		
	}

	//Konstruktor
	public RectangleDrawer()
	{
		super("Rectangle Drawer!");
		setBackground(backColor);
		setSize(350, 250);
		setResizable(false);
		setIconImage(Toolkit.getDefaultToolkit().getImage("Icon.ico"));
//		setIconImage(getClass().getResource("res/Icon.ico"));
		addMouseListener(new MyMouseListener());
		addMouseMotionListener(new MyMouseDragListener());
		setVisible(true);
	}
	
	public void paint(Graphics g)
	{
		g.drawString(String.valueOf(paintList.size()), getInsets().left+ 3, getInsets().top +10); //Schreibt Elemente
		
		if (curRect != null)
		{
			g.drawRect(curRect.x, curRect.y, curRect.width, curRect.height);
		}
		
		if (!paintList.isEmpty())
		{
			// Zeichnet jedes Rechteck aus der Liste auf das Fenster
			for (Iterator<Rectangle> it = paintList.iterator(); it.hasNext();)
			{
				Rectangle rect = it.next();
				g.drawRect(rect.x, rect.y, rect.width, rect.height);	
			}
		}
		
		
	}
	
	class MyMouseListener
	 extends MouseAdapter
	 {
		//Beim ersten Klick gettet es die Klick-Koordinaten, also die Stelle,
        //an der das Rechteck beginnt.
		@Override 
		public void mousePressed(MouseEvent event)
		{
			setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
			curRect = new Rectangle(event.getX(), event.getY(), 0, 0);
		}
		
		
		//Ergibt beim Loslassen der Maustatse das letztendlich Rechteck
		@Override
		public void mouseReleased(MouseEvent event)
		{
			setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
			curRect = null;
		}
	 }
	class MyMouseDragListener
	 extends MouseMotionAdapter
	{
		//Berechnet, wie lang das Rechteck sein muss und lässt es zeichnen
		// - während des Ziehens
		@Override
		public void mouseDragged(MouseEvent event)
		{
			curRect = new Rectangle(
			 event.getX(), event.getY(),
			 event.getX() - curRect.x,
			 event.getY() - curRect.y);
			
			repaint();
		}
	}
}

Bei der Marco13-Version passiert genau das Gleiche wie bei Schandros, nur dass wenigstens beim Erstellen neuer Rechtecke die alten erhaltenbleiben.

:autsch:
 

Schandro

Top Contributor
Java:
//in mouseDragged:
curRect = new Rectangle(event.getX(), event.getY(), 0, 0);
// in paint
g.drawRect(curRect.x, curRect.y, curRect.width, curRect.height);
Du malst ein Rechteck mit 0 breite und höhe, natürlich kann man es nicht sehen. Mein Code oben war kein kompletter Code, da hat natürlich noch gefehlt das man den Punkt speichert wo die maustaste gedrückt wurde und anhand dessen jedesmal in mouseDragged die höhe und breite berechnet.
 

Hutmacher

Bekanntes Mitglied
Ein Rechteck mit Width und Height = 0 erzeuge ich nicht in der mouseDragged-Methode, sondern in der mousePressed-Methode. Denn wenn du das erste Mal klickst, sieht man ja sowieso höchstens einen Punkt (der auch vom Cursor überdeckt wird).

Nach dem Pressen
Java:
 //Beim ersten Klick gettet es die Klick-Koordinaten, also die Stelle,
        //an der das Rechteck beginnt.
        @Override 
        public void mousePressed(MouseEvent event)
        {
            setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
            curRect = new Rectangle(event.getX(), event.getY(), 0, 0);
        }
sind ja die Klick-Koords in curRect gespeichert.
Diese benutze ich dann ja auch zur Berechnung in mouseDragged:
Java:
//Berechnet, wie lang das Rechteck sein muss und lässt es zeichnen
        // - während des Ziehens
        @Override
        public void mouseDragged(MouseEvent event)
        {
            curRect = new Rectangle(
             event.getX(), event.getY(),
             event.getX() - curRect.x,
             event.getY() - curRect.y);
            
            repaint();
        }

Also tue ich ja das, was du sgast, aber es geht trotzdem nicht.
 
S

SlaterB

Gast
Java:
public class Test {

	public static void main(String[] args) {
		new RectangleDrawer();
	}
}

class RectangleDrawer extends Frame {
	private static Color backColor = new Color(240, 240, 240);// Hintergrundfensterfarbe
	private Vector<Rectangle> paintList; // damit paint alles erneut zeichnen
	// kann und nicht nur das letzte
	private Rectangle curRect; // das aktuell zu zeichnende Viereck

	// Konstruktor
	public RectangleDrawer() {
		super("Rectangle Drawer!");
		curRect = new Rectangle(0, 0, 0, 0); // Init.
		paintList = new Vector<Rectangle>(); // Init.

		setBackground(backColor);
		setSize(350, 250);
		setResizable(false);
		setIconImage(Toolkit.getDefaultToolkit().getImage("Icon.ico"));
		// setIconImage(getClass().getResource("res/Icon.ico"));
		addMouseListener(new MyMouseListener());
		addMouseMotionListener(new MyMouseDragListener());
		addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		setVisible(true);
	}

	public void paint(Graphics g) {
		g.drawString(String.valueOf(paintList.size()), getInsets().left + 3,
				getInsets().top + 10); // Schreibt Elemente

		if (curRect != null) {
			g.drawRect(curRect.x, curRect.y, curRect.width, curRect.height);
		}

		if (!paintList.isEmpty()) {
			// Zeichnet jedes Rechteck aus der Liste auf das Fenster
			for (Iterator<Rectangle> it = paintList.iterator(); it.hasNext();) {
				Rectangle rect = it.next();
				g.drawRect(rect.x, rect.y, rect.width, rect.height);
			}
		}

	}

	class MyMouseListener extends MouseAdapter {
		// Beim ersten Klick gettet es die Klick-Koordinaten, also die Stelle,
		// an der das Rechteck beginnt.
		@Override
		public void mousePressed(MouseEvent event) {
			setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
			curRect = new Rectangle(event.getX(), event.getY(), 0, 0);
		}

		// Ergibt beim Loslassen der Maustatse das letztendlich Rechteck
		@Override
		public void mouseReleased(MouseEvent event) {
			setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
			if (curRect != null) {
				paintList.add(curRect);
			}
			curRect = null;
		}
	}

	class MyMouseDragListener extends MouseMotionAdapter {
		// Berechnet, wie lang das Rechteck sein muss und lässt es zeichnen
		// - während des Ziehens
		@Override
		public void mouseDragged(MouseEvent event) {
			curRect.width = event.getX() - curRect.x;
			curRect.height = event.getY() - curRect.y;
			repaint();
		}
	}
}
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Best Practice Wie viele Referenzen machen Sinn? Weniger ist mehr? Allgemeine Java-Themen 1
D Input/Output Implementierung eines CommandHandlers/Parsers für viele Eingaben Allgemeine Java-Themen 26
T Multithreading: Wie viele Threads sollte ich erstellen? Allgemeine Java-Themen 12
Tacofan Hangman so viele Labels wie Buchstaben Allgemeine Java-Themen 5
K Variablen Konstruktor, unendlich viele Allgemeine Java-Themen 3
E Beliebig viele Worte Allgemeine Java-Themen 5
G Methoden Unterschiedliche viele Parameter Allgemeine Java-Themen 17
L MouseListener für viele Objekte erstellen Allgemeine Java-Themen 16
H Sehr viele Threads effizient Verwalten Allgemeine Java-Themen 13
R Arrayausgabe enthält viele Leerzeichen Allgemeine Java-Themen 4
M Threads Viele Aufrufe aus Thread, komisches Verhalten Allgemeine Java-Themen 8
C Threads Verbraucht eine Zeitabfrage viele Rechen-Ressourcen? Allgemeine Java-Themen 8
J BlueJ Methode hat zu viele Parameter Allgemeine Java-Themen 6
D (Viele) Daten performant speichern und lesen Allgemeine Java-Themen 5
S Viele zip-files zu einem kombinieren..? Allgemeine Java-Themen 3
KrokoDiehl Viele JARs und deren Resourcen Allgemeine Java-Themen 9
S Zu viele Felder. Allgemeine Java-Themen 4
S Viele Bilder -> Speicher ausgelastet? / (De-)serialisierung geht nicht mehr richtig Allgemeine Java-Themen 8
R Moeglichst viele Datumsstrings in Date Objekte konvertieren? Allgemeine Java-Themen 3
O viele Datensätze aus Datenbank - Java Heap Space - Excepion Allgemeine Java-Themen 25
C Viele Informationen aus zwei Collections vergleichen Allgemeine Java-Themen 2
T viele Threads Allgemeine Java-Themen 14
T Designfrage: Viele, kleine Objekte Allgemeine Java-Themen 13
M Beliebig viele Typen bei Generics Allgemeine Java-Themen 3
F Viele generische Parameter sinnvoll? oder besser casten? Allgemeine Java-Themen 10
E Viele if Abfragen auf viele Strings --> Alternative zu if Allgemeine Java-Themen 8
J Viele Fragen. =) Hoffentlich könnt ihr helfen Allgemeine Java-Themen 9
V 1 Methode für viele verschiedene Klassen? Allgemeine Java-Themen 9
S Viele Fragen eines Umsteigers (von .NET) Allgemeine Java-Themen 6
K Zu viele Threads -> langsamer angehen. Allgemeine Java-Themen 3
O Warum kann ich so keine Elemente löschen und erhalte einen IllegalStateException? Allgemeine Java-Themen 4
JavaJüngling beliebige Collection die Comperable Elemente enthält als Parameter Allgemeine Java-Themen 37
B Einfach Elemente zweier Arraylisten kreuz und quer vergleichen, min und max Problem? Allgemeine Java-Themen 16
H Elemente aus ArrayList in Array speichern Allgemeine Java-Themen 8
E Elemente innerhalb einer ArrayList vergleichen Allgemeine Java-Themen 33
J In einem Set doppelte Elemente erzeugen Allgemeine Java-Themen 4
GreenTeaYT Elemente eines 2Dim LinkedList von links nach rechts ausgeben? Allgemeine Java-Themen 0
H ArrayList: Leere Elemente finden? Allgemeine Java-Themen 2
Streeber Probleme mit AWT-EventQueue: ArrayList Elemente hinzufügen Allgemeine Java-Themen 1
Z Elemente einer ArrayList von rechts wegnehmen Allgemeine Java-Themen 5
E ArrayList Anzahl der gleichen Elemente Allgemeine Java-Themen 4
K Neue Elemente in JList einfügen Allgemeine Java-Themen 2
A Collections Array-Elemente in ArrayList kopieren ohne Schleife Allgemeine Java-Themen 7
S GUI - Drag & Drop Elemente Allgemeine Java-Themen 10
J Elemente zu einer List hinzufügen? Allgemeine Java-Themen 9
T OpenOffice Interface Elemente Ein/Ausblenden Allgemeine Java-Themen 5
S Aus einer Liste<Oberklasse> alle Elemente die eine bestimmte Unterklasse von Oberklasse haben filter Allgemeine Java-Themen 8
D prüfen, ob Enums bestimmte Elemente enthalten Allgemeine Java-Themen 3
M Elemente aus ArrayList, die in ArrayList ist Allgemeine Java-Themen 2
Z Elemente einer HashTabelle gezielt ansprechen Allgemeine Java-Themen 10
S Alle Elemente von zwei Listen vergleichen Allgemeine Java-Themen 10
C Auf Oberflaechen Elemente zugreifen Allgemeine Java-Themen 8
Iron Monkey Array-Elemente Allgemeine Java-Themen 9
S Array: Anzahl Elemente mit best. Wert zählen Allgemeine Java-Themen 4
R Elemente eines Vectors [Java 1.4] Allgemeine Java-Themen 5
B Liste auf gleiche Elemente untersuchen? Allgemeine Java-Themen 2
C Auf ArrayList Elemente referenzieren? Allgemeine Java-Themen 17
M Progblem bei Zugriff auf Array Elemente Allgemeine Java-Themen 4
der JoJo [TreeSelection] wie bekomme ich alle Elemente Allgemeine Java-Themen 4
G Alle Möglichkeiten n Elemente Anzuordnen. Allgemeine Java-Themen 13
M Elemente aus Liste entfernen? Allgemeine Java-Themen 7
Z Elemente in Vector nach Häufigkeit sortieren. Allgemeine Java-Themen 13
E Reihenfolge der Elemente einer ArrayList? Allgemeine Java-Themen 4
J Netbeans: wie auf grafische elemente zugreifen, andere Datei Allgemeine Java-Themen 2
B Nach Deserialisieren: Elemente des JFrames ohne Funktion Allgemeine Java-Themen 5
G Umkehrung der Array Elemente Allgemeine Java-Themen 2
K Elemente im ArrayList vergleichen Allgemeine Java-Themen 9
F Elemente überdecken sich! Allgemeine Java-Themen 13
G anzahl "verwendeter" elemente eines arrays ermitte Allgemeine Java-Themen 2
S alle elemente aus hashmap lesen Allgemeine Java-Themen 8
T Elemente eines Arrays mischen Allgemeine Java-Themen 5
C Collection, LinkedList, Elemente Allgemeine Java-Themen 4
S Einzelne Elemente in einer Bild Datei Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben