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
Annonceindlæg fra Barco
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.
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(); } }
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)
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
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(); } }
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).
Du har ændret: JTextField tidsFelt = new JTextField til tidsFelt = new JTextField Det er det eneste ikk..??
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
Jow, det skulle jeg mene (min kortidshukommelse er ikke perfekt :-)
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.
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)
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
Kurser inden for grundlæggende programmering