Avatar billede a-torsten Nybegynder
15. maj 2003 - 09:30 Der er 11 kommentarer og
1 løsning

Problemer med tråde og JSwing

Hejsa...

Hvad er problemet i denne kode :
import javax.swing.*;
import java.util.*;
import java.awt.*;

public class TraadFrame extends JFrame
{
    private JTextField tidsFelt;
   
    private int i = 0;
    private boolean tidStoppet = false;

    public TraadFrame()
    {
        setTitle("Dette er en test");
        setSize(300,200);
   
        JTextField tidsFelt = new JTextField("");
        tidsFelt.setBounds(10,10,200,20);
   
        Container c = getContentPane();
        c.setLayout(null);
        c.add(tidsFelt);

        setVisible(true);
        koerTid();   
    }
   
    public void koerTid()
    {
        while (!tidStoppet)
        {
            try
            {
                String tid = "" + i++;
                tidsFelt.setText(tid);
                Thread.sleep(1000);
               
                if (i==20)
                {
                    Thread.interrupted();
                }
            }
            catch(InterruptedException ex)
            {
                tidsFelt.setText("Tiden er stoppet");
            }
        }
    }

    public static void main(String args[])
    {
        new TraadFrame();
    }
}


Den virker hvis jeg kaster i ind i en System.out......

Og den virker også hvis jeg implementere Runable og kaster den ind i en run() metode...

Hvorfor virker denne kode ikk med Swing..?

-Anders
Avatar billede soreno Praktikant
15. maj 2003 - 09:33 #1
Prøv dette:

              String tid = "" + i++;
              tidsFelt.setText(tid);
              repaint();
              Thread.sleep(1000);
             

Ellers vil tidsfelt ikke blive repainted før der sker et event der eksplicit laver en repaint.
Avatar billede soreno Praktikant
15. maj 2003 - 09:37 #2
Nej, det er ikke det der er galt.
Det er din manglende oprettelse af en tråd.

+ du skal ikke erklære tidsFelt igen.

Kode:
import javax.swing.*;
import java.util.*;
import java.awt.*;

public class TraadFrame extends JFrame implements Runnable
{
    private JTextField tidsFelt;
 
    private int i = 0;
    private boolean tidStoppet = false;
    private Thread internalThread;
   
    public TraadFrame()
    {
        setTitle("Dette er en test");
        setSize(300,200);
 
        tidsFelt = new JTextField("");
        tidsFelt.setBounds(10,10,200,20);
 
        Container c = getContentPane();
        c.setLayout(null);
        c.add(tidsFelt);

        setVisible(true);
        //koerTid(); 
        internalThread = new Thread(this);
        internalThread.start();
    }
 
    public void run()
    {
        while (!tidStoppet)
        {
            try
            {
                String tid = "" + i++;
                tidsFelt.setText(tid);
                Thread.sleep(1000);
             
                if (i==20)
                {
                    Thread.interrupted();
                }
            }
            catch(InterruptedException ex)
            {
                tidsFelt.setText("Tiden er stoppet");
            }
        }
    }

    public static void main(String args[])
    {
        new TraadFrame();
    }
}
Avatar billede a-torsten Nybegynder
15. maj 2003 - 09:38 #3
Det giver samme fejl :

java.lang.NullPointerException

    at TraadFrame.koerTid(TraadFrame.java:35)

    at TraadFrame.<init>(TraadFrame.java:25)

    at TraadFrame.main(TraadFrame.java:53)
Avatar billede a-torsten Nybegynder
15. maj 2003 - 09:39 #4
Soreno... Jeg ved godt det virker ved at oprette en tråd....

Men jeg undre mig bare meget over at den gerne vil skrive ud til en consol med System.out.println(i++), men ikk til et JTextField...

-Anders
Avatar billede soreno Praktikant
15. maj 2003 - 09:40 #5
Det gør det også:
import javax.swing.*;
import java.util.*;
import java.awt.*;

public class TraadFrame extends JFrame
{
    private JTextField tidsFelt;
 
    private int i = 0;
    private boolean tidStoppet = false;
    private Thread internalThread;
   
    public TraadFrame()
    {
        setTitle("Dette er en test");
        setSize(300,200);
 
        tidsFelt = new JTextField("");
        tidsFelt.setBounds(10,10,200,20);
 
        Container c = getContentPane();
        c.setLayout(null);
        c.add(tidsFelt);

        setVisible(true);
        //koerTid(); 
        run();
    }
 
    public void run()
    {
        while (!tidStoppet)
        {
            try
            {
                String tid = "" + i++;
                tidsFelt.setText(tid);
                Thread.sleep(1000);
             
                if (i==20)
                {
                    Thread.interrupted();
                }
            }
            catch(InterruptedException ex)
            {
                tidsFelt.setText("Tiden er stoppet");
            }
        }
    }

    public static void main(String args[])
    {
        new TraadFrame();
    }
}
Avatar billede soreno Praktikant
15. maj 2003 - 09:42 #6
Det var nok din erklæring af tidsFelt 2 gange der drillede - du instantierede den lokale variabel - den gik ud af scope og dermed brugte du en uinitialiseret variabel (den globale).
Avatar billede a-torsten Nybegynder
15. maj 2003 - 09:47 #7
Du har ændret:
JTextField tidsFelt = new JTextField
til
tidsFelt = new JTextField

Det er det eneste ikk..??
Avatar billede a-torsten Nybegynder
15. maj 2003 - 09:48 #8
Hvad er mest "rigtigt" .. At oprette en tråd og køre den med start() og run() eller den måde jeg her har gjort det på... Og Hvorfor..??

-Anders
Avatar billede soreno Praktikant
15. maj 2003 - 09:49 #9
Jow, det skulle jeg mene (min kortidshukommelse er ikke perfekt :-)
Avatar billede soreno Praktikant
15. maj 2003 - 09:54 #10
Jeg ville oprette en tråd med start()

Hvis du har flere komponenter på din frame kan du få problemer med din fremgangsmåde. Hvis nu du har en knap hvor det tager 2 sekunder før resultatet returnerer (eks. et eller andet db opslag) så vil dit textfelt ikke blive opdateret før der returneres fra knappen. Eksekveringen af dit program foregår jo nemlig sekventielt.

tryk på knap -> opdater tekstfelt


Det vil du undgå ved at oprette en tråd. Så vil eksekveringen være parallel.

tryk på knap
opdater tekstfelt


Men at have et flertrådet program kræver discipling hvad angår læsning/skrivning af variabler - diverse synkroniserings mekanismer bør anvendes.
Avatar billede soreno Praktikant
15. maj 2003 - 10:00 #11
Jeg *tror* forresten også at (test evt. selv):
Thread.sleep(1000);

vil give problemer med at kunne trykke på knappe.
opdater tekstfelt -> sleep() -> opdater tekstfelt -> sleep() -> ..

Der er ikke meget tid til at nå at trykke på knappen.. (hvis min formodning er korrekt)
Avatar billede dempex Nybegynder
08. oktober 2003 - 13:04 #12
En tråd skal altid startes med tråd.start() , må aldrig bruge run, lige lært det i skolen
MVH
Ove
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