Tristate Ankreuzfelder in Java

stimmen
11

Ich könnte wirklich eine tristated Checkbox in Java verwenden. Es klingt wie eine einfache Sache, aber ich habe nur wirklich gesehen hässlich Implementierungen [Anmerkung: link jetzt gebrochen].

Drei Radiobuttons nehmen einfach zu viele Immobilien und werden wahrscheinlich für die Nutzer in meinem Fall verwirrend sein. Es ist im Grunde für einen Suchdialog. Ich brauche wahr, falsch oder Optionen „do not care“. Gibt es eine andere Technik, die Menschen benutzen?

Veröffentlicht am 11/08/2009 um 23:25
quelle vom benutzer
In anderen Sprachen...                            


9 antworten

stimmen
14

Verwenden Sie ein Drop-down.

Beantwortet am 11/08/2009 um 23:26
quelle vom benutzer

stimmen
0

Ich würde nur den einen verwenden Sie auf dem Laufenden.

Solange Ihre Komplexität in einer anderen Klasse ist (das funktioniert) und es wirkt wie jede andere Kontrolle, wer sich interessiert? (Das scheint die Annahme, hinter allen Swing zu sein scheinen die meisten Swing-Klassen über diese kompliziert zu sein.)

Beantwortet am 11/08/2009 um 23:55
quelle vom benutzer

stimmen
2

Dass „hässliche Implementierungen“ ist ein alter Link. Einer der Vorschläge auf dieser Seite wurde vor ein paar Jahren aktualisiert. Ich habe nicht die alte Implementierung getestet, so dass ich weiß nicht, ob die neuen besser oder schlechter ist.

TriStateCheckBox Revisited

Beantwortet am 12/08/2009 um 00:57
quelle vom benutzer

stimmen
0

Ändern Sie die Benutzeroberfläche. Tri-State-Check-Box ist ungewöhnlich und kann wirklich Benutzer verwirren. Der Rückgang ist nach unten gute Option, aber für mehr als ein Ereignis im Dialog wird es auch eine Menge Verwirrung Benutzer bringen.

Beantwortet am 12/08/2009 um 10:28
quelle vom benutzer

stimmen
5

Ich fand einen Weg, um ein Tri-State-Checkbox zu machen, indem Sie einfach einen Zuhörer und fügte hinzu:


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

Dann in dem Anwendungscode, es ist nur eine einzige Zeile:


jCheckBox1.addActionListener(new TriStateActionListener(getResourceMap().getIcon("TriStateIcon")));

Nach all dem Feedback, ich denke, ein Drop-down eine bessere Wahl sein kann. Aber wollte ich sonst meinen Code hier für jedermann teilen.

Beantwortet am 12/08/2009 um 18:15
quelle vom benutzer

stimmen
2

Tri-State-Check-Boxen sind Standard-UI-Idiom für Treeviews mit teilweise überprüft Kinderknoten. Sie sind weit verbreitet in der Schicht-Management in komplexen hierarchischen Ansichten wie Google Earth verwendet.

Beantwortet am 30/09/2009 um 08:14
quelle vom benutzer

stimmen
3

JIDE haben Open Source einige sehr schöne Funktionalität in ihrer gemeinsamen Schicht , von denen ein Tri - State - Checkbox sein geschieht

Tri-State-Kontrollkästchen

Ich würde vorschlagen , dass Sie die gehen laufen webstart Demo zu sehen , ob es Ihren Bedürfnissen entspricht

Beantwortet am 24/03/2012 um 12:43
quelle vom benutzer

stimmen
4

Geben Sie hier image description

In dieser Implementierung kann der drei Zustand nur über programmatisch festgelegt werden. Um Look and Feel portable es Bilder verwenden, die innerhalb des gleichen Java-Paket platziert werden müssen.

Geben Sie hier image description Geben Sie hier image description Geben Sie hier image description

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

Musterrahmen:

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;
}
Beantwortet am 09/04/2013 um 10:18
quelle vom benutzer

stimmen
4

Ich weiß nicht , warum jemand die Lösungen mit zusätzlichen Symbolen png - Dateien geben würde , während Java api große funcionality gibt für zwingende paintIcon (..) Methode.

Die beste leichte Lösung CheckBox Zustand zu erinnern ist , IMO ClientProperty Attribut.

Geben Sie hier image description

/*
 * Tri-state checkbox example
 * @s1w_
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


class TCheckBox extends JCheckBox implements Icon, ActionListener {

    final static boolean MIDasSELECTED = true;  //consider mid-state as selected ?


    public TCheckBox() { this(""); }

    public TCheckBox(String text) {
        super(text);
        putClientProperty("SelectionState", 0);
        setIcon(this);
        addActionListener(this);
    }

    public TCheckBox(String text, int sel) {
        /* tri-state checkbox has 3 selection states:
         * 0 unselected
         * 1 mid-state selection
         * 2 fully selected
        */
        super(text, sel > 1 ? true : false);

        switch (sel) {
            case 2: setSelected(true);
            case 1:
            case 0:
                putClientProperty("SelectionState", sel);
                break;
           default:
                throw new IllegalArgumentException();
        }
        addActionListener(this);
        setIcon(this);
    }

    @Override
    public boolean isSelected() {
        if (MIDasSELECTED && (getSelectionState() > 0)) return true;
        else return super.isSelected();
    }

    public int getSelectionState() {
        return (getClientProperty("SelectionState") != null ? (int)getClientProperty("SelectionState") :
                                         super.isSelected() ? 2 :
                                         0);
    }

    public void setSelectionState(int sel) {
        switch (sel) {
            case 2: setSelected(true);
                    break;
            case 1: 
            case 0: setSelected(false);
                    break;
           default: throw new IllegalArgumentException();
        }
        putClientProperty("SelectionState", sel);
    }


    final static Icon icon = UIManager.getIcon("CheckBox.icon");

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
        icon.paintIcon(c, g, x, y);
        if (getSelectionState() != 1) return;

        int w = getIconWidth();
        int h = getIconHeight();
        g.setColor(c.isEnabled() ? new Color(51, 51, 51) : new Color(122, 138, 153));
        g.fillRect(x+4, y+4, w-8, h-8);

        if (!c.isEnabled()) return;
        g.setColor(new Color(81, 81, 81));
        g.drawRect(x+4, y+4, w-9, h-9);
    }

    @Override
    public int getIconWidth() {
        return icon.getIconWidth();
    }

    @Override
    public int getIconHeight() {
        return icon.getIconHeight();
    }

    public void actionPerformed(ActionEvent e) {
        TCheckBox tcb = (TCheckBox)e.getSource();
        if (tcb.getSelectionState() == 0)
            tcb.setSelected(false);

        tcb.putClientProperty("SelectionState", tcb.getSelectionState() == 2 ? 0 :
                                                     tcb.getSelectionState() + 1);

        // test
        System.out.println(">>>>IS SELECTED: "+tcb.isSelected());
        System.out.println(">>>>IN MID STATE: "+(tcb.getSelectionState()==1));
    }
}

Verwendung: TCheckBox tcb = new TCheckBox("My CheckBox");

Beantwortet am 05/11/2014 um 04:03
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more