Avatar billede ripley Nybegynder
17. januar 2003 - 11:16 Der er 11 kommentarer og
2 løsninger

Spørgsmål om Threads / run

Ud fra en øvelse i en bog er jeg ved at lave et Java-program, der skal lave en GUI med 4 knapper.
Trykker man på en "Start"-knap, vises tiden på min GUI (på et label).
Det er lavet dels vha. tråde og så princippet med to objekter, der står og sender
information frem og tilbage.

***********************************************************
Jeg har en TimerInterface.java, som de to andre klasser nedarver fra:
***********************************************************

public interface TimerInterface
{
    public abstract void timerFired();
}



***********************************************************
Jeg har en DigitalClock.java, der repræsenterer min GUI og det ene objekt:
***********************************************************

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

public class DigitalClock extends JFrame implements TimerInterface
{
    Timer timer;
    JLabel label = new JLabel();
    JButton btnStart = new JButton("START");
    JButton btnStop = new JButton("STOP");
    JButton btnSuspend = new JButton("SUSPEND");
    JButton btnResume = new JButton("RESUME");
    JPanel top = new JPanel();
    JPanel bottom = new JPanel();
    MyJButtonListener myJButtonListener;

    DigitalClock()
    {
        timer = new Timer(this,10000);
        setUpGUI();
    }

    private void setUpGUI()
    {
        Container c = getContentPane();
        c.setLayout(new BorderLayout());
        bottom.setLayout(new GridLayout());
        bottom.add(btnStart);
        bottom.add(btnStop);
        bottom.add(btnSuspend);
        bottom.add(btnResume);
        c.add(BorderLayout.SOUTH,bottom);
        top.setLayout(new GridLayout());
        top.add(label);
        c.add(BorderLayout.NORTH,top);
        myJButtonListener = new MyJButtonListener();
        btnStart.addActionListener(myJButtonListener);
        setSize(400,100);
        show();
    }
    class MyJButtonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            if(e.getActionCommand().equals("START"))
            {
                timer.startTimer();
            }
            else if(e.getActionCommand().equals("STOP"))
            {
       
            }
            else if(e.getActionCommand().equals("SUSPEND"))
            {
                       
            }
            else if(e.getActionCommand().equals("RESUME"))
            {
                   
            }
           
        }
    }

    public void timerFired()
    {
        Date date = new Date();
        System.out.println(date);
        //label.setText(date.toString());
    }

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


***********************************************************Til sidst har jeg en klasse, Timer, der udgør det andet objekt:
***********************************************************

import java.util.*;

public class Timer implements Runnable
{
    TimerInterface tIntObj;
    int interval;
    Thread timerThread = new Thread();   
   
    Timer(TimerInterface tIntObj, int interval)
    {
        this.tIntObj = tIntObj;
        this.interval = interval;
    }
   
    public void run()
    {
        while(true)
        {
            for (int i = 0; i< interval; i++)
            tIntObj.timerFired();
        }
    }

    public void startTimer()
    {
        timerThread.run();
    }
   
}


***********************************************************
Og problemet er så, at skidtet ikke virker!
Jeg tror selv problemet ligger i, at min variabel timerThread af typen Thread
ikke kører run-metoden som defineret i Timer, men sin egen run-metode, der
findes i klassen Thread.
Jeg skal have denne variabel af typen Thread - det er angivet i opgaven - så
mit spørgsmål lyder: hvordan får jeg den variabel til at køre min run-metode
i stedet for sin egen???!! Er der nogle kloge hoveder, der kan gennemskue det?
***********************************************************
Avatar billede carstenknudsen Nybegynder
17. januar 2003 - 11:23 #1
Når du laver en new Thread(Runnable) skal du kalde start
ikke run direkte.
Avatar billede ripley Nybegynder
17. januar 2003 - 11:25 #2
Øhm - hvordan og hvorledes skal jeg så ændre i min kode??
Avatar billede di8leva Nybegynder
17. januar 2003 - 11:28 #3
prøv med at ændre:
timerThread.run(); --> timerThread.start();
Avatar billede di8leva Nybegynder
17. januar 2003 - 11:32 #4
hmm, er det ikke lidt fejl?
hvis du laver om Timer -->
---------------------------------------
public class Timer implements Runnable
{
    TimerInterface tIntObj;
    int interval;
    Thread timerThread;
   
    Timer(TimerInterface tIntObj, int interval)
    {
        this.tIntObj = tIntObj;
        this.interval = interval;
        timerThread = new Thread()
        {
          public void run()
          {
            runIt();
          }
        }
    }
   
    public void runIt()
    {
        while(true)
        {
            for (int i = 0; i< interval; i++)
            tIntObj.timerFired();
            try
            {
              Thread.sleep(500);
            }
            catch(Exception e) { e.printStackTrace(); }
        }
    }

    public void startTimer()
    {
        timerThread.start();
    }
   
}
Avatar billede di8leva Nybegynder
17. januar 2003 - 11:34 #5
oops, little mistake:
timerThread = new Thread()
        {
          public void run()
          {
            runIt();
          }
        }
+ ;
=)

Thread.sleep er før at hvis du ikke låter den thread vila lidt så tar den ALL kraft fra processorn, og då blir grafiken aldrig tegnet =)
Avatar billede ripley Nybegynder
17. januar 2003 - 11:48 #6
Jeg forstod ikke helt mistake'n??
+;
=)
Skal det stå sådan - eller kan du ikke lige skrive præcist, som det skal stå?
Avatar billede carstenknudsen Nybegynder
17. januar 2003 - 11:57 #7
timerThread = new Thread()
        {
          public void run()
          {
            runIt();
          }
        }
;
Avatar billede di8leva Nybegynder
17. januar 2003 - 12:01 #8
som carsten skriver
Avatar billede ripley Nybegynder
17. januar 2003 - 12:12 #9
Hm - jeg synes nu, jeg får et mylder af fejl!!
bl.a. kan den ikke lide "public void run" - "illegal start of expression"

- og den skriver, at Timer skal erklæres abstract, fordi den ikke definerer run()
Avatar billede ripley Nybegynder
17. januar 2003 - 12:17 #10
Okay - et mylder af fejl var så meget sagt.
; skulle placeres en tand længere oppe end I havde angivet (?)
Så er jeg nede på de 2 fejl, jeg beskrev før!
Avatar billede di8leva Nybegynder
17. januar 2003 - 12:20 #11
ok, didn't see that one =)
der er en del fejl i din kod, men det nemmeste mådet att gøre det kørbart er nok.

public class Timer implements Runnable
{
    TimerInterface tIntObj;
    int interval;
    Thread timerThread;
   
    Timer(TimerInterface tIntObj, int interval)
    {
        this.tIntObj = tIntObj;
        this.interval = interval;
        timerThread = new Thread()
        {
          public void run()
          {
            Timer.this.run();
          }
        };
    }
   
    public void run()
    {
        while(true)
        {
            for (int i = 0; i< interval; i++)
            tIntObj.timerFired();
            try
            {
              Thread.sleep(500);
            }
            catch(Exception e) { e.printStackTrace(); }
        }
    }

    public void startTimer()
    {
        timerThread.start();
    }
   
}
Avatar billede viht Nybegynder
18. januar 2003 - 12:40 #12
Hvis i bruger Timers skal ikke definere run, men actionPerformed(ActionEvent event)

Der er jo en ambiguity i det i kalder klassen det samme som javax.swing.Timer og den definerer actionPerformed og ikke run!
Avatar billede viht Nybegynder
18. januar 2003 - 12:45 #13
Er det i øvrigt ikke bedre bare at definere end indre klasse, hvis der er noget trådarbejde der skal udføres? Det gør jeg oftest.

public class Worker1 {
  ...
  public Worker1(Work work) {
      new Worker1Worker(work).start();
  }
  private class Worker1Worker extends Thread {
      ...
      public Worker1Worker(Work work) {
        this.work = work;
      }
      public void run() {
        work.doWork();
      }
  }
}
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