Помогите сделать JTree с JCheckBox - PullRequest
4 голосов
/ 17 сентября 2009

У меня необычная ситуация, когда мне нужно иметь JTree с каждым узлом, содержащим 2 флажка и метку (с возможностью добавления прослушивателя, чтобы сказать, когда установлены какие-либо из возможных флажков). Мне также нужно, чтобы корневой узел имел ту же компоновку (что, как я предполагаю, означает создание JPanel с 2 JCheckBoxes и JLabel), с возможностью выбора всех флажков вниз по дереву, если установлен один в корне.

Любое руководство или примеры? Я проверил предыдущие вопросы здесь и связанные с ними примеры ... некоторые из которых позволили мне добраться до точки «взгляда» на дерево, но без указания направления для реализации действия, стоящего за ним.

Спасибо!

Ответы [ 3 ]

5 голосов
/ 17 сентября 2009

Это может быть хорошее время, чтобы взглянуть на старый код JTreeTable , который даст вам дерево, отображаемое в первом столбце, и свободу отображать ячейки для каждого столбца справа от узел дерева, как вы пожелаете, в вашем случае установите флажки и метку, и вы позволите TableCellEditors работать с вашим JTable, как вы привыкли. Предупреждение заключается в том, что хотя код в этой ссылке работает, он немного запутан.

Есть альтернатива. Ниже я продемонстрировал реализацию Tree Table, которая должна быть лучше и называется Outline, предоставляемой NetBeans (хотя вам не нужно разрабатывать с IDE NetBeans, вам просто нужен jar). Эта статья показывает, как легко начать работу.

Мне удалось создать быстрый пример таблицы дерева Outline в Eclipse (с импортированным в мой проект org-netbeans-swing-outline.jar) примерно за 30 минут (я медленно набираю):

private void buildFrame() {
    frame = new JFrame("Demo");
    frame.setSize(300, 300);
    addStuffToFrame();
    frame.setVisible(true);

}


private void addStuffToFrame() {
    MyTreeNode top = new MyTreeNode("top");
    createNodes(top);
    DefaultTreeModel model = new DefaultTreeModel(top);     
    //here are the netBeans tree table classes 
    OutlineModel outlineModel = 
             DefaultOutlineModel.createOutlineModel(model, new MyRowModel());
    Outline outline = new Outline();
    outline.setRootVisible(true);
    outline.setModel(outlineModel);
    frame.getContentPane().add(new JScrollPane(outline));
}

private void createNodes(MyTreeNode top) {
    MyTreeNode child = new MyTreeNode("child 2");
    top.add(new MyTreeNode("child 1"));
    child.add(new MyTreeNode("g-child1"));
    child.add(new MyTreeNode("g-child2"));
    child.add(new MyTreeNode("g-child3"));
    top.add(child);
    top.add(new MyTreeNode("child3"));
    top.add(new MyTreeNode("child4"));

}

Я создаю TreeNode для хранения Boolean, который будет хорошо взаимодействовать со встроенным флажком JTable, отображающим механизм.

public class MyTreeNode extends DefaultMutableTreeNode {
    Boolean data1 = null;
    Boolean data2 = null;
    String name = null;
    MyTreeNode (String name) {
        this.name=name;
    }

    void setData1(Boolean val) {data1=val;}
    void setData2(Boolean val) {data2=val;}
    Boolean getData1() {return data1;}
    Boolean getData2() {return data2;}
    String getName() {return name;}

}

NetBeans RowModel - это ключ к созданию таблицы вместо простого JTree:

public class MyRowModel implements RowModel {

    public Class getColumnClass(int col) {
        switch (col) {
        case 0: return String.class;
        case 1: return Boolean.class; //these return class definitions will
        case 2: return Boolean.class; //trigger the checkbox rendering
        default:return null;    
        }
    }

    public int getColumnCount() {
        return 3;
    }

    public String getColumnName(int col) {
        return "";
    }

    public Object getValueFor(Object node, int col) {
        MyTreeNode n = (MyTreeNode)node;
        switch (col) {
        case 0: return n.getName();
        case 1: return n.getData1();
        case 2: return n.getData2();
        default:return null;
        }
    }

    public boolean isCellEditable(Object node, int col) {
        return col > 0;
    }

    public void setValueFor(Object node, int col, Object val) {
        MyTreeNode n = (MyTreeNode)node;
        if (col == 1)      {n.setData1((Boolean)val);}
        else if (col == 2) {n.setData2((Boolean)val);}
        //EDIT:  here is a recursive method to set all children
        //       selected for one of the two checkboxes as it is 
        //       checked by the parent
        for (Enumeration children = n.children();
                       children.hasMoreElements(); ) {
            MyTreeNode child = (MyTreeNode) children.nextElement();
            setValueFor(child, col, val);
        }


    }

}

вот готовый, хотя и упрощенный продукт:

альтернативный текст http://img17.imageshack.us/img17/6643/picture1hz.png

Я обновил метод setValueFor, чтобы перебирать дочерние узлы и устанавливать флажки как выбранные или отмененные при изменении родительского элемента.

1 голос
/ 17 сентября 2009
0 голосов
/ 13 декабря 2009

Не было ясно, куда идут методы buildFrame (), addStuffToFrame () и createNodes (). Я поместил их все в созданный мной класс OutlineJFrame, расширяющий JFrame, и удалил «фрейм». Предисловие, где бы оно ни появилось. Затем в методе main () моего проекта он просто создал один из этих объектов OutlineJFrame и установил для его видимости значение true. Когда это побежало, я получил изменяемый размер, но пустое окно. Где были строки? Где были узлы?

Затем я спросил Гертжана, гуру NetBeans, что я делаю не так, и он прислал мне переписать. Но у него было такое же поведение.

Но я знаю, что мой java в порядке, потому что другой демонстрационный проект, который я сделал (FileTreeJFrame), отображает объекты outline.java просто отлично.

...