Question

Hi everyone I am stack so if anyone can assist in any way it would be great. I am using eclipse and the program is compiling and running. I have 3 classes and they are in the same package. So I want to pass the value of i in the class ThreadQuizCountdown to other class PanelQuizCountdown int the JTextField with name timeField currently i is displayed in the console I have been trying to do it but I couldn't so if anyone can give a hand. Here is the code

/**The driver class of the program. Here is the JFrame 
 * class name RunQuizCountdown.java
 * @author Kiril Anastasov
 * @date 09/03/2012
 */

import java.awt.*;
import javax.swing.*;

public class RunQuizCountdown 
{
    public static void main(String[] args) 
    {

        JFrame application = new JFrame();
        PanelQuizCountdown panel = new PanelQuizCountdown();
        application.add(panel);
        application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        application.setSize(200,300);
        application.setLocationByPlatform(true);
        application.setVisible(true);
    }

}



/** Here is the GUI of the program
 * class name PanelQuizCountdown.java
 * @author Kiril Anastasov
 * @date 09/03/2012
 */

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;   

public class PanelQuizCountdown extends JPanel implements ActionListener
{
    JTextField timeField, answerField;
    JLabel messageLabel, correctLabel, totalLabel;
    int x, y;
    int correct;
    int total;

    ThreadQuizCountdown myQuiz;

    PanelQuizCountdown()
    {
        timeField = new JTextField(5);
        myQuiz = new ThreadQuizCountdown(timeField);
        this.add(timeField);
        myQuiz.begin();


        messageLabel = new JLabel("What is the result of " + x + " * " + y);
        this.add(messageLabel);

        answerField = new JTextField(5);
        this.add(answerField);

        correctLabel = new JLabel("You gave : " + correct +  " correct answers");
        this.add(correctLabel);

        totalLabel = new JLabel("You answered: " + total + " questions");
        this.add(totalLabel);





    }


    public void actionPerformed(ActionEvent ae)
    {

    }
}

/** Here is the thread of the program
 * class name ThreadQuizCountdown.java
 * @author Kiril Anastasov
 * @date 09/03/2012
 */

import javax.swing.JTextField;

public class ThreadQuizCountdown implements Runnable
{
    JTextField  timeField;
    Thread myThread = new Thread(this);

    int i = 30;
    boolean go = true;

    ThreadQuizCountdown(JTextField theTimeField)
    {
        timeField = theTimeField;
    }

    public void run()
    {


        while(go)
        {           
            System.out.println(i);      

            try 
            { 
                myThread.sleep(1000);          
            } 
            catch (InterruptedException ie) 
            {
                 System.out.println("thread exception");
            }

            timeField = new JTextField(26);

            if(i == 0 )
            {
                go = false;
            }
            i--;
        }

    }

    public void begin()
    {
        myThread.start();
    }

    public void finish()
    {
        myThread.stop();
    }
}
Was it helpful?

Solution

Use delegation, add to the begin() method parameters for your delegate class that conforms interface, like

interface DelegationInterface {
   void countdownTick(int i);
}

in ThreadQuizCountdown: add private field and modify begin method:

private DelegationInterface delegate;

public void begin(DelegationInterface delegate) {
   this.delegate = delegate;
   myThread.start();
}

next, modify run(): (notice that we call countdown in critical section, in this case it doesn't matter, but if you will have many timers, it will help to avoid problems)

public void run() {
....
  myThread.sleep(1000); 
  if (delegate != null) {
      synchronized(delegate) {
          delegate.countdownTick(i);
      }
  }
....
}

And finally, add implementation of interface to panel:

public class PanelQuizCountdown extends JPanel implements ActionListener, DelegationInterface {
    ....
    public void countdownTick(int i) {
        // place i to to timeField
    }
    ....
}

That's it!

OTHER TIPS

It is not a good practice to show countdown in a text field while you have the option of using a label instead. Anyway, I debugged your code and after applying the steps below it will run in the way you desire.

In ThreadQuizCountdown class, in the while loop of run() method, add this line

timeField.setText( i +"" );

which sets the time value to the textfield, which is your first obvious missing. You can add this line before try-catch block.

Secondly, remove this line: timeField = new JTextField(26); from the same while loop, it's silly to assign your textfield to a new object every time.

Applying these will make your work done.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top