TableCellRenderer

I've made a TableCellRenderer to be used in a treetable. For some reason when I click on a row containing a leaf node and then click on a row containing a folder node, the icon for the row with the folder node is changed to a leaf icon. This is all the code I've done for the JTable. I have the isExpanded method called below always return true. All the other code I have is for my TreeTableModel.Any ideas on how to fix this? Any questions please ask. Thanks.
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.tree.*;
public class TreeTableCellRenderer  extends JLabel implements TableCellRenderer
    private int _offset;
     public TreeTableCellRenderer()
        super();
     public Icon getExpandedIcon()
          return( UIManager.getIcon("Tree.expandedIcon"));
     public Icon getCollapsedIcon()
          return( UIManager.getIcon("Tree.collapsedIcon"));
     public Icon getLeafIcon()
          return( UIManager.getIcon("Tree.leafIcon") );          //Tree.openIcon and Tree.closedIcon
    @Override
     public Component getTableCellRendererComponent(JTable table, Object color, boolean isSelected, boolean hasFocus,int row, int column)
        TreeTableModel model = (TreeTableModel) table.getModel();
        _offset = model.getLevel(row)*10;
          this.setFont(UIManager.getFont("Tree.font"));
          if (model.isLeaf(row))
               this.setIcon( getLeafIcon() );
          else if( ((TreeTable)table).isExpanded(row) )
               this.setIcon( getExpandedIcon() );
          else
               this.setIcon( getCollapsedIcon() );
          this.setText(model.getNode(row).toString());
          return( this );
        @Override
    public void paintComponent(Graphics g)
        g.translate(_offset,0);
        super.paintComponent(g);
}Edited by: jrw10293 on Oct 7, 2009 7:31 PM

The override of paint() in your code is reminiscent of the treetable renderer in the Sun example but that renderer is a JTree, not a JLabel. The override ensures the tree is painted such that the correct tree node appears in the table row. There would be no such requirement for a label so the results you are getting will be due to this function.

Similar Messages

  • JTable text alignment issues when using JPanel as custom TableCellRenderer

    Hi there,
    I'm having some difficulty with text alignment/border issues when using a custom TableCellRenderer. I'm using a JPanel with GroupLayout (although I've also tried others like FlowLayout), and I can't seem to get label text within the JPanel to align properly with the other cells in the table. The text inside my 'panel' cell is shifted downward. If I use the code from the DefaultTableCellRenderer to set the border when the cell receives focus, the problem gets worse as the text shifts when the new border is applied to the panel upon cell selection. Here's an SSCCE to demonstrate:
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.EventQueue;
    import javax.swing.GroupLayout;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTable;
    import javax.swing.border.Border;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableColumn;
    import sun.swing.DefaultLookup;
    public class TableCellPanelTest extends JFrame {
      private class PanelRenderer extends JPanel implements TableCellRenderer {
        private JLabel label = new JLabel();
        public PanelRenderer() {
          GroupLayout layout = new GroupLayout(this);
          layout.setHorizontalGroup(layout.createParallelGroup().addComponent(label));
          layout.setVerticalGroup(layout.createParallelGroup().addComponent(label));
          setLayout(layout);
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
          if (isSelected) {
            setBackground(table.getSelectionBackground());
          } else {
            setBackground(table.getBackground());
          // Border section taken from DefaultTableCellRenderer
          if (hasFocus) {
            Border border = null;
            if (isSelected) {
              border = DefaultLookup.getBorder(this, ui, "Table.focusSelectedCellHighlightBorder");
            if (border == null) {
              border = DefaultLookup.getBorder(this, ui, "Table.focusCellHighlightBorder");
            setBorder(border);
            if (!isSelected && table.isCellEditable(row, column)) {
              Color col;
              col = DefaultLookup.getColor(this, ui, "Table.focusCellForeground");
              if (col != null) {
                super.setForeground(col);
              col = DefaultLookup.getColor(this, ui, "Table.focusCellBackground");
              if (col != null) {
                super.setBackground(col);
          } else {
            setBorder(null /*getNoFocusBorder()*/);
          // Set up our label
          label.setText(value.toString());
          label.setFont(table.getFont());
          return this;
      public TableCellPanelTest() {
        JTable table = new JTable(new Integer[][]{{1, 2, 3}, {4, 5, 6}}, new String[]{"A", "B", "C"});
        // set up a custom renderer on the first column
        TableColumn firstColumn = table.getColumnModel().getColumn(0);
        firstColumn.setCellRenderer(new PanelRenderer());
        getContentPane().add(table);
        pack();
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          public void run() {
            new TableCellPanelTest().setVisible(true);
    }There are basically two problems:
    1) When first run, the text in the custom renderer column is shifted downward slightly.
    2) Once a cell in the column is selected, it shifts down even farther.
    I'd really appreciate any help in figuring out what's up!
    Thanks!

    1) LayoutManagers need to take the border into account so the label is placed at (1,1) while labels just start at (0,0) of the cell rect. Also the layout manager tend not to shrink component below their minimum size. Setting the labels minimum size to (0,0) seems to get the same effect in your example. Doing the same for maximum size helps if you set the row height for the JTable larger. Easier might be to use BorderLayout which ignores min/max for center (and min/max height for west/east, etc).
    2) DefaultTableCellRenderer uses a 1px border if the UI no focus border is null, you don't.
    3) Include a setDefaultCloseOperation is a SSCCE please. I think I've got a hunderd test programs running now :P.

  • TableCellRenderer with JTextPane and HTML

    I'm writing a TableCellRenderer that will be rendering HTML content using a custom extension to the JTextPane class. Where I'm having trouble is in calculating the necessary height to set the table row based on the content of the cell (in this case HTML text in my JTextPane component). I know the width of the table cell and I can figure out the width of the content (taking into account the formatting because of the HTML content). This all works perfectly until the column width shrinks enough to cause the underlying view to word wrap.
    Here is the code snippet from my JTextPane to count the number of lines of text and calculate the width of the content
      public int getWidthOfContent() {
        getLineCount();
        return m_iWidthOfContent;
      public int getWidthOfContent(int p_iWidthOfArea) {
        getLineCount(p_iWidthOfArea);
        return m_iWidthOfContent;
      public int getLineCount(int iComponentWidth) {
        int iWidth = 0;
        int iBreakCount = 0;
        int iHardBreakCount = 0;
        int iTotalWidth = 0;
        int iTotalContentWidth = 0;
        int iMaxHeight = 0;
        Document doc = getDocument();
        ElementIterator it = new ElementIterator(doc.getDefaultRootElement());
        StyleSheet styleSheet = null;
        if(doc instanceof HTMLDocument) {
          styleSheet = ((HTMLDocument)doc).getStyleSheet();
        if(iComponentWidth == -1) {
          iWidth = getWidth();
        else {
          iWidth = iComponentWidth;
        Element e;
        while ((e=it.next()) != null) {
          AttributeSet attributes = e.getAttributes();
          Enumeration enumeration = attributes.getAttributeNames();
          boolean bBreakDetected = false;
          while(enumeration.hasMoreElements()) {
            Object objName = enumeration.nextElement();
            Object objAttr = attributes.getAttribute(objName);
            if(objAttr instanceof HTML.Tag) {
              HTML.Tag tag = (HTML.Tag)objAttr;
    //          if(tag == HTML.Tag.BODY) {
    //            UCSParagraphView pv = new UCSParagraphView(e);
    //            if(pv.willWidthBreakView(iWidth)) {
    //              iHardBreakCount++;
              FontMetrics fontMetrics = null;
              if(styleSheet != null && styleSheet.getFont(attributes) != null) {
                fontMetrics = getFontMetrics(styleSheet.getFont(attributes));
              if(fontMetrics != null && fontMetrics.getHeight() > iMaxHeight) {
                iMaxHeight = fontMetrics.getHeight();
              if(tag.breaksFlow()) {
                //This must be a breaking tag....this will add another line to the count
                bBreakDetected = true;
                if(tag.equals(HTML.Tag.BR) || tag.isBlock() && (!tag.equals(HTML.Tag.HEAD) && !tag.equals(HTML.Tag.BODY))) {
                  if(iTotalContentWidth == 0) {
                    iTotalContentWidth = iTotalWidth;
                    iTotalWidth = 0;
                  else if(iTotalWidth > iTotalContentWidth) {
                    iTotalContentWidth = iTotalWidth;
                    iTotalWidth = 0;
                  else {
                    iTotalWidth = 0;
                  if(tag.equals(HTML.Tag.H1) || tag.equals(HTML.Tag.H2) || tag.equals(HTML.Tag.H3) || tag.equals(HTML.Tag.H4)) {
                    iHardBreakCount += 3; //These count as three lines (Blank - Content - Blank)
                  else {
                    iHardBreakCount++;
                iBreakCount++;
          if(!bBreakDetected) {
            Font font;
            FontMetrics fontMetrics;
            if(e.getDocument() instanceof HTMLDocument) {
              font = ((HTMLDocument)e.getDocument()).getStyleSheet().getFont(e.getAttributes());
              fontMetrics = getFontMetrics(font);
            else {
              font = getFont();
              fontMetrics = getFontMetrics(font);
            int iRangeStart = e.getStartOffset();
            int iRangeEnd = e.getEndOffset();
            if(fontMetrics.getHeight() > iMaxHeight) {
              iMaxHeight = fontMetrics.getHeight();
            if(e.isLeaf()) {
              String strText;
              try {
                strText = this.getText(iRangeStart, iRangeEnd - iRangeStart);
                if(strText.equals("\n")) {
                  //iBreakCount++;
                iTotalWidth += SwingUtilities.computeStringWidth(fontMetrics, strText);
              catch (BadLocationException ex) {
                //Something happened.....don't care....just eat the exception
        m_iMaxFontHeight = iMaxHeight;
        m_iWidthOfContent = iTotalWidth;
        m_iHardBreakCount = iHardBreakCount;
        if(iWidth > 0) {
          int iLineCount = (iTotalWidth / iWidth) + iBreakCount;
          return iLineCount;
        return 1;
      }And here is the code from my TableCellRenderer that uses the above information
       public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                                                      boolean hasFocus, int row, int column) {
         if(ValidationHelper.hasText(value) && value.toString().indexOf("<html>") != -1) {
           UCSHTMLTextPane pane = new UCSHTMLTextPane();
           pane.setText(ValidationHelper.getTrimmedText(value.toString()));
           BigDecimal lWidthCell = new BigDecimal(table.getCellRect(row, column, false).getWidth() - 15);
           BigDecimal lWidthContent = new BigDecimal(pane.getWidthOfContent(lWidthCell.intValue()));
           int iHardBreakCount = pane.getHardBreakCount();
           BigDecimal lLineCount = lWidthContent.divide(lWidthCell, BigDecimal.ROUND_CEILING);
           int iLineCount = lLineCount.intValue();
           double dWidthCell = lWidthCell.doubleValue();
           double dWidthContent = lWidthContent.doubleValue();
           double dWidthContentPlusFivePercent = dWidthContent + (dWidthContent * .01);
           double dWidthContentMinumFivePercent = dWidthContent - (dWidthContent * .01);
           if(dWidthCell >= dWidthContentMinumFivePercent && dWidthCell <= dWidthContentPlusFivePercent) {
             iLineCount++;
           iLineCount += iHardBreakCount;
           int iMaxFontHeight = pane.getMaxFontHeight();
           int iHeight = (iMaxFontHeight * iLineCount) + 5;
           if ( (iLineCount > 0) && (table.getRowHeight(row) != iHeight)) {
             pane.setPreferredSize(new Dimension(0, iHeight));
             if(m_bAutoAdjustHeight) {
               table.setRowHeight(row, iHeight);
           if(iLineCount == 1) {
             if(iHeight != table.getRowHeight()) {
               if(m_bAutoAdjustHeight) {
                 table.setRowHeight(iHeight);
           setComponentUI(pane, table, row, column, isSelected, hasFocus);
           return pane;
    }Any suggestions?

    Hello,
    You must initialize correctly your JTextPane like this:
    javax.swing.text.html.HTMLEditorKit htmlEditorKit = new javax.swing.text.html.HTMLEditorKit();
    javax.swing.text.html.HTMLDocument htmlDoc = (javax.swing.text.html.HTMLDocument)htmlEditorKit.createDefaultDocument();
    setEditorKit(htmlEditorKit);
    setDocument(htmlDoc);
    setEditable(true);
    setContentType("text/html");

  • MultiLineCellRenderer (TableCellRenderer) not working in 1.4

    I have the following custom TableCellRenderer I use to display a multi-line cell in a JTable. The row height is suppose to adjust itself automatically so that all the text is visible. This worked perfectly fine in 1.3. In 1.3, the JTextArea was given a preferred size after setting the text, so when calling the getPreferredSize() method, I would get the dimensions of the text area needed to display the entire text. In 1.4, however, I seem to get the default preferred size (100x34) even after setting the text, so my row height is never set properly. Does anybody have any work around for this?
    public class MultiLineCellRenderer extends JTextArea
      implements TableCellRenderer {
      JTable mTable;
        public MultiLineCellRenderer(JTable table) {
          super();
          mTable = table;
          setLineWrap(true);
          setWrapStyleWord(true);
          setOpaque(true);
          setEditable(false);
        public Component getTableCellRendererComponent(JTable jTable,
            Object obj, boolean isSelected, boolean hasFocus, int row,
            int column) {
          // set the text
          setText((obj == null)?"":obj.toString());
          // get the current row height
          int height = mTable.getRowHeight(row);
          System.out.println("Get Preferred Size: " + getPreferredSize());
          System.out.println("Get Size: " + getSize());
          // if the current height is insufficient, resize the row height
          if (height < this.getPreferredSize().getHeight()) {
            mTable.setRowHeight(row, (int)(getPreferredSize().getHeight()));
          return this;
    }

    Hi,
    I am also using almost the similar code and using JDK1.3, but I am using my table in a scroll pane. Problem is that when I am using the scroll bar, sometimes the text in cells get wrapped and sometimes not.
    Some changes in my code from your code are :
    1. I am not extending my renderer from JTextArea, instead using a member variable of JTextArea in my renderer class and returning that after setting the text and row height from getTableCellRendererComponent() method.
    2. I am not keeping table as a member variable in the class. I am setting row height of the table instance that comes in the getTableCellRendererComponent() method.
    Can anyone tell me why it does not work while scrolling?
    My code is something like below:
    public class MultiLineCellRenderer implements TableCellRenderer {
       JTextArea myLabel;
         public MultiLineCellRenderer(JTable table) {
            myLabel = new JTextArea(); 
            myLabel.setLineWrap(true);
           myLabel.setWrapStyleWord(true);
           myLabel.setOpaque(true);
           myLabel.setEditable(false);
    public Component
    getTableCellRendererComponent(JTable jTable,
    Object obj, boolean isSelected, boolean
    boolean hasFocus, int row,
             int column) {
           // set the text
           myLable.setText((obj == null)?"":obj.toString());
           // get the current row height
           int height = jTable.getRowHeight(row);
    // if the current height is different, resize the row height
    if (height != myLabel.getPreferredSize().getHeight()) {
    jTable.setRowHeight(row, (int)(getPreferredSize().getHeight()));
           return myLabel;

  • How to do a TableCellRenderer with Windows XP Look'n Feel ?

    In my application i use a sortable JTable view. In order to visualize the sorted column selected by user interaction i wrote my own TableCellRenderer implemantation to feature this with an icon in the table header which shows an arrow symbol for ascending or descending sort order. In addition to that i installed a handler which underlines the header label when the user hovers over a header column with the mouse. This all works perfectly but now i challenged the following problem: The application works in a Microsoft Windows XP environment and uses the corresponding XP Look'n Feel (available since Java SDK 1.4.2). The entire application makes uses of this specific
    Look'n Feel but as i use a userdefined TableCellRenderer the table outlook is the one of the 'old' default windows Look'n Feel not the one of Windows XP. If i use the default renderer all looks what it should look like but the enhanced sorting and hover capabilities get lost.
    My question: How do i combine the xp look with my enhanced table header features ?
    I had a look at com.sun.java.swing.plaf.windows.WindowsTableHeaderUI and there's an embedded inner class named XPDefaultRenderer which makes use of the xp skinning technology and paints the correct xp like border. Unfortunately this class is declared private and the com.sun.java.swing.plaf.windows.XPStyle which is being used inside is package private. So no chance to implement a userdefined swing component that features the xp Look'n Feel.
    Is this whole thing organized like that to fulfill copyright restictions in relation to the xp Look'n Feel which should stay unmodified ? Or is there another chance to get the userdfined renderer to feature the correct Look'n Feel ? At the moment the table header doesn't fit in the Look'n Feel at all which is annoying. Is there a solution ? Please help if you know any possible way to solve this. Thank you.

    Just a followup on the missing mouse-over effect and the bad sizing of
    XP table headers in 1.4.2. These problems are covered by bug reports:
    http://developer.java.sun.com/developer/bugParade/bugs/4855121.html
    http://developer.java.sun.com/developer/bugParade/bugs/4774013.html
    Both of these bugs will be fixed in 1.5. Here is a workaround you can
    use for 1.4.2.
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.table.*;
    import com.sun.java.swing.plaf.windows.*;
    public class XPTableHeaderRenderer extends DefaultTableCellRenderer
                           implements MouseListener, MouseMotionListener {
        private JTableHeader header;
        private DefaultTableCellRenderer oldRenderer;
        private int rolloverColumn = -1;
        public XPTableHeaderRenderer(JTableHeader header) {
         this.header = header;
         this.oldRenderer = (DefaultTableCellRenderer)header.getDefaultRenderer();
         header.addMouseListener(this);
         header.addMouseMotionListener(this);
        private void updateRolloverColumn(MouseEvent e) {
         int col = header.columnAtPoint(e.getPoint());
         if (col != rolloverColumn) {
             rolloverColumn = col;
             header.repaint();
        public void mouseMoved(MouseEvent e) {
         updateRolloverColumn(e);
        public void mouseEntered(MouseEvent e) {
         updateRolloverColumn(e);
        public void mouseExited(MouseEvent e) {
         rolloverColumn = -1;
         header.repaint();
        public void mousePressed(MouseEvent e) {
         rolloverColumn = -1;
         header.repaint();
        public void mouseReleased(MouseEvent e) {
         updateRolloverColumn(e);
        public void mouseClicked(MouseEvent e) {
        public void mouseDragged(MouseEvent e) {
        public Component getTableCellRendererComponent(JTable table, Object value,
                                     boolean isSelected, boolean hasFocus,
                                     int row, int column) {
         JComponent comp =
             (JComponent)oldRenderer.getTableCellRendererComponent(table,
                                              value, isSelected,
                                              hasFocus || (column == rolloverColumn),
                                              row, column);
         comp.setBorder(new EmptyBorder(3, 8, 4, 8));
         return comp;
        public static void main(String[] a) throws Exception {
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
         JFrame f = new JFrame();
         JTable table = new JTable(5, 5);
         f.getContentPane().add(new JScrollPane(table));
         if (System.getProperty("java.version").startsWith("1.4.2")) {
             // Replace the XP renderer with our own
             JTableHeader header = table.getTableHeader();
             TableCellRenderer renderer = header.getDefaultRenderer();
             String name = renderer.getClass().getName();
             if (name.equals("com.sun.java.swing.plaf.windows.WindowsTableHeaderUI$XPDefaultRenderer")) {
              header.setDefaultRenderer(new XPTableHeaderRenderer(header));
         f.setBounds(100, 100, 200, 200);
         f.setVisible(true);
    }Cheers,
    /Leif

  • Problem Regarding TableCellRenderer

    I am facing problem with JTable's row/cell focus appearence.
    tableAlert is a table :
    private MultiSpanCellTable tableAlert =
    new MultiSpanCellTable(new AttributiveCellTableModel(columnHeaders, 0), false)
    Here MultiSpanCellTable is JTable Type
    tableAlert.setDefaultRenderer(Object.class ,new AttributiveCellRenderer());
    Here AttributiveCellRenerer is a userdefined Renderer which implements TableCellRenderer
    my probelem is when I am clicking to a list Item which is a label(Icon) appearence of the particular row should be changed.
    Here afew lines of code when list item is clicked:
    getListTableHeader().addMouseListener(new MouseAdapter()
    public void mouseReleased(MouseEvent e)
    if (e.getClickCount() >= 1)
    int index = getListTableHeader().locationToIndex(e.getPoint());
    try
    if (((ae_AlertEventInfo)theAlerts.values().toArray()[index]).ackRequiredFlag)
    AcknowledgeEvent ackEvent = new AcknowledgeEvent(
    this, (ae_AlertEventInfo)theAlerts.values().toArray()[index]);
    fireAcknowledgeEvent(ackEvent);
    ((HeaderListModel)listModel).setElementAt(ACK,index);
    catch(Exception ex) {;}
    How can I call table renderer from here.

    How can I call table renderer from here.The renderer is called automatically by JTable API.
    You cannot call it directly yourself.
    However, one thing you could do, is to change customizing
    variables in the renderer or something alike.
    After that you could call something like tableAlert.repaint() or
    tableAlert.updateUI()

  • Custom TableCellRenderer

    Hi I have problem with TableCellRenderer. I whant to put some components in to table cell, and i made my TableCellRenderer wich extends JPanel. When i put components on it the are not visible, but they are on this panel (i check with getComponentCount()). And the are added too all cells in column. I need to have difrent components in difrent number in each cell. For example:
    in cell 0: 3 radiobuttons
    in cell 1: 4 labels and 4 Textfields
    in cell 2: 5 checkboxes
    and so on..
    Can anybody tell me if is posible to do this?? And i would be greateful i some one help me to do this if it is possible.
    Thanx in advance.

    Hi you all!
    Here is my new code that sets the color correctly in all the JPanels that are part of the TableCellRenderer. However, I still get a little fifth row that is not filled with the correct color.
    public class ScheduleCellRenderer extends JPanel implements TableCellRenderer{
      public final static Color NORMAL_COLOR = new Color(255, 255, 184);
      public final static Color SELECT_COLOR = Color.blue;
      GridLayout m_gridlRoot = new GridLayout();
      JPanel[] m_jpanCells = new JPanel[4];
       * Creates a ScheduleCellRenderer.
      public ScheduleCellRenderer() {
        try {
          jbInit();
          for (int i = 0; i < m_jpanCells.length; i++) {
            m_jpanCells[i] = new JPanel();
            (m_jpanCells).setBackground(NORMAL_COLOR);
    this.add(m_jpanCells[i]);
    catch(Exception e) {
    e.printStackTrace();
    * Inits the GUI components.
    * This method is autogenerated by JBuilder 4.
    private void jbInit() throws Exception {
    m_gridlRoot.setRows(4);
    m_gridlRoot.setColumns(1);
    m_gridlRoot.setHgap(0);
    m_gridlRoot.setVgap(0);
    this.setBackground(new Color(255, 255, 184));
    this.setOpaque(true);
    this.setLayout(m_gridlRoot);
    * Returns the Component to render a specified cell.
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    if(isSelected){
    for (int i = 0; i < m_jpanCells.length; i++) {
    (m_jpanCells[i]).setBackground(SELECT_COLOR);
    }else if(value instanceof AltTimeData){
    for (int i = 0; i < m_jpanCells.length; i++) {
    (m_jpanCells[i]).setBackground(Color.green);
    }else if(value instanceof TimeData){
    for (int i = 0; i < m_jpanCells.length; i++) {
    (m_jpanCells[i]).setBackground(Color.white);
    }else if(!isSelected){
    for (int i = 0; i < m_jpanCells.length; i++) {
    (m_jpanCells[i]).setBackground(NORMAL_COLOR);
    return this;
    Regards
    Johan

  • Problem with TableCellRenderer

    Hi all, I need to put a JLabel within an ImageIcon in third column of a JTable,
    so i implement the TableCellRenderer , i test the code, but only text show, third column's JLabel doesn't show, it shows :
    javax.swing.JLabel[,0,0,0x0,invalid,alignmentX=0.0,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,defaultIcon=javax.swing.ImageIcon@107f45d,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=,verticalAlignment=CENTER,verticalTextPosition=CENTER]
    here is part of code:
    QueryTable.getColumnModel().getColumn(2).setCellRenderer(new LabelTableRenderer());
    Object[] k = { ser.getTheAccount(), ser.getTheDate(), ss};
    qtm.addRow(k); //qtm is a DefaultTableModel instance
    class LabelTableRenderer extends JLabel implements TableCellRenderer {
    public LabelTableRenderer() {
    super();
    setOpaque(true);
    public Component getTableCellRendererComponent(JTable table,
    Object value, boolean isSelected, boolean hasFocus, int
    row,
    int column) {
    return this;
    i don't know where's the problem with my TableCellRenderer , anyone can help me please?
    thanx in advance
    hallelujah, Dino

    hi thanx for your help, i already refer that thread, but it doesn't work for me .:(
    all i want to do is put a JLabel within ImageIcon or only an ImageIcon in a column of JTable
    third column should display ImageIcon, but still show junk strings, hope someone can help me.
    i post my code here,
    String[] columns = {
    "aa", "bb", "cc"};
    Object[][] data = {
    ser.getTheAccount(), ser.getTheDate(), ser.getTheImage()} //String,String,ImageIcon
    DefaultTableModel dt = new DefaultTableModel(data, columns);
    QueryTable = new JTable(dt) {
    public Class getColumnClass(int column) {
    System.out.println("col:" + column + " " +
    getValueAt(0, column).getClass().toString());
    return getValueAt(0, column).getClass();
    jScrollPane1.getViewport().add(QueryTable, null);
    QueryTable.setBorder(BorderFactory.createEtchedBorder());
    QueryTable.setPreferredSize(new Dimension(300, 100));
    QueryTable.getTableHeader().setReorderingAllowed(false);
    QueryTable.setRowHeight(100);
    dt = new DefaultTableModel();
    dt.setDataVector(data, columns);
    i don't know where's the problem, please help me, thanx in andvance.
    hallelujah,
    Dino

  • JCheckBox and TableCellRenderer

    I'm using a boolean value as a column within a JTable. I want to change the color of a JCheckBox from black to red in the column based on a test.
    I created a class to extend JCheckBox which implements TableCellRenderer. When the JTable is displayed, the checkbox is there, but you can't see the check in the box, just a square until you press the mouse key on the checkbox, then either the checked or unchecked
    condition can be seen.
    Here's the setup of the JTable:
    TableName.setDefaultRenderer(Boolean.class,
    new gridTableCellRenderer(DisplayData));
    If I comment out the line above, the checkbox appears correctly showing the checked or unchecked condition without depressing the mousebutton.
    Here's the class itself:
    package NewPackage;
    import javax.swing.*;
    import javax.swing.table.*;
    import java.awt.*;
    import java.util.*;
    class gridTableCellRenderer extends JCheckBox implements TableCellRenderer {
    private Vector DisplayData = null;
    public gridTableCellRenderer( Vector DisplayData ) {
    super();
    // setOpaque(true);
    this.DisplayData = DisplayData;
    public Component getTableCellRendererComponent( JTable table,
    Object value, boolean isSelected,
    boolean hasFocus, int row, int column ) {
    Display record = (Display) DisplayData.get(row);
    if ( record.getItemID() == 0 ) {
    switch( column ) {
    case 0:
    // setBackground(Color.red);
    // setForeground(Color.black);
    // setEnabled(false);
    break;
    default:
    break;
    } /* ...end of switch statement... */
    } /* ...end of if ( record.getItemID() == 0... */
    else {
    switch( column ) {
    case 0:
    // setBackground(Color.lightGray);
    // setForeground(Color.black);
    // setEnabled(true);
    break;
    default:
    break;
    } /* ...end of switch statement... */
    } /* ...end of else statement... */
    return this;
    } /* ...end of method getTableCellRendererComponent()... */
    } /* ...end of class declaration gridTableCellRenderer... */
    As you can see, I've commented out all of the logic in an effort to try to find out what was causing the problem. As I said before, the only way I can get the checkboxes to appear correctly is commenting out the line:
    TableName.setDefaultRenderer(Boolean.class,
    new gridTableCellRenderer(DisplayData));
    Thanks in advance....

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
    public class Test extends JFrame {
        public Test() {
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         Container content = getContentPane();
         String[] head = {"Boolean","String","Boolean"};
         Object[][] data  = {{new Boolean(true), "Hello", new Boolean(false)},
                       {new Boolean(true), "There", new Boolean(true)},
                       {new Boolean(false), "Hello", new Boolean(false)},
                       {new Boolean(true), "There", new Boolean(false)}};
         JTable jt = new JTable(new MyModel(data, head));
         jt.setDefaultRenderer(Boolean.class, new MyRenderer());
         content.add(jt, BorderLayout.CENTER);
         setSize(200,200);
         show();
        public static void main(String[] arghs) { new Test(); }
    class MyModel extends DefaultTableModel {
        public MyModel(Object[][] Data, Object[] Head) { super(Data, Head); }
        public Class getColumnClass(int col) {
         switch (col) {
             case 0:
             case 2: return Boolean.class;
             default: return Object.class;
    class MyRenderer extends JCheckBox implements TableCellRenderer {
        public Component getTableCellRendererComponent(JTable table,
                       Object value, boolean isSelected,
                       boolean hasFocus, int row, int column ) {
         setSelected(((Boolean)value).booleanValue());
         if (((String)table.getValueAt(row, 1)).equals("Hello")) {
             setBackground(Color.red);
         } else {
             setBackground(Color.pink);
         return this;
    }

  • JTable, L&F and a TableCellRenderer

    hey guys :)
    i have a lil prob in my swing application. i use a JTable to display my data and i use custom CellEditors and CellRenderers - so far so good. the problem i have now, that the cell itself isnt highlighted (in any way) if it's row is currently selected.
    therefore i took my renderer and changed this method:
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    if(isSelected)
         setBackground(new Color(204,204,255));
         System.out.println("selected");
    else
         setBackground(Color.white);
    [...]that's in accordance with the metal L&F color scheme.
    it works - but it's not the right way to do that... and if the user changes the L&F it's obvious.
    my question is, how can i get the colors (foreground and background) wich i have to use?
    (i know it's an L&F method but i hadnt found it up to now)
    ta :)

    If the component you are producing is a JLabel then the easiest way to do this is to make your TableCellRenderer extend the DefaultTableCellRenderer and start your getTableCellRendererComponent method with a call to the same method in the superclass e.g.
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    // ... make your other changes to label
    return label;
    This is the easiest way to get all the selection, focus, etc. behaviour
    so long as you can use the JLabel.
    If you need to know how to do it for a different component ask.

  • Setting cursor in JTable TableCellRenderer

    I'm trying to get the cursor to change (hand cursor) when mousing over a cell in a JTable. I've tried making my own TableCellRenderer as such:
    public class DrillDownCellRenderer 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);
        setText((String)value);
        setForeground(Color.blue);
        setCursor(new Cursor(Cursor.HAND_CURSOR));
        return this;
        * draws line under text
      public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.setColor(getForeground());
        g.fillRect(0,getHeight()-2,getFontMetrics(getFont()).stringWidth(getText()),1);
    }This doesn't seem to affect the cursor at all. Am I missing something?
    Maybe I'm going about this wrong from the start. I'd like some of the columns to appear like a "Link" which will let the user click and open up a new JFrame or some other action (It's my intention to fire this off through some sort of listener in the JTable but I havn't gotten that far yet). Maybe there's a better way to accomplish this?

    u can try this if you like its a slight enhancement with overidding getToolTipText(MouseEvent me) compile and run and watch behaviour
    good luck
    krishna
    import javax.swing.table.*;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    public class DrillDownCellRenderer extends DefaultTableCellRenderer
    public static final String HTML_START = "<html><a href=#>";
    public static final String HTML_END = "</a></html>";
    public static final DrillDownCellRenderer DDCR = new DrillDownCellRenderer();
    public DrillDownCellRenderer()
    super();
    public static void main(String[] args) throws Exception
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    JFrame f = new JFrame();
    DefaultTableModel dtm = new DefaultTableModel(10, 4);
    Date d = null;
    for(int i = 0; i < dtm.getRowCount(); i++)
    d = new Date();
    dtm.setValueAt(new Integer(i + 1), i, 0);
    dtm.setValueAt(d, i, 1);
    dtm.setValueAt(new Long(d.getTime()), i, 2);
    if(i % 2 == 0)
    dtm.setValueAt("http://www.yahoo.com" + d.getTime(), i, 3);
    else
    dtm.setValueAt("http://javasoft.com" + d.getTime(), i, 3);
    JTable t = new JTable(dtm)
    public TableCellRenderer getCellRenderer(int row, int col)
    if(super.convertColumnIndexToModel(col) == 3)
    return DDCR;
    return super.getCellRenderer(row, col);
    public String getToolTipText(MouseEvent me)
    int col = super.columnAtPoint(me.getPoint());
    if(super.convertColumnIndexToModel(col) == 3)
    int row = super.rowAtPoint(me.getPoint());
    Rectangle rec = super.getCellRect(row, col, false);
    String value = (String)super.getValueAt(row, col);
    int x = rec.x + DDCR.getFontMetrics(DDCR.getFont()).
    stringWidth(value);
    if(me.getPoint().x <= x)
    super.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    else
    super.setCursor(Cursor.getDefaultCursor());
    else
    super.setCursor(Cursor.getDefaultCursor());
    return super.getToolTipText(me);
    JScrollPane jsp = new JScrollPane(t);
    JLabel l = new JLabel(HTML_START + "http://javasoft.com" + HTML_END);
    f.getContentPane().add(l, BorderLayout.SOUTH);
    f.getContentPane().add(jsp);
    f.pack();
    f.show();
    public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean hasFocus, int row, int column)
    super.getTableCellRendererComponent
    (table, value, isSelected, hasFocus, row, column);
    setForeground(Color.blue);
    // can use html if you like
    // setText(HTML_START + value + HTML_END);
    return this;
    public void paintComponent(Graphics g)
    super.paintComponent(g);
    g.setColor(getForeground());
    g.fillRect(0, getHeight() - 2, getFontMetrics(getFont()).
    stringWidth(getText()),1);
    }

  • Problem showing imageicon in cell using TableCellRenderer

    Hi all,
    I am using a tablecellrenderer to display an icon in a particular jtable column to reflect a value in the underlying model.
    When I do this, the column does not display the ImageIcon at all. My code for the CellRenderer is below.
    It should also be noted that I use another table cell renderer on the whole table to remove the line around the selection on the selected cell. This all works fine.
    public class StatusCellRenderer implements TableCellRenderer {
        private static ImageIcon blueIcon = new ImageIcon("images/blue.gif");
        private static ImageIcon redIcon = new ImageIcon("images/red.gif");
        private JLabel label = new JLabel();
        // Constructors
        public StatusCellRenderer() {
            label.setHorizontalAlignment(JLabel.CENTER);
            label.setVerticalAlignment(JLabel.CENTER);
        // TableCellRenderer interface implementation
        public Component getTableCellRendererComponent(JTable table,
        Object value,
        boolean isSelected,
        boolean hasFocus,
        int row,
        int column) {
            if (Integer.parseInt(value.toString()) > 0){
                label.setIcon(blueIcon);
                label.repaint();
                return label;
            else if (Integer.parseInt(value.toString()) == 0){
                label.setIcon(redIcon);
                label.repaint();
                return label;
            else
                return null;
    }

    First question: What do you see in the column where you expect the Icon?
    First suggestion: extend DefaultTableCellRenderer instead of implementing TableCellRenderer interface. Just a suggestion.
    second question: Have you set the renderer for the class of objects in target column to be the StatusCellRenderer?
    As camrickr says you need to post a little more code. Maybe a SMALL demo program illustrating your problem. Use code tags for legibility.
    Cheers
    DB

  • TableCellRenderer -- not showing as "selected" in JTable

    Hi,
    I have a a JTable, and for one of my columns, i do
    for (int i = 0; i < dataModel.getColumnCount(); i++) {
         column = table.getColumnModel().getColumn(i);
              if (i ==0)
                     column.setCellRenderer(new NotificationCellRenderer());
         private class NotificationCellRenderer implements TableCellRenderer {
              public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                   JLabel label = new JLabel(String.valueOf(value));
                   label.setToolTipText(label.getText() + " and more description goes here");
                   return label;
         }so it looks fine...but then when i select a row in my table, all the cells of the row are "highlighted" with the blue color...except for the column which uses that cell renderer....
    how can fix this?
    thanks

    Or, maybe an easier approach is to override the getToolTipText(...) method of JTable:
            JTable table = new JTable(data, columnNames)
                public String getToolTipText( MouseEvent e )
                    int row = rowAtPoint( e.getPoint() );
                    int column = columnAtPoint( e.getPoint() );
                    Object value = getValueAt(row, column);
                    return value == null ? null : value.toString();
            };

  • Wrong behaviours with TableCellRenderer

    Hi.
    I implemented my tablecellrenderer for dates. The problem is that the values of the column I rendered are not visually selected when I click on them.
    Moreover:
    when I click on a cell, sometimes it changes its content, according to the row I was selecting before.
    if three rows have the same date value, all three are selected.
    I tried using setOpaque (true) but this selected all the rows in that column.
    Here is my renderer..thanks for any little help
    public class DateTableCellRenderer extends JLabel implements TableCellRenderer {
    Timestamp curDate;
    public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean hasFocus, int rowIndex, int vColIndex) {
    if(value!=null){
    if (value instanceof Timestamp) {
    curDate = (Timestamp) value;
    SimpleDateFormat a = new SimpleDateFormat("dd/MM/yyyy", Locale.ITALY);
    String text = a.format(curDate);
    this.setText(text);
    if (isSelected) {
    this.setOpaque(true);
    setForeground(table.getSelectionForeground());
    setBackground(table.getSelectionBackground());
    } else {
    this.setOpaque(false);
    setForeground(table.getForeground());
    setBackground(table.getBackground());
    return this;
    }

    You're right. I forgot using the code tags to format my class. Here is my situation:
    I have a dinamic JTable to which I added a TableSorter. In the model I added object like BigDecimal, Strings and Timestamp and I created a TableCellRenderer for each type I can have inside the table. The wrong behaviours are those described in the previous post.
    Any help?
    Thanks camickr, but I think that the link you gave me is wrong

  • TableCellRenderer, drawing to the object

    i have hit a bit of a snag and need a recommendation......
    i'm building an application that will allow the user to drag office cubicles onto a layout and move them around, etc. the list of available cubicles (sizes and such) are stored in a JTable and displayed on the left side as a single column.
    The issue i have run into is in my cell renderer.
    The user is able to create custom cubicle sizes/shapes in a seperate editor, these cubicles are then added to the table, i would like to be able to render scaled down versions of the cubicles inside the cells in the JTable as pictoral icons for each cube. inside my cell renderer class when i override the getTableCellRendererComponent method i am able to set the text, or apply an Icon but i can not get a Graphics hook to do any kind of drawing, which is what i need to do to create the scaled image of the cubicle. so i guess my question is, is it possible to draw to the TableCellRenderer object before returning it? since it is possible to write text or an icon and set the background color i am lead to believe that a Graphics context exists for the object although calls to getGraphics return null.
    thanks for any insight.
    -xian
    another solution is to store a scaled icon object in each Cubicle object but again i need to create the Icon dynamically, is there an easy facility to draw to an Icon object?

    thx for the response, i did give this a try, however since i am returning "this" it would only work for one cell, to use the paint method i would have to create a seperate instance of my cell renderer for every cubicle size and because the user can add additional cubicle sizes/shape at any time it is impossible for me to create the paint methods at run time....
    i'm starting to think that pre-drawing the cubicle thumbnail to an ImageIcon and applying that to the JLabel may accually be the easiest way to go.
    thanks!
    -xian

Maybe you are looking for