2012-08-24 61 views
2

見下文:我可以在ActionListener上使用get和set嗎?爲什麼不工作?

/這是我的主要/

package br.com.general; 

public class Main { 

    public static void main(String[] args) { 

     Wind w = new Wind(); 
     w.start(); 

     while(true){ 
      //System.out.printf("%b\n", w.button()); 
      if(w.button()){ 
       System.out.printf("xx %b\n", w.button()); 
      } 
     } 

    } 

} 

/這是我的JFrame窗口有一個按鈕/

package br.com.general; 

import javax.swing.JButton; 
import javax.swing.JFrame; 

public class Wind extends JFrame{ 

    private static final long serialVersionUID = 1L; 
    Act a = new Act(); 

    public Wind() { 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

     JButton B = new JButton("on"); 

     getContentPane().setLayout(null); 

     B.setBounds(10, 10, 50, 30); 
     B.addActionListener(a); 

     add(B); 
     setSize(100, 100); 
    } 

    public void start() { 
     setVisible(true); 
    } 
    public boolean button(){ 
     return(a.button()); 
    } 
    public void buttonOk(){ 
     a.zero(); 
    } 
} 

/*和這到底是我的ActionListener我的按鈕*/

package br.com.general; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

public class Act implements ActionListener { 
    boolean s; 
    public void actionPerformed(ActionEvent ae) { 
     s = true; 

    } 
    public boolean button(){ 
     return(s); 
    } 
    public void zero(){ 
     s = false; 
    } 
} 

如果您運行,您可以看到不起作用,但是如果在主要中刪除「//」並啓用「System.out.printf(」%b \ n「,w。按鈕());」它開始運作.... 爲什麼?有人可以幫助我嗎?

回答

0

這是一個很好的問題!在理想的世界中,無論第一個System.out.println(…)是否被註釋掉,您的代碼都將毫無問題地運行。

的問題是,優化的Java代碼並執行始終檢索在Act類的s標誌的當前值。

爲了避免這種情況(在這種情況下是錯誤的)優化,您可以使用volatile修飾符:volatile boolean s;。這要求JVM至總是從內存中檢索實際值並防止對其進行緩存,請參見Atomic Access in The Java Tutorials

0

看起來你擁有耗費所有資源的硬死循環。您可能應該在循環中插入小延遲(例如,10-100ms)。這可以使用Thread.wait()方法完成。在你的情況下,由System.out.printf()產生延遲,因爲控制檯輸出很慢。

+0

我不認爲資源消耗是這裏的問題(儘管在大多數情況下[忙等待](http://en.wikipedia.org/wiki/Busy_waiting)確實不好):嘗試添加一些內容事件處理程序方法(例如'System.out.println(「Button clicked」);'),你會看到它被立即執行並且GUI響應。 – siegi

相關問題