# Mit Java erstellte Zeichnungen speichern & Formen "freihändig" zeichnen?



## TimeStreamer (23. April 2006)

Moin.
Also gegeben ist folender Code

```
import javax.swing.*;
import java.awt.*;
import java.awt.Color.*;
import java.awt.Graphics.*;
import java.awt.event.*;
import java.awt.image.BufferedImage.*;
import java.applet.*;
import java.util.*;
import java.io.*;
import javax.imageio.ImageIO.*;
import com.sun.image.codec.jpeg.*;

//Start des Applets 
public class Paint extends Applet implements MouseListener, MouseMotionListener
{
//Deklaration der Applet-Elemente
boolean kreis;
private int mouseX=-11, mouseY=-22, mouse2X=-12, mouse2Y=-23, diameter=6, freediameter=4;
int n = 400;
String[] Farbe= {"", "Schwarz", "Rot", "Orange", "Braun", "Gelb", "Grün", "Blau", "Türkis", "Lila", "Pink"};
String[] Zeichen= {"", "Kreis", "Gerade", "Viereck", "gestrichelte Linie", "Punkt", "Freihand", "Sprühpistole"};
String[] Groeße = {"", "Sehr Klein", "Klein", "Mittel", "Groß", "Sehr Groß"};
Label BeschriftungA= new Label ("Zeichenmodus:");
Label BeschriftungB= new Label ("Zeichengröße:");
Label BeschriftungC= new Label ("Farbe");
Label Grenze= new Label ("Hinweis: Nur der Rahmeninhalt wird gespeichert!");
Button Speichern= new Button ("Bild Speichern");
Choice Farbauswahl= new Choice ();
Choice Groeßenauswahl= new Choice ();
Choice Zeichenauswahl= new Choice ();
Color brown= new Color (165, 42, 42);
Color tuerkis= new Color (64, 224, 208);
Color purple= new Color (160, 32, 240);
Random zufall = new Random();

//Initialisierung und Layout Festlegung
public void init()
{
setBackground(new Color(255,255,255)); //Hintergrundfarbe des Applets
setLayout ( null);//Layout wird deklariert

//Koordinaten & Größen der Dialogelemente:
//(X-Koord,Y-Koord,Breite,Höhe);
Grenze.setBounds(120,720,300,20);
BeschriftungA.setBounds(10,60,100,20);
Zeichenauswahl.setBounds(10,80,100,20);
BeschriftungB.setBounds(10,140,100,20);
Groeßenauswahl.setBounds(10,160,100,20);
BeschriftungC.setBounds(10,220,100,20);
Farbauswahl.setBounds(10,240,100,20);
Speichern.setBounds(250,20,120,30);

//Dialogelemente werden auf das Applet gesetzt:
add(Grenze);
add(BeschriftungA);
add(BeschriftungB);
add(BeschriftungC);
add(Zeichenauswahl);
add(Groeßenauswahl);
add(Farbauswahl);
add(Speichern);
//MouseListener und MouseMotionListener werden gesetzt
addMouseListener(this);
addMouseMotionListener(this);
//ItemListener für die Choice-Boxen und den "Speichern" Button
Zeichenauswahl.addItemListener(new ZeichenauswahlListener());
Groeßenauswahl.addItemListener(new GroeßenauswahlListener());
Farbauswahl.addItemListener(new FarbauswahlListener());
Speichern.addActionListener(new SpeichernListener());


//+++++++++++++++++ITEMZUWEISUNG AN DIE CHOICE BOXEN++++++++++++++++++++++++++++
 //Choice-Box "Zeichenauswahl" bekommt als Inhalt die Werte des Strings
 //"Zeichen" zugewiesen:
 for (int i=0;i<=7;i++)
 {
 Zeichenauswahl.addItem(Zeichen [i]);
 }
 
 //Choice-Box "Groeßenauswahl" bekommt als Inhalt die Werte des Strings
 //"Groeße" zugewiesen:
 for (int i=0;i<=5;i++)
 {
 Groeßenauswahl.addItem(Groeße [i]);
 }
 
 //Choice-Box "Farbauswahl" bekommt als Inhalt die Werte des Strings
 //"Farbe" zugewiesen:
 for (int i=0;i<=10;i++)
 {
 Farbauswahl.addItem(Farbe [i]);
 }
 
 }

//+++++++++++++++++++CHOICE-LISTENER & ACTION-LISTENER+++++++++++++++++++++++++

/*Listener für Zeichenauswahl: Wenn in  der Zeichenauswahl eine andere Wahl getroffen wird,
wird ein anderer Zeichenmodus und ein entsprechender MouseModus aktiviert.*/
class ZeichenauswahlListener implements ItemListener
{
public void itemStateChanged (ItemEvent e)
    {   
    //Testfunktion zum Prüfen ob bei Itemauswahl eine Ausgabe erfolgt
    System.out.println("" + String.valueOf(Zeichen[Zeichenauswahl.getSelectedIndex()]));
}
}

/*Listener für Groeßenauswahl: Wenn in der Groeßenauswahl eine andere Auswahl 
getroffen wird, ändert sich die Liniendicke.*/
class GroeßenauswahlListener implements ItemListener
{
public void itemStateChanged (ItemEvent e)
    {   
    //Testfunktion zum Prüfen ob bei Itemauswahl eine Ausgabe erfolgt
    System.out.println("" + String.valueOf(Groeße[Groeßenauswahl.getSelectedIndex()]));
    //Funktionen für die Größenänderung durch Ändern des Wertes für diameter:
    if(Groeßenauswahl.getSelectedItem() == "Sehr Klein")
    {diameter= 2;
    freediameter= 2;}
    if(Groeßenauswahl.getSelectedItem() == "Klein")
    {diameter= 4;
    freediameter= 3;}
    if(Groeßenauswahl.getSelectedItem() == "Mittel")
    {diameter= 6;
    freediameter= 4;}
    if(Groeßenauswahl.getSelectedItem() == "Groß")
    {diameter= 8;
    freediameter= 6;}
    if(Groeßenauswahl.getSelectedItem() == "Sehr Groß")
    {diameter= 10;
    freediameter= 8;}
}
}

/*Listener für Farbauswahl: Wenn in der Farbauswahl eine andere Auswahl 
getroffen wird, wird ein neuer Farbwert übergeben*/
class FarbauswahlListener implements ItemListener
{
public void itemStateChanged (ItemEvent e)
    {   
    //Testfunktion zum Prüfen ob bei Itemauswahl eine Ausgabe erfolgt
    System.out.println("" + String.valueOf(Farbe[Farbauswahl.getSelectedIndex()]));
}}
/*Bei Klick auf den Button, wird das Bild gespeichert*/
class SpeichernListener implements ActionListener
{
public void actionPerformed (ActionEvent e)
    {   } 
}

//++++++++++++++++++++++++++MAUSFUNKTIONEN+++++++++++++++++++++++++++++++++++++

//Hier wird überprüft, was in der Choice Box "Zeichenauswahl" gewählt wurde und
//der entsprechende MouseListener/MouseMotionListener ausgewählt, der die 
//entsprechende Zeichenfunktion durchführen kann.
public void mousePressed(MouseEvent e) 
{
if(Zeichenauswahl.getSelectedItem() == "Kreis")
{mouseX = e.getX();
mouseY = e.getY();
repaint();
kreis=true;}}
public void mouseReleased(MouseEvent e) 
{
while(kreis==true)
{mouse2X = e.getX();
mouse2Y = e.getY();
kreis=false;}
}
public void mouseDragged(MouseEvent e) 
{
if(Zeichenauswahl.getSelectedItem() == "Gerade")
{mouseX = e.getX();
mouseY = e.getY();
repaint();}
if(Zeichenauswahl.getSelectedItem() == "Gestrichelte Linie")
{mouseX = e.getX();
mouseY = e.getY();
repaint();}
if(Zeichenauswahl.getSelectedItem() == "Viereck")
{mouseX = e.getX();
mouseY = e.getY();
repaint();}
if(Zeichenauswahl.getSelectedItem() == "Freihand")
{mouseX = e.getX();
mouseY = e.getY();
repaint();}
if(Zeichenauswahl.getSelectedItem() == "Sprühpistole")
{mouseX = e.getX();
mouseY = e.getY();
repaint();}
}
public void mouseEntered(MouseEvent e) 
{}
public void mouseExited(MouseEvent e) 
{}
public void mouseMoved(MouseEvent e) 
{}
public void mouseClicked(MouseEvent e) 
{
if(Zeichenauswahl.getSelectedItem() == "Punkt")
{mouseX = e.getX();
mouseY = e.getY();
repaint();}
}

//++++++++++++++++++++++++++++ZEICHEN-FUNKTIONEN+++++++++++++++++++++++++++++++

public void update (Graphics g)
{
paint(g);
}
//Hier sind sämtliche Zeichenoperationen deklariert
public void paint(Graphics g)
{
Graphics2D g2d=(Graphics2D)g;
g2d.drawRect(120,60,650,650);// Rahmen wird gezeichnet

//Funktion für die Farbänderung
if(Farbauswahl.getSelectedItem() == "Schwarz")
g2d.setColor(Color.BLACK);
    if(Farbauswahl.getSelectedItem() == "Rot")
   g2d.setColor(Color.RED);
   if(Farbauswahl.getSelectedItem() == "Orange")
   g2d.setColor(Color.ORANGE);
    if(Farbauswahl.getSelectedItem() == "Braun")
    g2d.setColor(brown);
    if(Farbauswahl.getSelectedItem() == "Gelb")
    g2d.setColor(Color.YELLOW);
    if(Farbauswahl.getSelectedItem() == "Grün")
    g2d.setColor(Color.GREEN);
    if(Farbauswahl.getSelectedItem() == "Blau")
    g2d.setColor(Color.BLUE);
    if(Farbauswahl.getSelectedItem() == "Türkis")
    g2d.setColor(tuerkis);
    if(Farbauswahl.getSelectedItem() == "Lila")
    g2d.setColor(purple);
    if(Farbauswahl.getSelectedItem() == "Pink")
g2d.setColor(Color.MAGENTA);

//Hier sind sämtliche Zeichenoperationen deklariert und werden über die
//Choice-Box "Zeichenauswahl" angesteuert.
if(Zeichenauswahl.getSelectedItem() == "Punkt")
 g2d.fillOval (mouseX, mouseY, diameter, diameter);
 if(Zeichenauswahl.getSelectedItem() == "Freihand")
 g2d.fillOval (mouseX, mouseY, diameter, diameter);
 if(Zeichenauswahl.getSelectedItem() == "Sprühpistole")
 g2d.fillOval ((mouseX + zufall.nextInt(25)), mouseY + zufall.nextInt(25), freediameter, freediameter);
 if(Zeichenauswahl.getSelectedItem() == "Kreis")
 g2d.drawOval(mouseX, mouseY, mouse2X, mouse2Y);
 /*if(Zeichenauswahl.getSelectedItem() == "Linie")
 if(Zeichenauswahl.getSelectedItem() == "gestrichelte Linie")*/
 if(Zeichenauswahl.getSelectedItem() == "Viereck")
 g2d.drawRect(mouseX, mouseY, mouse2X, mouse2Y);//(x1,y1,x2,y2)
 }
}
```

Das Programm soll, wenn es mal fertig ist, auf einem Applet eine Zeichnung bestehend aus diversen Formen wie z.B. Kreis oder Viereck erstellen können und diese dann in einer Datei abspeichern.
Die Formen sollen dabei vom Benutzer selbst gezeichnet werden können, sprich sie sollen also nicht fest vorgegeben im AppletCode stehen sondern gewissermaßen "frei-hand" gezeichnet werden können.
Jetzt hab ich folgende 3 Probleme:
1. Um Dinge wie Linien etc zu zeichnen, benötigt man ja 2 Koordinaten (eine Startkoordinate undeine Endkoordinate), wie schaffe ich es, dass beide Koordinaten mit Hilfe der Maus festgelegt werden können?
Ich hab das erstmal nur mit einem Kreis versucht und da war mein bisheriger Ansatz dass er bei gedrückter Maustaste die Startkoordinate übergibt (was auch soweit klappt) und dann in dem Moment in dem die Maustaste losgelassen wird eine Zweite übergeben wird:

```
public void mousePressed(MouseEvent e) 
{
if(Zeichenauswahl.getSelectedItem() == "Kreis")
{mouseX = e.getX();
mouseY = e.getY();
repaint();
kreis=true;}}
public void mouseReleased(MouseEvent e) 
{
while(kreis==true)
{mouse2X = e.getX();
mouse2Y = e.getY();
kreis=false;}
}
```

2. Habe ich das Problem dass wenn die Anwendung vielleicht für einen kurzen Moment in den Hintergrund gerät, die bereits erstellte Zeichnung gelöscht wird.
Wie kann ich das verhindern?

und last but not least:
Wie funktioniert das eigentlich mit dem Bilder abspeichern? 

Ich wäre für Code Beispiele dankbar, da ich sooo bewandert in der Sprache nicht bin (erkennt man auch sicherlich am Code *hust*) 

Danke schonmal vorab für jede Hilfe!
mfg


----------



## flashray (23. April 2006)

Hallo TimeStreamer,

schau mal hier:

edit: kann sich zwar nicht mit Picasso messen, aber immerhin für den Anfang ist es schon OK  .


```
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.*;

public class ArtofDrawingExample extends JFrame {

	private JQDrawPanel drawPanel = new JQDrawPanel();

	private JPanel buttonPanel = new JPanel();

	private JButton save = new JButton("save image");

	private JButton clear = new JButton("clear board");

	private JToolBar tb = new JToolBar();

	private JToggleButton b1 = new JToggleButton("yellow filled oval");

	private JToggleButton b2 = new JToggleButton("blue blank square");

	private JToggleButton b4 = new JToggleButton("red freehand");

	private ButtonGroup bg = new ButtonGroup();

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

	public ArtofDrawingExample() {
		super("Art of Drawing Example!");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocationByPlatform(true);
		this.setAlwaysOnTop(true);

		save.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				BufferedImage bufferedImage = new BufferedImage(drawPanel
						.getWidth(), drawPanel.getHeight(),
						BufferedImage.TYPE_INT_RGB);
				drawPanel.paint(bufferedImage.getGraphics());
				try {
					ImageIO
							.write(bufferedImage, "JPEG",
									new File("drawing.jpg"));
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		});

		clear.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				drawPanel.handpointslist = null;
				drawPanel.handpoints = null;
				drawPanel.handpointslist = new ArrayList<List<Point>>();
				drawPanel.handpoints = new ArrayList<Point>();

				drawPanel.rects = null;
				drawPanel.rect = null;
				drawPanel.rects = new ArrayList<Integer[]>();
				drawPanel.rect = new Integer[4];

				drawPanel.ovals = null;
				drawPanel.oval = null;
				drawPanel.ovals = new ArrayList<Integer[]>();
				drawPanel.oval = new Integer[4];
				
				drawPanel.repaint();
			}
		});

		buttonPanel.add(save);
		buttonPanel.add(clear);

		bg.add(b1);
		bg.add(b2);
		bg.add(b4);
		b4.setSelected(true);

		tb.add(b2);
		tb.add(b1);
		tb.add(Box.createGlue());
		tb.add(b4);

		this.add(drawPanel, BorderLayout.CENTER);
		this.add(buttonPanel, BorderLayout.SOUTH);
		this.add(tb, BorderLayout.NORTH);
		
		this.pack();
		this.setVisible(true);
	}

	class JQDrawPanel extends JPanel {
		private List<Point> points = new ArrayList<Point>();

		private Integer[] rect = new Integer[4];

		private List<Integer[]> rects = new ArrayList<Integer[]>();

		private Integer[] oval = new Integer[4];

		private List<Integer[]> ovals = new ArrayList<Integer[]>();

		private List<Point> handpoints = new ArrayList<Point>();

		private List<List<Point>> handpointslist = new ArrayList<List<Point>>();

		public JQDrawPanel() {
			this.setPreferredSize(new Dimension(400, 400));
			
			this.addMouseListener(new MouseListener() {
				public void mouseClicked(MouseEvent e) {
					JQDrawPanel.this.repaint();
				}

				public void mousePressed(MouseEvent e) {
					if (b1.isSelected()) {
						oval[0] = e.getX();
						oval[1] = e.getY();
					} else if (b2.isSelected()) {
						rect[0] = e.getX();
						rect[1] = e.getY();
					}
					JQDrawPanel.this.repaint();
				}

				public void mouseReleased(MouseEvent e) {
					if (b1.isSelected()) {
						oval[2] = e.getX();
						oval[3] = e.getY();
						ovals.add(oval);
						oval = new Integer[4];
					} else if (b2.isSelected()) {
						rect[2] = e.getX();
						rect[3] = e.getY();
						rects.add(rect);
						rect = new Integer[4];
					} else {
						handpointslist.add(handpoints);
						handpoints = new ArrayList<Point>();
					}
					JQDrawPanel.this.repaint();
				}

				public void mouseEntered(MouseEvent e) {
					JQDrawPanel.this.repaint();
				}

				public void mouseExited(MouseEvent e) {
					JQDrawPanel.this.repaint();
				}

			});
			this.addMouseMotionListener(new MouseMotionListener() {
				public void mouseDragged(MouseEvent e) {
					if (b4.isSelected())
						handpoints.add(e.getPoint());
					JQDrawPanel.this.repaint();
				}

				public void mouseMoved(MouseEvent e) {
					JQDrawPanel.this.repaint();
				}
			});
		}

		protected void paintComponent(Graphics g) {
			super.paintComponent(g);

			// Draw filled ovals
			g.setColor(Color.YELLOW);
			for (Integer[] o : ovals)
				g.fillOval(o[0], o[1], o[2] - o[0], o[3] - o[1]);
			// Draw empty square
			g.setColor(Color.BLUE);
			for (Integer[] r : rects)
				g.drawRect(r[0], r[1], r[2] - r[0], r[3] - r[1]);
			// Draw freehand
			g.setColor(Color.RED);
			if (handpointslist != null)
				for (List<Point> hps : handpointslist) {
					Point lasthp = null;
					for (Point h : hps) {
						if (lasthp != null) {
							g.drawLine(lasthp.x, lasthp.y, h.x, h.y);
						}
						lasthp = h;
					}
				}
		}
	}
}
```


Vg Erdal


----------



## TimeStreamer (23. April 2006)

Super, vielen Dank!
Ich werd gleich mal schauen wie ich das was mir fehlt bei mir einbaue.


----------

