[JAVA] Invoke PaintComponent

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • battler
  • Registratie: November 2004
  • Laatst online: 30-06 15:11
Ik wil graag op een plaatje een lijntje tekenen. Dit lijntje moet regelmatig geüpdate worden aangezien hij verplaatst van positie.

Classe LoadImage:

Bevat:
Constructor
PaintComponent
Run

Nu geeft de Constructor een waarde waardoor het lijntje op de juiste plek wordt gezet. Graag zou ik willen dat de Run method ervoor zorgt dat dit lijntje constant wordt getekend. Als het goed is wordt door de methode repaint PaintComponent aangeroepen. Helaas werkt dit bij mij niet.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 public LoadImage(int S) {
        snelheid = S;
        setPreferredSize(new Dimension(142, 71));
        try {
            img = ImageIO.read(new File("Dashboard.jpg"));
            System.out.println("LoadImage, Constructor tekent Dashboard");
            //repaint();p
        } catch (IOException e) {
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        g.drawImage(img, 0, 0, null);
        g.setColor(Color.GREEN);
        //Omzetten van snelheid naar radialen
        double radialen = ((((snelheid + i) - 50) / 100.0) * (Math.PI));
        //Bepaal coordinaten
        x = (straal) + (Math.sin(radialen) * straal);
        y = (straal) - (Math.cos(radialen) * straal);
        //Teken lijn
        g.drawLine(72, 70, (int) x, (int) y);
        System.out.println("Class: LoadImage, Method:Paintcomponent" + i);
    }

    public void run() {
        while (true) {
            try {
                repaint();<== Dit zou ervoor moeten zorgen dat PaintComponent wordt uitgevoerd. 
                System.out.println("Class: LoadImage, Method:Run, Invoked:" + i);
                i++;
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(LoadImage.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }


Ik snap dat de PaintComponent elke keer dezelfde lijn zal tekenen. Maar de println wordt niet eens uitgevoerd.

[ Voor 5% gewijzigd door battler op 23-12-2009 12:58 ]

Lux.Architectuur | Van Dromen tot Wonen | www.Lux-a.nl


Acties:
  • 0 Henk 'm!

  • Salandur
  • Registratie: Mei 2003
  • Laatst online: 16-09 15:50

Salandur

Software Engineer

start je ergens een aparte thread op om de run methode uit te voeren? zonder deze aan te roepen zal de lijn niet opnieuw getekend worden.

Assumptions are the mother of all fuck ups | iRacing Profiel


Acties:
  • 0 Henk 'm!

  • battler
  • Registratie: November 2004
  • Laatst online: 30-06 15:11
Uiteraard: De run methode wordt wel netjes uitgevoerd, op mijn verwachting van de repaint methode na dan.

Lux.Architectuur | Van Dromen tot Wonen | www.Lux-a.nl


Acties:
  • 0 Henk 'm!

  • Raynman
  • Registratie: Augustus 2004
  • Laatst online: 22:31
Je bedoelt dus dat de println op regel 23 niet uitgevoerd wordt en die op regel 30 wel? Kun je anders een iets completer plaatje geven van welke objecten je creëert en waar je wat op aanroept? Maakt het misschien iets makkelijker. (Maar ik heb dit spul sowieso niet meer zo vers in mijn geheugen zitten.)

Acties:
  • 0 Henk 'm!

  • battler
  • Registratie: November 2004
  • Laatst online: 30-06 15:11
Main Class: Hier wordt dus op een jPanel een jPanel gemaakt
code:
1
2
3
4
        jPanel7.add(new MakeGUI().MakePanel(200, 0));
        jPanel7.add(new MakeGUI().MakePanel(400, 0));
        jPanel7.add(new MakeGUI().MakePanel(600, 0));
        jPanel7.add(new MakeGUI().MakePanel(800, 0));


De Jpanel die erop wordt gegooid voegt ook gelijk de klasse LoadImage toe (regel 6).
En maakt ook gelijk een thread van de classe LoadImage (regel 9)
code:
1
2
3
4
5
6
7
8
9
10
11
    public JPanel MakePanel(int x, int y) {
        JPanel p = new JPanel();
        p.setBackground(Color.RED);
        p.setSize(200, 75);
        p.setLocation(x, y);
        p.add(new LoadImage(70));
        p.setVisible(true);
        System.out.println("Class:MakeGUI, Method:MakePanel");
        (new Thread(new LoadImage())).start();
        return p;
    }


Deze code wordt dus 4 keer uitgevoerd (voor elke jpanel 1 keer).
Uiteindelijk blijft de run methode lopen als aparte thread. In deze methode verwacht ik dat hij PaintComponent aanroept d.m.v de repaint(); (regel 30). Helaas wordt de PaintComponent maar 4 keer uitgevoerd, en dus niet elke keer door de run methode aangeroepen.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
   public LoadImage(int S) {
        snelheid = S;
        setPreferredSize(new Dimension(142, 71));
        try {
            img = ImageIO.read(new File("Dashboard.jpg"));
            System.out.println("LoadImage, Constructor tekent Dashboard");
            //repaint();p
        } catch (IOException e) {
        }
    }
[

    @Override
    public void paintComponent(Graphics g) {
        g.drawImage(img, 0, 0, null);
        g.setColor(Color.GREEN);
        //Omzetten van snelheid naar radialen
        double radialen = ((((snelheid + i) - 50) / 100.0) * (Math.PI));
        //Bepaal coordinaten
        x = (straal) + (Math.sin(radialen) * straal);
        y = (straal) - (Math.cos(radialen) * straal);
        //Teken lijn
        g.drawLine(72, 70, (int) x, (int) y);
        System.out.println("LoadImage, Paintcomponent" + i);
    }

    public void run() {
        while (true) {
            try {
                repaint();
                System.out.println("Class: LoadImage, Method:Run, Invoked:" + i);
                i++;
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(LoadImage.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

Lux.Architectuur | Van Dromen tot Wonen | www.Lux-a.nl


  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
Je constructor matched niet met het gebruik in je code, en de getoonde code is niet compleet. Ik kan je overigens aanraden om te kijken naar SwingWorker of javax.swing.Timer om dingen in de achtergrond cq herhaald te doen ipv je eigen threading te regelen.

Bijna alle methoden in Swing moeten op de event-thread aangeroepen moeten worden, controleer dus of je alle Swing gerelateerde classes aanmaakt en intialiseert op de eventthread. (NB: repaint() scheduled een paint event op event thread). Controleer daarom goed of je je applicatie start zoals in Swing's Threading Policy wordt beschreven (te vinden in de javadoc).

Je realiseert je neem ik aan wel dat het laden van het plaatje op de huidige thread (event thread?) gebeurt doordat je dat in de constructor doet en niet in de nieuwe thread.

Acties:
  • 0 Henk 'm!

  • battler
  • Registratie: November 2004
  • Laatst online: 30-06 15:11
Who calls paintComponent:
When a window becomes visible (uncovered or deminimized) or is resized, the "system" automatically calls the paintComponent() method for all areas of the screen that have to be redrawn.
Called indirectly from a user-defined listener via repaint()

Volgens mij initialiseer ik dus alles om PaintComponent aan te roepen.

http://www.leepoint.net/n...calls-paintcomponent.html

Lux.Architectuur | Van Dromen tot Wonen | www.Lux-a.nl


Acties:
  • 0 Henk 'm!

  • Maniacs
  • Registratie: November 2009
  • Laatst online: 23-08 16:05
Je methode MakePanel klopt volgens mij niet:
Je maakt een nieuwe JPanel aan en voegt daar op regel 6 een nieuwe LoadImage instantie aan toe. Die LoadImage instantie moet je ook als thread starten, niet een nieuwe instantie zoals op regel 9 gebeurd.

b.t.w. een while(true) loop in een runnable is niet echt netjes.

Groeten,
Mark

Acties:
  • 0 Henk 'm!

  • battler
  • Registratie: November 2004
  • Laatst online: 30-06 15:11
De run methode wordt gewoon uitgevoerd. Het probleem wat ik heb is dat de run methode PaintComponent niet aanroept.

Lux.Architectuur | Van Dromen tot Wonen | www.Lux-a.nl


Acties:
  • 0 Henk 'm!

  • momania
  • Registratie: Mei 2000
  • Laatst online: 00:24

momania

iPhone 30! Bam!

Wat is LoadImage, waar extend je van?

Waarom doe je dit:
Java:
1
2
3
        p.add(new LoadImage(70));
// ....
        (new Thread(new LoadImage())).start();
:?
Nu heb je dus 2 LoadImage objecten. 1 die je toevoegt als component aan je panel. Een ander die je in een Thread gebruikt en non stop probeert te verversen (wat niet gaat lukken, want het is een in de ruimte zwevend gui component nu ;) )

Ik neem aan dat je diegene die je aan je component toevoegt wil laten verversen? ;)

Voordat je uberhaupt met threads in de weer gaat, en eigenlijk zelfs voordat je met GUI's bezig gaat, lijkt het me handig dat je eerst wat basis OO dingen gaat proberen met wat console apps ofzo :)

Neem je whisky mee, is het te weinig... *zucht*


Acties:
  • 0 Henk 'm!

  • Maniacs
  • Registratie: November 2009
  • Laatst online: 23-08 16:05
UIteraard wordt de run uitgevoerd, je start toch een nieuwe thread. Je start alleen de verkeerde Runnable:
Als je de LoadImage instantie op regel 6 toekent aan een variabele en deze variabele aan de nieuwe thread instantie op regel 9 meegeeft wordt het juiste object gerepaint. Zoals je code nu is wordt een niet getoond object gerepaint.
En zolans Remus al zei: De constructor van LoadImage is niet consistent in je code voorbeeld. Is dit alle relevante code?

Gr,
Mark

Acties:
  • 0 Henk 'm!

  • battler
  • Registratie: November 2004
  • Laatst online: 30-06 15:11
momania schreef op zondag 27 december 2009 @ 16:31:
Wat is LoadImage, waar extend je van?
Class LoadImage extends JPanel implements Runnable
Waarom doe je dit:
Java:
1
2
3
        p.add(new LoadImage(70));
// ....
        (new Thread(new LoadImage())).start();
:?
Nu heb je dus 2 LoadImage objecten. 1 die je toevoegt als component aan je panel. Een ander die je in een Thread gebruikt en non stop probeert te verversen (wat niet gaat lukken, want het is een in de ruimte zwevend gui component nu ;) )
De eerste is om te kijken of er daadwerkelijk een image wordt getekend op de jPanel. Het getal 70 is een variabele positie.
Vervolgens probeer ik een thread te maken die de methode PaintComponent aanroept. Dat hij nog niets kan tekenen e.d is logisch. Maar hij kan in iedergeval een println naar buiten gooien. Helaas doet hij dit laatste dus niet.
Ik neem aan dat je diegene die je aan je component toevoegt wil laten verversen? ;)

Voordat je uberhaupt met threads in de weer gaat, en eigenlijk zelfs voordat je met GUI's bezig gaat, lijkt het me handig dat je eerst wat basis OO dingen gaat proberen met wat console apps ofzo :)
Dit is juist om te leren. Maar naar mijn weten maak ik (nog) geen OO fouten. Als dit wel zo is, kan je aangeven wat er niet goed is?

Uiteraard ontzettend bedankt voor de moeite die je al hebt genomen ;)
UIteraard wordt de run uitgevoerd, je start toch een nieuwe thread. Je start alleen de verkeerde Runnable:
Als je de LoadImage instantie op regel 6 toekent aan een variabele en deze variabele aan de nieuwe thread instantie op regel 9 meegeeft wordt het juiste object gerepaint. Zoals je code nu is wordt een niet getoond object gerepaint.
En zolans Remus al zei: De constructor van LoadImage is niet consistent in je code voorbeeld. Is dit alle relevante code?
Uiteraard ook jij bedankt voor de genomen moeite.
Ik denk dat ik mijn vraag niet goed stel. Hoewel de methode PaintComponent anders doet vermoeden verwacht ik op dit moment niet dat hij wat tekent. Het enige wat ik verwacht is de volgende println: System.out.println("LoadImage, Paintcomponent" + i);. Zodat ik zie dat de Run Methode in iedergeval PaintComponent aanroept.

Ik probeer PaintComponent aan te roepen door de methode Repaint(); te gebruiken in mijn Run methode.
Aldus de volgende link: http://www.leepoint.net/n...calls-paintcomponent.html

Lux.Architectuur | Van Dromen tot Wonen | www.Lux-a.nl


Acties:
  • 0 Henk 'm!

  • momania
  • Registratie: Mei 2000
  • Laatst online: 00:24

momania

iPhone 30! Bam!

battler schreef op zondag 27 december 2009 @ 17:14:
[...]
Dit is juist om te leren. Maar naar mijn weten maak ik (nog) geen OO fouten. Als dit wel zo is, kan je aangeven wat er niet goed is?
repaint() schiet intern events af, om zo vanuit de event dispatcher door je gui heen te lopen en alle dirty objecten te repainten (niet helemaal, maar iets in die geest).

Dat je nu een ImageLoader in een aparte thread draait en daar de repaint iedere keer aan roept is leuk, maar die instance van de ImageLoader is geen onderdeel van je GUI. Dat bedoelde ik met een 'in de ruimte zwevend gui component'. De event dipacher weet dat het component een invisible component is en zal het dus nooit iedere keer gaan painten... zonde van de cpu ;)

Maar uiteindelijk: wat wil je leren? GUI of threading? Doe 1 van de 2 en niet tegelijk. GUI lijkt altijd op het eerste gezicht makkelijk in java, je tovert snel wat dingen op het scherm. Maar om het uiteindelijk met een goed ontwerp met goed gebruik van de event dispatcher enzo werkend te krijgen is een heel ander verhaal. :)

Neem je whisky mee, is het te weinig... *zucht*


Acties:
  • 0 Henk 'm!

  • Maniacs
  • Registratie: November 2009
  • Laatst online: 23-08 16:05
battler schreef op zondag 27 december 2009 @ 17:14:
Ik denk dat ik mijn vraag niet goed stel. Hoewel de methode PaintComponent anders doet vermoeden verwacht ik op dit moment niet dat hij wat tekent. Het enige wat ik verwacht is de volgende println: System.out.println("LoadImage, Paintcomponent" + i);. Zodat ik zie dat de Run Methode in iedergeval PaintComponent aanroept.
Ok, die println zal niet gebeuren omdat je de repaint() methode aanroept op een object wat niet visible is. Als je in de repaint code kijkt zie je dat indien een component niet visible is, er geen PaintEvent wordt afgevuurd, en dus wordt de paintComponent methode niet aangeroepen.

Swing werkt intern met events om de GUI up-to-date te houden. Je kan op nagenoeg elke UI actie die je kan bedenken een event listener zetten waarna je je update/repaint kan uitvoeren. Je hoeft dus eigenlijk nooit zelf met threads in de weer, tenzij je iets wilt wat niet afhangt van de user-/systeem input, maar tijdgebonden is.
Nu weet ik niet wat je precies wilt bereiken met je code maar wellicht is het voldoende om een eventlistener aan een UI actie te hangen, of het systeem het juiste Swing event te laten afvuren.

Groeten,
Mark
Pagina: 1