Avatar billede skurggman Nybegynder
23. marts 2009 - 17:11 Der er 13 kommentarer og
1 løsning

Java Applet sleep()

Hejsa,

Jeg skal præsentere en masse billeder i min java applet, hvilket får fint med labels og icons osv... Men indimellem hvert billede præsenteres skal der været et andet billede (et fixation point om man vil "+"). Den skal være der i 1 sekund. Jeg har forsøgt mig uden held med at lade tråden sove, og er gået videre til at prøve med at idle (busywaite) i et antal sekunder på følgende måde:

stimulu.setIcon(null);
stimulu.setText("+++");
stimulu.repaint();
long now = System.currentTimeMillis();
while(System.currentTimeMillis()<now+wait){
    // idle
}

Nu er det noget tid siden jeg har kodet java sidst så har sikkert set mig blind på noget. Men det sjove er at den faktisk venter et sekund med at præsentere det næste billede, men den tegner ikke noget nyt imens - hvilket undrer mig, da jeg kalder repaint inden jeg idler.

Nogen hints?
Avatar billede arne_v Ekspert
23. marts 2009 - 17:25 #1
Du maa ikke sleepe i event traaden.
Avatar billede arne_v Ekspert
23. marts 2009 - 17:28 #2
Start en traad som sleeper og goer noget og som kalder SwingUtilities.invokeLater (eller EventQueue ditto).
Avatar billede arne_v Ekspert
23. marts 2009 - 17:28 #3
Et eksempel med tekst:

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

public class NewDynNum extends JFrame implements ActionListener {
    private JTextField txt;
    private JButton btn;
    private int n;
    public NewDynNum() {
        n = 0;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        txt = new JTextField();
        txt.setText(Integer.toString(n));
        getContentPane().add(txt, BorderLayout.CENTER);
        btn = new JButton("Count 10 up");
        btn.addActionListener(this);
        getContentPane().add(btn, BorderLayout.SOUTH);
        pack();
    }
    public void incr() {
        n++;
        txt.setText(Integer.toString(n));
    }
    public void actionPerformed(ActionEvent ev) {
        if (ev.getSource() == btn) {
            T t = new T(this);
            t.start();
        }
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                NewDynNum f = new NewDynNum();
                f.setVisible(true);
            }
        });
    }
}

class T extends Thread {
    private NewDynNum dn;
    public T(NewDynNum dn) {
        this.dn = dn;
    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    dn.incr();
                }
            });
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }
    }
}
Avatar billede skurggman Nybegynder
23. marts 2009 - 17:38 #4
hmm okay, men jeg bruger faktisk ikke engang sleep()...
Avatar billede skurggman Nybegynder
23. marts 2009 - 17:44 #5
problemet er måske ikke så meget sleep som det er at den ikke repaint()'er som den burde, for den idle'r fint.
Avatar billede arne_v Ekspert
23. marts 2009 - 17:46 #6
sleep og busy wait har samme effekt paa Swing - busy wait spiler bare en masse CPU kraft
Avatar billede skurggman Nybegynder
23. marts 2009 - 17:48 #7
okay, jeg prøver det :) tak for hjælpen.
Avatar billede skurggman Nybegynder
23. marts 2009 - 18:10 #8
public void paintCross(long wait) throws InterruptedException{
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                URL imageURL = applet.class.getResource("./pics/cross.jpg");
                icon = new ImageIcon(imageURL);
                stimulu.setIcon(icon);
                stimulu.setText("");
                stimulu.repaint();
            }
        });
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
    }

Hjælper ingenting... som sagt så sleeper den fint, men den repainter stadig ikke før den påbegynder sleep()
Avatar billede skurggman Nybegynder
23. marts 2009 - 23:27 #9
Nogen hjælp at hente?
Avatar billede arne_v Ekspert
24. marts 2009 - 00:19 #10
Jeg gætter på at du stagigvæk kaldet sleep fra event tråden. Det duer ikke.

Når bruger klikke på next button eller whatever, så starter du en tråd som først bruger invokeLater til at vise pausebillede, sleeper 1 sekun dog så bruger invokeLater til at vise det rigtige billede.
Avatar billede arne_v Ekspert
24. marts 2009 - 00:29 #11
Eksempel:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Paging extends JFrame implements ActionListener {
    private JTextField txt;
    private JButton btn;
    public Paging() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        txt = new JTextField();
        txt.setText("");
        getContentPane().add(txt, BorderLayout.CENTER);
        btn = new JButton("Vis nyt billede");
        btn.addActionListener(this);
        getContentPane().add(btn, BorderLayout.SOUTH);
        this.setSize(300, 300);
    }
    public void load(String s) {
        txt.setText(s);
    }
    public void actionPerformed(ActionEvent ev) {
        if (ev.getSource() == btn) {
            T t = new T(this);
            t.start();
        }
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                Paging f = new Paging();
                f.setVisible(true);
            }
        });
    }

}

class T extends Thread {
    private static int n = 0;
    private Paging pag;
    public T(Paging dn) {
        this.pag = dn;
    }
    public void run() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                pag.load("Nu viser vi billede af nogle pausefisk");
            }
        });
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                n++;
                pag.load("Nu viser vi et rigtigt billede nummer " + n);
            }
        });
    }
}
Avatar billede arne_v Ekspert
24. marts 2009 - 00:29 #12
Det er så en app der viser tekst - du skal selv omskrive til en applet som vise billede.
Avatar billede skurggman Nybegynder
24. marts 2009 - 10:28 #13
Det er præcist den opførsel jeg leder efter - bare smid et svar og tusind tak for hjælpen!
Avatar billede arne_v Ekspert
24. marts 2009 - 13:36 #14
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester