AWT Neuzeichnen unterbinden

KäseSahne

Mitglied
Hallo Java-Gemeinde,

bin neu hier im Forum und habe gleich schon eine Frage (Neuling auf dem Gebiet grafische Oberfläche). Ich hoffe, dass ihr mir dabei weiterhelfen könnt. Habe bereits das halb Internet abgegrast aber leider nichts funktionierends für mich gefunden.

Zum Problem:

Ich habe mir ein Frame erzeugt, auf das ich ein Panel mit einem Button gelegt habe.
Als nächstes habe ich ein zweites Frame erzeugt, auf das ich ebenfalls ein Panel gelegt habe. Auf diesem Panel sollen durch Knopfdruck Ovale gezeichnet werden.
Desweiteren habe ich eine Klasse Oval, die von Panel erbt. Dort habe ich die paint(Graphics g)-Methode überschrieben und zusätzlich eine drawOval-Methode geschrieben, der ich die Parameter für ein Oval übergebe und repaint() aufrufe.

Durch Knopfdruck wird mir auch ein Oval gezeichnet. Jedoch wird beim erneuten Drücken das alte Oval "gelöscht" und ein neues gezeichnet (hängt wahrscheinlich mit dem repaint()-Aufruf zusammen??). Wie stelle ich es an, dass die neuen Ovale auf dem Panel hinzugefügt werden ohne die alten zu löschen?

Vielen Dank im Voraus!

Gruß
 
G

Gast2

Gast
Ich würde alles auf einem BufferedImage zeichnen.
In der paint Methode zeichnest du dann nur das BufferedImage auf das Panel. Dann hast du die volle Kontrolle darüber wann du das BufferedImage leeren willst.
 

KäseSahne

Mitglied
Gibt es vlt. eine nicht so professionelle Methode um das Problem zu lösen?
Habe mir gerade die API zu BufferedImage angeschaut, weiß aber nicht so recht, wie man da Elemente hinzufügen kann bzw. wie das Teil funktioniert:(.
 
G

Gast2

Gast
Du musst keine Komponenten hinzufügen, du kannst dort wie auf nem JPanel einfach drauf zeichnen:

Java:
public class BufferedImageExample extends JPanel {
	private static final long serialVersionUID = 1L;
	
	private BufferedImage img;
	
	public BufferedImageExample() {
		img = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
		
		// fill image
		Graphics g = img.getGraphics();
		g.drawOval(50, 50, 100, 25);
	}
	
	public void manipulateImage() {
		// image bearbeiten, leeren, neuzeichnen, oder oder oder
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		
		g.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), this);
	}
}
 

KäseSahne

Mitglied
Danke :toll:

Habe es jetzt mit Hilfe deines Quellcodes für ein ganz normales Frame hinbekommen. Der entscheidende Abschnitt war der:

Graphics g = img.getGraphics();

Habe nämlich immer gelesen, dass man möglichst auf den Einsatz von .getGraphics() verzichten soll aber nur so konnte ich meine paint-Methode mit g beliebig aufrufen.
 
G

Gast2

Gast
Ja Moment!
Den
Code:
getGraphics()
Aufruf sollte (oder darf) man nicht auf Komponenten Aufrufen die einen Bereich zugeteilt bekommen worauf sie zeichnen dürfen, also z.b. Frames, Panels oder jegliche Art von Components.

Auf einem BufferedImage ist der Aufruf kein Problem, sonst könntest du damit auch nicht wirklich was anfangen ;)
Wenn du dir jetzt irgendwie mit getGraphics das Graphics Objekt von deinem Frame geholt hast, dann ist das falsch!
 

KäseSahne

Mitglied
Hmm... ok.

Ich habe eine Klasse (1.) geschrieben, die von Frame erbt, mit der ich das "Zeichen"-Frame erzeugen kann.

In der nächsten Klasse (2.), die von Panel erbt, habe ich die Methoden drawOval und paint. Der drawOval-Methode übergebe ich die Parameter, die ich für das Oval benötige und ein Frame f. In dieser Methode rufe ich dann paint(f.getGraphics()) auf.

In der letzten Klasse, in der auch die main steht, erzeuge ich im Konstruktor das Hauptfenster mit dem Button. Desweiteren erzeuge ich dort ein Objekt der (1.) und der (2.) Klasse. Im ActionListener meines Buttons rufe ich die drawOval-Methode der (2.) Klasse auf und übergebe dieser das Objekt der (1.) Klasse.

Ich hoffe, dass ich meinen aktuellen Stand verständlich machen konnte.
Und es ist richtig, dass man es so nicht machen sollte?

Was kann denn im schlimmsten Fall mit meiner Variante passieren?
 
G

Gast2

Gast
Und es ist richtig, dass man es so nicht machen sollte?
Ganz genau.

Was kann denn im schlimmsten Fall mit meiner Variante passieren?
Es funktioniert nicht wie gewollt.
Probleme können da vor allem auftreten wenn du das Fenster verschiebst oder die die Größe änderst.

Aber selbst wenns laufen sollten, mach es lieber gleich richtig!
 

KäseSahne

Mitglied
So, habe jetzt das BufferedImage so gut es geht reingefriemelt. Soweit funktioniert es auch.
Wenn ich jetzt auf den "Zeichnen"-Button klicke, "blitzt" mein Zeichen-Frame immer auf (Bild verschwindet kurz und wird aktualisiert wieder angezeigt) ist das normal?

Außerdem habe ich jetzt zusätzlich ein "Löschen"-Button eingebaut, der den Inhalt des "Zeichen"-Frames löschen soll. In meiner "Zeichen"-Klasse habe ich dann die Methode loeschen hinzugefügt, die mein BufferedImage img überschreint. Diese rufe ich dann im ActionListener auf. Wenn ich jetzt auf löschen klicke ist der Inhalt zwar weg aber ich kann nichts neues mehr zeichnen. Gibts dafür eine Lösung?
 
G

Gast2

Gast
Wenn ich jetzt auf den "Zeichnen"-Button klicke, "blitzt" mein Zeichen-Frame immer auf (Bild verschwindet kurz und wird aktualisiert wieder angezeigt) ist das normal?
Nein.

Außerdem habe ich jetzt zusätzlich ein "Löschen"-Button eingebaut, der den Inhalt des "Zeichen"-Frames löschen soll. In meiner "Zeichen"-Klasse habe ich dann die Methode loeschen hinzugefügt, die mein BufferedImage img überschreint. Diese rufe ich dann im ActionListener auf. Wenn ich jetzt auf löschen klicke ist der Inhalt zwar weg aber ich kann nichts neues mehr zeichnen. Gibts dafür eine Lösung?
Ja, bestimmt.

Poste mal deinen Code.
 

KäseSahne

Mitglied
Hier mein Code:

Code:
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
public class DrawFrame extends Panel{
	
	public BufferedImage img;
	Graphics g;	
	
	public DrawFrame(){		
		img = new BufferedImage(500 ,500, BufferedImage.TYPE_INT_ARGB);		
		g = img.getGraphics();	
	}	
	
	public void manipulieren(int posX, int posY, int w, int h, Color color,int fuellen, int object){		
		if(object == 0){
				if(fuellen == 0){
					g.setColor(color);
					g.drawOval(posX, posY, w, h);
				}
				else{
					g.setColor(color);
					g.fillOval(posX, posY, w, h);					
				}
			}
			else{
				if(fuellen == 0){
					g.setColor(color);
					g.drawRect(posX, posY, w, h);
				}
				else{
					g.setColor(color);
					g.fillRect(posX, posY, w, h);
				}				
			}					
	}
	
	public void loeschen(){
		//img = new BufferedImage(500 ,500, BufferedImage.TYPE_INT_ARGB);
	}
	
	public void paint(Graphics g){
		super.paint(g);
		g.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), this);
		
	}
}

Code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.Serializable;
public class MainFrame extends Frame{	
		
	public static void main(String[]args){
		new MainFrame("DasFenster");
	}
	
	public MainFrame(String titel){
		super(titel);
		setSize(500, 500);
		setLocation(200, 200);		
		Panel panel = new Panel();
		panel.setLayout(new GridLayout(3,0));
		Button a = new Button("DerZeichenButton");
		Button aa = new Button("DerClearButton");
		Button aaa = new Button("DerExitButton");
		panel.add(a);
		panel.add(aa);
		panel.add(aaa);
		add(panel);
		addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent we){
				System.exit(0);
			}
		});
		setVisible(true);			
		
		final DrawFrame df = new DrawFrame();
		final Frame f = new Frame("DasTolleFenster");
		f.setBackground(Color.white);		
		f.setSize(500,500);
		f.setLocation(800, 200);		
		f.setVisible(true);
		
		
		
		a.addActionListener(new ActionListener(){			
			public void actionPerformed(ActionEvent arg0) {							
						int posX = (int)(Math.random()*300+1);
						int posY = (int)(Math.random()*300+1);
						int w = (int)(Math.random()*200+1);
						int h = (int)(Math.random()*200+1);										
						int object = (Math.random()<=0.5 ? 0 : 1);
						if(object == 0)
							h = w;
						int fuellen = (Math.random()<=0.5 ? 0 : 1);
						int color = (int)(Math.random()*7+1);
						Color c = null;						
						switch(color){
						case(1):
							c = Color.black;
							break;
						case(2):
							c = Color.blue;
							break;
						case(3):
							c = Color.cyan;
							break;
						case(4):
							c = Color.gray;
							break;
						case(5):
							c = Color.green;
							break;
						case(6):
							c = Color.yellow;
							break;
						case(7):
							c = Color.red;
							break;
						}	
						df.manipulieren(posX, posY , w, h, c, fuellen, object);
						f.add(df);
						f.setVisible(true);
												
			}			
		});
		
		aa.addActionListener(new ActionListener(){			
			public void actionPerformed(ActionEvent e) {
				df.loeschen();
				f.add(df);
				f.setVisible(true);
			}		
		});
		
		aaa.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				System.exit(0);
			}
		});
				
	}
	
}

Wurde noch ein bisschen verändert: Es wird jetzt per Zufall entweder ein Kreis oder Rechteck gemalt, mit zufälliger Größe, gefüllt oder nicht und zufälliger Farbe.
 
G

Gast2

Gast
Also:
- verwende sprechende Variablennamen. a, aa, aaa ... das geht gar nicht ;)
- beim malen/löschen hast du immer das drawFrame neu geaddet, ein einfaches repaint reicht aus
- im DrawFrame hast du dir das Graphics objekt gespeichert. Nach dem löschen (und damit neu erstellen das BI) ist das Graphics Objekt ungültig.

Das waren jetzt so die sachen die mir aufgefallen sind.
Insgesamt ist der Code nicht wirklich schön, da fehlt es etwas an struktur.

Java:
public class MainFrame extends Frame {	
		
	public static void main(String[]args){
		new MainFrame("DasFenster");
	}
	
	public MainFrame(String titel){
		super(titel);
		setSize(500, 500);
		setLocation(200, 200);		
		Panel panel = new Panel();
		panel.setLayout(new GridLayout(3,0));
		Button a = new Button("DerZeichenButton");
		Button aa = new Button("DerClearButton");
		Button aaa = new Button("DerExitButton");
		panel.add(a);
		panel.add(aa);
		panel.add(aaa);
		add(panel);
		addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent we){
				System.exit(0);
			}
		});
		setVisible(true);			
		
		final DrawFrame df = new DrawFrame();
		final Frame f = new Frame("DasTolleFenster");
		f.setBackground(Color.white);		
		f.setSize(500,500);
		f.setLocation(800, 200);		
		f.setVisible(true);
		f.add(df);
		f.pack();

		a.addActionListener(new ActionListener(){			
			public void actionPerformed(ActionEvent arg0) {							
						int posX = (int)(Math.random()*300+1);
						int posY = (int)(Math.random()*300+1);
						int w = (int)(Math.random()*200+1);
						int h = (int)(Math.random()*200+1);										
						int object = (Math.random()<=0.5 ? 0 : 1);
						if(object == 0)
							h = w;
						int fuellen = (Math.random()<=0.5 ? 0 : 1);
						int color = (int)(Math.random()*7+1);
						Color c = null;						
						switch(color){
						case(1):
							c = Color.black;
							break;
						case(2):
							c = Color.blue;
							break;
						case(3):
							c = Color.cyan;
							break;
						case(4):
							c = Color.gray;
							break;
						case(5):
							c = Color.green;
							break;
						case(6):
							c = Color.yellow;
							break;
						case(7):
							c = Color.red;
							break;
						}	
						df.manipulieren(posX, posY , w, h, c, fuellen, object);
						df.repaint();
			}			
		});
		
		aa.addActionListener(new ActionListener(){			
			public void actionPerformed(ActionEvent e) {
				df.loeschen();
				df.repaint();
			}		
		});
		
		aaa.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				System.exit(0);
			}
		});
				
	}
}

Java:
public class DrawFrame extends Panel{
	
	public BufferedImage img;
	
	public DrawFrame(){		
		img = new BufferedImage(500 ,500, BufferedImage.TYPE_INT_ARGB);			
		setPreferredSize(new Dimension(500, 500));
	}	
	
	public void manipulieren(int posX, int posY, int w, int h, Color color,int fuellen, int object){
		Graphics g = img.getGraphics();
		
		if(object == 0){
				if(fuellen == 0){
					g.setColor(color);
					g.drawOval(posX, posY, w, h);
				}
				else{
					g.setColor(color);
					g.fillOval(posX, posY, w, h);					
				}
			}
			else{
				if(fuellen == 0){
					g.setColor(color);
					g.drawRect(posX, posY, w, h);
				}
				else{
					g.setColor(color);
					g.fillRect(posX, posY, w, h);
				}				
			}
	}
	
	public void loeschen(){
		img = new BufferedImage(500 ,500, BufferedImage.TYPE_INT_ARGB);
	}
	
	public void paint(Graphics g){
		super.paint(g);
		g.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), this);
		
	}
}
 

KäseSahne

Mitglied
Vielen, vielen Dank. Jetzt rennt es :toll:
Die Variablen muss ich wirklich mal etwas aussagekräftiger benennen :D Habe ich mir leider angewöhnt, da die Programme noch so klein sind :oops:
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Thallius JScrollPane Scrollpos setzen nach Neuzeichnen AWT, Swing, JavaFX & SWT 3
A Neuzeichnen bei AbstractAction AWT, Swing, JavaFX & SWT 4
A Swing JFrame neuzeichnen lassen, position neu berechnen lassen? AWT, Swing, JavaFX & SWT 9
M GUI muss updaten und neuzeichnen AWT, Swing, JavaFX & SWT 3
J JavaFX Automatisches Neuzeichnen ("Repaint") abstellen. AWT, Swing, JavaFX & SWT 10
E Swing Neuzeichnen von JPanel AWT, Swing, JavaFX & SWT 4
V automatisches neuzeichnen verhindern AWT, Swing, JavaFX & SWT 3
P problem mit neuzeichnen AWT, Swing, JavaFX & SWT 2
L Beim Neuzeichnen einer Swing GUI kurz Schwarzer Hintergrund AWT, Swing, JavaFX & SWT 8
D Jpanel neuzeichnen AWT, Swing, JavaFX & SWT 5
N Swing MainWindow(JFrame) aktualisieren(neuzeichnen) repaint AWT, Swing, JavaFX & SWT 4
P Swing JTextArea - beim neuzeichnen bleibt manchmal weißer Kasten AWT, Swing, JavaFX & SWT 10
S Swing JFrame neuzeichnen - bleibt grau AWT, Swing, JavaFX & SWT 18
D jScrollPane - neuzeichnen AWT, Swing, JavaFX & SWT 4
S Probleme beim Neuzeichnen eines JLabels AWT, Swing, JavaFX & SWT 6
R Bestimmte Komponenten vom Neuzeichnen abhalten AWT, Swing, JavaFX & SWT 2
G SWT - Neuzeichnen AWT, Swing, JavaFX & SWT 2
P Zeichnen in Canvas und Neuzeichnen AWT, Swing, JavaFX & SWT 3
J NeuZeichnen eines JXTitledPanels? AWT, Swing, JavaFX & SWT 4
A Komponente entfernen. Kein neuzeichnen nach validate() AWT, Swing, JavaFX & SWT 2
B Swing GUI neuzeichnen AWT, Swing, JavaFX & SWT 5
N Flackern beim neuzeichnen von JPanel AWT, Swing, JavaFX & SWT 19
H neuzeichnen von graphics nach minimierung oder ähnlichem AWT, Swing, JavaFX & SWT 10
W Problem beim neuzeichnen eines Rechteckes (SWT) AWT, Swing, JavaFX & SWT 2
M drawLine() in JPanel hinzufügen ohne Neuzeichnen AWT, Swing, JavaFX & SWT 3
A Null pointer exception beim Neuzeichnen AWT, Swing, JavaFX & SWT 4
R Neuzeichnen eines JFrame mit repaint AWT, Swing, JavaFX & SWT 3
G JScrollPane scrollt nach Neuzeichnen von selber AWT, Swing, JavaFX & SWT 2
S neuzeichnen AWT, Swing, JavaFX & SWT 4
T JLabel neuzeichnen nach überdecken durch andere Fenster AWT, Swing, JavaFX & SWT 5
A Problem beim Neuzeichnen AWT, Swing, JavaFX & SWT 2
S AWT: Panel durch anderes Panel ersetzen. Neuzeichnen-Problem AWT, Swing, JavaFX & SWT 4
J Anklicken der Symbolleiste und Neuzeichnen des Buttons AWT, Swing, JavaFX & SWT 6
M Probleme mit JTable neuzeichnen! AWT, Swing, JavaFX & SWT 2
S SWT [TextBox] Bestimmtes Zeichen entfernen unterbinden AWT, Swing, JavaFX & SWT 3
M Swing JTable - Umsortieren einzelner Spalten unterbinden AWT, Swing, JavaFX & SWT 6
G Fenster minimieren bei [win]+[d] drücken unterbinden! AWT, Swing, JavaFX & SWT 10
X Doppelte Daten in DefaultListModel unterbinden AWT, Swing, JavaFX & SWT 3
O Skalierung des Center-Bereichs unterbinden AWT, Swing, JavaFX & SWT 2
J Drag'n Drop imm selben Frame unterbinden AWT, Swing, JavaFX & SWT 3
U Maximieren für SWT Shell unterbinden AWT, Swing, JavaFX & SWT 2
I JEditorPane vorladen der Seiten unterbinden AWT, Swing, JavaFX & SWT 2
B Verschieben einer Komponente unterbinden AWT, Swing, JavaFX & SWT 6
X Verschwinden des JMenu unterbinden AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben