How to dynamically override a method in an object - java

If this is possible, how can I change what a method does after I might have created an instance of that class and wish to keep the reference to that object but override a public method in it's class' definition?
Here's my code:
package time_applet;
public class TimerGroup implements Runnable{
private Timer hour, min, sec;
private Thread hourThread, minThread, secThread;
public TimerGroup(){
hour = new HourTimer();
min = new MinuteTimer();
sec = new SecondTimer();
}
public void run(){
hourThread.start();
minThread.start();
secThread.start();
}
/*Please pay close attention to this method*/
private Timer activateHourTimer(int start_time){
hour = new HourTimer(start_time){
public void run(){
while (true){
if(min.changed)//min.getTime() == 0)
changeTime();
}
}
};
hourThread = new Thread(hour);
return hour;
}
private Timer activateMinuteTimer(int start_time){
min = new MinuteTimer(start_time){
public void run(){
while (true){
if(sec.changed)//sec.getTime() == 0)
changeTime();
}
}
};
minThread = new Thread(min);
return min;
}
private Timer activateSecondTimer(int start_time){
sec = new SecondTimer(start_time);
secThread = new Thread(sec);
return sec;
}
public Timer addTimer(Timer timer){
if (timer instanceof HourTimer){
hour = timer;
return activateHourTimer(timer.getTime());
}
else if (timer instanceof MinuteTimer){
min = timer;
return activateMinuteTimer(timer.getTime());
}
else{
sec = timer;
return activateSecondTimer(timer.getTime());
}
}
}
So for example in the method activateHourTimer(), I would like to override the run() method of the hour object without having to create a new object. How do I go about that?

No you can not override same method more then one time in the same class and you are creating an annonymous class of HourTimer.
hour = new HourTimer(start_time){
public void run(){
while (true){
if(min.changed)//min.getTime() == 0)
changeTime();
}
}
};
you can do it in another way by putting an if else condition inside activateHourTimer method as fallows-
private Timer activateHourTimer(int start_time){
if(Condition1){
hour = new HourTimer(start_time){
public void run(){
while (true){
//First Condition
}
}
};
}else if(Condition2){
hour = new HourTimer(start_time){
public void run(){
while (true){
//Second Condition
}
}
};
}else{
hour = new HourTimer(start_time){
public void run(){
while (true){
//Third Condition
}
}
};
}
hourThread = new Thread(hour);
return hour;
}

You can't override a method of a local (anonymous) class, but you can override the whole method via an anonymous class:
TimerGroup customTimerGroup = new TimerGroup() {
private Timer activateHourTimer(int start_time) {
hour = new HourTimer(start_time){
public void run() {
// do something different
}
};
hourThread = new Thread(hour);
return hour;
}
};

Related

Class countdown timer doesn't reset

I have a class countdown timer that I want to reset but when it resets it wont start again.
Basicaly when the counter gets to 0 (when the status is "done"), sets x = 1 and then in the activity checks if x = 1 , and then the counter resets. When the reset method from within the class is called it shows that it has reset but it wont start counting again
Timer class:
public class countdown_timer {
private long pls;
private long millisInFuture;
private long countDownInterval;
private boolean status;
int x = 0;
public countdown_timer(long pMillisInFuture, long pCountDownInterval) {
this.millisInFuture = pMillisInFuture;
this.countDownInterval = pCountDownInterval;
this.pls = pMillisInFuture;
status = false;
Initialize();
}
public void Stop() {
status = false;
}
public int GetNumberX() {
return x;
}
public void Reset() {
millisInFuture = pls;
x=0;
}
public void Start() {
status = true;
}
public void Initialize() {
final Handler handler = new Handler();
Log.v("status", "starting");
final Runnable counter = new Runnable() {
public void run() {
long sec = millisInFuture / 1000;
if (status) {
if (millisInFuture <= 0) {
Log.v("status", "done");
x = 1;
} else {
Log.v("status", Long.toString(sec) + " seconds remain");
millisInFuture -= countDownInterval;
handler.postDelayed(this, countDownInterval);
}
} else {
Log.v("status", Long.toString(sec) + " seconds remain and timer has stopped!");
handler.postDelayed(this, countDownInterval);
}
}
};
handler.postDelayed(counter, countDownInterval);
}
Activity that uses the timer class:
mycounterup = new countdown_timer(startcard, 1000);
xup = mycounterup.GetNumberX();
if (xup == 1) {
mycounterup.Reset();
mycounterup.Start();
Thanks for any help.
try changing your start method as and one thing more i don't know if its a typo or what change mycounter.Start(); to mycounterup.Start();
public void Start() {
status = true;
Initialize();
}
save the counter state so that next time if you have to pause or resume the thing you are able to do it also
You should change your Reset method:
public void Reset() {
millisInFuture = pls;
x=0;
Initialize();
}

Java simultaneous execution

I am trying execute two jobs simultaneously. One of the things that I am trying to do is displaying a count up timer and the other one is moving the ball.
This is where I create the timer and also call the moveBall method
button.addChangeListener(new ChangeListener() {
int start = 0;
public void stateChanged(ChangeEvent e) {
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
timeValue.setText(++start + " sec");
}
};
timer = new Timer(1000, taskPerformer);
timer.start();
ball.moveBall();
}
});
This is my moveBall method
public void moveBall() {
Thread ball = new Thread() {
double counter = 0;
int t = (int) (2 * Vy / 9.8);
public void run() {
try {
while (t >= 0) {
// calculate Vx and Vy
Ball.this.setX(Ball.this.getX() + Vx);
Ball.this.setY(Ball.this.getY() - Vy);
counter += 50;
if (counter == 1000) {
t--;
counter = 0;
}
paintingComponent.repaint();
Thread.sleep(20);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
ball.start();
}
When I execute the above code the label for displaying the time passed is not changing at all during the ball is moving and when the movement is over it takes the last number that it supposed to take.
This is a example two executions of two threads, Java simultaneous execution
public class ThreadExecutor extends Thread {
private String name;
private int executionCount;
public ThreadExecutor(final String name, final int executionCount) {
this.name = name;
this.executionCount = executionCount;
}
#Override
public void run() {
int count = 1;
while (count <= executionCount) {
System.out.println("Executing thread ".concat(name).concat(" : ") + count);
count++;
}
}
}
public class Main {
public static void main(String args[]) {
final ThreadExecutor one = new ThreadExecutor("One", 1);
final ThreadExecutor two = new ThreadExecutor("Two", 2);
one.start();
two.start();
}
}

Failed to override toString method

I wrote a timer class. And I want to override its toString method. But when I call the toString method, it still returns the super implementation. (fully qualified name of the class)
Here is my timer class:
import android.os.Handler;
import android.widget.TextView;
public class Timer implements Comparable<Timer> {
private Handler handler;
private boolean paused;
private TextView text;
private int minutes;
private int seconds;
private final Runnable timerTask = new Runnable () {
#Override
public void run() {
if (!paused) {
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
}
text.setText (toString ()); //Here I call the toString
Timer.this.handler.postDelayed (this, 1000);
}
}
};
//Here is the toString method, anything wrong?
#Override
public String toString () {
if (Integer.toString (seconds).length () == 1) {
return minutes + ":0" + seconds;
} else {
return minutes + ":" + seconds;
}
}
public void startTimer () {
paused = false;
handler.postDelayed (timerTask, 1000);
}
public void stopTimer () {
paused = true;
}
public void resetTimer () {
stopTimer ();
minutes = 0;
seconds = 0;
text.setText (toString ()); //Here is another call
}
public Timer (TextView text) {
this.text = text;
handler = new Handler ();
}
#Override
public int compareTo(Timer another) {
int compareMinutes = ((Integer)minutes).compareTo (another.minutes);
if (compareMinutes != 0) {
return compareMinutes;
}
return ((Integer)seconds).compareTo (another.seconds);
}
}
I can see that the text view's text is the fully qualified name of the Timer class. I even tried this.toString but it doesn't work either.
You're calling toString() from your anonymous inner class - the new Runnable() { ... }. That means you're calling toString() on your anonymous class instance, not on the Timer instance. I suspect you're getting a $1 in the output, showing that it's an anonymous inner class.
Try:
text.setText(Timer.this.toString());
... so that you call it on the enclosing Timer instance instead.
Here's a short but complete console app to demonstrate the difference:
class Test
{
public Test() {
Runnable r = new Runnable() {
#Override public void run() {
System.out.println(toString()); // toString on anonymous class
System.out.println(Test.this.toString()); // toString on Test
}
};
r.run();
}
public static void main(String[] args) {
new Test();
}
#Override public String toString() {
return "Test.toString()";
}
}
Output:
Test$1#15db9742
Test.toString()

Progressbar: how to create deep copy of original object

I'm trying to use a progress bar similar to this one below in Java:
public class MyProgressSplashScreen extends JWindow
{
private final JProgressBar progressbar;
private final ExecutorService autoProgressExecutor = Executors.newFixedThreadPool(1);
public MyProgressSplashScreen(final int theMin, final int theMax)
{
super();
final JPanel contentPanel = new JPanel(new BorderLayout());
contentPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
if (theMin != -1 && theMax != -1)
{
progressbar = new JProgressBar(SwingConstants.HORIZONTAL, theMin, theMax);
}
else
{
progressbar = new JProgressBar(SwingConstants.HORIZONTAL);
progressbar.setIndeterminate(true);
}
progressbar.setStringPainted(true);
contentPanel.add(progressbar, BorderLayout.SOUTH);
add(contentPanel);
pack();
setAlwaysOnTop(true);
}
public void showProgress(final int theValueTo, final int theEstimatedTimeInSeconds)
{
showProgress(progressbar.getValue(), theValueTo, theEstimatedTimeInSeconds);
}
public void showProgress(final int theValueFrom, final int theValueTo,
final int theEstimatedTimeInSeconds)
{
setVisible(true);
autoProgressExecutor.execute(new Runnable()
{
#Override
public void run()
{
int numberOfSteps = theValueTo - theValueFrom;
long timeToWait = TimeUnit.SECONDS.toMillis(theEstimatedTimeInSeconds)
/ numberOfSteps;
for (int i = theValueFrom; i <= theValueTo; i++)
{
progressbar.setValue(i);
try
{
TimeUnit.MILLISECONDS.sleep(timeToWait);
}
catch (final InterruptedException e) { }
}
if (progressbar.getValue() == 100) { setVisible(false); }
}
});
}
}
I am however not able to pass a copy of the MyProgressSplashScreen in order to let a separate thread update the progress.
For instance the program below starts counting from 0 to 10 and then restarts from 0 to 30 while it shouldn't reset to zero!
public class TestSplashScreen
{
private final MyProgressSplashScreen myProgressSplashScreen = new MyProgressSplashScreen(-1,-1);
public static void main(String args[])
{
TestSplashScreen testInvoke = new TestSplashScreen();
testInvoke.synchronize();
}
public void synchronize()
{
Runnable runnable = new Runnable()
{
#Override
public void run()
{
myProgressSplashScreen.showProgress(10, 2);
myProgressSplashScreen.toFront();
MyRunnable myRunnable = new MyRunnable();
myRunnable.setSyncProgressSplashScreen(myProgressSplashScreen);
Thread t1 = new Thread(myRunnable);
t1.start();
}
};
runnable.run();
}
}
class MyRunnable implements Runnable
{
MyProgressSplashScreen syncProgressSplashScreen;
public void setSyncProgressSplashScreen(MyProgressSplashScreen syncProgressSplashScreen)
{
this.syncProgressSplashScreen = syncProgressSplashScreen;
}
#Override
public void run()
{
syncProgressSplashScreen.showProgress(30, 3);
}
}
The problem is you call syncProgressSplashScreen.showProgress 2 times. The first time it blocks the thread causing it to increment from 0 to 10 then you call it again going from 0 to 30. Remove the line that reads myProgressSplashScreen.showProgress(10, 2); and it wont do it 2 times. Also I noticed you dont set your maximum value for the progress bar so unless you call myProgressSplashScreen.showProgress(100, 2) it wont go to 100%.

java swing timer not going off

I can't seem to get this timer to go off. the program compiles and from my understanding this should ping every 1000ms or 1 second and perform the lines in the actionPerformed{} function.
public void stringGeneration(String args[]){
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
String fullIstring = java.lang.String.valueOf(injectString[0] + injectString[1] + injectString[2] + injectString[3] + injectString[4]);
jLabel3.setText(fullIstring);
System.out.println("output");
}
};
Timer timer = new Timer(1000, taskPerformer);
timer.setRepeats(true);
timer.start();
//Thread.sleep(500);
}
i just gave you an example and not something to copy paste. But you can try this if you want to try as is. In your case the above example should look like:
class HeartBeatTask extends TimerTask {
private int timerInterval;
public HeartBeatTask(int timeInterval)
{
this.timerInterval = timeInterval;
}
public void run()
{
String fullIstring = java.lang.String.valueOf(injectString[0] + injectString[1] + injectString[2] + injectString[3] + injectString[4]);
jLabel3.setText(fullIstring);
System.out.println("output");
}
}
Your method will then call the above class like this:
public void stringGeneration(String args[]){
HeartBeatTask tt = new HeartBeatTask();
t1.schedule(tt, 0, 1000 * 60 * 2);
}
This is how i would to a scheduled task in java:
import java.util.TimerTask;
class HeartBeatTask extends TimerTask
{
private int timerInterval;
public HeartBeatTask(int timeInterval)
{
this.timerInterval = timeInterval;
}
public void run()
{
// Your function call to schedule here
}
public static void main(String[] args)
{
java.util.Timer t1 = new java.util.Timer();
HeartBeatTask tt = new HeartBeatTask();
t1.schedule(tt, 0, 1000 * 60 * 2);
}
}
Hope that helps

Categories