Failed to override toString method - java

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()

Related

Returning Value from ActionListener

I have a method that implements ActionListener. At the bottom of the class I have some get methods. However whenever I call the get methods in another class, I get a NullPointerException.
package com.FishingGame.Screen;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class HandleActions implements ActionListener{
private boolean goFishing = false, sell = false, checkW = false;
private int test = 12;
public HandleActions(){
}
void resetAllVars(){
goFishing = false;
sell = false;
checkW = false;
}
public void actionPerformed(ActionEvent e) {
String bSource = e.getActionCommand();
resetAllVars();
if(bSource == "go fishing"){
System.out.println("1");
goFishing = true;
}else if(bSource == "sell"){
System.out.println("2");
sell = true;
}else if(bSource == "check weather"){
System.out.println("3");
checkW = true;
}
}
public boolean getGoFishing(){
return goFishing;
}
public boolean getSell(){
return sell;
}
public boolean getCheckW(){
return checkW;
}
public int getTest(){
return test;
}
}
public class Game implements Runnable {
HandleActions h;
Window w;
public Game() {
w = new Window(600, 400, "Game");
w.add(w.mainScreen());
w.setVisible(true);
System.out.println(h.getTest());
}
Thread thread = new Thread(this);
#Override
public void run() {
}
public static void main(String args[]) {
Game g = new Game();
}
}
The console says the error is coming from the h.getTest() call. Is it something to do with the fact that the HandleActions class implements ActionListener. I can return values just fine from other classes.
the variable is uninitialized
HandleActions h;
public Game() {
h =new HandleActions(); //initialize
...
}

Dispatch an event to main java

I have a CountDownTimer class that when it finishes counting down it should dispatch an event to main java (or any class that uses it) letting it know it has finished.
Here is my class:
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Label;
public class CountTimer {
private Label targetText;
private String direction;
private int minutes;
private int seconds;
private int totalSeconds;
private int timeTotal;
private int timeLoaded;
private Boolean test;
Timer timer;
public CountTimer(int min,int sec,String dir,Label targetTextField)
{
minutes = min * 60;
seconds = sec;
timeTotal = minutes + seconds;
if (dir == "down") {
totalSeconds = minutes + seconds;
}
else {
totalSeconds = 0;
}
if (targetTextField != null) {
targetText = targetTextField;
}
direction = dir;
}
public void start()
{
timer = new Timer(){
public void run(){
timeLoaded += 1;
if (direction == "up") {
totalSeconds++;
}
else {
totalSeconds--;
}
seconds = totalSeconds % 60;
minutes = (int) Math.floor(totalSeconds / 60);
String minutesDisplay = (minutes < 10) ? "0" + Integer.toString(minutes) : Integer.toString(minutes);
String secondsDisplay= (seconds < 10) ? "0" + Integer.toString(seconds): Integer.toString(seconds);
if (targetText != null) {
targetText.setText( minutesDisplay + ":" + secondsDisplay);
}
if (test=true) {
consoleLog(minutesDisplay + ":" + secondsDisplay);
}
if(timeTotal == timeLoaded) {
//DISPATCH CUSTOM EVENT TO MAIN.JAVA HERE
Window.alert("OK");
timer.cancel();
}
}
};
timer.scheduleRepeating(1000);
}
public int getTimeTotal()
{
return timeTotal;
}
public int getTimeLoaded()
{
return timeLoaded;
}
public int getProg()
{
return (int) Math.floor(timeLoaded/timeTotal*100);
}
public native final void consoleLog(String msg)/*-{
console.log(msg);
}-*/;
}
Please help, how can i do this?
I believe you are looking to implement the Publish-Subscribe pattern.
http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern
You can allow your object to have subscribers register with it. Once you have finished your operation it can then notify the subscribers that it has finished.
Example:
public interface Subscriber {
public void notify();
}
public class Publisher {
private ArrayList<Subscriber> subscribers = new ArrayList<>();
public void addSubscriber(Subscriber s) {
subscribers.add(s);
}
public void doWork() {
System.sleep(100);
notifyAll();
}
private void notifyAll() {
for(Subscriber s : subscribers) {
s.notify();
}
}
}
There are several options.
If you have this requirement frequently, or you need to notify multiple Activities/widgets, you may consider using an EventBus:
How to use the GWT EventBus
Alternatively, your CountTimer can simply call a public static method in your main class:
MyApp.doSomething();

How to dynamically override a method in an object

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;
}
};

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