如何在更改变量值时更新JTextField?

时间:2013-03-28 06:51:47

标签: java multithreading swing

我有两个Java(.java) files。一个有JButtonJTextField,另一个有Thread。在第一个Java file中,我向ActionListener添加了一个JButton,这样,当按下按钮时,一个线程(创建的第二个.java文件的对象和启动的线程)运行它会连续修改整数变量。如何在JTextField(第1个.java文件)中显示该整数变量(第2个.java文件)的值?

Detection.java

package sample;
public class Detection implements Runnable
{
    public String viewers;
    public int count;
    public void run() 
    {                         
        try 
        {
            while (true) 
            {
                // i have written code for displaying video.
                // and it say how many no. of people in the video 
                // the no of people is stored in a variable "count"

                viewers=""+count; //storing count as string so as to display in the JTextField
            }           
        }                
        catch (Exception e)
        {
            System.out.println("Exception: "+e);
        }
    }
}

UsrInterfac.java

//使用WindowBuilder构建eclipse juno

package sample;
import java.awt.EventQueue;    
import javax.swing.JFrame;   
import javax.swing.JButton;    
import javax.swing.JTextField;    
import java.awt.event.ActionListener;    
import java.awt.event.ActionEvent;    

public class UsrInterfac 
{    
    private JFrame frame;
    private JTextField textField;
    Detection dd = new Detection();
    Thread th = new Thread(dd);

    /**
     * Launch the application.
     */
    public static void main(String[] args) 
    {
        EventQueue.invokeLater(new Runnable() 
        {
            public void run() 
            {
                try 
                {
                    UsrInterfac window = new UsrInterfac();
                    window.frame.setVisible(true);
                } 
                catch (Exception e) 
                {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public UsrInterfac() 
    {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() 
    {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JButton btnStartThread = new JButton("Start Thread");
        btnStartThread.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent arg0) 
            {               
                th.start();                 
            }
        });
        btnStartThread.setBounds(59, 133, 117, 23);
        frame.getContentPane().add(btnStartThread);

        textField = new JTextField();
        textField.setBounds(270, 134, 104, 20);
        frame.getContentPane().add(textField);
        textField.setColumns(10);
    }
}

2 个答案:

答案 0 :(得分:3)

从基础知识开始,使用Swing时,最好使用LayoutManagers,与使用Absolute Positioning相比,这可以使您的工作更轻松。 每当需要从另一个线程更改View中的某些内容时,始终建议使用EventQueue.invokeLater(...)/EventQueue.invokeAndWait(...)进行更改。

这个小样本程序,或许可以帮助您了解如何实现您的愿望: - )

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

public class ThreadCounter
{
    private CustomThread cThread;
    private JTextField tField;
    private JButton button;
    private int counter;

    public ThreadCounter()
    {
        counter = 0;
    }

    private void displayGUI()
    {
        JFrame frame = new JFrame("Thread Counter Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        tField = new JTextField(10);
        tField.setText("0");
        button = new JButton("Start");
        button.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent ae)
            {
                if (counter == 0)
                {
                    cThread = new CustomThread(tField);
                    cThread.setFlagValue(true);
                    cThread.start();
                    counter = 1;
                    button.setText("Stop");
                }
                else
                {
                    try
                    {
                        cThread.setFlagValue(false);
                        cThread.join();
                    }
                    catch(InterruptedException ie)
                    {
                        ie.printStackTrace();
                    }
                    counter = 0;
                    button.setText("Start");
                }
            }
        });

        contentPane.add(tField);
        contentPane.add(button);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new ThreadCounter().displayGUI();
            }
        });
    }
}

class CustomThread extends Thread
{
    private int changingVariable;
    private JTextField tField;
    private boolean flag = true;

    public CustomThread(JTextField tf)
    {
        changingVariable = 0;
        tField = tf;
    }   

    public void setFlagValue(boolean flag)
    {
        this.flag = flag;
    }

    @Override
    public void run()
    {
        while (flag)
        {
            EventQueue.invokeLater(new Runnable()
            {
                @Override
                public void run()
                {
                    tField.setText(
                        Integer.toString(
                            ++changingVariable));
                }
            });

            try
            {
                Thread.sleep(1000);
            }
            catch(InterruptedException ie)
            {
                ie.printStackTrace();
            }
        }
        System.out.println("I am OUT of WHILE");
    }    
}

答案 1 :(得分:1)

理想情况下,您应该发布您的代码。无论如何,当您调用线程代码时,要么传递第一个类(对象)的实例,要么传递JTextField的实例,以便线程可以在文本字段中设置新值。