2010-02-02 98 views
4

我想要創建兩個或多個共享狀態的JButton,即當鼠標按鈕被按下時,任何一個都被呈現爲被按下(又名「武裝」),或者如果它們是複選框,檢查/取消選中同步等在JButton之間共享狀態

對於用戶而言,它必須出現,就好像兩個按鈕都在同一按鈕,出現在多個地方的層級(在現實中搖擺不允許這樣。)

我可以通過創建一個單一的ButtonModel並將相同的模型分配給兩個按鈕來獲得一半的路程。此同步他們的武裝/檢查/選擇的狀態等

然而,這是不按鈕之間共享這樣一個明顯的效果是聚焦 - 點擊一項按鈕提供該按鈕的焦點(由按鈕內的矩形指示)並將其從另一個按鈕上移除。我想渲染這兩個按鈕,就好像它們被聚焦,只要或者按鈕真的有焦點。

有沒有一個乾淨的方法來做到這一點?

理想情況下,我希望它獨立於所選的外觀。

編輯:我發現了共享ButtonModel的另一個問題。當其中一個按鈕失去焦點時,它將模型的armedpressed屬性設置爲false。發生這種情況處理mousePressed後,所以如果你按下第二個按鈕時,第一個按鈕有焦點,它不會進入按下狀態,直到你再次按下它。

回答

3

通過對兩個按鈕使用相同的ButtonModel,您做出了非常好的舉動。

現在爲您的焦點問題。答案是否定的。不存在L&F不可知的方式。 您必須覆蓋BasicButtonUI(或您正在使用的任何一個ButtonUI)並覆蓋焦點繪製邏輯。

+0

我認爲你是對的,有必要擴展ButtonUI,但可以委託給默認的UI。這是我目前正在使用的技術的一部分。 – finnw 2010-02-03 22:32:49

+0

這是什麼L&F?我在另一篇文章中看到了它。 – 2013-04-01 17:34:53

+1

@davidblaine L&F =外觀 – 2013-04-01 17:36:01

1

我假設你已經有了文本,聽衆之類的東西。

去BasicButtonUI的paint方法,我們可以看到它實際上檢查按鈕是否有焦點,然後再做一定的繪畫。所以除非你可以同時擁有兩個關注的組件,否則唯一能做的就是使用其他按鈕的UI進行繪製。

這兩個按鈕都需要是FocusButton,需要互相調用setButton。除此之外,我還沒有打算添加任何空檢查。

public class FocusButton extends JButton { 
    private JButton btn; 

    public FocusButton() { 
     addFocusListener(new FocusListener() { 
      public void focusGained(FocusEvent e) { 
       // Other button seems to repaint when focus is gained anyway 
      } 

      public void focusLost(FocusEvent e) { 
       btn.repaint(); 
      } 
     }); 
    } 

    public void setButton(JButton btn) { 
     this.btn = btn; 
    } 

    public void paint(Graphics g) { 
     if (!btn.hasFocus()) { 
      super.paint(g); 
     } else { 
      btn.paint(g); 
     } 
    } 
} 

編輯:這不工作也很好,如果你的按鈕大小都不一樣,顯然在所有的,如果他們都應該有不同的文本不起作用。

+0

不錯的想法,如果可以擴展到3個或更多的按鈕,可能是最簡單的解決方案。 – finnw 2010-02-03 14:05:14

+0

您可以存儲一個按鈕列表,而不僅僅是一個,更改油漆以使用列表中聚焦的任何一種方法,並重新繪製所有丟失的焦點。 – lins314159 2010-02-03 23:25:28

3

這裏就是我所做的:

  • 擴展JButton一個新的類SharedFocusButton
  • SharedFocusButton覆蓋hasFocusgetModelpaintBorder
  • JButton.paintBorder(Graphics)ButtonUI.update(Component, Graphics)正在運行時,臨時更改hasFocus的行爲,以便在組中的任何按鈕具有焦點時返回true。也暫時改變的getModel行爲返回一個代理ButtonModel(在其它時間它返回共享ButtonModel
  • 代理ButtonModel行爲類似於默認,共享ButtonModel,不同之處在於它拒絕改變armedpressed屬性的值,以false,同時處理focusLost事件。 (因爲每個按鈕都有自己的UI處理焦點事件,這不會自動發生)
  • 手柄focusGainedfocusLost,迫使組中的所有按鈕重繪自己

遺留問題:
焦點遍歷應該可能被修改,這樣標籤鍵決不會將焦點從同一組中的一個按鈕轉移到另一個按鈕。

+0

我認爲你的解決方案比我的解決方案效果更好,因爲你不限於相同尺寸的按鈕(如果用戶調整窗口大小,很難控制)和外觀。 – lins314159 2010-02-03 23:29:24