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

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.

  • 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;

  • Problem of custom table model

    Hi,
    i m leaning JTable recently, following is an experimental code which i wrote, it has a custom table model and custom tablecellrenderer, the custom tablecellrender determine the column of # of Years greater or equal than 5 should display color green, less than 5 should display color red, it works well, however, the custom table model should be smart enough to know that the # of Years column contains numbers (which should generally be right aligned and have a particular format), it also should know that the Vegetarian column contains boolean values, which can be represented by check boxes, but it didn't, i don't know why, i have implement a getColumnClass method,
    but it seems not work, have i make any mistakes? Any idea? Thanks
    import java.awt.BorderLayout;
    import java.awt.Container;
    import java.awt.Dimension;
    import javax.swing.JFrame;
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.TableColumn;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.UIManager;
    import java.awt.Color;
    import java.util.Vector;
    public class CellRenderTestVector extends JFrame {
         protected JTable table;
         protected int width = 100;
         protected MyCustomTableModel model;
         public CellRenderTestVector() {
              JPanel pan0 = new JPanel(new BorderLayout());
              Container contentPane = getContentPane();
              pan0.setPreferredSize(new Dimension(500,200));
              model = new MyCustomTableModel();
              table = new JTable();
              table.setAutoCreateColumnsFromModel(false);
              table.setModel(model);
              table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
                            TableColumn column = null;
              for (int i = 0; i < model.getColumnCount(); i++) {
                   DefaultTableCellRenderer renderer = new
                     ColoredTableCellRenderer();
                   column = new TableColumn(i,
                              width, renderer, null);
                              table.addColumn(column);
              TableColumn t_column = table.getColumnModel().getColumn(2);
              System.out.println(table.getColumnModel());
              JScrollPane scrollPane = new JScrollPane(table);
              pan0.add(scrollPane, BorderLayout.CENTER);
              contentPane.add(pan0);
                public class ColoredTableCellRenderer extends DefaultTableCellRenderer {
              public void setValue(Object value) {
                   Color  m_color;
                   Color GREEN = new Color(0, 128, 0);
                   Color RED = Color.red;
                   if (value instanceof Integer) {
                        Integer m_data = (Integer)value;
                        m_color = m_data.intValue() >= 5 ? GREEN : RED;
                                           setForeground(m_color);
                               setText(m_data.toString());
                   else {
                        super.setValue(value);
         public class Columndata {
              protected String m_title;
              public Columndata(String title) {
                   m_title = title;
         public class Rowdata {
              protected String fname;
              protected String lname;
              protected String sport_type;
              protected Integer no_year;
              protected Boolean vegetarian;
              public Rowdata(String fn, String ln,
                        String sp, int ny, boolean vg) {
                   fname = fn;
                   lname = ln;
                   sport_type = sp;
                   no_year = new Integer(ny);
                   vegetarian = new Boolean(vg);
         public class MyCustomTableModel extends AbstractTableModel {
              protected final Columndata m_column[] =
                        {new Columndata("First Name"),
                         new Columndata("Last Name"),
                         new Columndata("Sport"),
                         new Columndata("# of Years"),
                         new Columndata("Vegetarian")
              protected Vector m_vector;
              public MyCustomTableModel() {
                   m_vector = new Vector();
                   setDefaultData();
              public void setDefaultData() {
                   m_vector.removeAllElements();
                   m_vector.addElement(new Rowdata("Mary", "Campione",
                                                           "Snowboarding", 5, false));
                   m_vector.addElement(new Rowdata("Alison", "Huml",
                                                           "Rowing",3,true));
                   m_vector.addElement(new Rowdata("Kathy", "Walrath",
                                                           "Knitting",2, false));
                   m_vector.addElement(new Rowdata("Sharon", "Zakhour",
                                                           "Speed reading",20,true));
                   m_vector.addElement(new Rowdata("Philip", "Milne",
                                                           "Pool",10,false));
              public int getColumnCount() {
                   return m_column.length;
              public int getRowCount() {
                   return m_vector==null ? 0 : m_vector.size();
              public String getColumnName(int col) {
                   return m_column[col].m_title;
              public Object getValueAt(int nRow, int nCol) {
                   if (nRow < 0 || nRow>=getRowCount()) return "";
                   Rowdata row = (Rowdata)m_vector.elementAt(nRow);
                   switch (nCol) {
                   case 0: return row.fname;
                   case 1: return row.lname;
                   case 2: return row.sport_type;
                   case 3: return row.no_year;
                   case 4: return row.vegetarian;
                   return "";
              public Class getColumnClass(int c) {
                   return getValueAt(0, c).getClass();
         public static void createAndShowGUI() {
              try {
                UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
              } catch (Exception evt) {}
                   JFrame f = new CellRenderTestVector();
                   f.setTitle("TableTest");
                   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                   f.pack();
                 f.setVisible(true);
         public static void main(String[] args) {
              javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
    }

    You need to write your custom TableCellRenderes/Editors for each type. And don't forget to register your custom renderes via myTable.setDefaultRendere().

  • JTable Renderer-Promblem when using custom renderer

    Hi. i've just started studying Swing component.
    So i'm about to ask for help to solve the problem during using custom TableCellRenderer.
    Here is my own Renderer which extends JLable and implements TableCellRenderer
    public Component getTableCellRendererComponent(JTable table, Object value,boolean isSelected,boolean hasFocus,int row,int column)
         if (isSelected) {
         setForeground(table.getSelectionForeground());
         super.setBackground(table.getSelectionBackground());
         else {
         setForeground(table.getForeground());
         setBackground(table.getBackground());
         JLabel right=new JLabel("LEFT");
         JLabel left=new JLabel("RIGHT");
         this.setLayout(new BorderLayout());
         this.add(left,BorderLayout.WEST);
         this.add(right,BorderLayout.EAST);
         return this;
    note: There are 3 JLabel components. Two components are added to the component will be returned.
    This code works fine.
    but whenever try to resize the column display using above renderer, The " Text " runs in resizing.(making traces)
    Please anybody try to run this code, show me some solution.
    thank you

    A renderer will have its getTableCellRendererComponent method called repeatedly, every time a cell is to be repainted, and its the renderer associated with that cell. Therefore, avoid doing things in this method that should only be done once, for example:
    JLabel right=new JLabel("LEFT");
    JLabel left=new JLabel("RIGHT");
    this.setLayout(new BorderLayout());
    this.add(left,BorderLayout.WEST);
    this.add(right,BorderLayout.EAST);Can you do that in the renderer's constructor?

  • JTable custom grid line painting

    In my JTable, I need to change the appearance of the line between two cells (either making it into a dashed line or just changing the color, the latter probably being easier). I am currently planning to turn off the JTable's grid lines and paint my own grid lines with a custom TableCellRenderer. Does anyone have a better suggestion, or a guide on a good way to do what I'm trying to accomplish? Thanks.

    The table grid is painted in the BasicTableUI.paintGrid which is unfortunately a private method. However, you can do the following:
    1. Use JTable.setGridColor API to change the color
    2. Override the JTable.paintComponent and set a custom stroke before calling the super implementation. Here the assumption is that the core implementation doesn't change the stroke (which it doesn't in JDK 5.0). Not the cleanest way to do this, but it should work. Don't forget to restore the old stroke when you're done in paintComponent.

  • Proble with Custom JTable Header

    Hi
    I want create Custom JTable with JTextField on column header, so that user can enter some text. As of now i am able to create the text box on header using custom TableCellRenderer but i am not able to make it editable.....
    Please help me. if any one need more info, pls let me know.

    KetuRai wrote:
    Then what should i do to achieve this functionality. Do any one have sample code?
    Or other alternative to achieve this.I don't know If this is the best way but my approach is using a InputDialog and a custom renderer.
    just click on the table header and input a text. Good Luck!
    import java.awt.Color;
    import java.awt.Component;
    import javax.swing.*;
    import javax.swing.table.*;
    import java.awt.event.*;
    public class TableHeaderDemo {
        public void createAndShowUI() {
            JFrame frame = new JFrame("Click Table Header to change text");
            String[] columnName = {"CheckBox Column", "Data Column"};
            Object[][] data = {{"Data 1", "Data 2"},
            {"Data 3", "Data 4"}, {"Data 5", "Data 6"}};
            final JTable myTable = new JTable(data, columnName);
            myTable.getTableHeader().setDefaultRenderer(new MyRenderer());
            myTable.getTableHeader().addMouseListener(new java.awt.event.MouseAdapter() {
                public void mousePressed(MouseEvent e) {
                    int col = myTable.getTableHeader().columnAtPoint(e.getPoint());
                    String str = javax.swing.JOptionPane.showInputDialog("Enter a text: ");
                    myTable.getColumnModel().getColumn(col).setHeaderRenderer(new MyRenderer(str));
                    myTable.getTableHeader().revalidate();
                    myTable.getTableHeader().repaint();
            JScrollPane scrollPane = new JScrollPane(myTable);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setResizable(false);
            frame.getContentPane().add(scrollPane);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        class MyRenderer implements TableCellRenderer {
            JTextField text = new JTextField();
            MyRenderer(String str) {
                text.setText(str);
            MyRenderer() {
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                    boolean hasFocus, int row, int column) {
                text.setBorder(BorderFactory.createRaisedBevelBorder());
                text.setBackground(Color.BLUE);
                text.setForeground(Color.WHITE);
                text.setHorizontalAlignment(JTextField.CENTER);
                return text;
        public static void main(String[] args){
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new TableHeaderDemo().createAndShowUI();
    }

  • How do the AbstractTableModel, ColumnModel and TableCellRenderer interact?

    could someone please explain to me how the AbstractTableModel, TableColumnModel and the TableCellRenderer interact?
    That is, if I have a table which used a custom AbstractTableModel, and a custom TableCellRenderer, then how do I cause the renderer to render the correct data?
    Do I have to manually invoke it from my table model? does it get called automatically for every column/row combination?
    also if I want to add a column to the table and I use:
    TableColumnModel's addColumn(TableColumn colum), do I have to invoke AbstractTableModel's fireTableStructureChanged() as well?
    Also, I implemented AbstractTableModel's
    Object valueAt(int row, int column)
    but that method is never invoked in my code. Is that ok?
    int getRowCount(), and int getColumnCount() are invoked on the other hand.
    nir

    I misspelled the name of the method.
    I was using Object getValueAt(int row, int column)...
    still this method is never invoked (I have debug messages there and they are never shown).
    And I am setting the default renderer...
    Here is my ccode:
       // this is how I define my table and table model.
       // PlayerTableDataModel is class implementing AbstractTableModel
       // dataSource is the object that will supply the data that will be presented in the table.
       PlayerTableDataModel tableModel = new PlayerTableDataModel(dataSource);
       table = new JTable(tableModel);
       table.getTableHeader().setReorderingAllowed(false);
       tableModel.setTable(table);
       table.setDefaultRenderer(RoundResult.class, new RoundResultRenderer(dataSource));
       table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);Here is my PlayerTableDataModel class:
    public class PlayerTableDataModel extends AbstractTableModel
        private DataSource dataSource;
        private JTable table;
        public PlayerTableDataModel(DataSource dataSource) {
         super();
         this.dataSource; = dataSource;;     
        // This is the method I invoke when I want to dynamically add a new column to the table.
        public void addNewColumn(GameTableHeaderRenderer headerRenderer) {
         TableColumn newColumn = new TableColumn(getColumnCount());
         newColumn.setHeaderRenderer(headerRenderer);
         newColumn.setResizable(true);
         TableColumnModel cm = table.getColumnModel();
         cm.addColumn(newColumn);
         fireTableStructureChanged();
        public void setTable(JTable table) {
         this.table = table;
        public int getRowCount() {
         return dataSource.getNumRoundsPlayed();
        public int getColumnCount() {
         if (table == null) {
             return 0;
         return dataSource.numberOfPlayers();
        public Object getValueAt(int row, int column) {
         System.out.println("this is never shown");
        public boolean isCellEditable(int row, int col) {
            return false;      
        // I want each cell in the table to hold an object of class RoundResult
        public Class getColumnClass(int c) {
         return RoundResult.class;
    }why do I have to implement getValueAt(), if it is never invoked?

  • Can't understand how TableCellRenderer is meant to work

    I've not done much Swing work and I'm trying to understand how a customer TableCellRenderer is meant to work. I know I've made a stupid mistake here somewhere but I can't find any specific docs on what I'm try to do.
    Basically I have a column in my JTable which holds my own Counter object. I want to render the cell so that the current value of the counter is displayed, along with 2 little buttons that allow the user to increment/decrement the counter value.
    The code is below, I seem to have 3 problems:
    1) One click on the button seems to increment the counter several times (inserting some log statements it seems that the MouseListener is being added several times?)
    2) The value on the counter doesn't seem to get refreshed/repainted once the button is clicked, only some time later (e.g. when I click on a different cell in the JTable)
    3) The +/- buttons dont "depress" when they are clicked.
    Any help much appreciated!
    public Component getTableCellRendererComponent(
    JTable table, Object lagInput,
    boolean isSelected, boolean hasFocus,
    int row, int column) {
    removeAll();
    final Counter counter = (Counter)counter;
    final JButton increment = new JButton("+");
    increment.setMargin(new Insets(1,1,1,1));
    increment.setPreferredSize(new Dimension(15,15));
    final JButton decrement = new JButton("-");
    decrement.setMargin(new Insets(1,1,1,1));
    decrement.setPreferredSize(new Dimension(15,15));
    final JTable finalTable = table;
    final int finalColumn = column;
    table.addMouseListener(new MouseAdapter(){
    public void mousePressed(MouseEvent e) {
    Rectangle panelBounds = finalTable.getTableHeader().getHeaderRect(finalColumn);
    Rectangle buttonBounds = increment.getBounds();
    buttonBounds.translate(panelBounds.x, panelBounds.y);
    if (buttonBounds.contains(e.getX(), e.getY())){
    counter.increment();
    Rectangle buttonBoundsDec = decrement.getBounds();
    buttonBoundsDec.translate(panelBounds.x, panelBounds.y);
    if (buttonBoundsDec.contains(e.getX(), e.getY())){
    counter.decrement();
    setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridheight = 2;
    c.gridx = 0;
    c.gridy = 0;
    add(counter);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridheight = 1;
    c.gridx = 0;
    c.gridy = 1;
    add(increment);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridheight = 1;
    c.gridx = 1;
    c.gridy = 1;
    add(decrement);
    return this;
    }

    If that's all there is to the Counter class, it seems to me that what you really want is a JTable of JSpinners.import java.awt.Component;
    import javax.swing.*;
    import javax.swing.table.TableCellEditor;
    import javax.swing.table.TableCellRenderer;
    public class SpinnerTable {
       void makeUI() {
          Integer[][] data = new Integer[10][5];
          String[] colNames = new String[data[0].length];
          for (int i = 0; i < data[0].length; i++) {
             colNames[i] = "Column " + i;
             for (int j = 0; j < data.length; j++) {
                data[j] = 0;
    JTable table = new JTable(data, colNames) {
    @Override
    public Class getColumnClass(int column) {
    return Integer.class;
    table.setDefaultEditor(Integer.class, new TableCellSpinner(table));
    table.setDefaultRenderer(Integer.class, new TableCellSpinner(table));
    table.setRowHeight(new JSpinner().getPreferredSize().height + table.
    getIntercellSpacing().height);
    JScrollPane scrollPane = new JScrollPane(table);
    JFrame frame = new JFrame("SpinnerRendererTable");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 400);
    frame.setLocationRelativeTo(null);
    frame.add(scrollPane);
    frame.setVisible(true);
    public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    new SpinnerTable().makeUI();
    class TableCellSpinner extends AbstractCellEditor
    implements TableCellRenderer, TableCellEditor {
    JTable table;
    JSpinner spinner = new JSpinner();
    JTextField editor = ((JSpinner.DefaultEditor) spinner.getEditor()).
    getTextField();
    TableCellSpinner(JTable table) {
    this.table = table;
    public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean hasFocus, int row, int column) {
    spinner.setValue((Integer) value);
    if (isSelected) {
    editor.setBackground(table.getSelectionBackground());
    } else {
    editor.setBackground(table.getBackground());
    if (hasFocus) {
    spinner.setBorder(BorderFactory.createLineBorder(table.getGridColor()));
    } else {
    spinner.setBorder(null);
    return spinner;
    public Component getTableCellEditorComponent(JTable table, Object value,
    boolean isSelected, int row, int column) {
    spinner.setValue((Integer) value);
    spinner.setBorder(BorderFactory.createLineBorder(table.getGridColor()));
    return spinner;
    public Object getCellEditorValue() {
    return spinner.getValue();
    }Check that out carefully in case I've missed anything.
    db
    edit Added the code for the isSelected border
    Edited by: Darryl.Burke

  • TableCellRenderer confusion

    I have a custom TableCellRenderer and I have the getTableCellRendererComponent method in it in order to set the background to a different colour. However, this sets the background of the whole column, not a single cell.
    How can I isolate a single cell?
    I want to do this, but I am not selecting the cell in the table at all. It is independant of user interaction with the table. I want the background to change after values have come back from a database, simply to highlight these values to the user.
    Anyone have any ideas?
    Thanks in advance

    I'm not sure I understand. I can isolate the row and column, and I set the component based on this, but all in that column seem to be set, even with an if statement. Here's the code:
    Its alright, I've got it sorted now, but thankyou.
    For anyone that's interested:
    In my custom cell renderer I have a Vector which will store int values representing rows that have changed and need highlighting. In the calling class, if a user updates this row, I call CapmTableCellRenderer.addCellChanged(rowInt);
    I can now use this Vector to check if the row Int in getTableCellRendererComponent is in the Vector (i.e is a row changed by the user)
    In the below example I change the font to bold if it has been changed, and keep it as normal if it has not
    public class CapmTableCellRenderer extends DefaultTableCellRenderer implements TableCellRenderer{
    public Vector rowsChanged = new Vector();
    public JTable my_table;
    public Object my_value;
    public CapmTableCellRenderer() {
    public Component getTableCellRendererComponent(JTable table,
    Object value,
    boolean isSelected,
    boolean hasFocus,int row,int column)
    JLabel myComp = (JLabel) super.getTableCellRendererComponent(table,
              value, isSelected, hasFocus, row, column);
    //interogate vector for matching row int
    for (int y=0; y< rowsChanged.size(); y++){
    if (row == ((Integer)rowsChanged.elementAt(y)).intValue()) {
    myComp.setFont(new Font(myComp.getFont().getFontName(),1,myComp.getFont().getSize()));
    else {
    myComp.setFont(new Font(myComp.getFont().getFontName(),0,myComp.getFont().getSize()));
    return this;
    public void addCellChanged(int cellRow) {
    rowsChanged.add(new Integer(cellRow));
    }

  • Help needed in JTables

    Hello,
    Can any one help me in a small question.
    I use JTable to display some values it is a two dimentional table.
    Now can any one tell me how to put an icon in to a particular cell of the table
    it may be and cell.
    Best Regards,
    Sreedhar

    You can use a custom TableCellRenderer to do this. There are good examples of doing this in the JTable lessons in the turorial on this site. To put icons in particular cells you need to define the conditions where a icon should be displayed and then code that logic into your renderer.
    After you have read the tutorial and started on your own renderer post specific questions.
    Cheers
    DB

  • JTable: How to reference the selected row during a drag?

    I am implementing Drag and Drop on the rows of a JTable.
    I want to change the background colour of each successive JTable row ("highlight" the row) as another row is dragged over it (I already have similar functionality implemented in a custom TableCellRenderer, but the Drag and Drop code knocks it out) .
    I have run into a problem: All of the JTable methods refer to the rows as ints--0, 1, 2, etc.
    Here is my approach:
    I get the reference to the row by using:
         "int dragEnteredRow = table.rowAtPoint( e.getPoint() ); "
    With the intention to use the variable dragEnteredRow to change each row's foreground colour:
         "dragEnteredRow.setForeground( selected ); "
    That gives me an error message from the compiler:
    "... Can't invoke a method on a int.
         dragEnteredRow.setBackground( Color.yellow ); ... "
    Here is some more of the code (it implements the Macintosh Drag and Drop API):
    [javacode]     
    "     public boolean dragMoved( DragEvent e ) {
         dragEntered( e );
              return true;
         public boolean dragEntered( DragEvent e ) {
         int dragEnteredRow = table.rowAtPoint( e.getPoint() );
              dragEnteredRow.setBackground( Color.yellow ); // These two lines fail at the compiler
    //     table.rowAtPoint( e.getPoint() ).setBackground( Color.yellow );
              if ( dragEnteredRow == -1 ) {;
                   System.out.println( "out of bounds !!" );
              } else {               
                   System.out.println( "Drag Entered at : Row" + dragEnteredRow ); // This test code works
                   System.out.println( "" );
                   return true;
    [javacode]
    My Question: What is the proper approach to solving this problem?
    Many thanks in advance for a solution.
         

    the method rowAtPoint(e.getPoint()) returns an integer with the index of the row at point e, and not the instance of the row.
    You have to use this integer to reference the row through a method like getValueAt(row int,col int) of the DefaultTableModel
    Hope this helps

  • JTable display cell previous/last selected/edited/clicked value/JComponent

    I have a problem with the minesweeper I made,
    The game board is a JTable containing custom gadgets in the cells,
    The first game goes without problem, but I press the JButton starting a new game,
    I randomly refill the JTable with new custom gadgets,
    My problem is that the last cell I clicked in the JTable is still in the clicked state with the previous value and I cannot click or see the new custom gadget that ought to be there ...
    The custom gadgets extends JLabel and use custom AbstractCellEditor and custom TableCellRenderer, but I think it is not related to my custom gadgets,
    I work on OSX,
    Any hint to my problem's origin?
    Any solutions?

    My code included not related classes I eliminated to use only standard java classes,
    here is is the minimal code for my mine sweeper reproducing the problem on the third launch
    any hint? :
    import java.awt.Container;
    import java.awt.Point;
    import java.awt.event.ActionEvent;
    import java.awt.event.MouseEvent;
    import java.util.Random;
    import javax.swing.AbstractAction;
    import javax.swing.Action;
    import javax.swing.JButton;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTable;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableModel;
    public class MyMineSweeper
       private class JTableCellRenderer implements javax.swing.table.TableCellRenderer
          private javax.swing.table.TableCellRenderer defaultRenderer;
          public JTableCellRenderer(javax.swing.table.TableCellRenderer aRenderer)
             defaultRenderer = aRenderer;
          public java.awt.Component getTableCellRendererComponent(javax.swing.JTable aTable, Object anElement, boolean isSelected, boolean hasFocus, int aRow, int aColumn)
             if(anElement instanceof javax.swing.JComponent)
                return (javax.swing.JComponent)anElement;
             return defaultRenderer.getTableCellRendererComponent(aTable, anElement, isSelected, hasFocus, aRow, aColumn);
       private class JTableCellEditor extends javax.swing.AbstractCellEditor implements javax.swing.table.TableCellEditor
          private javax.swing.JComponent component;
          private int theClickCountToStart = 0;
          public java.awt.Component getTableCellEditorComponent(javax.swing.JTable aTable, Object anElement, boolean isSelected, int aRow, int aColumn)
             component = (javax.swing.JComponent) anElement;
             return component;
          public Object getCellEditorValue()
             return component;
          public boolean isCellEditable(java.util.EventObject anEvent)
             if(anEvent instanceof java.awt.event.MouseEvent)
                return ((java.awt.event.MouseEvent)anEvent).getClickCount() >= theClickCountToStart;
             return true;
          public int getClickCountToStart()
             return theClickCountToStart;
          public void setClickCountToStart(int aClickCountToStart)
             theClickCountToStart = aClickCountToStart;
       private class Tile extends javax.swing.JLabel
          public class JTileMouseListener implements java.awt.event.MouseListener
             public void mouseClicked(MouseEvent e)
                if(isRevealed()==false)
                   reveal();
             public void mousePressed(MouseEvent e)
             public void mouseReleased(MouseEvent e)
             public void mouseEntered(MouseEvent e)
             public void mouseExited(MouseEvent e)
            public void reveal(int aY, int anX)
               Tile tile = ((Tile)theMapModel.getValueAt(aY, anX));
               if(tile.isRevealed()==false)
                  tile.reveal();
            public void changed()
               if(theNeighbourCount==0)
                  if(theX>0)
                     if(theY>0)
                        reveal(theY-1, theX-1);
                     reveal(theY, theX-1);
                     if(theY<theMapModel.getRowCount()-1)
                        reveal(theY+1, theX-1);
                  if(theY>0)
                     reveal(theY-1, theX);
                  if(theY<theMapModel.getRowCount()-1)
                     reveal(theY+1, theX);
                  if(theX<theMapModel.getColumnCount()-1)
                     if(theY>0)
                        reveal(theY-1, theX+1);
                     reveal(theY, theX+1);
                     if(theY<theMapModel.getRowCount()-1)
                         reveal(theY+1, theX+1);
                   setBackground(java.awt.Color.WHITE);
                else if(theNeighbourCount==9)
                   setText("*");
                   setBackground(java.awt.Color.RED);
                   System.out.println("no!");
                   theMap.setEnabled(false);
                else
                   setText(String.valueOf(theNeighbourCount));
                   setBackground(java.awt.Color.WHITE);
                setBorder(javax.swing.BorderFactory.createEmptyBorder());
                if(isFinished()==true)
                   System.out.println("victory!");
                   theMap.setEnabled(false);
                theMapModel.fireTableCellUpdated(theY,theX);
          private DefaultTableModel theMapModel;
          private int theX;
          private int theY;
          private short theNeighbourCount;
          protected boolean revealed = false;
          public Tile(int aYIndex, int anXIndex, short aNeighbourCount)
             theMapModel = (DefaultTableModel)theMap.getModel();
             theX = anXIndex;
             theY = aYIndex;
             theNeighbourCount = aNeighbourCount;
             addMouseListener(new JTileMouseListener());
             setOpaque(true);
             setHorizontalAlignment(CENTER);
             setBackground(java.awt.Color.LIGHT_GRAY);
             setBorder(javax.swing.BorderFactory.createRaisedBevelBorder());
             setSize(getHeight(), getHeight());
          public void reveal()
             revealed = true;
             theRevealedTileCount +=1;
             changed();
          public boolean isRevealed()
             return revealed;
       private JFrame theFrame;
       private JTable theMap;
       private int theMapSize = 10;
       private int theTrapCount = 5;
       private int theRevealedTileCount = 0;
       private void startGame()
          Point[] traps = new Point[theTrapCount];
          Random generator = new Random();
          for(int trapIndex = 0; trapIndex<theTrapCount; trapIndex+=1)
             Point newPoint = null;
             boolean alreadyTrapped = true;
             while(alreadyTrapped==true)
                newPoint = new Point(generator.nextInt(theMapSize-1), generator.nextInt(theMapSize-1));
                alreadyTrapped = false;
                for(int existingTrapIndex= 0; existingTrapIndex<trapIndex;existingTrapIndex++)
                   if(newPoint.equals(traps[existingTrapIndex])) alreadyTrapped = true;
             traps[trapIndex] = newPoint;
          TableModel mapModel = theMap.getModel();
          for(int yIndex = 0; yIndex<theMapSize; yIndex+=1)
             for(int xIndex = 0; xIndex<theMapSize; xIndex+=1)
                short neighbours = 0;
                int x = 0;
                int y = 0;
                for(int trapIndex = 0; trapIndex<theTrapCount; trapIndex+=1)
                   x = traps[trapIndex].x - xIndex;
                   y = traps[trapIndex].y - yIndex;
                   if(x==0 && y==0)
                      trapIndex = theTrapCount;
                   else if((x==1 || x==-1) && (y==1 || y==-1))
                      neighbours += 1;
                   else if((x==0) && (y==1 || y==-1))
                      neighbours += 1;
                   else if((x==1 || x==-1) && (y==0))
                      neighbours += 1;
                if(x==0 && y==0)
                   mapModel.setValueAt(new Tile(yIndex, xIndex, (short) 9), yIndex, xIndex);
                else
                   mapModel.setValueAt(new Tile(yIndex, xIndex, neighbours), yIndex, xIndex);
          theRevealedTileCount  = 0;
          theMap.setEnabled(true);
       private boolean isFinished()
          return ((theMapSize*theMapSize)-theRevealedTileCount)==theTrapCount;
       public MyMineSweeper()
          theFrame = new javax.swing.JFrame("mine sweeper");
          JPanel cp = new JPanel();
          theMap = new JTable(new DefaultTableModel(10,10)
             public Class getColumnClass(int column)
                return getValueAt(0, column).getClass();
          theMap.setDefaultRenderer(JComponent.class, new JTableCellRenderer(theMap.getDefaultRenderer(JComponent.class)));
          JTableCellEditor editor = new JTableCellEditor();
          theMap.setDefaultEditor(JComponent.class, editor);
          editor.setClickCountToStart(0);
          theMap.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
          startGame();
          cp.add(theMap);
          Action newGameAction = new AbstractAction("new game")
             public void actionPerformed(ActionEvent e)
                startGame();
          JButton newGameTrigger = new JButton(newGameAction);
          cp.add(newGameTrigger);
          theFrame.getContentPane().add(cp);
          theFrame.pack();
          theFrame.show();
       public JFrame getFrame()
          return theFrame;
      }

  • Progress bar in a JProgressBar component is not always drawn

    Hi experts,
    I have a strange issue with a swing application. This app contains of a JFrame including a JTable. This table has multiple columns, one of them is a JProgressBar (implementing a TableCellRenderer). Multiple background threads are running, every of them updates one row's progress bar via the InvokeLater() method. This works fine.
    At a specific point within the runtime of the application, the value of a progress bar is set back to 0, and instead of the default percentage text a custom string is displayed (then continuing to progress with this custom text set). This works fine as well.
    Problem is, that when a custom string is set to one progress bar as described above, then the bars of the other JProgressBars are not painted any more. But the default percentage text of these other JProgressBars are still incremented and painted correctly. When the one progress bar, that has the custom string set, has finished and this row is removed from table, then the other progress bars are again painted correctly (including the default percentage text).
    A part of the custom TableCellRenderer class is shown here:
         public class ProgressRenderer extends JProgressBar implements TableCellRenderer
         public ProgressRenderer()
              super(SwingConstants.HORIZONTAL);
              setBorderPainted(false);
              setStringPainted(true);
         public Component getTableCellRendererComponent(JTable table, Object value,
              boolean isSelected, boolean hasFocus, int row, int column)
              if(value != null)
                   setValue(((JProgressBar) value).getValue());
                   setString(((JProgressBar) value).getString());
                   setMinimum(((JProgressBar) value).getMinimum());
                   setMaximum(((JProgressBar) value).getMaximum());
              return this;
    ...Any ideas what could be wrong here?
    I am really out of ideas here :(
    Thanks in advance for your help!
    Kind regards, Matthias

    I have solved the problem:
         public Component getTableCellRendererComponent(JTable table, Object value,
              boolean isSelected, boolean hasFocus, int row, int column)
              if(value != null)
                   setString(((JProgressBar) value).getString());
                   setMinimum(((JProgressBar) value).getMinimum());
                   setMaximum(((JProgressBar) value).getMaximum());
                   setValue(((JProgressBar) value).getValue());
              return this;
         }

  • Html text in label is moving when used as a renderer in a table cell

    Hi everybody,
    Because it is impossible to use gradient background for html, I created a custom TableCellRenderer that uses a JLabel (for the html text) inside a JPanel with a gradient background. (I use jdk1.5.0_06)
    However, in the code that I'm posting, something strange happens. The text is moving up and down as I move with the arrow button along the first row, from left to right and backwards, crossing the entire row.
    You can see for yourself. If someone can explain this behavior, please help!
    public class MyFrame extends javax.swing.JFrame {
        public static void main(String args[]) {
               new MyFrame().setVisible(true);
        public MyFrame() {
             setTitle("Use LEFT & RIGHT buttons to test");
            javax.swing.JTable table = new javax.swing.JTable();
            table.setModel(new javax.swing.table.DefaultTableModel(
                new Object [][] { {"", "", ""}, {"", "", ""}, {"", "", ""}, {"", "", ""}, {"", "", ""}, {"", "", ""} },
                new String []   { "Title 1", "Title 2", "Title 3" }
                public Class getColumnClass(int columnIndex) {
                    return String.class;
            table.setRowHeight(30);
            table.setRowHeight(0,100);
            table.setRowSelectionInterval(0,0);
            table.setColumnSelectionInterval(0,0);
            table.setValueAt("This text MOVES up-down as you move across THIS ROW!!!",0,0);
            table.setValueAt("This text MOVES up-down as you move across THIS ROW!!!",0,1);
            table.setValueAt("This text DOES NOT MOVE as you move across THIS ROW!!!",0,2);
            table.setDefaultRenderer(String.class,new StringRenderer());
            getContentPane().add(table, java.awt.BorderLayout.CENTER);
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
            setBounds(200,200,500,300);
        class StringRenderer extends GradientPanel implements javax.swing.table.TableCellRenderer {
            public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                   label.setText("<html><p align=center>"+String.valueOf(value)+"</p></html>");
                setColors(new java.awt.Color(255,255,255),isSelected?new java.awt.Color(255,100,100):new java.awt.Color(255,200,200));
                label.setBorder(hasFocus?new javax.swing.border.LineBorder(java.awt.Color.yellow,1):null);
                return this;
        class GradientPanel extends javax.swing.JPanel {
            private java.awt.Color c1,c2;
            protected javax.swing.JLabel label;
            public GradientPanel() {
                label = new javax.swing.JLabel();
                setLayout(new java.awt.GridBagLayout());
                java.awt.GridBagConstraints gbc = new java.awt.GridBagConstraints();
                gbc.fill = java.awt.GridBagConstraints.BOTH;
                gbc.weightx = 1.0;
                gbc.weighty = 1.0;
                gbc.insets = new java.awt.Insets(5,5,5,5);
                add(label, gbc);
            public void setColors(java.awt.Color c1, java.awt.Color c2) {
                this.c1 = c1;
                this.c2 = c2;
                this.repaint();
            public void paintComponent(java.awt.Graphics g) {
                if ( c1 != null && c2 != null ) {
                    java.awt.Graphics2D g2d = (java.awt.Graphics2D)g;
                    g2d.setPaint(new java.awt.GradientPaint(0,0,c2,0,this.getHeight(),c1,false));
                    g2d.fillRect(0,0,this.getWidth(),this.getHeight());
    }

    If someone can explain this behavior, please help!Can't explaing the behavour, but it seems to work fine when you use a JeditorPane or JTextPane which are specifically designed to display HTML.

Maybe you are looking for

  • How to make Clsuter aware EJB

              Platform: Weblogic 6.0sp2 in WINNT           Hai,           I have made IP loadbalancing ( The DNS Host entry swaps IP in intervals) as per           the documentation. By Using the clsuter IP i have created a cluster entey in the          

  • Announcement Oracle9iAS Portal Patch Release 3.0.9.8.3 For Solaris is now available

    Oracle9iAS Portal Patch Release 3.0.9.8.3 For Solaris is now available for download from metalink. Bugnumber for the patch release is 2131815. You must install this patch release over an Oracle9iAS 1.0.2.2 installation of Oracle9iAS Portal. You can i

  • [SOLVED] dwm doesn't compile with moveresize function

    I'am trying to compile dwm with moveresize function but I get this error: dwm build options: CFLAGS = -std=c99 -pedantic -Wall -Os -I. -I/usr/include -I/usr/include/X11 -DVERSION="5.7.2" -DXINERAMA LDFLAGS = -s -L/usr/lib -lc -L/usr/lib/X11 -lX11 -L/

  • 1 Powerbook working with Printer, 1 Not

    We have 2 G4 Powerbooks at home, and a HP PSC 1350 printer connected to the Airport Express. My Powerbook prints via wireless perfectly, but the other one doesn't. It happily sees the printer, tries to print, then tells me the print is Idle. I've tri

  • Chat and vision eGift card - another undelivered !

    I purchased $30US an e-gift card on 15 02 2015  for a friend.Than on 17/02/2015 ireceived email from chat and vision with lie "Brilliant news: Your friend has received your eGift Card. Best regards, Cynthia Appleby Customer Care Officer ChatandVision