I'm working on an application that simulated process of writing text message on mobile phone. On the canvas I first draw already typed message. If any and on button pressed I retrieve correct set of characters. Here I'm able to loop through them and highlight currently active/selected character. However I need to hide this set of characters lets say after 2 sec. I made two attempt to solve this problem but both do not work properly.

Timer

public void keyPressed(int key)
    {
        //Rest of the function that is not relevant to problem
        charSet = true;
        repaint();
        
        if(nml.getThreadState()) // boolean check, if true execute
        {
            System.out.println("Cancel timer");
            timeTask.cancel();
            System.out.println("Start new timer");
            tk = new TimeKeeping();
            timeTask.schedule(tk, 2000);  
            System.out.println("New timer started");            
        }
        else
        {
            System.out.println("Start new timer");
            tk = new TimeKeeping();
            timeTask.schedule(tk, 2000);  
            System.out.println("New timer started");
            
        }
    }

private class TimeKeeping extends TimerTask
    {
        public void run()
        {
            nml.setThreadState(true);
            charSet = false;
            selChar = 0;
            charArr = null;
            lastChar = 0;
            nml.setThreadState(false);
            repaint();
            System.out.println("Timer expired");
        }
    }

In this case I'm hardly able to reach 4th character before all is reset to zero. It leaves an impression timeTask.cancel() was not executed at all and the first invoked Timer just expired and executed content of run() method.

Thread

public void keyPressed(int key)
    {
        //Rest of the code
        charSet = true;
        repaint();
        System.out.println("Number of active threads before is statement = "+Thread.activeCount());
        if(nml.getThreadState())
        {
            timeTask.interrupt();
            try
            {
                timeTask.start();
            }
            catch(IllegalThreadStateException itse)
            {
                
            }
        }
        else
        {
            try
            {
                timeTask.start();
            }
            catch(IllegalThreadStateException itse)
            {
                
            }
        }
    }

private class TimeKeeping extends Thread
    {
        public void run()
        {
            System.out.println("Number of active threads before run = "+Thread.activeCount());
            nml.setThreadState(true);
            try
            {
                Thread.sleep(2000);
            }
            catch(InterruptedException ie)
            {
            }            
            catch(IllegalMonitorStateException imse)
            {                
            }
            finally
            {
                charSet = false;
                selChar = 0;
                charArr = null;
                lastChar = 0;
                nml.setThreadState(false);
                repaint();
                System.out.println("Timer expired");
                notifyAll();
            }
        }
    }

In this scenario I'm able to loop through all characters, however when sleep time should expire the character set does not hide as if repaint method is never called. Bellow is small example of messages that I receive during execution

Number of active threads before is statement = 2
Number of active threads after if = 3
Number of active threads before run = 3
Number of active threads before is statement = 2
Number of active threads after if = 3
Uncaught exception java/lang/IllegalMonitorStateException.
Timer expired
Number of active threads before is statement = 2
Number of active threads after if = 2
Number of active threads before is statement = 2
Number of active threads after if = 2
Execution completed.

I'm not sure how to handle that exception and where it should be caught :(
Does anyone see anything wrong with this code?

Please keep in mind this is Java Microedition...

Recommended Answers

All 7 Replies

In the first version, I think the only problem is that you are calling cancel on the timer, instead of the timekeeping task. I ran this simplified example here and it works just fine.

import java.util.Timer;
import java.util.TimerTask;

public class FrameThread extends javax.swing.JFrame {

    Timer timer;
    TimeKeeping timeKeeperTask = null;
    boolean timerRunning = false;

    public FrameThread() {
        initComponents();
        timer = new Timer();
    }

    private class TimeKeeping extends TimerTask {
        public void run() {
            timerRunning = false;
            jLabel1.setText("time up!");
            System.out.println("Timer expired");
        }
    }

private void formKeyPressed(java.awt.event.KeyEvent evt) {
    //Rest of the function that is not relevant to problem
//        repaint();

    if (timerRunning) // boolean check, if true execute
    {
        System.out.println("Cancel timer");
        timeKeeperTask.cancel();
    }
    System.out.println("Start new timer");
    jLabel1.setText("running");
    timeKeeperTask = new TimeKeeping();
    timer.schedule(timeKeeperTask, 2000);
    timerRunning = true;
    System.out.println("New timer started");

}

    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                formKeyPressed(evt);
            }
        });
        getContentPane().setLayout(new java.awt.FlowLayout());

        jLabel1.setText("jLabel1");
        getContentPane().add(jLabel1);

        pack();
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new FrameThread().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JLabel jLabel1;
    // End of variables declaration

}
commented: Thank you for another great example of code :) +10

Awn, I just got frame with label, but nothing happens after it:?:

I forgot to mention I tried to cancel TimerTask, however results remind same. I hope they do lot of improvement to new MIDP 3 for next year

Sorry, I suppose I could have explained that a bit. If you press a key the timer starts. If you keep pressing keys before the 2 second timer expires, nothing changes. If you don't press a key in 2 seconds, the label changes to "Time up!".

It's just a stripped down version of your own code from the first example you posted. You were calling cancel() on the Time, instead of the object that extended TimerTask.

I can't really speak to the rest of your code. I was just looking at the timer operation.

I realize the functionality of the program after I went to see friends. Now is late night, I will continue with it tomorrow. Thank you for help Ezzaral

With help of SE developer forum I worked out solution with Timer and TimerTask.
Manipulating boolean inside TimerTask run() method wasn't good idea. Timer is thread processed at background. As being thread and sharing resources it would require synchronization. However manipulating boolean after cancel() and schedule() calls works fine.

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.