Dodanie MouseListenera do linii

0

Na JPanelu rysuję sobie linie przy pomocy metody:

@Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        for (UserDrawnLine line : userDrawnLines) {
            g.setColor(new Color(line.colorRValue,line.colorGValue, line.colorBValue));
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setStroke(new BasicStroke(line.thickness));
            g.drawLine(line.startPointX, line.startPointY, line.endPointX, line.endPointY);
        }
    }

Klasa linii:

public class UserDrawnLine {
    public int startPointX;
    public int startPointY;
    public int endPointX;
    public int endPointY;
    public int colorRValue;
    public int colorGValue;
    public int colorBValue;
    public float thickness;



    public UserDrawnLine(int startPointX, int startPointY, int endPointX, int endPointY, int colorRValue,int colorGValue,int colorBValue, float thickness) {
        this.startPointX = startPointX;
        this.startPointY = startPointY;
        this.endPointX = endPointX;
        this.endPointY = endPointY;
        this.colorRValue=colorRValue;
        this.colorBValue=colorBValue;
        this.colorGValue=colorGValue;
        this.thickness=thickness;
    }
} 

Chciałbym teraz umożliwić użytkownikowi klikanie prawym przyciskiem myszy na te linie i wywoływanie pewnych akcji. Niestety, linia nie jest komponentem i nie za bardzo wiem jak ugryźć temat. Myślałem o zapisywaniu punktów na których leży dana linia i po kliknięciu na JPanelu sprawdzaniu czy trafiłem w punkt na którym leży linia, ale to rozwiązanie wydaje się nienajlepsze. Macie może jakieś pomysły?

0

Jakby ktoś potrzebował na przyszłość to poradziłem sobie(z pomocą Stacka ofc :) ) w następujący sposób. Do klasy UserDrawnLine dodałem metodę sprawdzającą czy punkt leży na linii, bądź koło niej. Obecnie klasa wygląda tak:

public class UserDrawnLine {
    public int startPointX;
    public int startPointY;
    public int endPointX;
    public int endPointY;
    public int colorRValue;
    public int colorGValue;
    public int colorBValue;
    public float thickness;
    public double distance;



    public UserDrawnLine(int startPointX, int startPointY, int endPointX, int endPointY, int colorRValue,int colorGValue,int colorBValue, float thickness) {
        this.startPointX = startPointX;
        this.startPointY = startPointY;
        this.endPointX = endPointX;
        this.endPointY = endPointY;
        this.colorRValue=colorRValue;
        this.colorBValue=colorBValue;
        this.colorGValue=colorGValue;
        this.thickness=thickness;
        distance=Math.sqrt(Math.pow(endPointX - startPointX, 2) + Math.pow(endPointY - startPointY, 2));


    }

    public boolean isPointOnLine(int x, int y, double error){
        double dist = Math.sqrt(Math.pow(x - startPointX, 2) + Math.pow(y - startPointY, 2)) +
                Math.sqrt(Math.pow(x - endPointX, 2) + Math.pow(y - endPointY, 2));
        return Math.abs(dist - this.distance) <= error;
    }

} 

Następnie w Jpanelu sprawdzam który przycisk został naciśnięty i czy punkt leży na jakiejś linii.

@Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() == MouseEvent.BUTTON3) {
                Point pointClicked = e.getPoint();
                for (UserDrawnLine userDrawnLine : userDrawnLines) {
                    if (userDrawnLine.isPointOnLine(pointClicked.x, pointClicked.y, 50)) {
                        System.out.println("User right clicked on a line");
                    }
                }
            } else {
                drawing = true;
                lineStartingPoint = e.getPoint();
                lineEndingPoint = lineStartingPoint;
                repaint();
            }
        } 
0

Domyślam się, że chcesz stworzyć coś w rodzaju własnego edytora grafiki wektorowej. Jak klikniesz na linię to można ją przesunąć, jak na koniec to wydłużyć, kwadrat złapany za narożnik rozciągnąć itd.
Jeżeli tak to zamiast rysować tę linię bezpośrednio na panelu utwórz sobie klasę abstrakcyjną Component z metodami paint() i isClicked() lub coś w tym rodzaju. Wszystkie takie komponenty trzymasz sobie np. w liście i kiedy user klika prawym na panelu to iterując po liście sprawdzasz czy dla któregoś elementu is Clicked() nie zwróci true wtedy dla tego elementu wywołujesz odpowiednią akcję. Oczywiście każdy taki komponent może mieć swoje subkomponenty, np linia punkty końcowe, kwadrat narożniki, kółko środek itp. i w tej sytuacji przydaje się wzorzec projektowy o wdzięcznej nazwie Composite.

0
dymul napisał(a):

Domyślam się, że chcesz stworzyć coś w rodzaju własnego edytora grafiki wektorowej. Jak klikniesz na linię to można ją przesunąć, jak na koniec to wydłużyć, kwadrat złapany za narożnik rozciągnąć itd.

Nie do końca, ale po części tak.

dymul napisał(a):

Jeżeli tak to zamiast rysować tę linię bezpośrednio na panelu utwórz sobie klasę abstrakcyjną Component z metodami paint() i isClicked() lub coś w tym rodzaju. Wszystkie takie komponenty trzymasz sobie np. w liście i kiedy user klika prawym na panelu to iterując po liście sprawdzasz czy dla któregoś elementu is Clicked() nie zwróci true wtedy dla tego elementu wywołujesz odpowiednią akcję. Oczywiście każdy taki komponent może mieć swoje subkomponenty, np linia punkty końcowe, kwadrat narożniki, kółko środek itp. i w tej sytuacji przydaje się wzorzec projektowy o wdzięcznej nazwie Composite.

Bardzo fajne rozwiązanie, może mi się przydać. W razie czego będę Cię atakował o sprecyzowanie :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1