2010-02-02 286 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

相关问题