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.
 
S

SlaterB

Gast
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
 
G

Gast2

Gast
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());
    }
  }
}
 
S

SlaterB

Gast
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 ;)
 

propra

Aktives Mitglied
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.
 
S

SlaterB

Gast
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:

Marco13

Top Contributor
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 :D

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 ;) )
 

propra

Aktives Mitglied
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?
 
S

SlaterB

Gast
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 ;)
 

propra

Aktives Mitglied
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
 

GUI-Programmer

Top Contributor
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!
 

GUI-Programmer

Top Contributor
Dasselbe nochmals verbessert:
Mit Paintable Interface und eine abstrakte Klasse Figure und die Klassen Circle und Rect, die von Figure erben.
 
Zuletzt bearbeitet:

propra

Aktives Mitglied
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
 

GUI-Programmer

Top Contributor
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
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Starchild Beliebig viele Knöpfe AWT, Swing, JavaFX & SWT 5
H Quadrate dnamisch erzeugen und beliebig füllen AWT, Swing, JavaFX & SWT 7
D Swing JTable in JScrollpane beliebig verbreitern AWT, Swing, JavaFX & SWT 5
L JFreeChart - Legende beliebig positionieren AWT, Swing, JavaFX & SWT 16
M Grafische Objekte beliebig auf einer Oberfläche verschieben AWT, Swing, JavaFX & SWT 3
B viele JPanels auf JLayeredPane -> to SVG? AWT, Swing, JavaFX & SWT 15
H Viele ActionListener (MouseListener) - Performance AWT, Swing, JavaFX & SWT 24
L Ein Actionlistener für ein Textfeld, anstatt viele Actionlistener für ein Textfeld AWT, Swing, JavaFX & SWT 7
A JavaFX Sehr viele Exceptions bei Taschenrechner mit JavaFx AWT, Swing, JavaFX & SWT 2
M If für viele TextFields AWT, Swing, JavaFX & SWT 7
kaoZ Swing JMenuBar, Preferences, Properties... und viele andere lustige Dinge (Best Practice) AWT, Swing, JavaFX & SWT 15
K Viele Textfield mit Hilfe eines MousListener leeren - möglich? AWT, Swing, JavaFX & SWT 8
M Swing Erste Schritte mit der GUI, viele Probleme AWT, Swing, JavaFX & SWT 36
L unbestimmt viele JComboBox und ItemListener dazu erstellen AWT, Swing, JavaFX & SWT 2
P 2D-Grafik Viele Bilder zu einem Video AWT, Swing, JavaFX & SWT 3
Dit_ Wenn viele NebenFenster zum Locationsetzen das HauptFenster brauchen AWT, Swing, JavaFX & SWT 2
P SWT Composite und viele Labels AWT, Swing, JavaFX & SWT 10
D Zu viele repaints() AWT, Swing, JavaFX & SWT 17
R JTable für sehr viele Daten sehr langsam AWT, Swing, JavaFX & SWT 20
G Viele Fehler beim zeichen AWT, Swing, JavaFX & SWT 5
Z zu viele prozesse AWT, Swing, JavaFX & SWT 2
G zu viele/große BufferedImage führt zu Java heap space AWT, Swing, JavaFX & SWT 5
D Wie viele Pixel welches Icon? AWT, Swing, JavaFX & SWT 4
TheJavaKid Lösung für zu Viele JMenuItems. AWT, Swing, JavaFX & SWT 4
T viele Canvas auf einem Panel und das GUI schmiert ab AWT, Swing, JavaFX & SWT 6
Juelin Objekte refresh AWT, Swing, JavaFX & SWT 3
N Graphics Objekte scalen mit Veränderung des Bildschirms AWT, Swing, JavaFX & SWT 19
berserkerdq2 Skalieren sich javafx objekte automatisch auf die Bildschirmgröße AWT, Swing, JavaFX & SWT 6
Redeason Objekte in meiner GUI verschieben AWT, Swing, JavaFX & SWT 1
_user_q Objekte vom MainController in anderen Controller verwenden und andersherum (NullPointerException) AWT, Swing, JavaFX & SWT 14
_user_q JavaFX Wie kann ich alle Objekte außer eins deaktivieren (das Gleiche mit BoxBlur)? AWT, Swing, JavaFX & SWT 11
ExceptionOfExpectation MouseListener-Objekte zu den Graphics-Objekten einfügen AWT, Swing, JavaFX & SWT 3
donnico2 Objekte in der GUI ausgeben mit Hilfe einer DAO AWT, Swing, JavaFX & SWT 1
B JavaFX Von welcher Klasse und zu welchem Zeitpunkt werden Event-Objekte erstellt? AWT, Swing, JavaFX & SWT 3
J Objekte von 2 GUIs zusammenfassen AWT, Swing, JavaFX & SWT 2
T Swing Objekte in Liste AWT, Swing, JavaFX & SWT 2
stroggi Swing Mehrere transparentes Objekte (Grafiken) über einem Bild (JLabel) darstellen AWT, Swing, JavaFX & SWT 4
C JList: Bestimmte Objekte ausschließen AWT, Swing, JavaFX & SWT 1
MaxG. Swing Dynamisch grafische Objekte erzeugen AWT, Swing, JavaFX & SWT 12
Y Objekte grafisch darstellen ohne GMF - Composite auf Canvas? AWT, Swing, JavaFX & SWT 2
D Swing Swing Objekte sehen im Entwurf anders aus als beim Ausführen AWT, Swing, JavaFX & SWT 3
L Dynamischer Aufbau einer Tabelle über Objekte AWT, Swing, JavaFX & SWT 2
H Swing + Paint: Mehrere Objekte zeichnen lassen AWT, Swing, JavaFX & SWT 3
JG12111989 mehrere Polyline-Objekte zeichnen AWT, Swing, JavaFX & SWT 3
D Objekte einer Oberfläche in eine Datei/Ordner speichern AWT, Swing, JavaFX & SWT 9
T Rectangle Transparent und darunter liegende Objekte Bedienbar AWT, Swing, JavaFX & SWT 0
J Swing/AWT | Dynamisch erzeugte Objekte ansprechen AWT, Swing, JavaFX & SWT 1
Z Möglichkeit mit Listerners die Farbe meiner Objekte zu ändern AWT, Swing, JavaFX & SWT 15
GenerationLost Bilder an bestimmten Platz einfügen/Objekte visualisieren AWT, Swing, JavaFX & SWT 1
I Objekte aus contentPane löschen funktioniert nicht AWT, Swing, JavaFX & SWT 3
C Swing Java Objekte AWT, Swing, JavaFX & SWT 4
J JavaFX Eigene ListCell Problem(Objekte werden doppelt angezeigt) AWT, Swing, JavaFX & SWT 1
N Swing Alle Objekte anzeigen auch bei JPanel-Überlappung AWT, Swing, JavaFX & SWT 6
A Swing Focus der Radio Buttons + text bleibt gleich und gleichzeitige ausgabe zweier Objekte in 1. Fenster AWT, Swing, JavaFX & SWT 3
A Drag and Drop eigener Objekte AWT, Swing, JavaFX & SWT 7
M SWT Durchlagen der SWT Objekte mit Tabulator AWT, Swing, JavaFX & SWT 5
Ollek JList - neuer Eintrag in ArrayList dadurch keine Anzeige der Objekte AWT, Swing, JavaFX & SWT 18
S Swing Kopie eines JPanels inkl. aller objekte darin erstellen AWT, Swing, JavaFX & SWT 5
D Swing Objekte bewegen mit MouseMotionListener AWT, Swing, JavaFX & SWT 4
P Objekte anzeigen und verschieben - wie? AWT, Swing, JavaFX & SWT 6
F Swing ArrayList in JList anzeigen und Objekte auswählen AWT, Swing, JavaFX & SWT 2
G Objekte in und aus einer JTable laden AWT, Swing, JavaFX & SWT 5
propra Mehrere Objekte gleichzeitig verschieben AWT, Swing, JavaFX & SWT 7
propra Objekte auf Zeichenfläche verschieben AWT, Swing, JavaFX & SWT 2
T JList und Objekte AWT, Swing, JavaFX & SWT 7
M Objekte in JPanel bewegen AWT, Swing, JavaFX & SWT 4
E Objekte zu Path2D zusammensetzen AWT, Swing, JavaFX & SWT 2
M verschieben der Objekte in JPanel nur stückchenweise möglich AWT, Swing, JavaFX & SWT 14
4 AWT bestimmte Objekte zeichnen und löschen AWT, Swing, JavaFX & SWT 8
R komplette Objekte in JTable einfügen AWT, Swing, JavaFX & SWT 18
C File-Objekte an JList übergeben und abrufen AWT, Swing, JavaFX & SWT 6
J Objekte aus Defaulttablemodel AWT, Swing, JavaFX & SWT 5
K MouseListener für Objekte auf einem Frame AWT, Swing, JavaFX & SWT 4
S Swing mit ActionListener auf Objekte einer anderen Klasse zugreifen AWT, Swing, JavaFX & SWT 3
A Swing Dynamisch Objekte erzeugen AWT, Swing, JavaFX & SWT 3
M JGraph Kante ohne Objekte AWT, Swing, JavaFX & SWT 2
P Von einem Panel auf die Objekte des anderen Panels zugreifen AWT, Swing, JavaFX & SWT 3
F Swing Objekte mit Maus verschieben AWT, Swing, JavaFX & SWT 8
T Mehrere sich bewegende Objekte in einem Frame AWT, Swing, JavaFX & SWT 14
L Dynamisch Objekte in Canvas zeichnen AWT, Swing, JavaFX & SWT 5
J SWT 4 Objekte auf einem Composite anordnen AWT, Swing, JavaFX & SWT 5
L SWT Objekte in GC? AWT, Swing, JavaFX & SWT 8
M grafische objekte erstellen und bewegen AWT, Swing, JavaFX & SWT 4
E Swing Objekte werden nicht angezeigt AWT, Swing, JavaFX & SWT 6
J Ansprechen untergeordneter Objekte AWT, Swing, JavaFX & SWT 6
C JTree Einzelne Objekte färben AWT, Swing, JavaFX & SWT 4
Airwolf89 Swing Dynamisch auf Objekte in einer GUI zugreifen AWT, Swing, JavaFX & SWT 10
S Java3D: Alle Objekte in BranchGroup löschen während Laufzeit AWT, Swing, JavaFX & SWT 3
M Objekte weitergeben AWT, Swing, JavaFX & SWT 3
1 Bubble Breaker - Objekte fallen nicht runter AWT, Swing, JavaFX & SWT 3
W Objekte auf JPanel bewegen??? AWT, Swing, JavaFX & SWT 2
F "Objekte" mit "Verbindungen" grafisch darstellen AWT, Swing, JavaFX & SWT 4
G Objekte in JComboBox? AWT, Swing, JavaFX & SWT 7
P Speichern und Auswahl gezeichneter Objekte AWT, Swing, JavaFX & SWT 7
G Graphics Objekte in AWT Container einfügen AWT, Swing, JavaFX & SWT 2
D DnD ganzer Objekte(Objekt erstellen) AWT, Swing, JavaFX & SWT 2
W 2 Objekte in eine Tabellenzelle? AWT, Swing, JavaFX & SWT 3
L Objekte in Liste oder ähnliches anzeigen AWT, Swing, JavaFX & SWT 3
S JFrame-Klasse soll ein/mehrere Objekte einer JPanel-Klasse-& AWT, Swing, JavaFX & SWT 3
O Eigene GUI Objekte entwerfen? AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben