moveTo/lineTo Linie hervorheben

Schaaaf

Bekanntes Mitglied
Hallo,

ich habe per moveTo und lineTo Linien gezeichnet zwischen Punkten.

Ist es möglich, bei einem MouseClick auf eine dieser Linie diese hervorzuheben?
Also z.B. fetter werden zu lassen wie die anderen?

Bin dankbar für jede Anregung.
 

Marco13

Top Contributor
Falls es einzelne Line2Ds sind: Bei einem Mausklick alle segmente durchgehen, und mit Line2D#distanceToPoint (oder so) schauen, ob die Linie getroffen wurde, und falls ja, mit graphics2D.setStroke(new BasicStroke(3)); vor dem Zeichnen dieser Line2D einen dickeren Stift setzen.

Einzelne Segmente eines Path2Ds so hervorzuheben ist nicht direkt möglich - höchstens in dem man den Path mit einem PathIterator abläuft, jedes Segment wie angedeutet als Line2D interpretiert und prüft, und das angeklickte dann durch eine (mit passendem Stroke dicker gezeichnete) Line2D übermalt...
 

Schaaaf

Bekanntes Mitglied
Also, ich habe es wie folgt gemacht :

Java:
public void getMousePos(final Graphics2D g){
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(final MouseEvent e ) {
MousePosX = e.getX();
MousePosY = e.getY();
repaint();
}
});
checkPoint(g,MousePosX, MousePosY);
}

Java:
private void checkPoint(Graphics g,int MousePosX, int MousePosY){

for(int i = 0; i < Points.size(); i++) { 
int a,b;
a = (int)((MousePosX - Points.elementAt(i).x)/(Points.elementAt(i+1).x-Points.elementAt(i).x)); 
b = (int)((MousePosY - Points.elementAt(i).y)/(Points.elementAt(i+1).y-Points.elementAt(i).y));

if (a == b) {
((Graphics2D) g).setStroke( new BasicStroke( 3 ) );
g.drawLine((int)Points.elementAt(i).x, (int)Points.elementAt(i).y, (int)Points.elementAt(i+1).x, (int)Points.elementAt(i+1).y);
((Graphics2D) g).setStroke( new BasicStroke( 1 ) );
}	 		
}

Allerdings geht es noch nicht richtig. Es wird nicht immer die richige Linie dicker gemacht bzw. manchmal bin ich auch irgendwo auf dem Panel und trotzdem wird eine Linie dick. Warum?
 

Marco13

Top Contributor
Das Graphics, was du dort durschleifst, kann prinzipbedingt nicht das sein, was in paintComponent übergeben wird. Und was a und b sein sollen, erschließt sich mir auch nicht...
 

Schaaaf

Bekanntes Mitglied
Das Graphics, was du dort durschleifst, kann prinzipbedingt nicht das sein, was in paintComponent übergeben wird.

Warum nicht? Ich übergebe das doch mit aus der PaintComp. ?!

Mit a und b teste ich ob die MousePosition auf der geg. Strecke liegt.
 

Marco13

Top Contributor
Ja, aber man muss davon ausgehen, dass bei jedem Aufruf von paintComponent ein anderes Graphics übergeben wird. (Und wenn du es jetzt prüfst, und zweimal dasselbe kommt, heißt das nicht, dass das immer so ist).

Die Sache mit dem a und b ... was auch immer du da ausrechnest, es ist nicht das, was du willst. Bei einer senkrechten oder waagerechten Linie wird da durch 0 geteilt, und auch sonst... ?!

Nebnebei: Man sollte die Methode 'elementAt' bzw. die Klasse Vector als solche nicht verwenden. Statt
Java:
private Vector<Point> Points = new Vector<Point>();

void doSomething()
{
    int something = Points.elementAt(i).x + Points.elementAt(i+1).x * Points.elementAt(i).x / Points.elementAt(i+1).x
}
sollte man schreiben
Java:
// List statt Vector, Variablenname klein. (Das "new Vector" ist OK!)
private List<Point> points = new Vector<Point>();

void doSomething()
{
    // 'get' statt 'elementAt'. Subjektiv: Mehrfach benutzte Werte in Variablen speichern
    Point p0 = points.get(i);
    Point p1 = points.get(i+1);

    int something = p0.x + p1.x * p0.x / p1.x
}
 

Schaaaf

Bekanntes Mitglied
Und was kann ich da ändern mit dem übergegebenen Graphics?

Beim Testen, ob ein Punkt auf einer Strecke liegt, muss ja das "Lamda" gleich sein. Und das ist bei mir a (für x-Gleichung) und b (für y-Gleichung).
Aber stimmt, bei waagerechten/senkrechten Linien kommt das nicht hin....mmmhhh....Aber ne andere Formel find ich nicht. Ich poste einfach mal den Code ins MatheForum. Vlt. gibts da nen Zusatz?
 

HimBromBeere

Top Contributor
Das Prüfen auf "Geklicktheit" kannst du auch über Shape#interesects(x, y) lösen, hab ich nei mir auch gemacht, da sieht das etwa so aus:

Java:
public Shape getClickedShape(int x, int y) {		
	Iterator<Shape> i = shapes.iterator();
	while (i.hasNext()) {
		Shape s = i.next();
		if (s.intersects(new Rectangle2D.Double(x - 1, y - 1, 5, 5))) return s;
	}		
	return null;
}
Ob du nun für den Mauspuffer ein Rechteck oder ´nen Kreis verwendest, musst du selber wissen, ich hab halt bei mir ein 5px großes Quadrat genommen.
 

Marco13

Top Contributor
Die Geklicktheit zu überprüfen geht mit Line2D (Java Platform SE 6) (wie auch eben in http://www.java-forum.org/mathematik/131837-liegt-punkt-strecke.html erwähnt).

Das mit dem Graphics ... ja, ein paar Zeilen Pssudocode
Java:
class TheClass
{
    private Line2D highlightedLine = null; // Evtl. eine List, wenn's mehrere geben soll

    @Override
    public void mouseClicked(MouseEvent e)
    {
        highlightedLine = null; 
        for (all Points p0, p1)
        {
            Line2D line = new Line2D.Double(p0, p1);
            if (line.ptSegDistSq(e.getPoint()) < 5)
            {
                highlightedLine = line;
            }
        }
    }

    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
 
        // Male alles wie vorher
        ...


        if (highlightedLine != null)
        {
            g.setStroke( new BasicStroke( 3 ) );
            g.draw(highlightedLine); 
        }

    }
}
 

Ähnliche Java Themen


Oben