2D-Grafik Problem mit überzeichnen

ionhack

Mitglied
Folgender Quellcode(Auschnitte):

Java:
private class Listen2Actions implements ActionListener {
            @Override  public void actionPerformed(ActionEvent e) {
            Object src = e. getSource ();
            if (src == bu_aktu) {anzein_alt=anzein; anzein = Integer.parseInt(cu_eingaenge.getSelectedItem().toString());set = 1; zeichnen();}    
            ...                                                                          
        }
            
    }
 public void zeichnen () {
        g2 = (Graphics2D) panel.getGraphics();
        g2.setColor(color);
        if (set == 1){eingaengepaint(g2);
        ...
}
 public void eingaengepaint (Graphics2D g2){
    int i=0;
    while (i<anzein_alt){g2.setColor(bg); Hauptausgang ha = sort.new Hauptausgang(i); ha.draw(g2);Haupteingang he = sort.new Haupteingang(i); he.draw(g2);i++;}
    i=0;sort.hpaus.clear(); sort.hpein.clear();
    while (i<anzein){g2.setColor(color);Hauptausgang ha = sort.new Hauptausgang(i); ha.draw(g2);Haupteingang he = sort.new Haupteingang(i); he.draw(g2);db.heintragen("he"+sort.hpein.indexOf(he.h), "ha"+sort.hpaus.indexOf(ha.h));i++;}
 }

wenn ich nun anzein erhöhe, zeichnet er sie, aber wenn ich weniger mache bleiben die gezeichneten Rechtecke. Weiß jemand Rat?
Wenn ihr die weiteren Klassen benötigt (z.B. Haupteingang/Hauptausgang), sagt mir Bescheid.
Danke schon im Vorraus.
 
[JAVA=11] g2 = (Graphics2D) panel.getGraphics();[/code]
getGraphics an Komponenten aufzurufen ist in 99,999999% aller Fälle falsch.

Man zeichnet in dem man die paint(Graphics g) [AWT] bzw. paintComponent(Graphics g) [Swing] einer Komponente überschreibt.
siehe:
Galileo Computing :: Java ist auch eine Insel – 20 Grafikprogrammierung
bzw. der erste Thread hier im Forum:
http://www.java-forum.org/awt-swing-swt/43939-zeichnen-swing-tutorial.html
 
Also...
Es existiert da so eine Combobox (namens cu_eingaenge). Wenn ich auf ein Button drücke (namens bu_aktu) dann kriege ich die aktuelle ausgewählte Zahl. (In der Combobox sind die Zahlen von 2-10). Er weist nun dem Integer anzein_alt den alten Wert von cu_eingaenge und dem Integer anzein den aktuellen Wert. Schließlich werden anzein_alt-viele Rechtecke mit Hintergrundfarbe gemalt (bg) und anzein-viele Rechtecke mit Fordergrundfarbe(color). Die Rechtecke werden jeweils in einer einzelnen Klasse definiert. In einer solchen Klasse existiert auch ein Methode namens draw(Graphics2D). Wenn ich also eine neue Instanz erzeuge und die Methode aufrufe zeichnet er ein Rechteck.

Edit: ich zeichne ja nicht nur die Rechtecke und das Zeichnen funktioniert bis halt auf diese Rechtecke wunderbar. Außerdem will ich das Zeichnen besser kontrollieren und will nicht, dass die Zeichenfunktion automatisch aufgerufen wird.
 
Zuletzt bearbeitet:
Also ich habe dich da glaube ich noch immer nicht ganz verstanden, versuche aber mal selbst zu erklären was du meinst...

Du hast eine ComboBox mit den Zahlen 2-10. Und du hast einen Button. Wenn dieser geklickt wird, wird der aktuell ausgewählte Wert aus der ComboBox ausgelesen. Dieser Wert ist dann auch die Anzahl der zu zeichnenden Rechtecke, ja?

Hoffe ich habe dich richtig verstanden...

Michael... hat gesagt.:
Man zeichnet in dem man die paint(Graphics g) [AWT] bzw. paintComponent(Graphics g) [Swing] einer Komponente überschreibt.
siehe:
Galileo Computing :: Java ist auch eine Insel – 20 Grafikprogrammierung
bzw. der erste Thread hier im Forum:
Java programmieren aus Leidenschaft

Das ist übrigends wirklich ein zu beherzigender Tipp! 😉
 
ja, richtig.
Ich werde mal nachschauen^^

Nun, habe ein wenig nachgestöbert.
Eine Frage: Wenn also panel.getGraphics() vllcht. der Grund ist warum es net funktioniert (warum auch immer dann die anderen funktionieren), bzw. es einfach nicht schön ist. Wie kann man dann die aktuellen Zeichnungen auf dem Panel abrufen und darauf weiterzeichnen? Kann mir jemand da ein Tipp geben. Wäre nett.

MFG
 
Du könntest mit Hilfe der zu überschreibenden Methode für AWT

Java:
@Override
public void paint(Graphics g){

}

oder für Swing

Java:
@Override
public void paintComponent(Graphics g){

}

deine Zeichnung realisieren.

Merke dir in einer Objektvariable also einfach nur den Int-Wert der in der Combobox ausgewählten Zahl.
Nachdem du nun den Button geklickt hast rufst du ein repaint() (bei AWT) oder ein revalidate() (für Swing) auf. Diese Methode sorgt dafür, dass automatisch der Code in deiner paint/paintComponent-Routine ausgeführt wird.
Das bedeutet, dass du innerhalb dieser Methode einfach nur noch eine for schleife baust, um die Rechtecke zu zeichnen....
 
Danke.

Aber damit wäre ja das Problem mit den Rechtecken behoben, aber ein Problem wäre mit den anderen Zeichnungen aufetaucht.
Ich habe nämlich noch so ein Button. Wenn man auf ihn drückt und anschließend auf das Panel drückt, erscheint dort ein Graphics2D-Object (ist jetzt egal was für eins, meinetwegen ein Oval). In einer Schleife kann man es ja nicht packen^^. Wie dann?
 
Zuletzt bearbeitet:
Tu uns mal einen gefallen und schreib bitte nochmal Punkt für Punkt auf, was eigentlich überhaupt dein Programm machen soll...
Wofür das Ganze? Wofür diese Rechtecke und wofür jetzt noch so eine "Graphics2D-Zeichnung"...
 
Wenn also panel.getGraphics() vllcht. der Grund ist warum es net funktioniert
Wollte damit nicht sagen, dass es daran liegt. Wollte nur auf die korrekte Vorgehensweise hinweisen.

So wirklich verstanden habe ich das Ganze allerdings nicht. Geht es zum ein Zeichenprogramm?
Wenn man Objekte dauerhaft anzeigen will muss man diese "speichern" entweder man hält die Referenzen in Variablen (und diese eventuell in einer Liste) und arbeitet in der paint... diese ab oder man zeichnet auf ein Image (z.B. BufferedImage) und läst dieses in der paint... zeichnen.

Erstere Vorgehensweise ermöglicht das Editieren und Löschen bereits "gezeichneter" Objekte. Letztere ist fix.
 

Anhänge

Beschreiben... bin grad ein bißchen träge.

Hier was aus meiner Sammlung (Der relevante Code ist erst ab Zeile 65). Es wird ein Interface "DrawingObject" (man könnte auch bestehende aus der API verwenden) definiert. Dieses muss jedes Objekt welches sich zeichnen will implementieren. Die Klasse PaintingPanel ist quasi das Papier/Zeichenbrett und verwaltet die zu zeichnenden Objekt in einer Liste.

Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;

import javax.swing.*;

public class PaintingDemo extends JFrame {
	private PaintingPanel paintPanel;
	
	public PaintingDemo() {
		JMenuBar bar = new JMenuBar();
		JMenu menu = new JMenu("Datei");
		JMenuItem item;
		menu.add(item = new JMenuItem("Beenden"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				System.exit(0);
			}
		});
		bar.add(menu);
		
		menu = new JMenu("Einfügen");
		menu.add(item = new JMenuItem("Kreis"));
		item.setAccelerator(KeyStroke.getKeyStroke("K"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				paintPanel.add(new Circle());
				paintPanel.repaint();
			}
		});
		menu.add(item = new JMenuItem("Rechteck"));
		item.setAccelerator(KeyStroke.getKeyStroke("R"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				paintPanel.add(new Rectangle());
				paintPanel.repaint();
			}
		});
		menu.add(item = new JMenuItem("Radieren"));
		item.setAccelerator(KeyStroke.getKeyStroke("D"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				paintPanel.clear();
				paintPanel.repaint();
			}
		});
		bar.add(menu);
		
		this.setJMenuBar(bar);
		paintPanel = new PaintingPanel();
		paintPanel.setBackground(Color.WHITE);
		this.getContentPane().add(paintPanel);
	}

	public static void main(String[] args) {
		JFrame frame = new PaintingDemo();
		frame.setBounds(0, 0, 500, 300);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
	
	class PaintingPanel extends JPanel {
		List<DrawingObject> objList = new ArrayList<DrawingObject>();
		
		public void add(DrawingObject obj) {
			this.objList.add(obj);
		}
		
		public void clear() {
			this.objList.clear();
		}
		
		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			for (int i=0; i<objList.size(); i++)
				objList.get(i).paintObject(g);
		}
	}
	
	interface DrawingObject {
		public void paintObject(Graphics g);
	}
	
	class Circle implements DrawingObject {
		int x = (int)(Math.random()*400);
		int y = (int)(Math.random()*200);
		int d = (int)(Math.random()*200) +10;
		public void paintObject(Graphics g){
			g.drawOval(x, y, d, d);
		}
	}
	
	class Rectangle implements DrawingObject {
		int x = (int)(Math.random()*400);
		int y = (int)(Math.random()*200);
		int w = (int)(Math.random()*200) +10;
		int h = (int)(Math.random()*200) +10;
		public void paintObject(Graphics g){
			g.drawRect(x, y, w, h);
		}
	}
}
 
Erstmal vielen Danke..
führe es bei mir gerade aus und experimentiere...
mal schauen ob es mir weiterhilft. aber ich habe schon gute Vorahnungen^^.
MFG
Melde mich.
 
Nun. Bin zwar immer noch beim Einbinden und umändern. Aber es scheint eine super Idee zu sein. Kann alles rückgängig machen und so. Alles was zu zeichnen ist, kann ich immer in einem Array abrufen^^. Schön. Bedanke mich an damtre und Michael.
MFG
 

Zurück
Oben