1

I have implemented a tree table in swing refrring the tutorial available here .I have two columns in which Message Object or Fields objects under the Message will be displayed. If the node is a Field then it's Value will be displayed in the second column.I could view the required data successfully add a cell renderer to the second column where the value is a collection then addd a combo box to the cell. The issue comes when I add the cell editor. Below is my cell editor.

    private class ValueCellEditor extends AbstractCellEditor implements   TableCellEditor {
        JTextField textEditor = new JTextField();
        JComboBox comboBox = new JComboBox();
        Component comp;
        Field field = null;

        private ValueCellEditor(){
            int row=myTreeTable.getSelectedRow();
            Object object= myTreeTable.getValueAt(row, 3);
            TreePath path= myTreeTable.getPathForRow(row);
            Object o= path.getLastPathComponent();
            MyDataNode node=(MyDataNode)o;
            Field f=(Field)node.getNodeDataObject();

            comboBox.addItemListener(new ItemListener() {
                @Override
                public void itemStateChanged(ItemEvent e) {
                    if(field!=null){
                        if(e.getStateChange() == ItemEvent.SELECTED) {
                            field.setSelectedValue(comboBox.getSelectedItem());
                            field.setDefaultValue(comboBox.getSelectedItem());
                        }
                    }
                }
            });

            textEditor.addKeyListener(new KeyAdapter() {
                @Override
                public void keyReleased(KeyEvent e) {
                    if(field!=null){
                        field.setDefaultValue(textEditor.getText());
                    }
                }
            });
        }

        @Override
        public Component getTableCellEditorComponent
                (JTable table, Object value, boolean isSelected, int row, int column) {

            if(value instanceof List<?>) {
                populateComboBox((ArrayList)value);
                comp = comboBox;
            } else {
                textEditor.setText((String)value);
                comp = textEditor;
            }
            return  comp;
        }

        @Override
        public Object getCellEditorValue() {

            if(comp != null && comp instanceof JTextField ) {
                return  textEditor.getText();
            } else if( comp != null && comp instanceof JCheckBox) {
                return comboBox.getSelectedItem();
            }
            return null;
        }

        private void populateComboBox(List<Value> valueList){
            comboBox.removeAll();
            comboBox.setSelectedItem(null);
            for (Value val: valueList) {
                comboBox.addItem(val.getDescription());
            }

            if(field.getSelectedValue() != null) {
                comboBox.setSelectedItem(field.getSelectedValue());
            }
        }
    }

In my cell editor's constructor I have added a code as below through which I tried to get the current selected node of the selected row of the tree table. but the code I have entered does't work because of the 'getPathForRow' function does't support the tree table.

        int row=myTreeTable.getSelectedRow();
        Object object= myTreeTable.getValueAt(row, 3);
        TreePath path= myTreeTable.getPathForRow(row);
        Object o= path.getLastPathComponent();
        MyDataNode node=(MyDataNode)o;
        Field f=(Field)node.getNodeDataObject();

this is the table model I am using.

    import com.milleniumit.walle.frontend.frontEndDto.Field;

public class MyDataModel extends MyAbstractTreeTableModel {

    static protected String[] columnNames = { "Field", "Value" };
    static protected Class<?>[] columnTypes = 
        { MyTreeTableModel.class, Object.class};

    public MyDataModel(MyDataNode rootNode) {
        super(rootNode);
        root = rootNode;
    }

    public Object getChild(Object parent, int index) {
        return ((MyDataNode) parent).getChildren().get(index);
    }


    public int getChildCount(Object parent) {
        return ((MyDataNode) parent).getChildren().size();
    }


    public int getColumnCount() {
        return columnNames.length;
    }


    public String getColumnName(int column) {
        return columnNames[column];
    }


    public Class<?> getColumnClass(int column) {
        return columnTypes[column];
    }

    public Object getValueAt(Object node, int column) {
        MyDataNode mNode=(MyDataNode)node;
        Object obj =mNode.getNodeDataObject();

        if(column==0){
            return mNode.getName();
        }
        else if (column==1){
            if(obj instanceof Field){
                Field field=(Field)mNode.getNodeDataObject();
                if(field.getFieldDef().getListValue().size()>0){
                    return field.getFieldDef().getListValue();
                }
                else
                    return mNode.getDefaultValue();
            }
            else
                return mNode.getDefaultValue();
        }
        return null;
    }

    public boolean isCellEditable(Object node, int column) {
        return true; // Important to activate TreeExpandListener
    }

    public void setValueAt(Object aValue, Object node, int column) {
        MyDataNode mNode=(MyDataNode)node;

        if (mNode.getNodeDataObject() instanceof Field && column == 1) {
            Field field = (Field) mNode.getNodeDataObject();
            field.setDefaultValue(aValue);
            field.setSelectedValue(aValue);
        }
    }

}

I need to get the selected node of the tree table so that I can get the current selected field to edit it's changed value through the editor. Can someone please let me know where I am going wrong in my code. What's the correct approach to get the current selected node of this tree table.

sher17
  • 607
  • 1
  • 12
  • 31
  • 1
    I think you can use a combination of `JXTreeTable#getPathForRow` and `JXTreeTable#getSelectedRow`, this will give you a `TreePath`, which might give you a starting point – MadProgrammer Apr 06 '16 at 02:36
  • I am not using swingX it's swing only. getPathForRow() supports in JXTreeTable i guess. There's a nodeForRow in MyTreeTableModelAdapter class which returns the current selected node. But I dont know how to use it here. IS there a way to use it? Please refer the sample code at http://www.hameister.org/JavaSwingTreeTable.html . – sher17 Apr 06 '16 at 03:23
  • Well, it's a mess, SwingX would be easier, but `MyTreeTableCellRenderer` is an instance of `JTree`, you're going to have to work backwards from there to figure out how each node relates to each to a row and use `getPathForRow/Location` based on the information you can find – MadProgrammer Apr 06 '16 at 03:27
  • Yes I know it is a mess to work with a tree table in swing since there's no built in component available in the API. If someone go in this approach to an editable tree table in swing please help me through this. – sher17 Apr 06 '16 at 04:19

0 Answers0