Icons in jtable - custom rendering

The following code creates a table, then places an exclaimation point in each column in which the value exceeds the treshold value. I would like to modify the code so that, it places the exclaimation point in the status column of the row containing the value exceeding the treshold.
I need some assistance please.
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableRenderer extends JFrame
JTable table;
double T = 1;
public TableRenderer()
String[] columnNames = {"Status","Date", "Integer", "String"};
Object[][] data =
{"",new Date(), new Integer(1), "A"},
{"",new Date(), new Integer(2), "B"},
{"",new Date(), new Integer(3), "C"},
{"",new Date(), new Integer(4), "D"}
DefaultTableModel model = new DefaultTableModel(data, columnNames);
table = new JTable( model )
public Class XXXgetColumnClass(int column)
return getValueAt(0, column).getClass();
JScrollPane scrollPane = new JScrollPane( table );
getContentPane().add( scrollPane );
// Create cell renderer
TableCellRenderer renderer = new TestRenderer(T);
table.setDefaultRenderer(Object.class, renderer);
//table.setDefaultRenderer(Number.class, renderer);
//table.setDefaultRenderer(Date.class, renderer);
public static void main(String[] args)
TableRenderer frame = new TableRenderer();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setVisible(true);
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
class TestRenderer extends DefaultTableCellRenderer
    double Threshold;
        public TestRenderer(double t) {
            Threshold = t;
        public Component getTableCellRendererComponent(
        JTable table,
        Object value,
        boolean isSelected,
        boolean hasFocus,
        int row,
        int column)
        super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        setOpaque( true );
        Icon bang = new ImageIcon("C:/j2sdk1.4.2_04/bin/bang.gif");
                if (value instanceof Number){
                        if (((Number)value).doubleValue() > Threshold){
                            setIcon(bang);
                        else{
                            setIcon(null);
                            setBackground(Color.red);
                else{
                            setIcon(null);
                            setBackground(Color.yellow);                           
        return this;

I would like to modify the code so that, it places the exclaimation point in the status column of the row containing the value exceeding the treshold.So you add the renderer to the first column, not the column containing the Integer. Now in the renderer you need to get the value directly from the model:
Object testValue = table.getModel().getValueAt(row, 2);
if (testValue instanceof Number)

Similar Messages

  • Jtable custom renderer

    how to set or create custom renderer for a Jtable ?.. i want have following components in each cell of jtable.
    1)checkbox
    2)icon
    3)combobox
    i know how to render these components for Jtree, but i didn't get any method like setCellRendere() for Jtable.
    plz help !!

    You can use the both:
    JTable method:
    +Sets a default cell renderer to be used if no renderer has been set in a TableColumn.+
    public void setDefaultRenderer(Class<?> columnClass, TableCellRenderer renderer)TableColumn method:
    +Sets the TableCellRenderer used by JTable to draw individual values for this column.+
    public void setCellRenderer(TableCellRenderer cellRenderer)

  • JTable custom renderer never calls getTableCellRendererComponent()

    I have a custom renderer for Dates in my JTable. I've set it as the renderer on Date columns and I've also tried setting it as the table default for the Date type. In both cases the getTableCellRendererComponent() method never gets called.
    I've also tried right-justifying String columns with
              DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)table.getDefaultRenderer(String.class);
              renderer.setHorizontalAlignment(JLabel.RIGHT);
    but the Strings are always left-justified. Same with integers.
    I verify that the new renderer / alignments are actually set immediately after setting them. A few method calls later I notice that the alignments have changed back. My custom date renderer is still set, however.
    My code calls fireTableStructureChanged(). I set/reset all renderers after the call to fireTableStructureChanged(). I wonder if fireTableStructureChanged() rebuilds the table some teim later wiping out the renderer / alignments that I've set and replacing them with the defaults.
    Is there a callback or some method that I need to override after calling fireTableStructureChanged() in order to get my renderer / alignments to remain in effect?

    I can't post the code because it is proprietary and the application itself is large.
    The trouble seems to start when I call fireTableStructureChanged(). None of the toy examples in books that I've seen address fireTableStructureChanged(). The JavaDocs for Swing don't tell you about all of the side effects of fireTableSTructureChanged().
    You're comment about overriding getColumnClass() got my custom data renderer working. The Javadocs for DefaultTableModel and JTable don't mention when you need to override getColumnClass(). Overriding getColumnClass() in the TableModel seems to apply to JTable as well. I don't understand why, but it seems to work.
    I am able to justify my columns be creating a default renderer and calling setHorizontalAlignment() on it and setting it as the default for the JTable. The code below doesn't work, however:
    DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)table.getDefaultRenderer(int.class);
    renderer.setHorizontalAlignment(JLabel.RIGHT);
    It seems that the default renderers reset themselves back to their default state. I have no idea why, but that is what I am seeing.
    There is also a big difference in the way that primitives and wrappers are handled (i.e. int compared to Integer).
    One of the other posters here said that if I call setModel() that I would have to reset the renderers. The Javadocs don't say anything about that. (I only call setModel during initialization. I do update the actual data in the TableModel which can change the structure of the table. That is when I call fireTableStructureChanged() and all the difficulties start.)
    This whole episode has shown that the Swing Javadocs are next-to-worthless for writing real-world Swing applications. I've written several Swing applications over the years, and once they get beyond the simple level they become difficult to write and maintain due to the lack of documentation. For my next Java GUI I'm going to check out JavaFX (as soon as it is available on Linux). I don't see how it could be worse than Swing.
    Thanks for all of your help. You got me on the path to getting this solved.

  • JTable Custom Renderer not working after sort

    Hi All,
    I have a JTable which has a default renderer. The point of the renderer is to color the background based on the second column.
    It all words fine, until I sort by any of the columns. Clicking on a column header sorts, but the original background color remains.
    The JTable was created with a class that extended DefaultTableModel.
    Any help or ideas would be appreciated.
    Thanks.
    table.setDefaultRenderer(Object.class, new MyColorCellRenderer());
    public class MyColorCellRenderer extends javax.swing.table.DefaultTableCellRenderer {
            public MyColorCellRenderer() {
                setForeground(Color.white);
                setOpaque(true);           
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {                   
                Component comp = super.getTableCellRendererComponent(
                         table,  value, isSelected, hasFocus, row, column);
                String s = table.getModel().getValueAt(row, 1).toString();
                if (s.equalsIgnoreCase("Man")) {
                    comp.setBackground(Color.red);
                } else if (s.equalsIgnoreCase("Woman")) {
                    comp.setBackground(Color.orange);
                } else if (s.equalsIgnoreCase("Child")) {
                    comp.setBackground(Color.lightGray);
                } else if (s.equalsIgnoreCase("Pet")) {
                    comp.setBackground(Color.darkGray);
                } else {
                    comp.setForeground(null);
                return (comp);
        }Edited by: PeterG on Sep 23, 2008 7:54 AM

    Absolutely correct and fantastic!
    Thank you very much.
    New code below.
    public class MyColorCellRenderer extends javax.swing.table.DefaultTableCellRenderer {
            private JTable m_Table;
            public MyColorCellRenderer(JTable table) {
                m_Table = table;
                setForeground(Color.white);
                setOpaque(true);           
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {                   
                Component comp = super.getTableCellRendererComponent(
                         table,  value, isSelected, hasFocus, row, column);
                String s = table.getModel().getValueAt(m_Table.convertRowIndexToModel(row), 1).toString();
                if (s.equalsIgnoreCase("Man")) {
                    comp.setBackground(Color.red);
                } else if (s.equalsIgnoreCase("Woman")) {
                    comp.setBackground(Color.orange);
                } else if (s.equalsIgnoreCase("Child")) {
                    comp.setBackground(Color.lightGray);
                } else if (s.equalsIgnoreCase("Pet")) {
                    comp.setBackground(Color.darkGray);
                } else {
                    comp.setForeground(null);
                return (comp);
    }

  • Jscrollpane jtable custom renderer focus

    I have a jtable with a customrenderer [it extends JPanel].
    The renderer contains a JScrollPane because the contents of the cell might exceed the cell.
    The problem is that I cannot scroll.
    It seems that I don't have focus on the JscrollPane.
    I have tested with many other components, and they also don't have focus.
    ex: I have a jlabel with mouselistener.On mouseEntered I have a dialog to appear but nothing happens.
    Anyone knows how to make the cell have the focus when the mouse is over it, or any other thing that might help ?
    Thanks in advance

    You can use the both:
    JTable method:
    +Sets a default cell renderer to be used if no renderer has been set in a TableColumn.+
    public void setDefaultRenderer(Class<?> columnClass, TableCellRenderer renderer)TableColumn method:
    +Sets the TableCellRenderer used by JTable to draw individual values for this column.+
    public void setCellRenderer(TableCellRenderer cellRenderer)

  • JTable custom renderer selection color

    I have included JSpinners in the last column of my JTable. However when I highlight rows all cells with a JSpinner do not have a blue background and it looks rather odd. I would have thought the following code snippet would sort it out but it hasnt. Any suggestions?
                if (isSelected) {
                    super.setForeground(table.getSelectionForeground());
                    super.setBackground(table.getSelectionBackground());
                } import java.awt.*;
    import java.awt.event.MouseEvent;
    import java.util.Arrays;
    import java.util.EventObject;
    import javax.swing.*;
    import javax.swing.table.*;
    public class JTableRender {
        private Object[][] data = {
            {"1", "2", "5"},
            {"4", "5", "5"},
            {"7", "8", "5"},
            {"7", "8", "5"}};
        public void createGui() {
            Object[] columnNames = new Object[]{"A", "B", "C"};
            JTable table = new JTable(new DefaultTableModel(data, columnNames));
            TableColumn col = table.getColumnModel().getColumn(2);
            SpinnerNumberModel snm = new SpinnerNumberModel(0,0,100,1);
            col.setCellRenderer(new MySpinnerRenderer(snm));
            col.setCellEditor(new MySpinnerEditor(snm));
            JPanel pane = new JPanel(new BorderLayout());
            pane.add(new JScrollPane(table), BorderLayout.CENTER);
            JFrame f = new JFrame("JTableExample");
            f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            f.add(pane);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        public static void main(String[] args) {
            JTableRender te = new JTableRender();
            te.createGui();
        class MySpinnerRenderer extends JSpinner implements TableCellRenderer {
            public MySpinnerRenderer(SpinnerModel sm) {
                super(sm);
            public Component getTableCellRendererComponent(JTable table, Object value,
                    boolean isSelected, boolean hasFocus, int row, int column) {
                if (isSelected) {
                    super.setForeground(table.getSelectionForeground());
                    super.setBackground(table.getSelectionBackground());
                } else {
                    setForeground(table.getForeground());
                    setBackground(table.getBackground());
                setValue(Integer.parseInt(value.toString()));
                return this;
        class MySpinnerEditor extends AbstractCellEditor implements TableCellEditor {
            final JSpinner spinner = new JSpinner();
            public MySpinnerEditor(SpinnerModel sm){
                spinner.setModel(sm);
            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
                    int row, int column) {
                spinner.setValue(Integer.parseInt(value.toString()));
                return spinner;
            @Override
            public boolean isCellEditable(EventObject evt) {
                if (evt instanceof MouseEvent) {
                    return ((MouseEvent) evt).getClickCount() >= 2;
                return true;
            public Object getCellEditorValue() {
                return spinner.getValue();
    }Thanks in advance
    Calypso

    JSpinner is a complex component that is composed of several other components including an editor which also contains a JFormattedTextField. The API will explain all, but as an example:
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column) {
          JSpinner.NumberEditor editor = (NumberEditor) super.getEditor(); //!!
          JFormattedTextField tField = editor.getTextField();
          if (isSelected) {
            tField.setForeground(table.getSelectionForeground());
            tField.setBackground(table.getSelectionBackground());
          } else {
            tField.setForeground(table.getForeground());
            tField.setBackground(table.getBackground());
          setValue(Integer.parseInt(value.toString()));
          return this;
     

  • JTable loses selection with custom renderes

    Hello,
    I have a JXTreeTable with five columns, out of which I have custom rendered 3 columns. When I select a node is the tree, the corresponding columns are selected except the custom rendered columns. Any reason why it would be so?.
    I have set the row selection enabled to be true.
    I know I shouldnt be posting JXTreeTable questions here, but am hoping any JTable guru's might be able to help me out
    Thanks
    K

    The general structure of the renderer code would be:
    class CustomRenderer extends DefaultTableCellRenderer
         public Component getTableCellRendererComponent(
              JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
              super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
              if (! isSelected)
                   // add your custom code here to change background
              return this;
    }

  • Help! Using a custom renderer to display an image

    I have a JTable where I want to set the renderer of one column to a custom renderer. And I want this renderer to show either a play button image, or a stop button image, depending on the status, which is a Boolean value. However, the image won't show up when I run the application. Here's the code from the renderer...
    public class StatusRenderer extends DefaultTableCellRenderer {
    private ImageIcon playIcon = new ImageIcon("C:/play.jpg");
    private ImageIcon stopIcon = new ImageIcon("C:/stop.jpg");
    public StatusRenderer() {
    setHorizontalAlignment(JLabel.CENTER);
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
    Boolean b = (Boolean) value;
    setIcon(b.booleanValue() ? playIcon : stopIcon);
    return this;
    The application runs, but no icon shows up in the table cell. I'd really appreciate any help on this. Thanks.

    look at http://www2.gol.com/users/tame/swing/examples/JTableExamples1.html
    for some great table examples (they may need minor mods to work on 1.3/1.4)
    Basically I think you need something more like:
    public class StatusRenderer extends JLabel
      implements DefaultTableCellRenderer
        public StatusRenderer() {
            super();
            setHorizontalAlignment(JLabel.CENTER);
        public Component getTableCellRendererComponent(JTable table,
                                           Object value, boolean sSelected,
                                           boolean hasFocus, int row,
                                           int col)
            Boolean b = (Boolean) value;
            setIcon(b.booleanValue() ? playIcon : stopIcon);
            return this;
    }Don't forget to add the renderer to the column you want it in !

  • '...' not appearing in obscured table cell when using custom renderer.

    Hello all -
    I am using a custom JPanel as a cell renderer in a JTable to display two icons per cell. Unfortunately, I am running into a problem that occurs when resizing a column such that the width of the column is less than the size of the cell content. Normally, when resizing a cell in this manner, it will start to cut off the text within the cell and add '...' to signify that some material is obscured. However, using my cell renderer, the text simply cuts off with no indication whatsoever there is more content that is being hidden. I have tried looking through the JComponent code to find a function to overload but I haven't had much luck. Does anyone have any suggestions?
    For a simple example, compile and run the following code and try resizing the two columns. You should be able to notice the difference.
    Thanks,
    - Alex
    import java.awt.*;
    import java.awt.image.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.table.*;
    public class TwoIcons extends JFrame {
         public static void main(String[] args){
              createIcons();
              SwingUtilities.invokeLater
                   new Runnable()
                        public void run() {
                             new TwoIcons();
         public TwoIcons(){
              super("Test");
              DefaultTableModel tm = new DefaultTableModel(
                   new Object[][]{
                        {new IconPair("cross", "cross"), "just a string"},
                        {new IconPair("circle", "cross"),"just another string"},
                        {new IconPair("String", "circle"),"yet another string"}
                   }, new String[]{"Two Icons","String"}){
                   public Class getColumnClass(int columnIndex){
                        if(columnIndex==0){
                             return IconPair.class;
                        else
                             return super.getColumnClass(columnIndex);
              JTable table = new JTable(tm);
              final Color bg = table.getBackground();
              table.setDefaultRenderer(IconPair.class, new TableCellRenderer(){
                        RendererPanel renderer = new RendererPanel(bg);
                        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                             renderer.setIcons((IconPair)value);
                             return  renderer;
              JScrollPane scp = new JScrollPane(table);
              add(scp);
              setSize(400,100);
              setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              pack();
              setVisible(true);
         class RendererPanel extends JPanel{
              JLabel icon1, icon2;
              RendererPanel(Color bg){
                   setLayout(new BoxLayout(this,BoxLayout.LINE_AXIS) );
                   icon1=new JLabel();
                   icon2=new JLabel();
                   add(icon1);
                   add(icon2);
                   setBackground(bg);
              public void setIcons(IconPair value) {
                   icon1.setIcon(value.i1);
                   icon1.setToolTipText("Icon 1");
                   icon2.setIcon(value.i2);
                   icon2.setToolTipText("Icon 2");
                   //uncomment next 2 lines if you want text as well
                   icon1.setText(value.s1);
                   icon2.setText(value.s2);
         class IconPair {
              public Icon i1,i2;
              public String s1,s2;
              IconPair(String s1, String s2){
                   this.i1=(Icon)icons.get(s1);
                   this.i2=(Icon)icons.get(s2);
                   this.s1=s1;
                   this.s2=s2;
         static Map icons = new HashMap();
         public static  void createIcons(){
              Image img = new BufferedImage(10,10, BufferedImage.TYPE_INT_ARGB);
              Graphics2D g2=(Graphics2D)(img.getGraphics());
              g2.setColor(Color.BLUE);
              g2.drawLine(0,0,10,10);
              g2.drawLine(0,10,10,0);
              icons.put("cross",new ImageIcon(img));
              img = new BufferedImage(10,10, BufferedImage.TYPE_INT_ARGB);
              g2=(Graphics2D)(img.getGraphics());
              g2.setColor(Color.ORANGE);
              g2.drawOval(1,1,8,8);
              icons.put("circle",new ImageIcon(img));
    }

    Things aren't resizable in your layout for the custom renderer. Here's your code working as you want (I think)
    import java.awt.*;
    import java.awt.image.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.table.*;
    public class TwoIcons extends JFrame {
         public static void main(String[] args){
              createIcons();
              SwingUtilities.invokeLater
                   new Runnable()
                        public void run() {
                             new TwoIcons();
         public TwoIcons(){
              super("Test");
              DefaultTableModel tm = new DefaultTableModel(
                   new Object[][]{
                        {new IconPair("cross", "cross"), "just a string"},
                        {new IconPair("circle", "cross"),"just another string"},
                        {new IconPair("String", "circle"),"yet another string"}
                   }, new String[]{"Two Icons","String"}){
                   public Class getColumnClass(int columnIndex){
                        if(columnIndex==0){
                             return IconPair.class;
                        else
                             return super.getColumnClass(columnIndex);
              JTable table = new JTable(tm);
              final Color bg = table.getBackground();
              table.setDefaultRenderer(IconPair.class, new TableCellRenderer(){
                        RendererPanel renderer = new RendererPanel(bg);
                        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                             renderer.setIcons((IconPair)value);
                             return  renderer;
              JScrollPane scp = new JScrollPane(table);
              getContentPane().add(scp);
              setSize(400,100);
              setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              pack();
              setVisible(true);
         class RendererPanel extends JPanel{
              JLabel icon1, icon2;
              RendererPanel(Color bg){
                   setLayout(new BoxLayout(this,BoxLayout.LINE_AXIS) );
                   icon1=new JLabel();
                   icon2=new JLabel();
                   add(icon1);
                   add(icon2);
                   icon1.setMinimumSize(new Dimension(0, 0));
                   icon2.setMinimumSize(new Dimension(0, 0));
                   icon1.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
                   icon2.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
                   setBackground(bg);
              public void setIcons(IconPair value) {
                   icon1.setIcon(value.i1);
                   icon1.setToolTipText("Icon 1");
                   icon2.setIcon(value.i2);
                   icon2.setToolTipText("Icon 2");
                   //uncomment next 2 lines if you want text as well
                   icon1.setText(value.s1);
                   icon2.setText(value.s2);
         class IconPair {
              public Icon i1,i2;
              public String s1,s2;
              IconPair(String s1, String s2){
                   this.i1=(Icon)icons.get(s1);
                   this.i2=(Icon)icons.get(s2);
                   this.s1=s1;
                   this.s2=s2;
         static Map icons = new HashMap();
         public static  void createIcons(){
              Image img = new BufferedImage(10,10, BufferedImage.TYPE_INT_ARGB);
              Graphics2D g2=(Graphics2D)(img.getGraphics());
              g2.setColor(Color.BLUE);
              g2.drawLine(0,0,10,10);
              g2.drawLine(0,10,10,0);
              icons.put("cross",new ImageIcon(img));
              img = new BufferedImage(10,10, BufferedImage.TYPE_INT_ARGB);
              g2=(Graphics2D)(img.getGraphics());
              g2.setColor(Color.ORANGE);
              g2.drawOval(1,1,8,8);
              icons.put("circle",new ImageIcon(img));
    }Note that the ... is a function of the JLabel when it is too small to render its text.

  • JTable cell rendering lag

    I've got a JTable for which I wrote a custom CellRenderer that extends JLabel. For each cell, I set the icon for the JLabel that is going to be rendered in the cell. The icon is a gif with some transparent elements. So I set the JLabel to opaque and set the background color so it will show through in the transparent areas. Works like I intended it to, but there's a lag. The table I have has enough rows to scroll well beyond the JScrollPane that it's in. When I scroll down the table, all the cells show up briefly as only the background color, then change quickly to the icon that is in the JLabel. So when I scroll, the entire table seems to be the background color without any icons. When I stop scrolling, the icons fill in pretty quick. But it's disconcerting when scrolling. Once a certain region (set of rows) has been scrolled to once, the problem doesn't happen if you scroll away and then back to that same region.
    Thanks.
    ab.

    I had considered that and eliminated that route through some testing.
    I did sort of figure out what the problem is, but don't yet have a solution. The table I'm rendering has variable height rows. Even rows are one height, odd rows another height. In my custom renderer, I modify the row heights as:
              if (getTable() != null)
                   if (row % 2 == 0)
                        if(CommonStyle.SUMMARY_ROW_HEIGHT != getTable().getRowHeight(row))
                             getTable().setRowHeight(row, CommonStyle.SUMMARY_ROW_HEIGHT);
                   else
                        if(CommonStyle.ARROW_ROW_HEIGHT != getTable().getRowHeight(row))
                             getTable().setRowHeight(row, CommonStyle.ARROW_ROW_HEIGHT);
              }Turns out changing the row heights during the rendering process is what's causing the lag, perhaps there is some table structure changing event that I need to catch and suppress. I've got some optimization code in the cell renderer to no-op the repaint and property change events. I'll let you know what I find.
    Thanks.
    ab.

  • Problem with JTree custom renderer when editing

    I have a JTree which uses a custom renderer to display my own icons for different types of nodes. The problem I am having is when I setEditable to true and then attept to edit a node the icon switches back to the default icon, as soon as I am done editing it goes back.
    What I am doing wrong?

    Here is my rendererer
    public class DeviceTreeRenderer extends DefaultTreeCellRenderer implements GuiConstants {
       public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
          JLabel returnValue = (JLabel)super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
          if (value != null) {
             returnValue.setToolTipText(value.toString());
          if (value instanceof Device) {
             returnValue.setIcon(TREE_DEVICE);
             if (!((Device)value).isAlive()) {
                returnValue.setEnabled(false);
          else if (value instanceof GuiPanelGroup) {
             if (expanded) {
                returnValue.setIcon(TREE_PANEL_GROUP_OPEN);
             else {
                returnValue.setIcon(TREE_PANEL_GROUP_CLOSED);
          else if (value instanceof GuiPanel && ((GuiPanel)value).isDirty()) {
             returnValue.setIcon(TREE_PANEL_DIRTY);
          return returnValue;
    }Here is my editor:
    public class WwpJTreeCellEditor extends DefaultTreeCellEditor implements GuiConstants {
          private WwpJTree tree;
           * Creates a new WwpJTreeCellEditor.
           * @param tree The WwpJTree to associate with this editor.
          public WwpJTreeCellEditor(WwpJTree tree) {
             super(tree, (DefaultTreeCellRenderer)tree.getCellRenderer());
             this.tree = tree;
           * Overrides the default isCellEditable so that we check the isEditable() method
           * of the WwpJTreeNodes.
           * @param e An EventObject.
          public boolean isCellEditable(EventObject e) {
             boolean returnValue = super.isCellEditable(e);
             if (returnValue) {
                WwpJTreeNode node = this.tree.getSelectedNode();
                if (node == null || !node.isEditable() || node.isDragging()) {
                   returnValue = false;
             return returnValue;
       }In my JTree I make these calls:
    super.setCellRenderer(new DeviceTreeRenderer());
    super.setCellEditor(new WwpJTreeCellEditor(this));
    super.setEditable(true);

  • Cell with boolean value not rendering properly in Swing (custom renderer)

    Hello All,
    I have a problem rendenring boolean values when using a custom cell renderer inside a JTable; I managed to reproduce the issue with a dummy application. The application code follows:
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.lang.reflect.InvocationTargetException;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.logging.Logger;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    * Simple GUI that uses custom cell rendering
    * @author josevnz
    public final class SimpleGui extends JFrame {
         private static final long serialVersionUID = 1L;
         private Logger log = Logger.getLogger(SimpleGui.class.getName());
         private JTable simpleTable;
         public SimpleGui() {
              super("Simple GUI");
              setPreferredSize(new Dimension(500, 500));
              setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              setLayout(new BorderLayout());
         public void constructGui() {
              simpleTable = new JTable(new SimpleTableModel());
              simpleTable.getColumnModel().getColumn(2).setCellRenderer(new HasItCellRenderer());
              SpecialCellRenderer specRen = new SpecialCellRenderer(log);
              simpleTable.setDefaultRenderer(Double.class, specRen);
              simpleTable.setDefaultRenderer(String.class, specRen);
              simpleTable.setDefaultRenderer(Date.class, specRen);
              //simpleTable.setDefaultRenderer(Boolean.class, specRen);
              add(new JScrollPane(simpleTable), BorderLayout.CENTER);          
              pack();
              setVisible(true);
         private void populate() {
              List <List<Object>>people = new ArrayList<List<Object>>();
              List <Object>people1 = new ArrayList<Object>();
              people1.add(0, "Jose");
              people1.add(1, 500.333333567);
              people1.add(2, Boolean.TRUE);
              people1.add(3, new Date());
              people.add(people1);
              List <Object>people2 = new ArrayList<Object>();
              people2.add(0, "Yes, you!");
              people2.add(1, 100.522222);
              people2.add(2, Boolean.FALSE);
              people2.add(3, new Date());
              people.add(people2);
              List <Object>people3 = new ArrayList<Object>();
              people3.add(0, "Who, me?");
              people3.add(1, 0.00001);
              people3.add(2, Boolean.TRUE);
              people3.add(3, new Date());
              people.add(people3);
              List <Object>people4 = new ArrayList<Object>();
              people4.add(0, "Peter Parker");
              people4.add(1, 11.567444444);
              people4.add(2, Boolean.FALSE);
              people4.add(3, new Date());
              people.add(people4);
              ((SimpleTableModel) simpleTable.getModel()).addAll(people);
          * @param args
          * @throws InvocationTargetException
          * @throws InterruptedException
         public static void main(String[] args) throws InterruptedException, InvocationTargetException {
              final SimpleGui instance = new SimpleGui();
              SwingUtilities.invokeAndWait(new Runnable() {
                   @Override
                   public void run() {
                        instance.constructGui();
              instance.populate();
    }I decided to write a more specific renderer just for that column:
    import java.awt.Color;
    import java.awt.Component;
    import javax.swing.JTable;
    import javax.swing.UIManager;
    import javax.swing.table.DefaultTableCellRenderer;
    * Cell renderer used only by the DividendElement table
    * @author josevnz
    final class HasItCellRenderer extends DefaultTableCellRenderer {
         protected static final long serialVersionUID = 2596173912618784286L;
         private Color hasIt = new Color(255, 225, 0);
         public HasItCellRenderer() {
              super();
              setOpaque(true);
         @Override
         public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
              Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
              int desCol = table.convertColumnIndexToView(1);
              if (! isSelected && value instanceof Boolean && column == desCol) {
                   if (((Boolean) value).booleanValue()) {
                        comp.setForeground(hasIt);     
                   } else {
                        comp.setForeground(UIManager.getColor("table.foreground"));
              return comp;
          * Override for performance reasons
         @Override
         public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
              // EMPTY
         @Override
         protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
              // EMPTY
         @Override
         public void revalidate() {
              // EMPTY
         @Override
         public void validate() {
              // EMPTY
    } // end classBut the rendering comes all wrong (a String saying true or false, not the expected checkbox from the default renderer) and also there is a weird flickring effect as this particular boolean column is editable (per table model, not show here)...
    I can post the table model and the other renderer if needed (didn't want to put too much code on the question, at least initiallty).
    Should I render a checkbox myself for this cell in the custom renderer? I'm puzzled as I expected the default renderer part of the code to do this for me instead.
    Thanks!
    Edited by: josevnz on Apr 14, 2009 12:35 PM
    Edited by: josevnz on Apr 14, 2009 12:37 PM

    camickr
    Thats because the default render is a JLabel and it just displays the text from the toString() method of the Object in the table model.What I meant to say is that I expected the JCheckbox not a String representation of the boolean value.
    Thats because a different renderer is used depending on the Class of data in the column. Look at the source code for the JTable class to see what the "default >renderer for the Boolean class" is. Then you can extend that or if its a private class then you will need to copy all the code and customize it.At the end I looked at the code and replicated the functionality I needed. I thought than maybe there was a way to avoid replicating the same logic all over again in order to implement this functionality. Good advice, though.
    see you learned nothing from your last posting. This is NOT a SSCCE. 90% of the code you posted is completely irrelevant for the described problem. There is abosutelly no need to post the custom TableModel, because there is no need to use a custom TableModel for this problem. The TableModel has nothing to do with how a column is rendererd.The custom table model returns the type of the column (giving a hint to the renderer on what to expect, right?) and for the one that had a problem it says than the class is Boolean. That's why I mentioned it:
    public Class getColumnClass(int columnIndex) {
        // Code omited....
    You also posted data for 4 columns worth of data. Again, irrelevant. Your question is about a single column containing Boolean data, so forget about the other columns.
    When creating a SSCCE you don't start with your existing code and "remove" code. You start with a brand new class and only add in what is important. That way hopefully if you made a mistake the first time you don't repeat it the second time.That's what I did, is not the real application. I copy & pasted code in a haste from this dummy program on this forum, not the best approach as it gave the wrong impression.
    Learn how to write a proper SSCCE if you want help in the future. Point taken, but there is NO need for you to be rude. Your help is appreciated.
    Regards,
    Jose.

  • Multiple Icon on Jtable header

    Hi All:
    Any one had used multiple icons on JTable header ? According to the user's clicking positon under one column, one of these icons should change such as changing from sorting up arrows to sorting down arrows.
    I got the mouse clicking position on the header and column, then depend on the location, I wanted to perfrom different things. But I have not figured out if I should call header renderer to perform the repaint or not ? If I use JTable header render, how should I confine the one column that change should happen? I don't want to have all columns repainted. If I treat each column indivisually, should I reconstruct the JTable ? I used SortableTableModel to create the JTable.
    Any help is appreciated.
    Regards

    Here's the idea. I didn't test thisclass JComponentCellRenderer extends JButton implements TableCellRenderer {
        public JComponentCellRenderer (ImageIcon ii) { super("",ii); }
        public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
            setText(value.toString());
            return this;
    }and thentblChanges.getColumnModel().getColumn(0).setHeaderRenderer(new JComponentCellRenderer(new ImageIcon( "CheckBoxHeaderImage" )));

  • Problems with JTable custom cell renderers

    Hi All,
    I'm having a bit of a problem writing a custom renderer for a JTable.
    What seems to be happening is that the changes I apply in the renderer to the component are applied to ALL cells.
    All I want to do is have a different background color for certain cells....
    Ive derived from DefaultTableCellRenderer, so Im using its getTableCellRendererComponent to do most of the work.
    So, Ive got something like this:
    private class DirtyCacheRenderer extends DefaultTableCellRenderer
        public Component getTableCellRendererComponent(JTable table, Object value,
                              boolean isSelected, boolean hasFocus, int row, int column)
          // Modifies 'this'
          super.getTableCellRendererComponent(table,value,isSelected,hasFocus,row,column);
          // If the row/column is 'dirty' (I.e - if I want 2 color it diferently)
          if(((EditableTableModel)table.getModel()).isDirty(row,column))
            // The column is dirty. Set the color accordingly:
            super.setBackground(DIRTY_COLOR);
          return this;
      }The effect is that as soon as ONE cell gets its color set above, all of the cells do!
    Please help, its driving me mad!!!
    D

    I tried this and it worked. Tell me if it is OK for you.
    import javax.swing.table.TableCellRenderer;
    import java.awt.Color;
    import java.awt.Component;
    import javax.swing.JTable;
    import javax.swing.JLabel;
    public class testRenderer implements TableCellRenderer {
    JLabel cell = new JLabel();
    Color dirty = new Color(100,100,100);
    Color clear = new Color(0,0,0);
    public testRenderer() {
    cell.setOpaque(true);
    public Component getTableCellRendererComponent(JTable table,Object value,
    boolean isSelected,boolean hasFocus, int row, int column) {
    cell.setText(value.toString());
    // The column is dirty. Set the color
    if (row == column)     {
    cell.setBackground(dirty);
    } else {
    cell.setBackground(table.getBackground());
    return cell;
    }

  • Dynamic JTable and rendering column as JComboBox

    I originally posted this to the "Java Programming" topic, but it was suggested that I move it over here.
    I'm new to cell renderers and editors, so I'm hoping someone can put me on the right path.
    I've got a JTable that is initially empty. I've set one column to use a custom cell renderer that extends JComboBox and implements TableCellRenderer.
    The user can add rows to the table at any time, I'm using TableModel.addRow() for this. When I call addRow, I pass the entryies for the JComboBox column as a String[], with one array element for each entry in the JComboBox.
    In my custom renderer, I take the values from the array and use JComboBox.addItem() to add them to the JComboBox.
    When I run the code, it appears fine, but the JComboBox doesn't function, i.e. it is not editable (yes, the column is set as editable). I assume I need to add a custom editor. I tried
    table.setCellEditor(new DefaultCellEditor(ComboBoxCellRenderer);
    and the combobox was now editable, but it was empty and I got nullpointer exceptions.
    What am I missing?
    Any help is appreciated. Here is what I'm trying:
    **************** Constructing the table **************
    DefaultTableModel tablemodel = new DefaultTableModel(columnnames,0);
    datasourcestable = new JTable(tablemodel) ;
    // Set custom renderer for particular columns in this JTable
    ComboBoxCellRenderer renderer = new ComboBoxCellRenderer();
    TableColumn waveformscalarcolumn = datasourcestable.getColumnModel().getColumn(datasourcestable.getColumn("Title").getModelIndex());
    waveformscalarcolumn.setCellRenderer(renderer);
    // tried the following, combobox becomes editable but empty
    //waveformscalarcolumn.setCellEditor(new DefaultCellEditor(renderer));
    *************** Adding rows to the table (Event Code)*********************
    DefaultTableModel tablemodel = (DefaultTableModel)datasourcestable.getModel();
    Object[] rowdata = new Object[3];
    rowdata[0] = "gaga";
    String[] cboxentries = {"cbox entry 1","cbox entry 2"};
    rowdata[1] = cboxentries;
    rowdata[1] = "gaga"'
    tablemodel.addRow(rowdata);
    **************** Custom Cell Renderer **********************
    class ComboBoxCellRenderer extends JComboBox implements TableCellRenderer {
    public ComboBoxCellRenderer() {
    setOpaque(true);
    public Component getTableCellRendererComponent(JTable table, Object value,boolean isSelected, boolean hasFocus, int row, int column) {
    String[] stringarray = (String[]) value;
    for (int i=0; i<stringarray.length; i++){
    this.addItem(stringarray);
    return this;
    }

    Ah! Using the ArrayList of editors in getCellEditor() is very clever, that's the solution I couldn't come up with. Now I just have to remember to add and delete editors as I add and delete rows.
    Thanks, I've got everything working now. Here's are some code snippets, for anyone interested. I used Vector rather than ArrayList to be thread safe.
    // ******************* Global variables ***********
    Vector<TableCellEditor> editors = new Vector<TableCellEditor>(24,8);
    JTable table;
    // *************** construct table ****************
    DefaultTableModel tablemodel = new DefaultTableModel(columnnames,0);
    table = new JTable(tablemodel) {
         public TableCellEditor getCellEditor(int row,int col) {
              int modelcolumn = convertColumnIndexToModel(col);
              int fancycol = table.getColumn("Title").getModelIndex();
              if (modelcolumn == fancycol) {
                   return (TableCellEditor)editors.elementAt(row);
              } else {
                   return super.getCellEditor(row,col);
    // Set custom renderer for particular column in this JTable
    ComboBoxCellRenderer comboboxrenderer = new ComboBoxCellRenderer();
    TableColumn column = table.getColumnModel().getColumn(table.getColumn("Title").getModelIndex());
    column.setCellRenderer(comboboxrenderer);
    //*************** Adding rows to the table (Event Code)*********************
    DefaultTableModel tablemodel = (DefaultTableModel)table.getModel();
    Object[] rowdata = new Object[3];
    rowdata[0] = "gaga";
    String[] cboxentries = {"cbox entry 1","cbox entry 2"};
    JComboBox cellcombo = new JComboBox();
    cellcombo.addItem(cboxentries[0]);
    cellcombo.addItem(cboxentries[1]);
    DefaultCellEditor editor = new DefaultCellEditor(cellcombo);
    editors.add(editor);
    rowdata[1] = cellcombo.getItemAt(0);          // don't know if this matters
    rowdata[2] = "gaga2";
    tablemodel.addRow(rowdata);
    //**************** Custom Cell Renderer *********************
    class ComboBoxCellRenderer extends JComboBox implements TableCellRenderer {
         public ComboBoxCellRenderer() {
         public Component getTableCellRendererComponent(JTable table, Object value,boolean isSelected, boolean hasFocus, int row, int column) {
    // display value in our JComboBOx
              this.addItem(value);
              this.setSelectedItem(value);
              return this;
    }

Maybe you are looking for