-
Bug
-
Resolution: Unresolved
-
P4
-
7, 8u5
-
x86
-
windows_8
FULL PRODUCT VERSION :
jre6u21, jre7u45
ADDITIONAL OS VERSION INFORMATION :
Windows XP,, Windows 8.1
EXTRA RELEVANT SYSTEM CONFIGURATION :
java access bridge must be enabled in accessibility.properties
A DESCRIPTION OF THE PROBLEM :
When java access bridge is enabled, the getTableCellRendererComponent is often called with a null reference to the object to render. Without java acccess bridge enabled, everything works fine.
ADDITIONAL REGRESSION INFORMATION:
jre7u45
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run IncellEditDemo.jar and select the JComboboxess in the second column. The stdout shows the parameter of the call to getTableCellRendererComponent and getTableCellEditorComponent.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
RENDER: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "0: item 2", at: (0, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
EDIT: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
ACTUAL -
ENDER: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "null", at: (0, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "null", at: (0, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "null", at: (1, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "null", at: (1, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "null", at: (2, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "null", at: (2, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "null", at: (3, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "null", at: (3, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "null", at: (4, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
EDIT: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "null", at: (4, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "null", at: (5, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
EDIT: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "null", at: (5, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "null", at: (6, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package InCellEditDemo;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.accessibility.AccessibleContext;
import static javax.swing.BorderFactory.createTitledBorder;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
/**
*
*/
public class InCellEditView extends JFrame
implements ActionListener, WindowListener {
/**
*
*/
@SuppressWarnings("LeakingThisInConstructor")
public InCellEditView()
{
setTitle("Testapplikation In-Cell Edit in Tabellen");
addWindowListener(this);
}
/**
* Set accessibility info of context
*
* @param context
* @param name
* @param desc
*/
private void _setAccessibilityInfo(AccessibleContext context,
String name, String desc)
{
context.setAccessibleName(name);
context.setAccessibleDescription(desc);
}
/**
* Exit application
*
* @param e
*/
private void _handleOKButton(ActionEvent e)
{
System.exit(0);
}
/**
* Handle button action
*
* @param e
*/
@Override
public void actionPerformed(ActionEvent e)
{
String action = e.getActionCommand();
switch (action) {
case "Exit":
_handleOKButton(e);
break;
default:
break;
}
}
/**
*
*/
private void _setupLayout()
{
JPanel panel = new JPanel(new GridBagLayout());
JButton exitButton = new JButton("Exit");
exitButton.addActionListener(this);
_setAccessibilityInfo(exitButton.getAccessibleContext(), "Exit",
"With this button you will leave the applikation");
// Table view panel
JPanel tableViewPanel = new JPanel(new BorderLayout());
tableViewPanel.setBorder(createTitledBorder("Table view panel"));
JTable t = _createTable();
tableViewPanel.add(t.getTableHeader(), BorderLayout.PAGE_START);
tableViewPanel.add(t, BorderLayout.CENTER);
// Control panel
JPanel controlPanel = new JPanel(new GridBagLayout());
controlPanel.setBorder(createTitledBorder("Control panel"));
GridBagConstraints c = new GridBagConstraints();
c.gridy = 0;
c.gridx = 0;
c.gridwidth = 2;
c.insets.top = 0;
c.insets.left = 0;
c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.NONE;
controlPanel.add(exitButton, c);
// Layout panel
c.insets.bottom = 0;
c.insets.top = 0;
c.insets.left = 0;
c.insets.right = 0;
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;
panel.add(tableViewPanel, c);
c.gridy++;
panel.add(controlPanel, c);
add(panel);
pack();
}
public class MyTableModel extends DefaultTableModel {
private static final int NUM_COLUMNS = 2;
public int COL_ROWID = 0;
public int COL_ENUM = 1;
private final Object[][] _data;
private final Object[] _headers;
public MyTableModel(int rows)
{
super(rows, NUM_COLUMNS);
_headers = new Object[NUM_COLUMNS];
_headers[COL_ROWID] = "Row";
_headers[COL_ENUM] = "Enum";
setColumnIdentifiers(_headers);
_data = new Object[NUM_COLUMNS][rows];
for (int j = 0; j < rows; j++) {
String[] items = new String[rows];
for (int i = 0; i < rows; i++) {
items[i] = (j + ": item " + i);
}
_data[0][j] = j;
_data[COL_ENUM][j] = new JComboBox<>(items);
}
}
@Override
public Object getValueAt(int row, int col)
{
if ((row >= 0) && (row < getRowCount()) && (col >= 0) && (col
< getColumnCount())) {
if (col == COL_ENUM) {
return ((JComboBox) _data[col][row]).getSelectedItem();
}
else {
return _data[col][row];
}
}
return null;
}
public Object getDataAt(int row, int col)
{
if ((row >= 0) && (row < getRowCount()) && (col >= 0) && (col
< getColumnCount())) {
return _data[col][row];
}
return null;
}
};
public class MyComboRenderer extends DefaultTableCellRenderer {
public MyComboRenderer()
{
super();
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
System.out.println("RENDER: passed value is: \"" + value + "\", at: ("
+ row + ", " + column + "); isSelected: " + isSelected);
if (value == null) {
System.out.println("RENDER: returning <null>");
return null;
}
return super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
}
}
public class MyComboEditor extends DefaultCellEditor {
private final MyTableModel _m;
public MyComboEditor(MyTableModel m)
{
super(new JComboBox());
_m = m;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column)
{
System.out.println("EDIT: passed value is: \"" + value + "\", at: (" + row
+ ", " + column + "); isSelected: " + isSelected);
if (value == null) {
System.out.println("EDIT: returning <null>");
return null;
}
if (column == _m.COL_ENUM) {
return (JComboBox) _m.getDataAt(row, column);
}
return super.getTableCellEditorComponent(table, value, isSelected,
row, column);
}
};
private JTable _createTable()
{
MyTableModel m = new MyTableModel(7);
JTable table = new JTable(m) {
@Override
public boolean isCellEditable(int row, int column)
{
return column == ((MyTableModel) getModel()).COL_ENUM;
}
};
TableColumn tc = table.getColumnModel().getColumn(m.COL_ENUM);
tc.setPreferredWidth(70);
tc.setCellRenderer(new MyComboRenderer());
tc.setCellEditor(new MyComboEditor(m));
table.setRowHeight(22);
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
table.setShowGrid(true);
return table;
}
@Override
public void windowOpened(WindowEvent e)
{
}
@Override
public void windowClosing(WindowEvent e)
{
dispose();
}
@Override
public void windowClosed(WindowEvent e)
{
System.exit(0);
}
@Override
public void windowIconified(WindowEvent e)
{
}
@Override
public void windowDeiconified(WindowEvent e)
{
}
@Override
public void windowActivated(WindowEvent e)
{
}
@Override
public void windowDeactivated(WindowEvent e)
{
}
/**
*
* @param args
*/
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run()
{
InCellEditView view = new InCellEditView();
view._setupLayout();
view.setVisible(true);
}
});
}
}
---------- END SOURCE ----------
jre6u21, jre7u45
ADDITIONAL OS VERSION INFORMATION :
Windows XP,, Windows 8.1
EXTRA RELEVANT SYSTEM CONFIGURATION :
java access bridge must be enabled in accessibility.properties
A DESCRIPTION OF THE PROBLEM :
When java access bridge is enabled, the getTableCellRendererComponent is often called with a null reference to the object to render. Without java acccess bridge enabled, everything works fine.
ADDITIONAL REGRESSION INFORMATION:
jre7u45
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run IncellEditDemo.jar and select the JComboboxess in the second column. The stdout shows the parameter of the call to getTableCellRendererComponent and getTableCellEditorComponent.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
RENDER: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "0: item 2", at: (0, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
EDIT: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
ACTUAL -
ENDER: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "null", at: (0, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "null", at: (0, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "null", at: (1, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "0: item 0", at: (0, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "null", at: (1, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "null", at: (2, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "1: item 0", at: (1, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "3: item 0", at: (3, 1); isSelected: false
RENDER: passed value is: "null", at: (2, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "null", at: (3, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "2: item 0", at: (2, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "6: item 0", at: (6, 1); isSelected: false
EDIT: passed value is: "4: item 0", at: (4, 1); isSelected: false
RENDER: passed value is: "null", at: (3, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "null", at: (4, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "3: item 0", at: (3, 1); isSelected: false
EDIT: passed value is: "5: item 0", at: (5, 1); isSelected: false
RENDER: passed value is: "null", at: (4, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "null", at: (5, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "4: item 0", at: (4, 1); isSelected: false
EDIT: passed value is: "6: item 0", at: (6, 1); isSelected: false
RENDER: passed value is: "null", at: (5, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "null", at: (6, 1); isSelected: false
RENDER: returning <null>
RENDER: passed value is: "5: item 0", at: (5, 1); isSelected: false
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package InCellEditDemo;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.accessibility.AccessibleContext;
import static javax.swing.BorderFactory.createTitledBorder;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
/**
*
*/
public class InCellEditView extends JFrame
implements ActionListener, WindowListener {
/**
*
*/
@SuppressWarnings("LeakingThisInConstructor")
public InCellEditView()
{
setTitle("Testapplikation In-Cell Edit in Tabellen");
addWindowListener(this);
}
/**
* Set accessibility info of context
*
* @param context
* @param name
* @param desc
*/
private void _setAccessibilityInfo(AccessibleContext context,
String name, String desc)
{
context.setAccessibleName(name);
context.setAccessibleDescription(desc);
}
/**
* Exit application
*
* @param e
*/
private void _handleOKButton(ActionEvent e)
{
System.exit(0);
}
/**
* Handle button action
*
* @param e
*/
@Override
public void actionPerformed(ActionEvent e)
{
String action = e.getActionCommand();
switch (action) {
case "Exit":
_handleOKButton(e);
break;
default:
break;
}
}
/**
*
*/
private void _setupLayout()
{
JPanel panel = new JPanel(new GridBagLayout());
JButton exitButton = new JButton("Exit");
exitButton.addActionListener(this);
_setAccessibilityInfo(exitButton.getAccessibleContext(), "Exit",
"With this button you will leave the applikation");
// Table view panel
JPanel tableViewPanel = new JPanel(new BorderLayout());
tableViewPanel.setBorder(createTitledBorder("Table view panel"));
JTable t = _createTable();
tableViewPanel.add(t.getTableHeader(), BorderLayout.PAGE_START);
tableViewPanel.add(t, BorderLayout.CENTER);
// Control panel
JPanel controlPanel = new JPanel(new GridBagLayout());
controlPanel.setBorder(createTitledBorder("Control panel"));
GridBagConstraints c = new GridBagConstraints();
c.gridy = 0;
c.gridx = 0;
c.gridwidth = 2;
c.insets.top = 0;
c.insets.left = 0;
c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.NONE;
controlPanel.add(exitButton, c);
// Layout panel
c.insets.bottom = 0;
c.insets.top = 0;
c.insets.left = 0;
c.insets.right = 0;
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;
panel.add(tableViewPanel, c);
c.gridy++;
panel.add(controlPanel, c);
add(panel);
pack();
}
public class MyTableModel extends DefaultTableModel {
private static final int NUM_COLUMNS = 2;
public int COL_ROWID = 0;
public int COL_ENUM = 1;
private final Object[][] _data;
private final Object[] _headers;
public MyTableModel(int rows)
{
super(rows, NUM_COLUMNS);
_headers = new Object[NUM_COLUMNS];
_headers[COL_ROWID] = "Row";
_headers[COL_ENUM] = "Enum";
setColumnIdentifiers(_headers);
_data = new Object[NUM_COLUMNS][rows];
for (int j = 0; j < rows; j++) {
String[] items = new String[rows];
for (int i = 0; i < rows; i++) {
items[i] = (j + ": item " + i);
}
_data[0][j] = j;
_data[COL_ENUM][j] = new JComboBox<>(items);
}
}
@Override
public Object getValueAt(int row, int col)
{
if ((row >= 0) && (row < getRowCount()) && (col >= 0) && (col
< getColumnCount())) {
if (col == COL_ENUM) {
return ((JComboBox) _data[col][row]).getSelectedItem();
}
else {
return _data[col][row];
}
}
return null;
}
public Object getDataAt(int row, int col)
{
if ((row >= 0) && (row < getRowCount()) && (col >= 0) && (col
< getColumnCount())) {
return _data[col][row];
}
return null;
}
};
public class MyComboRenderer extends DefaultTableCellRenderer {
public MyComboRenderer()
{
super();
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
System.out.println("RENDER: passed value is: \"" + value + "\", at: ("
+ row + ", " + column + "); isSelected: " + isSelected);
if (value == null) {
System.out.println("RENDER: returning <null>");
return null;
}
return super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
}
}
public class MyComboEditor extends DefaultCellEditor {
private final MyTableModel _m;
public MyComboEditor(MyTableModel m)
{
super(new JComboBox());
_m = m;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column)
{
System.out.println("EDIT: passed value is: \"" + value + "\", at: (" + row
+ ", " + column + "); isSelected: " + isSelected);
if (value == null) {
System.out.println("EDIT: returning <null>");
return null;
}
if (column == _m.COL_ENUM) {
return (JComboBox) _m.getDataAt(row, column);
}
return super.getTableCellEditorComponent(table, value, isSelected,
row, column);
}
};
private JTable _createTable()
{
MyTableModel m = new MyTableModel(7);
JTable table = new JTable(m) {
@Override
public boolean isCellEditable(int row, int column)
{
return column == ((MyTableModel) getModel()).COL_ENUM;
}
};
TableColumn tc = table.getColumnModel().getColumn(m.COL_ENUM);
tc.setPreferredWidth(70);
tc.setCellRenderer(new MyComboRenderer());
tc.setCellEditor(new MyComboEditor(m));
table.setRowHeight(22);
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
table.setShowGrid(true);
return table;
}
@Override
public void windowOpened(WindowEvent e)
{
}
@Override
public void windowClosing(WindowEvent e)
{
dispose();
}
@Override
public void windowClosed(WindowEvent e)
{
System.exit(0);
}
@Override
public void windowIconified(WindowEvent e)
{
}
@Override
public void windowDeiconified(WindowEvent e)
{
}
@Override
public void windowActivated(WindowEvent e)
{
}
@Override
public void windowDeactivated(WindowEvent e)
{
}
/**
*
* @param args
*/
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run()
{
InCellEditView view = new InCellEditView();
view._setupLayout();
view.setVisible(true);
}
});
}
}
---------- END SOURCE ----------