Java中的三态复选框

Use*_*er1 12 java checkbox swing

我真的可以在Java中使用三态复选框.这听起来很简单,但我只看到了非常难看的实现 [注意:链接现在已经破了].

三个单选按钮只占用太多空间,在我的情况下可能会让用户感到困惑.它基本上用于搜索对话框.我需要真实,虚假或"不关心"的选择.是否有人们使用的不同技术?

Gan*_*alf 14

使用下拉菜单.

  • 虽然我同意@ byron的观点,但从用户的角度来看,三态复选框实际上是相当标准的. (8认同)
  • 哪位用户?我是开发人员和高级用户,我鄙视三态复选框,通常是因为不清楚第三个国家意味着什么; 通常,这意味着某些细节正在向您隐藏.这是一个可用性和可访问性的噩梦. (5认同)
  • 大多数情况下,这意味着该复选框适用于一类事物,并且这些事物具有不同的状态,并且您不希望它们发生更改.检查它全部检查,将其保持在第三状态不更改它.即使对于高级用户也很常见. (5认同)
  • 三态复选框的典型用法:更改多对象选择的属性,灰色+选中的第三个状态意味着“有些项目具有此属性,有些没有,我不会更改其中任何一个”。在 Microsoft 应用程序中最常见。 (2认同)

Use*_*er1 5

我找到了一种通过简单地添加一个监听器来制作三态复选框的方法:


public class TriStateActionListener implements ActionListener{
    final protected Icon icon;

    public TriStateActionListener(Icon icon){
        this.icon=icon;
    }

    public static Boolean getState(javax.swing.JCheckBox cb){
        if (cb.getIcon()==null) return null;
        if (cb.isSelected()) return true;
        else return false;
    }

    public void actionPerformed(ActionEvent e) {
        javax.swing.JCheckBox cb=(javax.swing.JCheckBox)e.getSource();
        if (!cb.isSelected()){
            cb.setIcon(icon);
        }
        else if (cb.getIcon()!=null){
            cb.setIcon(null);
            cb.setSelected(false);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在应用程序代码中,它只是一行:


jCheckBox1.addActionListener(new TriStateActionListener(getResourceMap().getIcon("TriStateIcon")));
Run Code Online (Sandbox Code Playgroud)

在得到所有反馈之后,我认为下拉可能是更好的选择.但是,我想在这里为其他人分享我的代码.


Dan*_*eón 5

在此输入图像描述

在此实现中,只能通过编程方式设置三个状态.要外观和感觉便携,它使用的图像必须放在同一个java包中.

在此输入图像描述 在此输入图像描述 在此输入图像描述

public class TristateCheckBox extends JCheckBox {

    private static final long serialVersionUID = 1L;
    private boolean halfState;
    private static Icon selected = new javax.swing.ImageIcon(TristateCheckBox.class.getResource("selected.png"));
    private static Icon unselected = new javax.swing.ImageIcon(TristateCheckBox.class.getResource("unselected.png"));
    private static Icon halfselected = new javax.swing.ImageIcon(TristateCheckBox.class.getResource("halfselected.png"));

    @Override
    public void paint(Graphics g) {
        if (isSelected()) {
            halfState = false;
        }
        setIcon(halfState ? halfselected : isSelected() ? selected : unselected);
        super.paint(g);
    }

    public boolean isHalfSelected() {
        return halfState;
    }

    public void setHalfSelected(boolean halfState) {
        this.halfState = halfState;
        if (halfState) {
            setSelected(false);
            repaint();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

样本框架:

public class NewJFrame19 extends javax.swing.JFrame {

    private final TristateCheckBox myCheckBox;

    public NewJFrame19() {
        myCheckBox = new TristateCheckBox();
        myCheckBox.setText("123123");
        add(myCheckBox);

        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new java.awt.FlowLayout());

        jButton1.setText("jButton1");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        getContentPane().add(jButton1);

        pack();
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        myCheckBox.setHalfSelected(true);
    }                                        

    public static void main(String args[]) {

        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Windows".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(NewJFrame19.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(NewJFrame19.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(NewJFrame19.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(NewJFrame19.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame19().setVisible(true);
            }
        });
    }
    private javax.swing.JButton jButton1;
}
Run Code Online (Sandbox Code Playgroud)

  • 我们将此方法用于表示开/关状态聚合的复选框.交互切换全部打开/关闭,中间状态只能通过与各个元素的交互来访问.工作得非常好,我认为在UI设计方面更加健全. (2认同)