repaint() w swingu

0

Dość ogólne pytanie: Jak używac repaint()?

A teraz trochę szczegółów =].

Moim celem jest na panelu Jpanel w pierwszej fazie programu wstawiac kułeczka w miejsca kliknięcia myszki (to działa mi bez zaRZutu) a następnie po wciścnięciu przycisku narysować linie łączące punkty ze sobą, po czym po każdorazowym wykonaniu pewnego algorytmu zaktualizować te połączenia(gdyż ulegną zmianie).

rysowanie kółeczek mam w ten sposób:

 addMouseListener(new MouseAdapter() {
       public void mousePressed(MouseEvent e) {
           if (!block) {
               rysujMiasto(e.getX(), e.getY());
               dodajMiasto(e.getX(), e.getY());
               //dodaje współrzędne miasta do tabeli którą wykorzystuje w algorytmie
           }
       }
   });
 MiastoPunkt miasto = new MiastoPunkt();
private void rysujMiasto(int x, int y) {


        // Update coordinates.
        miasto.setX(x);
        miasto.setY(y);
        repaint(miasto.getX() - 3, miasto.getY() - 3, 7, 7);
    } 
class MiastoPunkt {

    private int xPos;
    private int yPos;

    public void setX(int xPos) {
        this.xPos = xPos;
    }

    public int getX() {
        return xPos;
    }

    public void setY(int yPos) {
        this.yPos = yPos;
    }

    public int getY() {
        return yPos;
    }

    public void rysujMiasto(Graphics g) {
        g.setColor(Color.BLACK);
        g.drawOval(xPos - 3, yPos - 3, 6, 6);
    }
}
class MiastoLinia {

    private int xPos1;
    private int yPos1;
    private int xPos2;
    private int yPos2;

    public void setX1(int xPos) {
        this.xPos1 = xPos;
    }

    public int getX1() {
        return xPos1;
    }

    public void setX2(int xPos) {
        this.xPos2 = xPos;
    }

    public int getX2() {
        return xPos2;
    }

    public void setY1(int yPos) {
        this.yPos1 = yPos;
    }

    public int getY1() {
        return yPos1;
    }

    public void setY2(int yPos) {
        this.yPos2 = yPos;
    }

    public int getY2() {
        return yPos2;
    }

    
    public void rysujLinie(Graphics g) {
        g.setColor(Color.BLACK);
        g.drawLine(xPos1 - 3, yPos1 - 3, xPos2 - 3, yPos2 - 3);
    }
}

natomiast samo malowanie:

 
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (miastaLinie) {//okresla czy w danej chwili rysuje punkty czy linie 
            if (this.start == 2) { //ten warunek wstawilem aby po uruchomieniu programu nie bylo nic malowane nasamym
                                        // starcie(zawsze malowalo mi jedno kuleczko ktorego nie chcialem)
                
                  miasto.rysujMiasto(g);
            } else {
                start++; //nie wiem dokladnie jak to dziala ale zauwazylem ze przechodzil przez paintComponent 2 razy 
                            //zanim zaczol oczekiwac na akcje dlatego tez 2 razy przechodzi przez pentle dopiero potem maluje 
                            //po kliknieciu
            }
        } else {
            linia.rysujLinie(g);
        }
    }

nie wiem wlasnie jak wykorzystac repaint do namalowanie linii o odpowiedniej (zmiennej ) dlugosci

 MiastoLinia linia = new MiastoLinia();
public void rysujLinie(int x1, int y1, int x2, int y2){
        linia.setX1(x1);
        linia.setX2(x2);
        linia.setY1(y1);
        linia.setY2(y2);
        repaint(linia.getX1()-3,linia.getY1()-3,100,100);
    }

sam przycisk zmienia miastaLinie na false wiec paintcomponent przechodzic powinien do malowania linii
i wywolac rysowanie poloczen pomiedzy kolejnymi punktami tabeli w ktorej zapisuje wspolrzedne miasta po kliknieciu myszka

a maluje jedynie jedno polaczenie i sam nie do konca rozumiem czemu akurat te ;/.

moglby mi ktos rozkjasnic lub pokierowac w dobrym kierunku ?

0

Powinieneś wywoływac metodę repaint() (bezargumentową!), za każdym razem gdy zmienia sie kolekcja obiektów do narysowania. Nie powinieneś nigdy wywoływać (ani bezpośrednio, ani pośrednio) repaint() z metody paintComponent(), to prowadzi do nieskończonej pętli.

 addMouseListener(new MouseAdapter() {
       public void mousePressed(MouseEvent e) {
           if (!block) {
               //rysujMiasto(e.getX(), e.getY());
               dodajMiasto(e.getX(), e.getY());
               repaint();
               //dodaje współrzędne miasta do tabeli którą wykorzystuje w algorytmie
           }
       }
   });
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (miastaLinie) {//okresla czy w danej chwili rysuje punkty czy linie 
            if (this.start == 2) { //ten warunek wstawilem aby po uruchomieniu programu nie bylo nic malowane nasamym
                                        // starcie(zawsze malowalo mi jedno kuleczko ktorego nie chcialem)
 
                  //dla każdego miasta z kolekcji narysuj to miasto
            }
            ...
        }
    }
0

Super teraz działa elegancko.

Mam jeszcze jedno pytanie.
mój projekt dotyczy znajdywania najkrótszej drogi pomiędzy punktami.
chciałbym aby graf aktualizował się za każdym razem jak znajdzie się krótsza droga.

myślałem ze jeśli wrzucę repaint() w pętle wykonywanego algorytmu to się będzie aktualizować, ale aktualizacja okna jest dopiero po zakończeniu całego algorytmu.

rozumiem, że bez wątków się nie obejdzie?

0

Dobrze się domyślasz.

0

Jak chcesz jakieś porządne rysowanie. Powinieneś zrobić jakąś pętle renderingu na BufferStrategy (Canvas), określając fps.

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