How can set Font and Background color at child node of JXTreeTable

688 Views Asked by At

I have a simple Java swing application. So I have a JPanel with a JXTreeTable. I can insert into this TreeTable, soma row with child node, this is ok.

Now if I try to run my application, I can see this:

enter image description here

Also this is ok. So, now if I try to exapand one or more NODE I can see this:

enter image description here

I want know if is possible to change the rendere (set anothe background or another font color for the NODE child.

This is the code that I use to create JXTreeTable.

private void createTable(List<Entrate> v,String tipoConto){
    tableCatEntrate = new CustomTreeTableEntrate(v,tipoConto);
    daiProprietaJTableCatEntrate();
    jscrollPaneCatEntrate.setViewportView(tableCatEntrate);
}

This is the CustomTreeTableEntralte class:

public class CustomTreeTableEntrate extends JXTreeTable{

    public CustomTreeTableEntrate(List<Entrate> listaConti,String tipoConto){
        setTreeTableModel(new RandomTextTreeTableModel(listaConti,tipoConto));
        setRowSelectionAllowed(false);
        this.setDefaultRenderer(Object.class, new CustomTreeTableSpeseXCategoriaSpese());
    }
    class RandomTextTreeTableModel extends DefaultTreeTableModel {
        public final NumberFormat decimalFormatter2 = new DecimalFormat("#,##0.00");
        DefaultMutableTreeTableNode Root = null;
        final String[] ColName = {"","Acquisti/Vendite","Uscite","Entrate","Saldo"};
        //public LinkedHashMap<String, Entrate> mappaConti = new LinkedHashMap<String, Entrate>();
        String tipoConto;

        RandomTextTreeTableModel(List<Entrate>listaConti,String tipoConto) {
            Root = new DefaultMutableTreeTableNode();
            this.setRoot(Root);
            for (Entrate conti : listaConti) {
                DefaultMutableTreeTableNode node = new DefaultMutableTreeTableNode(conti);
                Root.add(node);
                if(conti.getListaContiFigli()!=null){
                    for (Entrate contoFiglio : conti.getListaContiFigli()) {
                        node.add(new DefaultMutableTreeTableNode(contoFiglio));
                        mappaConti.put(contoFiglio.getDescrizione(), contoFiglio);
                    }
                }
                contoTotale.setTotale(conti.getTotale()+contoTotale.getTotale());
                contoTotale.setTotalePubblico(conti.getTotalePubblico()+contoTotale.getTotalePubblico());
                contoTotale.setEntrate(conti.getEntrate()+contoTotale.getEntrate());
                contoTotale.setUscite(conti.getUscite()+contoTotale.getUscite());
            }

            DefaultMutableTreeTableNode node = new DefaultMutableTreeTableNode(contoTotale);
            Root.add(node);
        }

        @Override
        public Object getValueAt(Object arg0, int arg1) {
            try{
                if(arg1==0){
                    int numberElement = ((DefaultMutableTreeTableNode)arg0).getChildCount();
                    if(numberElement<=0)
                        return null;
                    //Conti c = (Conti)((DefaultMutableTreeTableNode)arg0).getChildAt(0).getUserObject();
                    return "";
                }
                Entrate c = (Entrate)((DefaultMutableTreeTableNode)arg0).getUserObject();
                if(c==null)
                    return null;
                if (arg1 == 0) {
                    return "";
                }else if (arg1 == 1) {
                    return c.getDescrizione();
                }else if (arg1 == 2) {
                    return decimalFormatter2.format(c.getUscite());
                }else if (arg1 == 3) {
                    return decimalFormatter2.format(c.getEntrate());
                }else if (arg1 == 4 && tipoConto!=null && tipoConto.equalsIgnoreCase(WFConst.TIPO_CONTO_DEFAULT_AMMINISTRAZIONE_PRIVATO)) {
                    return decimalFormatter2.format(c.getTotale());
                }else if (arg1 == 4 && tipoConto!=null && tipoConto.equalsIgnoreCase(WFConst.TIPO_CONTO_DEFAULT_AMMINISTRAZIONE_PUBBLICO)) {
                    return decimalFormatter2.format(c.getTotalePubblico());
                }
            }catch(Exception e){
                e.printStackTrace();
            }
            return arg0;
        }



    }

}

This is the TreeTableRenderer, I think that the problem, is in thi class because if I try to execute a Debug, I can't go into getTreeCellRendererComponent.

public class CustomTreeTableSpeseXCategoriaSpese extends JLabel implements TreeCellRenderer, TableCellRenderer {
    /**
     * 
     */
    DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
    private static final long serialVersionUID = 4842418316518803090L;
    private Font fontTotale = new Font("Verdana", Font.BOLD, 12);
    private Font fontNegativo = new Font("Verdana", Font.BOLD, 12);




    public Component getTableCellRendererComponent(JTable table, Object value, 
            boolean isSelected, boolean hasFocus, int row, int column) {
        setOpaque(true);



        if(column ==1){
            setHorizontalAlignment(SwingConstants.LEFT);
        }else{
            setHorizontalAlignment(SwingConstants.RIGHT);
        }

        if (row== table.getRowCount()-1) {
            setForeground(Color.BLACK);
            setBackground( Color.RED );
            setFont(fontTotale);
        }else if(row != table.getRowCount() && column !=4){
            setForeground( Color.BLACK );
            setBackground(new Color(200, 200, 200));
            setFont(UtilitySwing.getTableFont());
        }else if(row != table.getRowCount()-1 && column ==4){
            String valore = value.toString();
            if(valore.startsWith("-")){
                setForeground(Color.red);
                setFont(fontNegativo);
            }else{
                setForeground(Color.blue);
                setFont(fontNegativo);
            }
        }
        setText(value != null ? value.toString() : "<null>");
        return this;
    }



    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value,
            boolean selected, boolean expanded, boolean leaf, int row,
            boolean hasFocus) {
        setOpaque(true);

        if(expanded){
            setForeground(Color.PINK);
            setBackground( Color.PINK );
            setFont(fontTotale);
        }
        return this;
    }
} 
1

There are 1 best solutions below

5
mr.celo On

You are already using the TreeCellRenderer, so you're close. All you need to do is access the model (something like DefaultTreeModel) and use getPathToRoot() to see how deep in the tree you are and change the renderer accordingly.

An example:

DefaultTreeCellRenderer defaultTreeCellRenderer = new DefaultTreeCellRenderer() {
    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value,
                                                  boolean selected, boolean expanded, boolean leaf, int row,
                                                  boolean hasFocus) {
        setOpaque(true);

        DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
        if (model.getPathToRoot((TreeNode) value).length > 2) {
            //Do your rendering goodness here
        } else if (expanded) {
            setForeground(Color.PINK);
            setBackground(Color.PINK);
            setFont(fontTotale);
        }
        return this;
    }
};

Note I made some assumptions, so please correct to your need accordingly.

  1. The model is a DefaultTreeModel
  2. The node is a TreeNode
  3. You only care if the node is at least 3 levels deep

Also, check out the JavaDoc for this function to make sure it is what you need.