Member Avatar for Ajantis

Hello people!

I am working a little with JAVA programming. And I have a couple of assignments left. When they're both done, I graduate! :) However, I'm not fully familiar with threads. So I don't know how to solve these problems. I thought that perhaps someone could lead me in to a good direction of how to solve them, or similar. I just want to get this thing done.

I have seen a couple of examples of how to create Threads - by implementing Runnable and by making it extends Thread object.
But I still can't figure it out the nr 2 (and on) in the assignment. The SecTimer class looks like it could be a thread - but it said in instrunctions I should make a new class for threads.

So... I'm just lost in these... threads. I just can't make the time show properly - or at all. Perhaps there's some knowledge in coding I am yet to understand - perhaps it's just something simple. Or perhaps I just nested myself into thinking too much about it. Whatever it is - please help. I greately appriciate it! :)

Here's the assignment:
http://pastebin.com/mfc24d76


Here are the classes:
SecTimer class
http://pastebin.com/m25087995

SimpleTimer
http://pastebin.com/m5025d0e6

TimerGui
http://pastebin.com/m377c7065

Threads were a real tease for me cause I learned of them on my own too.

1 thing that will help you understand is that a Thread need only contain 1 function and an optional constructor.

public class MyThread extends Thread {
     String text;
     public MyThread(String text) {
           this.text = text;
     }
     public void run() {
          while (text != null)
               System.out.println(text);
     }
}

In this case, I used a constructor to pass the String "text" to the run method of the Thread (indirectly) by widening its scope in the class (this is why its good to make new classes for threads).

To start the thread and make it println "text" forever, I would use:

MyThread thread = new MyThread("HI");
thread.start();

where "HI" is the text I want it to print over and over again and thread is the defined MyThread which I can use later in my code.
or

new MyThread("HI").start();

where there is no "thread" variable -- if you do this, you should be careful that the thread takes care of exiting itself in its run() method.

There are 2 ways to make threads too. There's the way I showed you up top, where you have your class extend Thread and there's the way to make it implement Runnable (not both). To start the thread, you would do this:

new Thread( new Class() which implements Runnable ).start();

Thought I'd clear that up for you as a place to start. Google "java threads" for more info.

when you are finished with your thread, you want to Thread.interrupt() it (depending on what ur doing) and/or Thread.join();

Member Avatar for Ajantis

Yeah, I understand this part. :) Thanks for showing me. However, the thing is - I don't understand how I am supposed to show the time in the GUI. I make a new class for the Threads, and let the constructor have 3 inputs - hour, min, sec.

Now - I can make it partially work well - and make them print in the console, but I don't know how to make them appear on the GUI window. I'm unfamiliar of how data can be passed from classes to threads, and from threads to classes. That's basically my main concern, since I know nothing about it.

Also, as you see - in the SecTimer class, there is a method called "tick()" which is supposed to represent the timer tick, or however you call it in English. :P And... I get confused with this method and threading. If I do finish the method for tick()... then where do threads come in the picture? As they're basically one which SHOULD be "ticking", since I can set them to sleep for a certain amount of time.

So how do I approach the solution of this problem? I also need to know data passing between threads/classes.

Ooooh... seriously, I am totally confused about this one. I really hope I have explained this well. It's hard enough keeping track on all of this. lol

Again, I thank for any help (and your patience lol)

All the thread would have to do is sleep for a second then call the function tick() .

tick() would increment SecTimer's sec, min, or hour vars depending on what the values already are.

Your assignment says that you only need to create another class for the thread, not another file. Make the thread class a subclass of SecTimer. That way you have access to all the SecTimer variables and functions ( the only one you need is tick() ).

start() would initialize and start the thread which calls sleep then tick() in a while loop.
stop() would simply stop that timer, where it is.
reset() would set the sec, min, hr vars to 0 again and
tick() would modify the sec, min, hr variables and call myGUI.printTime(String time), where String time is written in a meaningful way using the sec, min, hr vars.

Try it yourself -- the key is the sleep thread must be a subclass of SecTimer

Member Avatar for Ajantis

Aha, allright! I'll keep that in mind! :) I tried doing as you say - and now I stumbled upon another error, which I don't fully understand either.

Here's my code:
http://pastebin.com/m68348a0f

The error which occurs is that my whole GUI window is copied once - but with no content. When I debugged the application it seemed that the code I wrote at line 71 was the reason behind it. I don't know why it happens or how I can fix it. Can someone explain to me why it happens as it does?

Best wishes

Wheres the subclass?

You are not overriding run() because SecTimer does not extend Thread or implement Runnable..

And what is this:

Runnable runnable = new TimerThreads();
runnable.run();

Read my first post that explains how to create and use threads. You said you understood it. You dont.

Member Avatar for Ajantis

Actually - I figured out the error just some time after I post that message up, but I was too occupied with other things to reply.

No, I should not have used the run method, because it was a method-calling. So, instead I did following...

I made a thread like this:

Thread runnable = new Thread(new TimerThreads());

Then I created it by writing

runnable.start();

Another error I did was, because of my lack of knowledge, is that I let my thread class - TimerThreads - inherit SecTimer. By doing so, that sub-class would call its super-class's constructor when the thread is created - thus I get an extra GUI window. It has now been fixed.

One thing I've come accross now is that, even though I did fix this problem, I still am not getting any output in the textboxes of the GUI. So... the time DOES count, but is not shown properly. Here's my coding:

http://pastebin.com/m64572b8f

This piece of code isnt right for many reasons...

@Override
public void run() {

        Thread runnable = new Thread(new TimerThreads()); //what does this do?
        runnable.start();

       //and why is this running in your main application and not in TimerThreads?
        while (true) {
            try {
               Thread.sleep(1000);                
                tick();
            } catch (Exception e) {
                System.out.println("Something interrupted the sequence." + sec + e);
            }
        }
    }

#1, you are not overriding anything... This run is like a normal function you just happened to call run().

#2, what's in the class TimerThreads? The only class or thread you should be creating is the one running the while loop, yet here's your while loop happening in the same thread as your main application...... Its not showing in the main app because your main app is running in the same thread as your while loop...... It's waiting for it to finish, but it never does. Threads make running several tasks parallel to each other easy because they are asynchronous. Here you have 1 tread running your main app and your while loop, where as your main app should be running in 1 thread, and your while loop in another.

Member Avatar for Ajantis

This piece of code isnt right for many reasons...

@Override
public void run() {

        Thread runnable = new Thread(new TimerThreads()); //what does this do?
        runnable.start();

       //and why is this running in your main application and not in TimerThreads?
        while (true) {
            try {
               Thread.sleep(1000);                
                tick();
            } catch (Exception e) {
                System.out.println("Something interrupted the sequence." + sec + e);
            }
        }
    }

#1, you are not overriding anything... This run is like a normal function you just happened to call run().

#2, what's in the class TimerThreads? The only class or thread you should be creating is the one running the while loop, yet here's your while loop happening in the same thread as your main application...... Its not showing in the main app because your main app is running in the same thread as your while loop...... It's waiting for it to finish, but it never does. Threads make running several tasks parallel to each other easy because they are asynchronous. Here you have 1 tread running your main app and your while loop, where as your main app should be running in 1 thread, and your while loop in another.

1# Nope, I am not overriding anything. I forgot to comment that one away - as I put it earlier when I was testing things.

2# I didn't put up the code for that? Well... must have forgotten then. Here it is, although there is much unnecessary code:

http://pastebin.com/m369402ed

I don't bother removing the redundant coding, until I get this stuff to work in the first place. But I know much is not necessary.

"yet here's your while loop happening in the same thread as your main application......"

Could you please explain to me? I don't understand this part. :)

Best wishes

Member Avatar for Ajantis

Ahhhhh - now I got it! :D

I made a reference to the SecTimer in my TimerThreads class. :)
Then, I made a constructor in my TimerThread class, which takes a SecTimer as input. Now... in the TimerThread class again, I let the input of the constructor given to the reference I made earlier in the class.... and thus... I could use the tick() method in the TimerThread class. :)

Thanks for all your help! Best wishes to you all.
The heck... I learned about programming here more than I ever did in my school. Thanks for it! :)

Glad you got it working :).

Let me show you how I did it with minimal code added to the SecTimer class:

import java.util.Timer;

public class SecTimer {

	cThread thread;        //create the cThread
	private TimerGUI myGUI;
	private int sec;
	private int min;
	private int hour;

	SecTimer(){
		myGUI=new TimerGUI(this);
		sec=0;
		min=0;
		hour=0;
	}

	public void start(){
		myGUI.printTime("start");
		thread = new cThread();   //define it as a new cThread
		thread.start();  //start the cThread
	}

	public void stop(){
		myGUI.printTime("stop");
		if (thread.isAlive())  //check if its alive 
			thread.interrupt();  //if it is, interrupt it
	}

	public void reset(){	
                myGUI.printTime("reset");
	}

	public void lap(){
                myGUI.printLap("lap");
	}

	public void tick(){
                System.out.println("INCREMENT");
	}
	
         //subclasses have access to all the functions in their parent class (tick() from SecTimer)
	public class cThread extends Thread {
		public void run() {
			while (true) {
				try {
					Thread.sleep(1000); 
                                        //calls tick, asynchronous to the main app's thread.
                                        tick();  //prints should be seamless
				} catch (InterruptedException e) {
					killThread(); //kill the thread if its interrupted
				}
			}
		}
		public void killThread() {
			try { 
				this.join();  //gives the thread time to close on its own, cleanly.
			} catch (InterruptedException e) { }
		}
	}
}
Member Avatar for Ajantis

Thanks for the extra info on this! :) I really need it - all information is good! :D just adds to the knowledge! The shorter the code, the greater efficiency.

However, I'm little unsure of so far, is when you use
"this.join();" thing. I don't know what that method does yet.
And why you put it in a separate method. Could you explain? :)

Thread.join() Waits for this thread to die.

Just think about what this thread does.
It does something in a while loop forever while waiting for an InterruptedException.
Once Thread.interrupt() is called, the InterruptedException is caught, forcing out of the while loop and into the function that takes care of the InterruptedException.
The function killThread() simply calls Thread.join() which waits for the thread to die.

So, to stop the thread cleanly, all you have to do is interrupt it :).

I put thread.join() in its own function just to keep it clean and readable. otherwise, there is an exception in and exception which looks messy. Plus, it makes it look more "complete" although thats not what we are aiming for. :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.