Adding functions to Thread class in Java - java

I have written a simple clock class to simulate time I need it to run at the same time as other threads so I made it threaded I have a few extra methods that get units of time used in my system but now I have changed it to a threaded system I can't seem to get hold of them.
Here is the code for the clock class
public class Clock extends Thread {
private Integer seconds;
private Integer minute;
private Integer hour;
public Clock()
{
setClock(0,0,0);
}
public void setClock(int hr, int min, int sec)
{
if(0 <= hr && hr < 24)
{
hour = hr;
}
else
{
hour = 0;
}
if(0 <= min && min < 60)
{
minute = min;
}
else
{
minute = 0;
}
if(0 <= sec && sec < 60)
{
seconds = sec;
}
else
{
seconds = 0;
}
}
public void tick()
{
this.seconds += 5;
this.minute += (int)(this.seconds/60);
this.seconds = this.seconds % 60;
this.hour += (int)(this.minute/60);
this.minute = this.minute % 60;
this.hour = this.hour % 24;
}
public int getMin()
{
return this.minute;
}
public int getHour()
{
return this.hour;
}
public String getTime()
{
return minute.toString() + "m" + seconds.toString() + "s";
}
public void run()
{
tick();
}
}
The three functions above the run are the ones causing the problem I have looked for a solution but can't find one I thought that ´extends´ was like inheritance and it would add those methods to the Thread.
Here is the thread declaration
Thread clock1 = new Clock();
I start it in the normal way of doing start then join as I am running multiple threads.
Thread TestJunc4 = new CarPark(100,TestTemp4,clock1);
I pass the thread into the other threads that need it then try and make a call like this , I am just giving the top part of the statement as the rest doesn't seem important.
while(clock.getHour() != 1)
The problem is I can't call the get methods like the ´getHour´ I am using net beans and when I get the list of functions they don't show up in it and if I add them manual I get the error that it can't find them.

Your Clock class is extending Thread. So and instance of Clock is a Thread too.
This means everywhere, where the java api expects an thread you can pass your clock object. But when you need special methods of your impl. your have to pass it as clock.
Clock clock1 = new Clock();

Related

How should the moveForward(lostTime) give the correct output when the hour and minute variables go below zero?

I knew the method of delaying by minutes, for instance, from 22:50 to 2:10. I inserted 200 in the parameter of delay method, I am concerned that the method of moving the time forward is not working as I attempted by setting the time 1:20 and moving 100 minutes (1 hour and 40 minutes) forward to 23:40. As I tried to run the code, the output displayed 1:40 after moving the time forward. Which line was wrong in the method of moveForward(int lostMinute)?
class Time
{
private int hour; // between 0 - 23
private int minute; // between 0 - 59
public Time()
{
this(0, 0);
}
public Time(int hr, int min)
{
hour = (hr >= 0 && hr < 24) ? hr : 0;
minute = (min >= 0 && min < 60) ? min : 0;
}
public int getHour()
{
return hour;
}
public int getMinute()
{
return minute;
}
public void setHour(int hour)
{
this.hour = (hour >= 0 && hour < 24) ? hour : 0;
public void setMinute(int minute)
{
this.minute = (minute >= 0 && minute < 60) ? minute : 0;
}
public String toString()
{
return String.format("%02d:%02d", hour, minute);
}
public void delay(int newMinute)
{
minute = minute + newMinute;
if(minute >= 60)
{
// (minute / 60) is an integer division and truncates the remainder, which refers to (minute % 60)
hour = hour + (minute / 60);
minute = minute % 60;
if(hour >= 24)
{
hour = hour % 24;
}
}
}
public void moveForward(int lostMinute)
{
if(minute < lostMinute)
{
hour = hour - ((60 + minute) / 60);
minute = (minute + 60) % 60;
if(hour < 0)
{
hour = (24 + hour) % 24;
}
}
else
{
minute = minute - lostMinute;
}
}
}
I saw that delay() is working correctly while moveForward() is not. To make the time notation clearer for sorting, I used String.format("%02d:%02d") to indicate the time between 00:00 and 23:59. Please note that I am not using import java.util.Calender; or 'import java.util.Date; because part of my project consists of sorting an array by just hours and then minutes. For instance, if we are trying to create the bus terminal project, we assume that the date and calendar do not matter in schedule.
public class MainTime
{
public static void main(String[] args)
{
Time t1 = new Time(23:50);
Time t2 = new Time(1:20);
Time t3 = new Time(4:50);
Time t4 = new Time(18:30);
Time t5 = new Time(14:15);
t1.delay(200);
t2.moveForward(100);
t3.delay(100);
t4.moveForward(20);
t5.moveForward(160);
System.out.println(t1.toString());
System.out.println(t2.toString());
System.out.println(t3.toString());
System.out.println(t4.toString());
System.out.println(t5.toString());
}
}
The constraints are when the change in time is greater than the minute in parameter and when the hour is going to zero. When I ran the code in NetBeans, t1 had 2:10 when I added 200 into 23:50 in delay(newMinute) method; t2 had 1:40 when I subtracted 100 from 1:20 in moveForward(lostMinute) method; t3 had 6:30 when I added 100 into 4:50 in delay(newMinute); t4 had 18:10 when I subtracted 20 from 18:30 in moveForward(lostMinute); t5 had 14:-25 when I subtracted 160 from 14:15 in moveForward(lostMinute). The variables t2 and t5 after execution should actually be 23:40 and 11:35, respectively.
Please determine which lines in public void moveForward(int lostMinute) make the improper output after subtracting the minutes from given time.
In case the minute goes to zero, 60 and modulo notation % could be useful; in case the hour goes to zero, 24 and modulo notation % could be useful. I hope for the moveForward(lostMinute) to work well in the cases when minute < 0 and when hour < 0.
java.time
LocalTime t1 = LocalTime.of(23, 50);
t1 = t1.plusMinutes(200);
System.out.println(t1.toString()); // 03:10
LocalTime t2 = LocalTime.of(1, 20);
t2 = t2.minusMinutes(100);
System.out.println(t2.toString()); // 23:40
LocalTime t3 = LocalTime.of(4, 50);
t3 = t3.plusMinutes(100);
System.out.println(t3.toString()); // 06:30
LocalTime t4 = LocalTime.of(18, 30);
t4 = t4.minusMinutes(20);
System.out.println(t4.toString()); // 18:10
LocalTime t5 = LocalTime.of(14, 15);
t5 = t5.minusMinutes(160);
System.out.println(t5.toString()); // 11:35
Output is given as comments. I think it is what you wanted. So don’t reinvent the wheel. Instead of rolling your own Time class, use LocalTime. It’s there for you to use, it has been developed and tested for you. LocalTime is a time of day in the interval from 00:00 to 23:59:59.999999999. Except that it include seconds and fraction of second it coincides with your interval. If you never set the seconds to something other than 0, they won’t be printed through the toString method. Also LocalTime implements Comparable, so sorting is straightforward.
Be aware that a LocalTime object is immutable, so instead of mutator methods it has methods that return a new LocalTime object with the new value. This is already demonstrated with plusMinutes and minusMinutes above. Also instead of myLocalTime.setHour(17); you need myLocalTime = myLocalTime.withHour(17);, etc.
What went wrong in your code?
Your moveForward method seems to be handling the hour correctly in the case where it is to be moved back to the previous hour, for example from 14:05 to 13:55 or from 14:55 to 13:05. In this case you are never subtracting lostMinutes, which I think you should somehow. When minute is 0–59, then ((60 + minute) / 60) will always be 1, so you are always subtracting exactly 1 hour, never 2 or more.
Genrally the expected ranges of the arguments to both delay and moveForward are unclear. I think they should have been documented and the arguments validated against the documented limits.
Link
Oracle tutorial: Date Time explaining how to use java.time.

Getting "Exception in thread "main" java.lang.StackOverflowError" and a lot of errors [duplicate]

This question already has answers here:
What is a StackOverflowError?
(16 answers)
Closed 6 years ago.
I'm really new to programming, and I'm working on a java assignment for school and I know That i got most of the code I've written wrong, but it's the first time I've really attempted anything like this.
I'm trying to trouble shoot, but i get the error
Exception in thread "main" java.lang.StackOverflowError
at a07.Time.(Time.java:27)
at a07.Time.(Time.java:27)
at a07.Time.(Time.java:27)
This continues for quite some time.
I was hoping someone could tell me the cause of the problem so i could start fixing.
Public class Time {
private int hour;
private int minute;
public static final int MIN_HOUR = 0;
public static final int MIN_MINS = 0;
public Time(int hours, int mins) {
minute = mins;
hour = hours;
Time t = new Time(hour, minute);
t.fixME();
}
private void fixME() {
int minEx = minute / 60;
int minLeft = minute % 60;
int newHour = hour + minEx;
minute = minLeft;
hour = newHour;
if (minute < MIN_MINS) {
int subHour = hour - 1;
int minNew = minute + 60;
hour = subHour % 24;
minute = minNew;
if (hour < MIN_HOUR) {
int hourUp = hour + 24;
hour = hourUp;
}
}
}
public int getHour() {
return hour;
}
public int getMinute() {
return minute;
}
public Time addMinutes(int mins) {
int newMinute = minute + mins;
minute = newMinute;
Time g = new Time(hour, mins);
return g;
}
public void print() {
if (hour == 0) {
System.out.printf("12:" + "%02f", minute + " AM");
}
if (hour != 0 && hour < 10) {
System.out.printf("0" + hour + ":" + "%02f", minute + " AM");
}
if (hour >= 10 && hour < 12) {
System.out.printf(hour + ":" + "%02f", minute + " AM");
}
if (hour >= 12) {
int pmHour = hour - 12;
if (pmHour == 0) {
System.out.printf("12:" + "%02f", minute + " PM");
} else if (pmHour < 12) {
System.out.printf(pmHour + ":" + "%02f", minute + " PM");
}
}
}
}
Sorry it's not formatted very well.
Any ideas?
Thanks.
The problem is in your constructor:
public Time(int hours, int mins) {
minute = mins;
hour = hours;
Time t = new Time(hour, minute);
t.fixME();
}
You're calling the constructor again with the line Time t = new Time(hour, minute), so you're stuck in an infinite recursive loop where you keep calling the function over and over again until your stack overflows. You don't actually need this line; you can just do the following:
public Time(int hours, int mins) {
minute = mins;
hour = hours;
fixME();
}
I don't think you fully understand how objects and constructors work though, you should probably try going through this: https://docs.oracle.com/javase/tutorial/java/javaOO/

Looped Accelerometer Data Calculations Android SDK

I've been struggling with an app for fall detection for quite some time now. The app runs, but it will freeze up at times, and then resume 10-15 seconds after.
My approach is to do integral calculations (which means I had to import a third party library: Apache Commons). For these integral calculations I need norm values.
I'm calling a method for calculating the norm when the sensor updates:
public void onSensorChanged(SensorEvent event){
acceleration.setText("\n " + event.values[0] + " , " + event.values[1] + " , " + event.values[2] + " \n");
x = event.values[0];
y = event.values[1];
z = event.values[2];
if (!checkFall)
sample(x, y, z);
}
calling the sample function makes the app run slow (visible through setting text on UI).
Sample which is seemingly the root of my problems looks like this:
private void sample(double x, double y, double z)
{
if(xList.size() < 120 && yList.size() < 120 && zList.size() < 120)
{
xList.add(x);
yList.add(y);
zList.add(z);
}
if(xList.size() == 120)
{
for (int j = 0; j < norm.length; j++)
{
norm[j] = sqrt(pow(xList.get(j), 2) + pow(yList.get(j), 2) + pow(zList.get(j), 2));
for(int p = 0; p < norm.length-1; p++)
{
for(int q = 0; q < diff.length; q++)
{
diff[q] = norm[p] - norm[p+1];
}
}
if (norm[j]/9.81 < 0.5)
{
final counterClass timer = new counterClass(4000, 20, norm, diff);
checkFall = true;
timer.start();
// if exceeded three times, save the arrayList and register fall
}
}
(I've tried disabling the timer call when the if statement norm[j]/9.81 < 0.5 has been met, because I thought the error may be in a function that a countdown timer is calling) - but to no help, the app freezes whenever the norm approaches 0.
There are no obvious errors in the logcat, which is why I'm having a hard time narrowing down where the error is. Perhaps I'm accessing the arrays in a terrible way?
If there is any missing information you'd like me to provide or if my questions is too vague, please let me know.
EDIT:
Counter Class
public counterClass(long millisInFuture, long countDownInterval, double[] norm, double[] diff) {
super(millisInFuture, countDownInterval); // Duration & how often onTick should be called
nor = norm;
dif = diff;
}
public void onTick(long millisUntilFinished) {
listFall(); // Adding accelerometer data to fall list array List each time its called
new Thread(new Runnable() {
#Override
public void run() {
vCheck(nor,dif);
}
}).start();
}

Creating a java Clock. increasing time

I am creating a clock in Java. I have managed to do some very basic stuff and now i want to implement a function.
If i set the time to i.e. 12:04:59 and use my timeTick Method it will increase the time with 1 second but the problem is it will say the time is 12:04:60 and it doesn't change to 12:05:00.
I've been struggling a while now and i can't really find a solution to it.
My code is below, i hope you can help me,
public class Clock{
public int seconds;
public int minutes;
public int hours;
public Clock ( int InsertSeconds, int InsertMinutes, int InsertHours){
seconds = InsertSeconds;
minutes = InsertMinutes;
hours = InsertHours;
}
public void timeTick(){
seconds = seconds + 1;
}
public String toString(){
return hours + ":" + minutes + ":" + seconds;
}
}
I am not planning to use Imports because i am a beginner it would be great if we can keep it simple.
The problem here lays in the timeTick() function. In a real clock example we have some extra rules for counting. Every time we count to 60 seconds, we add a minute. Every time we count to 60 minutes, we add an hour. So you have to implement these rules.
// lets make some simple code
public void timeTick(){
seconds = seconds + 1; // you can also use seconds++; it means exactly the same thing
if(seconds == 60){
minutes++; // we reached a minute, we need to add a minute
seconds = 0; // we restart our seconds counter
if(minutes == 60){
hours++; // we reached an hour, we need to add an hour
minutes = 0; // we restart our minutes counter
// and so on, if you want to use days (24 h a day) , months ( a bit more difficult ), ...
}
}
}
I hope this will help you, for a starter it might be a good idea to split the second part of code into a function, which deals with this situation. Good luck!
How about this:
public void timeTick () {
seconds++;
while (seconds >= 60) {
minutes++;
seconds-=60;
}
while (minutes >= 60) {
hours++;
minutes-=60;
}
}
Try this :
public void timeTick () {
seconds++;
if (seconds == 60)
{
seconds = 0;
minutes++;
if (minutes == 60)
{
minutes = 0;
hours++;
}
}
}
try this:
public class Clock{
public int seconds;
public int minutes;
public int hours;
public Clock ( int InsertSeconds, int InsertMinutes, int InsertHours){
seconds = InsertSeconds;
minutes = InsertMinutes;
hours = InsertHours;
}
public void timeTick(){
seconds = seconds + 1;
if(seconds==60){
minutes++;
seconds=0;
if(minutes==60){
hours++;
minutes=0;
}
}
}
public String toString(){
return hours + ":" + minutes + ":" + seconds;
}
}
You could check for when you have 60 seconds, then reset seconds to zero, and increase minutes by 1. e.g.
if (the condition you want to check) {
//increase the number of minutes.
//reset number of seconds.
}
If you're entering seconds values of more than 60, you'll need to work out how many minutes that equals using division, and the remaining number of seconds using the modulus operator: % e.g.
seconds = 125;
minutes = seconds / 60; // 2 minutes
remaining_seconds = seconds % 60; // 5 seconds

Java countdown time doesnt display correct time

Im currently working on a project that has a simple countdown where the user enters a time and it starts counting down from that time. it is GUI based and displays the countdown to the user. ive managed to make it count down but its not displaying correctly.
For example, if i enter 1min 30secs, it counts down from 1:30, to 1:01 then incorrectly displays 0:00 then it counts down from 0:59. it is correct until i get to a point where the minutes change to seconds and it doesnt display correctly for 1 second.
Countdown class:
class countdownClass implements ActionListener { //counts down then beeps
int counter;
public countdownClass(int counter) {
this.counter = counter;
}
public void actionPerformed(ActionEvent sc) { //counts down every second
counter--;
if(counter >= 1) { //a simple countdown
if(counter > 9){ //this statement is for aestetic purpose as before
seconds.setText("" + counter);
}else{
seconds.setText("0" + counter);
}
}
else if(minutesNum >= 1 && counter <= 0){ //if minute exists carry on the countdown
// 1:01 - > 1:00 - > 0:59
int minuteUpdate = minutesNum - 1;
if (minutesNum < 9){
minutes.setText("0" + Integer.toString(minutesNum));
seconds.setText("00");
if(counter <= 0){
minutes.setText("0" + Integer.toString(minuteUpdate));
}
}else{
minutes.setText("0" + Integer.toString(minutesNum));
seconds.setText("0" + Integer.toString(00));
minutes.setText("0" + Integer.toString(minuteUpdate));
}
counter = 60;
}
else if(minutesNum == 0 && counter == 0) { //once the countdown ends plays a beep
timer.stop();
seconds.setText("00");
finish.setText("Time is up!");
start.setEnabled(true);
try{
clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File("ring.wav")));
clip.start();
soundPlay = true;
}
catch (Exception e){
e.printStackTrace(System.out);
}
}
}
}
could you please help me identify where the code is going wrong and provide me with a fix for it.
Thanks for your time.
Your code looks a little over-engineered. Just convert the user-entered time into seconds and decrement that value every second. Then print the result with something like:
private static String secondsToMinutesAndSeconds(int time) {
int minutes = time / 60;
int seconds = time % 60;
return String.format("%02d:%02d", minutes, seconds);
}
E.g. 1 minute 30 seconds is just 90 seconds. Pass 90 into the above method and you get 01:30. If you need the minute and second values individually, it should be easy enough to edit that code example.
It appears that the minutes digit displayed is minuteUdpate which is set to one less than MinutesNum.
else if(minutesNum >= 1 && counter <= 0){ //if minute exists carry on the countdown
// 1:01 - > 1:00 - > 0:59
int minuteUpdate = minutesNum - 1;
if (minutesNum < 9){
minutes.setText("0" + Integer.toString(minutesNum));
seconds.setText("00");
if(counter <= 0){
minutes.setText("0" + Integer.toString(minuteUpdate));
}
}else{
minutes.setText("0" + Integer.toString(minutesNum));
seconds.setText("0" + Integer.toString(00));
minutes.setText("0" + Integer.toString(minuteUpdate));
}
counter = 60;
minutesNum is less than 9, and counter = 0 for 1:00, so this line should be done:
minutes.setText("0" + Integer.toString(minuteUpdate));
I'd remove that if block. The minutes number should not be decremented before the seconds number is changed to 60.
For me, your code is useless complex.
What you should do:
Use two variables to save minutes and seconds.
The start value of there two variables will be what the users put (Examples if its 3:50, minutes will be 3, second will be 50)
Start a timer every second, scale 1 second from counter and if seconds is <= 0, scale minutes and put seconds to 59. If minutes is 0 and seconds.
It's just a concept to show my idea:
private static int minutes = 0;
private static int seconds = 5;
private static Timer timer;
private static TimerTask task = new TimerTask()
{
#Override
public void run()
{
if (countdown())
System.out.println(minutes + ":" + seconds);
else
{
System.out.println("Finish!");
timer.cancel();
}
}
};
private static boolean countdown()
{
seconds --;
if (seconds < 0)
{
minutes--;
seconds = 59;
if (minutes == -1)
{
return false;
}
}
return true;
}
public static void main(String[] args)
{
timer = new Timer();
timer.schedule(task, 0, 1000);
}
You could work with seconds only and avoid the minutes variable.
(Example: 1 min => 60 seconds; and then use a method to fix it using division)
It's my first time i use ScheduledThreadPoolExecutor so it could not be perfect.
private static int minutes = 0;
private static int seconds = 5;
private static ScheduledThreadPoolExecutor executorService;
private static boolean countdown()
{
seconds --;
if (seconds < 0)
{
minutes--;
seconds = 59;
if (minutes == -1)
{
return false;
}
}
return true;
}
private static Runnable task = new Runnable()
{
#Override
public void run()
{
if (countdown())
System.out.println(minutes + ":" + seconds);
else
{
System.out.println("Finish!");
// by throwing an exception we will stop the countdown
throw new RuntimeException();
}
}
};
public static void main(String[] args)
{
executorService = new ScheduledThreadPoolExecutor(1);
executorService.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
try
{
// schedulate again the countdown
System.out.println("Wait 7 seconds");
Thread.sleep(7000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Schedulate again");
// since we work with the original values
// we must reset it
minutes = 0;
seconds = 5;
executorService.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
}
Remember: this code don't work if multi threads calls countdown method!
Anyway, you can use executorService.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS); to restore the countdown.

Categories