2D-Grafik Beliebig viele Objekte auf einer Zeichenfläche zeichnen

propra

Aktives Mitglied
Hallo zusammen,

ich möchte gerne auf einer Zeichenfläche, die ich von JPanel erben lasse mehrere Objekte Zeichnen. Es soll sich dabei um Rechtecke und Kreise handeln, wobei die Anzahl und auch die Reihenfolge, wo und in welcher Reihenfolge sie hinzugefügt werden, keine Rolle spielen soll.
Nachdem ich jetzt auch das angepinnte Tutorial zum Zeichnen mit Swing von Wildcard und den entsprechenden Abschnitt in Java ist auch eine Insel gelesen habe, fehlt es mir trotzdem noch an einer Idee, wie man das umsetzen kann.
Mein Problem ist, dass ich nicht genau weiß, wie ich paintComponent() überschreiben soll, ohne da Logik rein zu bringen.
Mein generelle Idee war es in einer Klasse Symbole eine Liste mit Rechtecken und eine mit Kreisen zu verwalten. In diesen Objekten Rechteck oder Kreis sind dann die Positionen auf der Zeichenfläche gespeichert.
Ich wäre dankbar, wenn mir jemand einen kurzen Ansatzpunkt liefern könnte.

Vielen Dank.
 
deine Klasse Symbole klingt gut und welche genaue Beschränkung befürchtest du für paintComponent()?
es sollte sicher vermieden werden, dort die Positionen der Objekte zu berechnen oder ähnlich aufwendiges,
aber sie einfach nur per Schleife zu durchlaufen und zu malen, das ist absolut in Ordnung, sonst ginge ja gar nix
 
Deine paintComponent Methode könnte so aussehen:
Java:
protected paintComponent(Graphics g) {
  for (Symbol symbol : symbols) {
    if (symbol.isCircle()) {
      g.fillOval(symbol.getX(), symbol.getY(), symbol.getWidth(), symbol.getHeight());
    } else if (symbol.isRectangle()) {
      g.fillRect(symbol.getX(), symbol.getY(), symbol.getWidth(), symbol.getHeight());
    }
  }
}
 
auch wenn bisschen billige Kritik, da es System-Klassen betrifft, aber im Folgepost zu deinem Link hast du ebenso Code der Art
Java:
        if (e.getButton() == MouseEvent.BUTTON1)
        {
            Clickable clickable = new Smiley(e.getX(), e.getY());
            System.out.println("Linke Maustaste - füge hinzu: " + clickable);
            paintPanel.addClickable(clickable);
        }
        else if (e.getButton() == MouseEvent.BUTTON3)
        {
          ...
manchmal muss so eine Unterscheidung sein wenn man die Originalklassen nicht mit (paint-)Code belasten kann oder will,
eine Typ-Abfrage wäre immerhin schon besser als instanceof-Test 😉
 
Ich danke Euch beiden.
Ich glaube ich habe noch ein anderes Problem. Für das ich auch noch einen Rat bräuchte.
Ich habe meinem Fenster eine Menuleiste spendiert, wo man dann nach Auswahl des Punktes Bearbeiten -> Hinzufügen aus einem Submenu -> Kreis oder -> Rechteck auswählen kann.
Der nächste Schritt ist in beiden Fällen auf jeden Fall das warten auf den Klick innerhalb der Zeichenfläche. Woraufhin dann das entsprechende Symbol gezeichnet wird.
Ich stelle mir jetzt vor, dies als sogenannten (Zeichen-)Modus irgendwie festzuhalten, damit ich nachher besser abfragen kann, welche Form dem Model hinzugefügt werden soll.
Sollte ich dazu eine separate Klasse Modus verwenden? Wie wird so etwas in einem Zeichenprogramm á la GIMP realisiert? Das soll natürlich nicht heißen, dass ich mein Programm mit GIMP vergleichen möchte oder das es jemals auch nur annähernd an den Funktionsumfang herankommen soll.
 
irgendwo festhalten ist korrekt,
fange so einfach an wie es für die Funktionalität reicht, setze irgendein Attribut der Klasse,
und wenn dann der Mausklick drankommst schaust du nach was gerade 'eingestellt ist'

falls du JRadioButtons oder vergleichbares verwendest, wird es vielleicht automatisch irgendwo gesichert
How to Use Menus (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Swing Components)
aber du hast wohl eher was anderes vor, eine einmalige Auswahl, die z.B. auch den Cursor ändert
 
Zuletzt bearbeitet von einem Moderator:
auch wenn bisschen billige Kritik, da es System-Klassen betrifft, aber im Folgepost zu deinem Link hast du ebenso Code der Art
...
manchmal muss so eine Unterscheidung sein wenn man die Originalklassen nicht mit (paint-)Code belasten kann oder will,
eine Typ-Abfrage wäre immerhin schon besser als instanceof-Test 😉

Abgesehen davon, dass das diese Abfrage im konkreten Fall nicht vermeiden kann (weil die Klasse MouseEvent eben so ist) stelle ich mir es auch schwierig vor, sowas in einem anderen Zusammenhang sauberer zu machen (weil das eine ziemlich komplexe Infrastruktur um MouseEvents herum erfordern würde, die WEIT über solche Dinge wie z.B. "Actions" in Swing hinausgehen würde).

Tatsächlich überzeugt das Argument, seine Originalklassen nicht mit paint-Code zu belasten schon viel eher, aber auch nur in erster Näherung, weil einen ja niemand zwingt, das in die gleiche Klasse zu schreiben - sowas wie
Java:
class PaintableThing implements Paintable {
    private Thing thing;
    public void paint(Graphics g) { g.drawLine(thing.getX(), thing.getY()...); }
...
wäre ja auch eine Option - oder grob im Stile von CellRenderern bei Swing. Erfordert ggf. auch ein bißchen mehr Verwaltung, aber ... there's no free lunch 😀

Ich hatte aber irgendwann schonmal überlegt (und in anderen Threads angedeutet, und erwähnt dass ich dazu mal einen philosophier-Thread eröffnen wollte) dass ich davon ausgehe, dass man theoretisch NIE Typabfragen zwingend braucht. Und tatsächlich wäre ein Instanceof-Test an dieser Stelle (immerhoch häßlich, aber zumindest) flexibler und leichter erweiterbar. Wenn man nun eine neue Form "Star", "Oval" oder sonstwas einfügt, muss die auch eine Methode haben "isCircle". Niemand will code wie
Java:
class BasicShape
{
    // Override what is necessary
    public boolean isRectangle() { return false; }
    public boolean isCircle() { return false; }
    public boolean isStar() { return false; }
    public boolean isTriangle() { return false; }
    public boolean isRoundRectangle() { return false; }
    public boolean isSuchANiftyShapedThingWithNoName() { return false; }
]
(wobei ich davon ausgehe, dass EikeB's Vorschlag nur eine der einfachsten (d.h. Anfänger"freundlichsten") Lösungen für den konkreten Fall von zwei Formen sein sollte - aber ein bißchen über OO nachdenken kann einem Anfänger auch nicht schaden 😉 )
 
Hm. Naja. Ein bißchen Inspiration gibt's vielleicht auch in http://www.java-forum.org/entwuerfe/113007-kein-swing-tutorial-2.html#post806480 (statt des Paintable-Interfaces würde es hier evtl. schon ein "Shape" tun - aber solche "isCircle()/isRectangle()"-Abfragen sollte man vermeiden. Das ist das Gegenteil von OOP.

Vielen Dank Marco, habe das erst gestern Abend gesehen. Hatte sich wohl mit meinem Post überschnitten.

irgendwo festhalten ist korrekt,
fange so einfach an wie es für die Funktionalität reicht, setze irgendein Attribut der Klasse,
und wenn dann der Mausklick drankommst schaust du nach was gerade 'eingestellt ist

Ich habe mich nun dazu entschlossen ein Enum DrawingMode mit den Werten NOTSELECTED (zur Initialisierung), ADDOVAL, ADDRECTANGLE einzufügen. In meinem Model verwalte ich nun diesen Modus.
In der actionPerformed-Methode des ActionListener für das MenuItem Hinzufügen -> Kreis rufe ich dann die Methode model.changeDrawingMode() auf. Ich frage mich nun, was ich hier übergeben soll?
Das ActionEvent oder lieber ein Objekt vom Typ DrawingMode, in dem Fall DrawingMode.ADDOVAL?
Vom Gefühl her würde ich sagen Variante 2, kann es aber nicht begründen. Vielleicht bin ich mit dem ActionEvent aber flexibler oder hat das Nachteile?
 
wie ich in diesem Fall schon schrieb 'fange so einfach an wie es für die Funktionalität reicht',
also wollte damit ausdrücken: 'ist mir eigentlich egal wie',
gerade solche Detailfragen sind nur unter Sichtung aller Details zu beantworten und schnell wieder zu ändern,
wirf ne Münze 😉
 
Ok, wollte nur sicherstellen, dass die Übergabe des ActionEvent an das Model nicht als schlechter Stil interpretiert wird.
Da im Moment die einfache Variante mit dem Enum-Objekt reicht, werde ich diese nutzen.
Vielen Dank
 
Habe mir die Beiträg mal durchgelesen und, da ich wieder mal (seit langen irgendwas zur Übung) programmieren wollte, habe ich hierzu mal ein Programm erstellt:
Klasse View:
Java:
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.JLabel;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JComboBox;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JTextField;
import java.awt.SystemColor;
import java.util.ArrayList;
import de.muntjak.tinylookandfeel.TinyLookAndFeel;
import javax.swing.JButton;

/**
 * @author GUI-Programmer
 * @version 09.11.2011 15:15
 */
public class View extends JPanel {
	private Controller controller;
	
	protected JPanel pnlControlls;
	protected JPanel pnlDrawingarea;
	protected JLabel lblFigur;
	protected JComboBox cmbobxFigur;
	protected JLabel lblFarbe;
	protected JComboBox cmbobxFarbe;
	protected String figurenbezeichnung;
	protected boolean figurAusgfuellt;
	protected Color figurenfarbe;
	protected Dimension figurengroesse;
	protected JLabel lblGroesse;
	protected JTextField txtfldBreite;
	protected JTextField txtfldHoehe;
	protected JLabel lblMal;
	protected JLabel lblPx;
	protected JButton btnLoeschen;
	protected JButton btnSpeichern;
	protected ArrayList<Figur> figurenliste;
	protected JLabel lblFuellung;
	protected JComboBox cmbobxFuellung;

	public View() {
		controller = new Controller(this);
		
		figurenbezeichnung = "Rechteck";
		figurAusgfuellt = true;
		figurenfarbe = Color.RED;
		figurengroesse = new Dimension(50, 50);
		figurenliste = new ArrayList<Figur>();
		
		try {
			UIManager.setLookAndFeel(new TinyLookAndFeel());
			SwingUtilities.updateComponentTreeUI(this);
		}
		catch(Exception ex) { }
		
		setPreferredSize(new Dimension(1000, 600));
		setBackground(Color.WHITE);
		setLayout(new BorderLayout(0, 0));
		
		pnlControlls = new JPanel();
		pnlControlls.setBackground(SystemColor.activeCaption);
		pnlControlls.setPreferredSize(new Dimension(150, 600));
		add(pnlControlls, BorderLayout.EAST);
		
		lblFigur = new JLabel("Figur:");
		lblFigur.setFont(new Font("Tahoma", Font.BOLD, 14));
		lblFigur.setForeground(Color.RED);
		
		cmbobxFigur = new JComboBox();
		cmbobxFigur.setModel(new DefaultComboBoxModel(new String[] {"Rechteck", "Kreis"}));
		cmbobxFigur.addActionListener(controller);
		
		lblFarbe = new JLabel("Farbe:");
		lblFarbe.setForeground(Color.RED);
		lblFarbe.setFont(new Font("Tahoma", Font.BOLD, 14));
		
		cmbobxFarbe = new JComboBox();
		cmbobxFarbe.setModel(new DefaultComboBoxModel(new String[] {"rot", "grün", "gelb", "blau", "Andere..."}));
		cmbobxFarbe.addActionListener(controller);
		
		lblGroesse = new JLabel("Gr\u00F6\u00DFe:");
		lblGroesse.setForeground(Color.RED);
		lblGroesse.setFont(new Font("Tahoma", Font.BOLD, 14));
		
		txtfldBreite = new JTextField();
		txtfldBreite.setText("50");
		txtfldBreite.setColumns(10);
		txtfldBreite.addKeyListener(controller);
		
		txtfldHoehe = new JTextField();
		txtfldHoehe.setText("50");
		txtfldHoehe.setColumns(10);
		txtfldHoehe.addKeyListener(controller);
		
		lblMal = new JLabel("x");
		
		lblPx = new JLabel("px");
		
		btnLoeschen = new JButton("L\u00F6schen");
		btnLoeschen.setFont(new Font("Tahoma", Font.BOLD, 12));
		btnLoeschen.addActionListener(controller);
		
		btnSpeichern = new JButton("Speichern");
		btnSpeichern.setFont(new Font("Tahoma", Font.BOLD, 12));
		btnSpeichern.addActionListener(controller);
		
		lblFuellung = new JLabel("Füllung:");
		lblFuellung.setForeground(Color.RED);
		lblFuellung.setFont(new Font("Tahoma", Font.BOLD, 14));
		
		cmbobxFuellung = new JComboBox();
		cmbobxFuellung.setModel(new DefaultComboBoxModel(new String[] {"ausgefüllt", "leer"}));
		cmbobxFuellung.addActionListener(controller);
		GroupLayout gl_pnlControlls = new GroupLayout(pnlControlls);
		gl_pnlControlls.setHorizontalGroup(
			gl_pnlControlls.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_pnlControlls.createSequentialGroup()
					.addGap(12)
					.addComponent(lblFigur, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE))
				.addGroup(gl_pnlControlls.createSequentialGroup()
					.addGap(12)
					.addComponent(cmbobxFigur, GroupLayout.PREFERRED_SIZE, 121, GroupLayout.PREFERRED_SIZE))
				.addGroup(gl_pnlControlls.createSequentialGroup()
					.addGap(12)
					.addComponent(lblFarbe, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE))
				.addGroup(gl_pnlControlls.createSequentialGroup()
					.addGap(12)
					.addComponent(cmbobxFarbe, GroupLayout.PREFERRED_SIZE, 121, GroupLayout.PREFERRED_SIZE))
				.addGroup(gl_pnlControlls.createSequentialGroup()
					.addGap(12)
					.addComponent(lblGroesse, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE))
				.addGroup(gl_pnlControlls.createSequentialGroup()
					.addGap(12)
					.addComponent(txtfldBreite, GroupLayout.PREFERRED_SIZE, 43, GroupLayout.PREFERRED_SIZE)
					.addGap(5)
					.addComponent(lblMal)
					.addGap(6)
					.addComponent(txtfldHoehe, GroupLayout.PREFERRED_SIZE, 44, GroupLayout.PREFERRED_SIZE)
					.addGap(5)
					.addComponent(lblPx))
				.addGroup(gl_pnlControlls.createSequentialGroup()
					.addContainerGap(31, Short.MAX_VALUE)
					.addComponent(btnSpeichern)
					.addGap(31))
				.addGroup(gl_pnlControlls.createSequentialGroup()
					.addContainerGap(36, Short.MAX_VALUE)
					.addComponent(btnLoeschen)
					.addGap(36))
				.addGroup(gl_pnlControlls.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblFuellung, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
					.addContainerGap(83, Short.MAX_VALUE))
				.addGroup(gl_pnlControlls.createSequentialGroup()
					.addContainerGap()
					.addComponent(cmbobxFuellung, GroupLayout.PREFERRED_SIZE, 121, GroupLayout.PREFERRED_SIZE)
					.addContainerGap(17, Short.MAX_VALUE))
		);
		gl_pnlControlls.setVerticalGroup(
			gl_pnlControlls.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_pnlControlls.createSequentialGroup()
					.addGap(12)
					.addComponent(lblFigur)
					.addGap(6)
					.addComponent(cmbobxFigur, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
					.addGap(26)
					.addComponent(lblFarbe)
					.addGap(6)
					.addComponent(cmbobxFarbe, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
					.addGap(26)
					.addComponent(lblGroesse)
					.addGap(6)
					.addGroup(gl_pnlControlls.createParallelGroup(Alignment.LEADING)
						.addComponent(txtfldBreite, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
						.addGroup(gl_pnlControlls.createSequentialGroup()
							.addGap(2)
							.addComponent(lblMal))
						.addComponent(txtfldHoehe, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
						.addGroup(gl_pnlControlls.createSequentialGroup()
							.addGap(2)
							.addComponent(lblPx)))
					.addGap(27)
					.addComponent(lblFuellung, GroupLayout.PREFERRED_SIZE, 17, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(cmbobxFuellung, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED, 269, Short.MAX_VALUE)
					.addComponent(btnSpeichern)
					.addGap(13)
					.addComponent(btnLoeschen)
					.addGap(11))
		);
		pnlControlls.setLayout(gl_pnlControlls);
		
		pnlDrawingarea = new JPanel() {
			@Override
			protected void paintComponent(Graphics g) {
				Graphics2D g2d = (Graphics2D) g.create();
				g2d.setComposite(AlphaComposite.SrcOver);
				for(Figur figur : figurenliste) {
					g2d.setColor(figur.getColor());
					if(figur.getDiscription().equals("Rechteck")) {
						if(figur.getFill()) g2d.fillRect(figur.getX(), figur.getY(), figur.getWidth(), figur.getHeight());
						else g2d.drawRect(figur.getX(), figur.getY(), figur.getWidth(), figur.getHeight());
					}
					if(figur.getDiscription().equals("Kreis")) {
						if(figur.getFill()) g2d.fillOval(figur.getX(), figur.getY(), figur.getWidth(), figur.getHeight());
						else g2d.drawOval(figur.getX(), figur.getY(), figur.getWidth(), figur.getHeight());
					}
				}
				g2d.dispose();
			}
		};
		pnlDrawingarea.addMouseListener(controller);
		add(pnlDrawingarea, BorderLayout.CENTER);
	}
	
	private static void createFrame() {
		JFrame f = new JFrame("Figuren Zeichner");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setContentPane(new View());
		f.pack();
		f.setLocationRelativeTo(null);
		f.setVisible(true);
	}
	
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				createFrame();
			}
		});
	}
	
	protected void showColorChooser() {
		JPanel content = new JPanel();
		content.setPreferredSize(new Dimension(650, 500));
		content.setLayout(new BorderLayout(0, 0));
		
		LookAndFeel lafOld = UIManager.getLookAndFeel();
		try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); }
		catch(Exception ignore) { }
		
		final JColorChooser colorchooser = new JColorChooser();
		colorchooser.setBackground(SystemColor.activeCaption);
		content.add(colorchooser, BorderLayout.CENTER);
		
		try { UIManager.setLookAndFeel(lafOld); }
		catch(Exception ignore) { }
		
		JPanel pnlButton = new JPanel();
		pnlButton.setPreferredSize(new Dimension(650, 60));
		pnlButton.setBackground(SystemColor.activeCaption);
		pnlButton.setLayout(new GridBagLayout());
		
		final JDialog dialog = new JDialog();
		
		JButton btnOK = new JButton("OK");
		btnOK.setPreferredSize(new Dimension(90, 30));
		btnOK.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				figurenfarbe = colorchooser.getColor();
				dialog.dispose();
			}
		});
		pnlButton.add(btnOK);
		content.add(pnlButton, BorderLayout.SOUTH);
		
		dialog.setTitle("Farbe wählen");
		dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		dialog.setModal(true);
		dialog.setContentPane(content);
		dialog.pack();
		dialog.setLocationRelativeTo(this);
		dialog.setVisible(true);
	}
}
Klasse Controller:
Java:
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

/**
 * @author GUI-Programmer
 * @version 09.11.2011 15:15
 */
public class Controller implements MouseListener, ActionListener, KeyListener {
	private View view;
	
	public Controller(View view) {
		this.view = view;
	}
	
	@Override
	public void actionPerformed(ActionEvent evt) {
		Object src = evt.getSource();
		if(src.equals(view.cmbobxFarbe)) {
			int index = view.cmbobxFarbe.getSelectedIndex();
			switch(index) {
				case 0 : view.figurenfarbe = Color.RED; break;
				case 1 : view.figurenfarbe = Color.GREEN; break;
				case 2 : view.figurenfarbe = Color.YELLOW; break;
				case 3 : view.figurenfarbe = Color.BLUE; break;
				case 4 : view.showColorChooser(); break;
			}
		}
		if(src.equals(view.cmbobxFigur)) {
			view.figurenbezeichnung = view.cmbobxFigur.getSelectedItem().toString();
		}
		if(src.equals(view.cmbobxFuellung)) {
			String fuellung = view.cmbobxFuellung.getSelectedItem().toString();
			if(fuellung.equals("ausgefüllt")) view.figurAusgfuellt = true;
			else if(fuellung.equals("leer")) view.figurAusgfuellt = false;
		}
		if(src.equals(view.btnLoeschen)) {
			view.figurenliste.removeAll(view.figurenliste);
			view.validate();
			view.repaint();
		}
		if(src.equals(view.btnSpeichern)) {
			int width = view.pnlDrawingarea.getWidth();
			int height = view.pnlDrawingarea.getHeight();
			BufferedImage image = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
			Graphics2D g2 = image.createGraphics();
			g2.setComposite(AlphaComposite.SrcOver);
			for(Figur figur : view.figurenliste) {
				g2.setColor(figur.getColor());
				if(figur.getDiscription().equals("Rechteck")) {
					g2.fillRect(figur.getX(), figur.getY(), figur.getWidth(), figur.getHeight());
				}
				if(figur.getDiscription().equals("Kreis")) {
					g2.fillOval(figur.getX(), figur.getY(), figur.getWidth(), figur.getHeight());
				}
			}
			g2.dispose();
			File file = new File("Figur.png");
			if(!file.exists()) try {
				file.createNewFile();
			}
			catch(IOException ex) {
				ex.printStackTrace();
			}
			try {
				ImageIO.write((RenderedImage) image, "png", file);
			}
			catch(IOException ex) {
				ex.printStackTrace();
			}
		}
	}

	@Override
	public void mouseClicked(MouseEvent evt) { }

	@Override
	public void mouseEntered(MouseEvent evt) { }

	@Override
	public void mouseExited(MouseEvent evt) { }

	@Override
	public void mousePressed(MouseEvent evt) {
		if(evt.getSource().equals(view.pnlDrawingarea)) {
			Figur figur = new Figur();
			figur.setDiscription(view.figurenbezeichnung);
			figur.setColor(view.figurenfarbe);
			figur.setFill(view.figurAusgfuellt);
			figur.setLocation(evt.getX(), evt.getY());
			figur.setSize(view.figurengroesse);
			view.figurenliste.add(figur);
			view.validate();
			view.repaint();
		}
	}

	@Override
	public void mouseReleased(MouseEvent evt) { }

	@Override
	public void keyPressed(KeyEvent evt) { }

	@Override
	public void keyReleased(KeyEvent evt) {
		Object src = evt.getSource();
		if(src.equals(view.txtfldBreite)) {
			try {
				int width = Integer.parseInt(view.txtfldBreite.getText());
				view.figurengroesse.width = width;
			} catch(Exception ignore) { }
		}
		if(src.equals(view.txtfldHoehe)) {
			try {
				int height = Integer.parseInt(view.txtfldHoehe.getText());
				view.figurengroesse.height = height;
			} catch(Exception ignore) { }
		}
		
	}

	@Override
	public void keyTyped(KeyEvent evt) { }
	
}

Klasse Figur:
Java:
import java.awt.Color;
import java.awt.Dimension;

/**
 * @author GUI-Programmer
 * @version 09.11.2011 15:15
 */
public class Figur {
	private boolean fill;
	private String discription;
	private int x, y;
	private int width, height;
	private Color color;
	
	public void setDiscription(String discription) {
		this.discription = discription;
	}
	
	public String getDiscription() {
		return discription;
	}
	
	public void setLocation(int x, int y) {
		this.x = x; this.y = y;
	}
	
	public int getX() {
		return x;
	}
	
	public int getY() {
		return y;
	}
	
	public void setSize(Dimension size) {
		this.width = size.width;
		this.height = size.height;
	}
	
	public int getWidth() {
		return width;
	}
	
	public int  getHeight() {
		return height;
	}
	
	public void setColor(Color color) {
		this.color = color;
	}
	
	public Color getColor() {
		return color;
	}
	
	public void setFill(boolean fill) {
		this.fill = fill;
	}
	
	public boolean getFill() {
		return fill;
	}
}
Vielleicht ist es ja ne ganz gute Lösung. Einen ausführbaren jar-File gibts auch.


P.S. Bin gerne für Kritik in Form von Verbesserungsvorschlägen zu haben!
 
Dasselbe nochmals verbessert:
Mit Paintable Interface und eine abstrakte Klasse Figure und die Klassen Circle und Rect, die von Figure erben.
 
Zuletzt bearbeitet:
Hallo GUI-Programmer,

habe den Quelltext aus dem ersten Beispiel jetzt mal kurz überflogen und werde das mit meiner Implementation vergleichen. Bei Bedarf dann das ein oder andere übernehmen.
Die Erweiterung habe ich mir heruntergeladen und etwas damit herum gespielt. Sieht gut aus und trifft das, was ich machen möchte sehr gut.

Vielen Dank
 
Wieder ne evtl. Verbesserung:
1. In der paintComponent() des pnlDrawingarea als erstes ein super.paintComponent(g); aufrufen
2. In der Klasse Controller die beiden Befehle view.validate() und view.repaint() durch view.pnlDrawingarea.repaint() an den zwei vorhandenen Stellen ersetzen
 

Zurück
Oben