按钮事件无法正常工作

时间:2015-02-15 17:18:27

标签: java

我对使用wait()和notify()方法有些怀疑。我有下一个代码,它有一些按钮事件,第一次用户按下它必须停止打印的按钮,第二次重新开始打印。我知道最好使用Runnable而不是Thread,但由于要求我必须使用Thread。第一次按下按钮时代码工作正常,但第二次没有,我想使用wait()和notify,但我不知道如何使用这个特定的代码。

class Thr extends Thread{
    private int count = 0;
    private long pause;
    private boolean canPrint = true;
    private JTextArea textArea;

    Thr(long miliseconds,JTextArea text){
        pause = miliseconds;
        textArea = text;
    }

    public void pushedButton(){
        if(canPrint)
           this.canPrint = false;
        else
            this.canPrint = true;

    }


    public void run()
    {
        while(this.canPrint)
        {
            try
            {
                this.printCounter();
                Thread.sleep(pause);
                this.count++;
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }


    }

    public void printCounter(){
        String time;
        time = Integer.toString(count);
        textArea.setText(time);  
    }
}

class Interface extends JFrame implements ActionListener{
    private JTextArea textArea,textArea2;
    private JButton button;
    private Thr thread,threadEvent;

    Interface()
    {
        textArea = new JTextArea(10,7);
        textArea2 = new JTextArea(10,7);
        thread = new Thr(2000,textArea);
        threadEvent = new Thr(1000,textArea2);
        button = new JButton("Pausar/Reanudar");
        this.getContentPane().add(button,BorderLayout.SOUTH);
        this.getContentPane().add(textArea,BorderLayout.WEST);
        this.getContentPane().add(textArea2,BorderLayout.EAST);

        thread.start();
        threadEvent.start();

        button.addActionListener(this);
    }

    public void actionPerformed(ActionEvent event)
    {
        threadEvent.pushedButton();
    }       
}


public class MensajesHilos {

    public static void main(String[] args){
        Interface i = new Interface();
        i.setTitle("Control Threads");
        i.setBounds(200, 200, 300, 240);
        i.setVisible(true);
    }
}

2 个答案:

答案 0 :(得分:0)

您编码的方式,如果您想获得所需的结果,

我觉得修改需要在run方法中完成,

   public void run()
    {
        while(true)
        {
            if(this.canPrint){
              try
              {
                this.printCounter();
                Thread.sleep(pause);
                this.count++;
              }
              catch(InterruptedException e)
              {
                e.printStackTrace();
              }
            }
        }
    }

通过这种方式,您的线程永远不会死亡,并根据canPrint布尔值切换打印。

另外,请确保声明canPrint变量volatile,以便对其进行更改直接写入主内存并立即反映。

答案 1 :(得分:0)

按钮事件无法正常工作

这是假的,如果你在actionPerformed方法中放置一个print语句,你会看到每次按下按钮都会调用它。

请注意,您可以简化此

if(canPrint)
   this.canPrint = false;
else
   this.canPrint = true;

this.canPrint = !this.canPrint;

请注意,始终将@Override anotation置于覆盖方法之上是一种好习惯。

@Override
public void actionPerformed(ActionEvent event)
{
    threadEvent.pushedButton();
} 

现在为什么不能得到预期的结果?

您忘记致电thread.pushedButton,因此canPrint只会在threadEvent对象中重置,永远不会在thread

请注意,一旦布尔值设置为false,您将退出loop,即使您将布尔值重新设置为true,该过程也不会重新启动。此示例将使用while(true),但是,您应该将true更改为任何sentinel值以处理程序的退出,因为这将永远循环。

@Override
public void run()
{
    while(true)
    {
        if(this.canPrint)
        {
                this.printCounter();
                this.count++;
        }
        try
        {
            Thread.sleep(pause);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

另外,请确保pause永远不会为0,否则您将吃掉所有计算机进程。

请注意,正如其他所述,您应该在您的案例中将在线程中访问的变量声明为volatile(canPrint)。