Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.gui > #1549 > unrolled thread

Adding custom cell render

Started by"Lionel van den Berg" <lionel.van.den.berg@THRWHITE.remove-dii-this>
First post2011-04-27 15:33 +0000
Last post2011-04-27 15:34 +0000
Articles 3 — 2 participants

Back to article view | Back to comp.lang.java.gui


Contents

  Adding custom cell render "Lionel van den Berg" <lionel.van.den.berg@THRWHITE.remove-dii-this> - 2011-04-27 15:33 +0000
    Re: Adding custom cell re "katjapanisch" <katjapanisch@THRWHITE.remove-dii-this> - 2011-04-27 15:33 +0000
      Re: Adding custom cell re "Lionel van den Berg" <lionel.van.den.berg@THRWHITE.remove-dii-this> - 2011-04-27 15:34 +0000

#1549 — Adding custom cell render

From"Lionel van den Berg" <lionel.van.den.berg@THRWHITE.remove-dii-this>
Date2011-04-27 15:33 +0000
SubjectAdding custom cell render
Message-ID<4631c40c$1@dnews.tpgi.com.au>
  To: comp.lang.java.gui
I asked a question about this a while ago, but I was ill-prepared. 
Rather than explaining I will hope that someone doesn't mind compiling 
some code that I've included below. I stuck it all in a file called 
JTableTest.java, compiled and ran it in Netbeans.

To see the problem, click Add a couple of times, and then select, last 
row and press delete. Click on one of the other cells, see the result.

Can anyone tell me what the problem is? If I remove the row 
tc.setCellEditor(new JTextFieldTableCellEditor()); it doesn't throw the 
exception.

Thanks

Lionel


/*
  * JTableTest.java
  *
  * Created on 27 April 2007, 18:20
  *
  * To change this template, choose Tools | Template Manager
  * and open the template in the editor.
  */

package tciworks;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

/**
  *
  * @author Lionel van den Berg.
  */
public class JTableTest extends JFrame {

     public JTableTest() {
         JPanel contentPane = new JPanel();
         contentPane.setLayout(new GridLayout(0, 1));
         final TestTable table = new TestTable(new TestTableModel());
         contentPane.add(table);
         this.setContentPane(contentPane);
         this.setSize(new Dimension(400, 400));
         JButton addButton = new JButton("Add");
         addButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 ((TestTableModel)table.getModel()).addRow();
             }
         });
         JButton deleteButton = new JButton("Delete");
         deleteButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 int rowNumber = table.getSelectedRow();
                 ((TestTableModel)table.getModel()).deleteRow(rowNumber);
             }
         });
         contentPane.add(addButton);
         contentPane.add(deleteButton);
     }

     protected void processWindowEvent(WindowEvent e) {
         super.processWindowEvent(e);
         if(e.getID() == WindowEvent.WINDOW_CLOSING) {
             System.exit(0);

         }
     }

     public static void main(String []args) {
         JTableTest test = new JTableTest();
         test.setVisible(true);
     }
}

/**
  * The constructer is extended to set the rendering, cell sizes, text 
position
  * and so on.
  *
  * @author Lionel van den Berg
  */
class TestTable extends JTable {


     public TestTable(AbstractTableModel tableModel) {
         super(tableModel);
         setRendering();
     }

     /**
      * Sets the location of text in cells, fonts etc.
      *
      */
     private void setRendering() {
         AbstractTableModel tableModel = (AbstractTableModel)getModel();
         TableColumn tc;
         DefaultTableCellRenderer crEditible = new 
DefaultTableCellRenderer(),
                 crNotEditible = new DefaultTableCellRenderer();
         crEditible.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
 
crNotEditible.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
         crNotEditible.setBackground(new Color(230, 230, 230));

         //all columns should have centralised text
         for(int columnIndex = 0; columnIndex < 
tableModel.getColumnCount();
             columnIndex++) {
             tc = getColumnModel().getColumn(columnIndex);
             tc.setCellEditor(new JTextFieldTableCellEditor());
             //if the column is editble, OR the whole table is not editible
             //(tableModel.isEditable() (means we don't distinguish between
             //cells). We use 0 for the row it's just a dummy row 
because we
             //know it applies to the whole column
             if(tableModel.isCellEditable(0, columnIndex)) {
                 tc.setCellRenderer(crEditible);
             } else {
                 tc.setCellRenderer(crNotEditible);
             }
         }
         setHeaderBold();
     }

     /** Gets the number of columns in the table. */
     public int getNumColumns() {
         return getModel().getColumnCount();
     }

     /**
      * Sets the headings of the table columns bold making them more visble.
      */
     public void setHeaderBold() {
         //set the headers bold
         JTableHeader header = getTableHeader();
         if(header == null) {
             return;
         }
         final Font boldFont = header.getFont().deriveFont(Font.BOLD);
         final TableCellRenderer headerRenderer = 
header.getDefaultRenderer();
         header.setDefaultRenderer(new TableCellRenderer() {
             public Component getTableCellRendererComponent(JTable table,
                     Object value, boolean isSelected, boolean hasFocus, 
int row,
                     int column ) {
                 Component comp = 
headerRenderer.getTableCellRendererComponent(
                         table, value, isSelected, hasFocus, row, column);
                 comp.setFont(boldFont);
                 return comp;
             }
         });
     }
}


class TestTableModel extends AbstractTableModel {

     private String[] columnNames = {"Column 1", "Column 2", "Column 3"};
     private ArrayList list = new ArrayList();
     private int count = 0;

     public TestTableModel() {
     }


     public int getRowCount() {
         return list.size();
     }


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


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


     public boolean isCellEditable(int row, int col) {

         //last two columns not editible
         if(col > 1) {
             return false;
         } else {
             return true;
         }
     }


     public boolean isColumnEditable(int col) {

         //last two columns not editible
         if(col > 1) {
             return false;
         } else {
             return true;
         }
     }

     /**
      * Creates a new dose and adds it to the table model.
      */
     public void addRow() {
         list.add(new String[]{"row" + count + " val1",
         "row" + count + " val2", "row" + count + " val3"});
         fireTableRowsInserted(list.size() - 1, list.size() - 1);
     }



     public void deleteRow(int row) {

         list.remove(row);

         fireTableRowsDeleted(row, row);
     }

      public Object getValueAt(int rowIndex, int columnIndex) {
          String []row = (String [])list.get(rowIndex);
          return row[columnIndex];
      }

      public void setValueAt(Object updateValue, int rowIndex, int 
colIndex) {
          String []row = (String [])list.get(rowIndex);
          row[colIndex] = (String)updateValue;
      }

     /**
      * Returns the array of column names for this table.
      *
      * @return the array of column names for this table.
      */
     public String[] getColumnNames() {
         return columnNames;
     }
}

class JTextFieldTableCellEditor extends AbstractCellEditor
         implements TableCellEditor {

     private JTextField tf = new JTextField();

     public JTextFieldTableCellEditor() {
         super();
     }

     public Object getCellEditorValue() {
         return tf.getText();
     }

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

         tf.setText(value.toString());
         tf.addFocusListener(new FocusAdapter() {
             public void focusGained(FocusEvent fe) {
                 tf.selectAll();
             }
         });
         tf.selectAll();
         return tf;
     }
}

---
 * Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24

[toc] | [next] | [standalone]


#1550 — Re: Adding custom cell re

From"katjapanisch" <katjapanisch@THRWHITE.remove-dii-this>
Date2011-04-27 15:33 +0000
SubjectRe: Adding custom cell re
Message-ID<1177678387.452515.44750@b40g2000prd.googlegroups.com>
In reply to#1549
  To: comp.lang.java.gui
On 27 Apr., 11:36, Lionel van den Berg <lione...@gmail.com> wrote:

> Can anyone tell me what the problem is? If I remove the row
> tc.setCellEditor(new JTextFieldTableCellEditor()); it doesn't throw the
> exception.

If you select the row by clicking on an editable cell, your cell
editor is not stopped before the row is deleted.
Try stopping the active cell editor in your action listener before
deleting.

 deleteButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int rowNumber = table.getSelectedRow();
                TableCellEditor editor = table.getCellEditor();
                if (editor != null) {
                    editor.stopCellEditing();
                }
                ((TestTableModel)
table.getModel()).deleteRow(rowNumber);
            }
        });

Otherwise, the selection of a new cell after row deletion will stop
the cell editor in the deleted
row, and JTable.editingStopped tries to set the new value for the
edited cell in a row that no longer exists.

If you don't set a custom cell editor, DefaultCellEditor will be used.
Because DefaultCellEditor stops cell editing on actionPerformed,
the exception does not occur.

Katja

---
 * Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24

[toc] | [prev] | [next] | [standalone]


#1554 — Re: Adding custom cell re

From"Lionel van den Berg" <lionel.van.den.berg@THRWHITE.remove-dii-this>
Date2011-04-27 15:34 +0000
SubjectRe: Adding custom cell re
Message-ID<46330079$1@dnews.tpgi.com.au>
In reply to#1550
  To: comp.lang.java.gui
katjapanisch@yahoo.com wrote:
> Otherwise, the selection of a new cell after row deletion will stop
> the cell editor in the deleted
> row, and JTable.editingStopped tries to set the new value for the
> edited cell in a row that no longer exists.

Excellent. Thank you. I've added some new code in my custom JTable to 
stop the editing an all is well :).

Thanks

Lionel.

---
 * Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.gui


csiph-web