Paint Anwendung: Freihandlinien zeichnen

Sessiolog

Mitglied
Grüße!

Ich habe ein kleines Problem mit meiner Paint-Anwendung. Diese soll das Feature beinhalten, Freihandlinien durch das Drücken/Ziehen der Maus zu zeichnen. Vergleichbar mit dem Bleistift-Tool in dem Microsoft-Paint-Programm. Das Programmieren des besagten Features stellt sich für mich jedoch als schwierig heraus. Meine Idee war es, in der mouseDragged-Methode die X und Y Koordinaten in zwei Arrays zu speichern. Die paintComponent-Methode kann daraus dann eine polyLine zeichnen. Soweit funktioniert es wie es funktionieren soll. Wenn ich allerdings nach dem Loslassen der Maus eine zweite Linie zeichnen möchte, verbindet das Programm unwillentlich den letzten Punkt der vorangeganen polyLine mit dem ersten Punkt der neuen polyLine. Gibt es unter euch Profi-Hackern vielleicht jemanden, der mir da ein bisschen auf Sprünge helfen könnte?

Java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics;
import java.awt.GridLayout;

class Malen2 extends JFrame implements ActionListener {
	int 		x,y,x2,y2;
	boolean 	drawL = false;
	JButton 	line;
	JPanel		pan;
	
	int [] pixelX = new int[10000];
	int [] pixelY = new int[10000];
	int i = 0;							//"int i" wird erst in der mouseDragged Methode verwendet
										// um Indexe für die beiden Arrays zu halten.
	public static void main (String [] args) {
		Malen frame = new Malen("Malen2");
		frame.setVisible(true);
		frame.setSize(400,400);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	} 		
	
	public Malen2 (String str) {
		super(str);
		line = new JButton("Freihand");
		line.setActionCommand("l");
		line.addActionListener(this);
		
		ZeichenPanel2 drawPanel = new ZeichenPanel2();
		//drawPanel.setBackground(Color.BLACK);
		
		pan = new JPanel();
		pan.setLayout(new GridLayout(0,1,0,0));
		pan.add(line);
		
		add(pan, BorderLayout.NORTH);
		add(drawPanel, BorderLayout.CENTER);
		
		addMouseListener(new InMalen2());
		addMouseMotionListener(new InMalen2());
		
		//Insets inset = circle.getInsets(); 		 
		//System.out.println(inset);
	}
	
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equals("l")) {
			drawL = true;
		}
	}
	
	class InMalen2 extends MouseAdapter implements MouseMotionListener {
		
		public void mousePressed(MouseEvent m) {
			x = m.getX();
			y = m.getY();
		}
		
		public void mouseDragged(MouseEvent m) {
			x2 = m.getX();
			y2 = m.getY();
			
			if (drawL) {				// Sollte der boolsche Wert "drawL" == true sein,
				pixelX[i] = x2 - 8;		// wird jede Veränderung der Mausposition bei
				pixelY[i] = y2 - 56;	// gedrückter Maustaste in diese zwei Arrays gespeichert.
				i+= 1;					// von x2 und y2 müssen noch festgelegt Werte subtrahiert 
			}							// werden, damit die PolyLine nicht versetzt gezeichnet wird
		}
	}

	class ZeichenPanel2 extends JPanel {
		protected void paintComponent(Graphics g) {
			super.paintComponent(g);
			g.setColor(Color.RED);
		
			if (drawL) {
				g.drawPolyline(pixelX, pixelY, i);
				repaint();
			}
		}
	}
}

Ich bedanke mich im Voraus für eure Hilfe! 🙂
 
Beim Neuansetzen verbindest du ja wieder mit deinem letzten Koordinaten-Paar, da liegt das Problem.
Durch das Absetzen sollte allerdings eine "Linie", also eine Vielzahl von Koordinaten-Paaren, abgeschlossen sein. Diese Information kannst du aktuell noch nicht abspeichern.

Du könntest hier ja eine weitere Klasse einführen, z.B. "Line" - Jede Line enthält dann eine Vielzahl von x- und y-Koordinaten-Paaren. In deiner Clicked-Methode erzeugst du eine neue Linie und initialisiert diese mit den entsprechenden x- und y-Koordinaten. Beim "draggen" werden neue Koordinaten-Paare hinzugefügt. Beim "Release" wird dieses Line-Objekt dann einer Liste von Lines hinzugefügt.

In deiner Draw-Methode iterierst du dann über die Lines der Liste und zeichnest sie alle (hier ist es wohl am einfachsten, wenn "Line" eine eigene Draw-Methode umsetzt, dann brauchst du nicht so viele Getter usw.)

MfG

DarXun
 
Ich denke mal, es liegt daran, dass du das Array mit den Koordinaten nie leerst.
Vermutlich musst du mouseReleased entsprechend implementieren, dass dann das Array geleert und alles auf Anfang gesetzt wird, damit es eine neue Linie ist.
 
Ja und? Ist ja schon gezeichnet 😛
Ne, du hast natürlich Recht. Ein Linien-Objekt mit Punkten wäre besser. Und dann eine Methode, mit der man ein Linienobjekt direkt zeichnen kann. Das wäre die optimale Lösung.
 

Neue Themen


Zurück
Oben