2010-06-28 77 views
2

我已經創建了一個自定義JButton類來表示壟斷委員會上的空間。遊戲是多人遊戲,因此繪製按鈕所需的大量信息保存在服務器上(通過RMI訪問)。停止在鼠標上重新繪製JButton?

我的問題是,當我將鼠標放在按鈕上時,它自動調用repaint()(並繪製邊框)。這使得程序非常慢,因爲每次鼠標移動到其中一個空間時,它都不得不從服務器上提取數據。

我一直在試圖找到一種方法來阻止這種情況的發生,但互聯網上的其他人似乎在獲取重新繪製()的按鈕而不是停止它的問題。

有誰知道我可以覆蓋的方法或屬性,我可以改變以阻止這種情況發生?

+1

難道你不能製作遊戲狀態的本地副本,而不是將其從服務器上拉出來? – josefx 2010-06-28 12:15:07

回答

4

我會建議重新考慮你的設計。我承認我並不知道所有的因素,但從你的描述來看,我認爲董事會的狀態不會經常變化,所以在每次嘗試嘗試時都不應該打電話給服務器。相反,如果您的服務器向客戶端廣播遊戲事件,則在調用repaint時,您將擁有本地需要的狀態。

此外,從您的描述中,聽起來好像您可以從您的repaint代碼中調用服務器,由鼠標事件觸發。這可以在美國東部時間完成。您不應該在繪畫線程中調用服務器,因爲它會減慢GUI的其餘部分。長時間運行的調用應該在工作線程中進行。請參閱SwingWorkerconcepts around threading in Swing瞭解更多詳情。

即便如此,我不認爲重繪重繪邏輯將是最佳的行動方案。爲您的按鈕提供它需要呈現的內容是更好的一步。

1

當然可以,但不能直截了當。

無論你試圖在JButton上畫什麼,都要將它轉儲到BufferedImage中。你的JButton的paint()本質上應該是返回一個緩衝圖像。 BufferedImages在重繪過程​​中速度非常快,它們只是一個像素矩陣,在重繪之間幾乎不需要時間。

package test; 

import java.awt.Graphics; 

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

public class ButtonTest { 
    public static void main(String[] args){ 
     new ButtonTest().test(); 
    } 

    public void test(){ 
     JFrame frame = new JFrame("TestFrame"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JPanel pnl = new JPanel(); 
     pnl.add(new MyButton()); 
     frame.add(pnl); 
     frame.setSize(600, 600); 
     frame.setVisible(true); 
    } 

    class MyButton extends JButton{ 
     public void paint(Graphics g){ 
      //return a buffered image everytime 
     } 
    } 
} 

儘管上述技術似乎有點笨,可以基本上具有在存儲器中一個緩衝的圖像,並且應該從paint()方法返回。無論從服務器(RMI)接收到的東西都可以使用在後臺運行的單獨線程轉儲到BufferedImage對象中。

1

您是否嘗試禁用焦點邊框的繪畫?詳情請看the JButton API documentation

此外,您可以嘗試緩存按鈕上顯示的數據。而且,是一個真正適合你想要做什麼的按鈕?請記住,用戶期望已知的GUI元素以非常特定的方式作出反應。

2

從來就應該是在重繪大計算()(和paint())你的揮杆組件的方法,更不用說服務器調用...