Java 如何在Swing中创建只读JCheckBox?

Java 如何在Swing中创建只读JCheckBox?,java,swing,checkbox,Java,Swing,Checkbox,我想让一列复选框指示长期程序的步骤 在这种情况下,用户不应更改复选框。它们通过后台进程进行更改 不幸的是,如果我调用setEnable(false)我不仅使复选框为只读,而且使其变暗 如何完成?这似乎有点奇怪,但会带来一些问题,比如如何更新状态,但基本上,您希望将按钮模型替换为一个选中的状态无法更改的人 例如 checkBox = new JCheckBox(); checkBox.setModel(new DefaultButtonModel() { @Override pu

我想让一列复选框指示长期程序的步骤

在这种情况下,用户不应更改复选框。它们通过后台进程进行更改

不幸的是,如果我调用
setEnable(false)
我不仅使复选框为只读,而且使其变暗


如何完成?

这似乎有点奇怪,但会带来一些问题,比如如何更新状态,但基本上,您希望将
按钮模型
替换为一个
选中的
状态无法更改的人

例如

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

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

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

});
现在,您可能还希望使复选框不可聚焦,以防止它接收键盘焦点


话虽如此,作为一个用户,我会发现这令人难以置信地沮丧,因为复选框“出现”可编辑

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

快速示例:

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();
        }



    }
}
import java.awt.AWTEvent;
导入java.awt.event.KeyEvent;
导入java.awt.event.MouseEvent;
导入javax.swing.JCheckBox;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JLayer;
导入javax.swing.JPanel;
导入javax.swing.plaf.LayerUI;
公共类JCheckBoxUnselectable{
公共静态void main(字符串参数[]){
JFrame=新JFrame();
frame.setTitle(“测试复选框”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel面板=新的JPanel();
添加(新JLabel(“测试复选框”);
JCheckBox checkbox=新的JCheckBox();
LayerUI LayerUI=新的MyLayerui子类();
JLayer JLayer=新JLayer(复选框,layerUI);
panel.add(jlayer);
框架。添加(面板);
frame.pack();
frame.setVisible(true);
}
静态类MyLayerUI子类扩展了LayerUI{
@凌驾
public void installUI(JComponent c){
super.installUI(c);
JLayer JLayer=(JLayer)c;
jlayer.setlayerventmask(
AWTEvent.MOUSE\u事件\u掩码|
AWTEvent.KEY\u事件\u掩码
);
}
@凌驾
公共用户界面(JComponentC){
JLayer JLayer=(JLayer)c;
jlayer.setlayerventmask(0);
super.ui(c);
}
@凌驾
受保护的void进程MouseEvent(MouseEvent e,JLayer l){
e、 消费();
}
@凌驾
受保护的无效processKeyEvent(KeyEvent e,

JLayer从复选框中删除鼠标侦听器和键绑定

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");
MouseListener[]ml=(MouseListener[])checkBox.getListeners(MouseListener.class);
对于(int i=0;i
不确定使用看起来像已启用的复选框但无法单击的内容是否是一个好主意。如果您正在查找仅表明某个步骤已完成的内容,为什么不使用适当的图像?绿色大勾号或其他内容。如果您使用的是java7,则可以使用
JLayer
并使用componentposs中的所有事件我已将其标记为复制品,以蚕食你的声誉(哈哈哈!:);@Sage记住,我知道你在哪里发帖;)我不喜欢这种解决方案,因为会破坏liskov的替代principle@nachokk我不喜欢(只读复选框的)基本概念+1,一种有趣的方法,但它似乎搞乱了焦点遍历,这可能是一个问题,也可能不是,这取决于复选框一开始是否应该是可聚焦的。