Probleme beim Zeichnen einer Geraden

Status
Nicht offen für weitere Antworten.

kulturfenster

Bekanntes Mitglied
Hallo,
Ich habe die Aufgabe, eine Gerade zu zeichnen, die durch 2 Clicks definiert wird. Dazu hab ich eine Punkt-Klasse erstellt, die mir die beiden Punkt liefern soll, und eine Gerade-Klasse, welche mir die Punkte verbinden und die Gerade zeichnen soll.

Hier mein Versuch:

Code:
package geradeZeichner;

import java.awt.geom.Line2D;
import java.awt.Graphics2D;
import java.awt.Graphics;
import javax.swing.JComponent;

public class Zeichner extends JComponent{

	private Line2D.Double l;
	private int x1;
	private int x2;
	private int y1;
	private int y2;
	
	public void paintComponent(Graphics g)
	{
		Graphics2D g2 = (Graphics2D) g;
		l = new Line2D.Double(x1,y1,x2,y2);
		g2.draw(l);
	}
	
	public void draw1(int x1, int y1)
	{
		this.x1 = x1;
		this.y1 = y2;
		repaint();
	}
	
	public void draw2(int x2, int y2)
	{
		this.x2 = x2;
		this.y2 = y2;
		repaint();
	}
	
}

Code:
package geradeZeichner;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;

public class Punkter {

	public static void main(String[] args)
	{
		JFrame frame = new JFrame("Zeichner");
		JPanel panel = new JPanel();
		final Zeichner z = new Zeichner();
		
		class Punkt1 implements MouseListener
		{
			public void mouseClicked(MouseEvent event)
			{
				int x1 = event.getX();
				int y1 = event.getY();
				z.draw1(x1, y1);
			}
			
			public void mousePressed(MouseEvent event) {}
			public void mouseReleased(MouseEvent event) {}
			public void mouseEntered(MouseEvent event) {}
			public void mouseExited(MouseEvent event) {}
		}
		
		class Punkt2 implements MouseListener
		{
			public void mouseClicked(MouseEvent event)
			{
				int x2 = event.getX();
				int y2 = event.getY();
				z.draw1(x2, y2);
			}
			
			public void mousePressed(MouseEvent event) {}
			public void mouseReleased(MouseEvent event) {}
			public void mouseEntered(MouseEvent event) {}
			public void mouseExited(MouseEvent event) {}
		}
		
		MouseListener listener1 = new Punkt1();
		MouseListener listener2 = new Punkt2();
		
		z.addMouseListener(listener1);
		z.addMouseListener(listener2);
		
		frame.add(z);
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(300,300);
		frame.setVisible(true);
	}
}
Das Problem ist, dass zwar ein Strich gezeichnet wird, sich dieser aber aber oberen Rand des Frames befindet. Der 2. Click wird zudem ignoriert.

Wo liegt der Fehler?? Ich nehme an, ich habe beim Anfügen der Mouselistener einen Murks gemacht. Leider fehlt mir das Wissen, um den Fehler zu erkennen.

Vielen Dank und schon mal schöne Pfingsten!
 
ah ja, klar!

Der Fehler ist leider damit nicht behoben, sondern es werden nur die eigentlich schwächen des Programms aufgezeigt... :cry:
Bei jedem Click bekomme ich nun einen horizontalen Strich mit der Länge der Differenz der Y-Werte, was ich mir leider nicht erklären kann. Wieso werden wie X-Werte nicht berücksichtigt?
 
hast du überhaupt keinen Willen, das ganze selber zu lösen?

mit einfachen Mitteln wie
System.out.println("zeiche Linie: x1: "+x1+", y1: "+y1+", x2: "+x2+", y2: "+y2);
in paintComponent und
System.out.println("neuer Punkt2: x2: " + x2 + ", y2: " + y2);
usw in den MouseListenern kannst du doch bis auf den letzten Millimeter herausfinden was das Programm wann genau tut,
nix einfacher als das..

einen Tippfehler bei den Variablenzuweisungen hast du irgendwo
(Suchaufgabe wenn du sonst schon nix alleine machst...)

und das Hauptproblem natürlich:
wieso sollte Java dafür sorgen, dass mal der eine und mal der andere MouseListener aktiv wird?
es werden selbstverständlich immer beide Listener aktiv,

wenn du nicht den Tippfehler bei den Variablenzuweisungen hättest, dann würden immer beide Punkte die gleichen Werte haben und nur ein Punkt gezeichet
(eine Linie der Länge 1 Pixel)
 
Nur mal so aus Neugier: Wenn du jetzt die Aufgabe hättest, eine Poly-Linie zu zeichnen (also eine Linie, die aus beliebige vielen Segmenten besteht), würdest du dann Methoden
public void draw1(int x1, int y1)
bis
public void draw1000(int x1000, int y1000)
und Klassen
class Punkt1 implements MouseListener
bis
class Punkt1000 implements MouseListener
erstellen, in der Hoffnung, dass der Benutzer zu faul ist, mehr als 1000 mal zu klicken?
 
Ein Hinweis:

Du benutzt nur einen Listener und merkst
dir ineiner Instanzvariablen (boolean bietet sich da an)
ob du gerade den Anfang oder das
Ende der Linie klickst.

Wesentlich bessere Vorgehensweise:

Du registrierst noch einen MouseMotionListener
und zeichnest in der mouseDragged-Methode.

mousePressed: Anfangspunkt merken
mouseDragged: Endpunkt merken und SOFORT (repaint) zeichnen
mouseReleased: Anfang und Ende FIX machen, um die Gerade
in der paint-Methode immer wieder
(bei Bedarf) zeichnen zu lassen
 
hmm, ok, ich sehe das Problem, dass meine beiden Listener gleichzeitig aufgerufen werden. Meine Linie endet in einem Punkt.
Leider ist es mir nicht gelungen, die Listener zeitlich versetzt aufzurufen. Eine Instanzvaribale konnte ich auch nicht ins Spiel bringen, da die inneren Klassen bekanntlich auch auf äussere Variblen zurückgreifen können, diese aber nicht verändern. Mein Counter, mit dem ich die Listener zu zählen versuchte, war also nutzlos.

Kann mir jemand einen weiterführenden Tipp geben?
 
ein Listener ist ein Objekt wie jedes andere,

schreib dafür eine eigene Klasse,
dann brauchst du dir über komische Argumente wie
'äussere Variblen zurückgreifen können, diese aber nicht verändern' (??)
gar nicht erst Gedanken zu machen

im Listener dann mit einem boolean-Flag oder Counter die Ereignisse unterscheiden,
was sollte da ein Problem sein?

flag true/falsch wechselnd, oder Counter gerade Zahlen/ ungerade Zahlen

-------

die Variante von Leroy wäre anspruchsvoller und inhaltlich anders (Maus gedrückt halten um zu zeichen)
aber auch möglich (die Stunden, bis du das begriffen hast, musst du dann aber Leroy nerven 😉 )
 
SlaterB hat gesagt.:
die Stunden, bis du das begriffen hast, musst du dann aber Leroy nerven
:shock:
Dann komm ich dem mal zuvor:

Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Gerade extends JPanel {
	int xAnf, yAnf;
	int xEnd, yEnd;
	
	public Gerade() {
		addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				xAnf = xEnd = e.getX();
				yAnf = yEnd = e.getY();
				repaint();
			}});
		addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseDragged(MouseEvent e) {
				xEnd = e.getX();
				yEnd = e.getY();
				repaint();
			}});
	}
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawLine(xAnf, yAnf, xEnd, yEnd);
	}

	public static void main(String[] args) {
		JFrame f = new JFrame("Gerade");
		f.getContentPane().add(new Gerade());
		f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
		f.setSize(400, 400);
		f.setLocationRelativeTo(null);
		f.setVisible(true);
	}
}

Fragen dazu erwünscht! 😀
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben