2013-12-12 39 views
2

我想要有一列复选框指示持续过程的步骤。如何在Swing中设置只读JCheckBox?

在这种情况下,用户不能更改复选框。它们被后台进程改变。

不幸的是,如果我打电话给setEnable(false),我会使复选框不仅是只读的,而且也是暗淡的。

如何完成?

+4

不确定这是一个好主意,使用看起来像启用复选框,但无法点击的东西。如果你追求的东西只是表明一个步骤已经完成,为什么不使用适当的图像呢?大绿色的蜱或什么的。 –

+0

如果您使用的是java7,则可以使用'JLayer'并使用组件中的所有事件 – nachokk

+0

[JButton:Simulate JButton press without action firing]的可能重复(http://stackoverflow.com/questions/20440676/jbutton-simulate -jbutton-press-without-action-firing) – Sage

回答

2

这似乎有点不可思议,但会提出如何更新状态的问题,但基本上,您想要将ButtonModel替换为无法更改的状态。

例如...

checkBox = new JCheckBox(); 
checkBox.setModel(new DefaultButtonModel() { 

    @Override 
    public boolean isSelected() { 
     return true; 
    } 

    @Override 
    public void setSelected(boolean b) { 
     // Stop events from being raised... 
    } 

}); 

现在,你可能还需要使复选框unfocusable,以防止它接收键盘焦点。

说了这么多,作为一个用户,我都会觉得这是非常令人沮丧的复选框“出现”编辑

+0

我已经把它标记为重复出来你的名声mua哈哈! :);) – Sage

+0

@Sage记住,我知道你在哪里发布;) – MadProgrammer

+0

我不喜欢这种解决方案导致休息liskov替代原则 – nachokk

3

您可以使用JLayer类,如果您使用的是Java7或swingX(JXLayer)。

简单的例子:

import java.awt.AWTEvent; 
import java.awt.event.KeyEvent; 
import java.awt.event.MouseEvent; 
import javax.swing.JCheckBox; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JLayer; 
import javax.swing.JPanel; 
import javax.swing.plaf.LayerUI; 

public class JCheckBoxUnselectable { 


    public static void main(String args []){ 
     JFrame frame = new JFrame(); 
     frame.setTitle("Test checkbox"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JPanel panel = new JPanel(); 
     panel.add(new JLabel("Test checkbox")); 
     JCheckBox checkbox = new JCheckBox(); 
     LayerUI<JComponent> layerUI = new MyLayerUISubclass(); 
     JLayer<JComponent> jlayer = new JLayer<>(checkbox, layerUI); 

     panel.add (jlayer); 
     frame.add(panel); 
     frame.pack(); 
     frame.setVisible(true); 

    } 



    static class MyLayerUISubclass extends LayerUI<JComponent>{ 


     @Override 
     public void installUI(JComponent c) { 
      super.installUI(c); 
      JLayer jlayer = (JLayer)c; 
      jlayer.setLayerEventMask(
        AWTEvent.MOUSE_EVENT_MASK | 
        AWTEvent.KEY_EVENT_MASK 
        ); 

     } 

     @Override 
     public void uninstallUI(JComponent c) { 
      JLayer jlayer = (JLayer)c; 
      jlayer.setLayerEventMask(0); 
      super.uninstallUI(c); 
     } 


     @Override 
     protected void processMouseEvent(MouseEvent e, JLayer l) { 
      e.consume(); 
     } 





     @Override 
     protected void processKeyEvent(KeyEvent e, 
       JLayer<? extends JComponent> l) { 
      e.consume(); 
     } 



    } 
} 

了解更多:How to decorate components with JLayer

+0

+1 ,有趣的方法,但它似乎混淆了焦点遍历,这可能会或可能不会成为问题,具体取决于复选框是否应该是可以聚焦的。 – camickr

3

从复选框中取出的MouseListener和键绑定。

MouseListener[] ml = (MouseListener[])checkBox.getListeners(MouseListener.class); 

for (int i = 0; i < ml.length; i++) 
    checkBox.removeMouseListener(ml[i]); 

InputMap im = checkBox.getInputMap(); 
im.put(KeyStroke.getKeyStroke("SPACE"), "none"); 
im.put(KeyStroke.getKeyStroke("released SPACE"), "none");