0

I am trying to animate a triangle when two triangles have been clicked twice. As soon as I click them twice triangle 0 starts moving until moveX reaches 20, while(moveX < 20), but then it doesn't seem to reach a terminated state, it doesn't go inside : if(t.getState() == Thread.State.TERMINATED), any ideas?

public class secondFrame extends JFrame implements Runnable {

}


public secondFrame(ChallengesDialog dialog) {

    component = new secFrameDrawComponent();
    createComponent();

    Thread t = new Thread(this);
    t.start();
}

private void createComponent() {

    sGen = new shapeGenerator(434, 231);

    createT();
}

class AddComponentListener implements MouseListener {

    public void mouseClicked(MouseEvent event) {


    for(int i = 0; i < count; i++) {
        if (component.getTri(i).contains(event.getX(), event.getY())) {
            component.setShapeFill("triangle", i);
            component.repaint();    

            countColors(i);

            setChallenge();
        }
...
MouseListener listener = new AddComponentListener();
component.addMouseListener(listener);                       

public void setChallenge() {

    //two red triangles
    if(challenge == 1 && triColorCount[1] == 2) {
        Thread t = new Thread(component);
        t.start();

        System.out.println("Thread's state: " + t.getState());

        if(t.getState() == Thread.State.TERMINATED) {
            //Unreachable
            System.out.println("Thread completed");
        }                   
    }
}
...

public void run() {

    while(threadFlag) { 
        ..
        timeLabel.setText("Elapsed time: " + elapsedTime);
        ..                      
    }
 }

public class secFrameDrawComponent extends JComponent implements Runnable {

    public void modTriangle(int x, int y) {

        sGen.setTriangleOffset(x, y);

        triangle[0] = sGen.getTriangle();
    }

    public void paintComponent(Graphics g) {

        Graphics2D g2 = (Graphics2D)g;

        draw(g2);       
    }

    public void run() {

        while(moveX < 20) {

            moveX+= 1;
            modTriangle(moveX, 0);
            repaint();

            try {
                Thread.sleep(170);
            } catch (InterruptedException e) {  
                e.printStackTrace();
            }
            System.out.println("moveX = " + moveX);
        }
        System.out.println("Thread completed exec");        
    }

    public void draw(Graphics2D g2) {

        g2.setStroke(new BasicStroke(2));

        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
            RenderingHints.VALUE_ANTIALIAS_ON);


        modTriangle(moveX, 0);
        g2.draw(triangle[0]);
        g2.draw(triangle[1]);
    }
zeller
  • 4,904
  • 2
  • 22
  • 40
user1420482
  • 147
  • 3
  • 12
  • 1
    How long does it take the thread to run? How long do you wait before checking the thread has terminated? – Peter Lawrey Sep 03 '12 at 14:26
  • 1
    Most likely when you check for termination in the other thread, your task is not even scheduled. Add some sleep before getting the state and see what happens. – zeller Sep 03 '12 at 14:29
  • I think zeller comment is correct. – kosa Sep 03 '12 at 14:29
  • 1
    If I add System.out.println("Thread's state: " + t.getState()); try { t.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } it reaches the terminated state but the animation is not shown – user1420482 Sep 03 '12 at 14:36
  • 1
    @user1420482 Which makes sense because you have waited for the Thread to finish, but you have blocked the GUI thread so you can't see any updates. – Peter Lawrey Sep 03 '12 at 14:39
  • is there a way to wait for the thread to finish and at the same time show the animation, by not blocking the GUI thread? – user1420482 Sep 03 '12 at 14:43

1 Answers1

1

Take a closer look at what you are doing. You start a new thread then immediately check if it's terminated. Of course it won't be, it takes a while until it's done with the animation. If you want to wait until a thread finishes, use the join() function. Note however, that will block the calling thread until the the thread you are "joining" has finished.

pap
  • 27,064
  • 6
  • 41
  • 46
  • Yeah, and if the other thread depends on the state, blocking shouldn't be a problem. – zeller Sep 03 '12 at 14:31
  • @zeller Typically, that is true. It may be an unwanted behavior in a GUI application though, as it will block the event processing thread, effectively "freezing" the interface until the animation thread finishes. – pap Sep 03 '12 at 14:33
  • You're right, in this case then, the user thread should poll the task thread's state or the task should notify the main thread when it is done (but this is somewhat offtopic...) – zeller Sep 03 '12 at 14:35
  • is there a workaround for not "freezing" the interface while the animation thread .sleep(millis) or .join()? – user1420482 Sep 03 '12 at 14:49
  • @user1420482 Yes. Don't wait for the animation to finish, just let it run it's course. – pap Sep 03 '12 at 14:52
  • If I let it run without sleeping or joining, it never reaches a terminated state. Is there a thread function that allows the animation thread to .sleep without stopping its GUI animation display? – user1420482 Sep 03 '12 at 15:01
  • I think I found a way of coding it without threads by using a Timer(m_interval, new Class()); where Class() implements ActionListener and animation is calculated inside actionPerformed. – user1420482 Sep 03 '12 at 16:24
  • and to add a time delay I found http://stackoverflow.com/questions/3072173/how-to-call-a-method-after-a-delay – user1420482 Sep 03 '12 at 22:25