Different cell editor in single column - Bug In Design?

Y

yancheng.cheok

Hello all,
In a single column, I wish to have different cell editor. By refering
to,

http://groups.google.com.my/group/c...model+cell+class+type&rnum=7#2adbd3e46e19e521
http://forum.java.sun.com/thread.jspa?forumID=257&threadID=211873

I manage to do the following implementation :

package org.yccheok.jstock.gui;

import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import org.yccheok.jstock.engine.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
*
* @author yccheok
*/
public class IndicatorJTable extends JTable {

/** Creates a new instance of IndicatorJTable */
public IndicatorJTable() {
}

public TableCellRenderer getCellRenderer(int row, int column)
{
final int modelRow = this.convertRowIndexToModel(row);
final int modelcolumn =
this.convertColumnIndexToModel(column);

return this.getDefaultRenderer(getModel().getValueAt(modelRow,
modelcolumn).getClass());
}

@Override
public TableCellEditor getCellEditor(int row, int column) {
final int modelRow = this.convertRowIndexToModel(row);
final int modelcolumn =
this.convertColumnIndexToModel(column);

return this.getDefaultEditor(getModel().getValueAt(modelRow,
modelcolumn).getClass());
}

private static final Log log =
LogFactory.getLog(IndicatorJTable.class);
}



with my own custom Table model.

When the JTable first display, it look fine. The cell which is being
specific as Double.class type, the display is correct :


Double, Float - same as Number, but the object-to-text translation is
performed by a NumberFormat instance (using the default number format
for the current locale).


When I double click on the cell specific as Double.class, and try to
enter non-numerical value and press enter, there suppose to be a red
border around, and doesn't allow my newly enter non-double value to be
written to the table. However, that is not the case, I am able to
write non-double value into the cell which is specific as Double.class
type.

I realize that my overridden getCellRenderer and getCellEditor in
JTable, able to return me a correct Double type renderer and cell
editor. However, the getColumnClass in table model, is unable to
return class specific to a particular cell. When editing process
start, JTable will also try to query information from Table Model
getColumnClass, which in turn will return String (Of course, I just
cann't make the particular column to return class Double. There are
other cell which is not Double)

public Class getColumnClass(int c) {
return super.getColumnClass(c);
}



This make the editing process behave incorrect. Please refer to the
following bug database related the design of table model.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4801881

May I know does any of you figure out a workaround on this?

Thank you very much!

cheok
 
T

Tom Hawtin

I realize that my overridden getCellRenderer and getCellEditor in
JTable, able to return me a correct Double type renderer and cell
editor. However, the getColumnClass in table model, is unable to
return class specific to a particular cell. When editing process
start, JTable will also try to query information from Table Model
getColumnClass, which in turn will return String (Of course, I just
cann't make the particular column to return class Double. There are
other cell which is not Double)

I'm not really following.

Why can't you just have TableCellRenderer.getTableCellRendererComponent
and TableCellEditor.getTableCellEditorComponent return components
depending on, say, row and column indexes or type of value?

Tom Hawtin
 
Y

yancheng.cheok

I'm not really following.

Why can't you just have TableCellRenderer.getTableCellRendererComponent
and TableCellEditor.getTableCellEditorComponent return components
depending on, say, row and column indexes or type of value?

Tom Hawtin

Yes. I had tried that too. It won't work either.

OK. Let's take the following examples. In my JTable, all the cells
should be Object, except one of it (at col=1, row=1) should be Double.

When I mean a cell should be Double, it means the following :

1. I key in a non double value in the particular cell and try to press
enter to update my table model. It is not allowed and will display red
border around the cell as follow:
http://yancheng.cheok.googlepages.com/invalid-double-when-press-enter.JPG

2. I key in a double value in the particular cell and try to press
enter. Everything is ok as follow:
http://yancheng.cheok.googlepages.com/double-when-press-enter.JPG

I try two methods to achieve my objective. However, neither one does
work. When I key in non double value and press enter, the following
exception will be thrown :

Exception in thread "AWT-EventQueue-0"
java.lang.IllegalArgumentException: Cannot format given Object as a
Number
at java.text.DecimalFormat.format(DecimalFormat.java:487)
at java.text.Format.format(Format.java:140)


First method
---------------

package javaapplication7;

import javax.swing.*;
import javax.swing.table.*;

/**
*
* @author YC Cheok
*/
public class MyTable extends JTable {

/** Creates a new instance of MyTable */
public MyTable() {
}

public TableCellEditor getCellEditor(int row, int column) {
if(row == 1 && column == 1) {
return this.getDefaultEditor(Double.class);
}

return super.getCellEditor(row, column);
}

public TableCellRenderer getCellRenderer(int row, int column) {
if(row == 1 && column == 1) {
return this.getDefaultRenderer(Double.class);
}

return super.getCellRenderer(row, column);
}
}

package javaapplication7;

/**
*
* @author YC Cheok
*/
public class NewJFrame extends javax.swing.JFrame {

/** Creates new form NewJFrame */
public NewJFrame() {
initComponents();
}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc=" Generated Code
">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new MyTable();


setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null, null, null},
{null, null, null, null},
{null, null, null, null},
{null, null, null, null}
},
new String [] {
"Title 1", "Title 2", "Title 3", "Title 4"
}
));
jScrollPane1.setViewportView(jTable1);

getContentPane().add(jScrollPane1,
java.awt.BorderLayout.CENTER);

pack();
}// </editor-fold>

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}

// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1;
// End of variables declaration

}


Second Method
-------------
package javaapplication7;

import javax.swing.*;
import javax.swing.table.*;
import javax.swing.table.DefaultTableCellRenderer;

/**
*
* @author YC Cheok
*/
public class MyTable extends JTable {

/** Creates a new instance of MyTable */
public MyTable() {
final TableCellEditor oldEditor =
this.getDefaultEditor(Object.class);
final TableCellRenderer oldRenderer =
this.getDefaultRenderer(Object.class);

javax.swing.DefaultCellEditor editor = new
javax.swing.DefaultCellEditor(new JTextField()) {
public java.awt.Component
getTableCellEditorComponent(JTable table, Object value, boolean
isSelected, int row, int column) {
if(row == 1 && column == 1) {
TableCellEditor e =
table.getDefaultEditor(Double.class);
return e.getTableCellEditorComponent(table, value,
isSelected, row, column);
}

return oldEditor.getTableCellEditorComponent(table,
value, isSelected, row, column);
}
};

javax.swing.table.DefaultTableCellRenderer renderer = new
javax.swing.table.DefaultTableCellRenderer() {
public java.awt.Component
getTableCellRendererComponent(JTable table, Object value, boolean
isSelected, boolean hasFocus, int row, int column) {
if(row == 1 && column == 1) {
TableCellRenderer e =
table.getDefaultRenderer(Double.class);
return e.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
}

return
oldRenderer.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
}
};

this.setDefaultEditor(Object.class, editor);
this.setDefaultRenderer(Object.class, renderer);
}
}
 
T

Tom Hawtin

I try two methods to achieve my objective. However, neither one does
work. When I key in non double value and press enter, the following
exception will be thrown :

Exception in thread "AWT-EventQueue-0"
java.lang.IllegalArgumentException: Cannot format given Object as a
Number
at java.text.DecimalFormat.format(DecimalFormat.java:487)
at java.text.Format.format(Format.java:140)

JTable.getCellEditor by default returns an editor whose behaviour is
dependent on the the column class. So don't use broken editors supplied
by JTable.

Tom Hawtin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top