-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
1.4.0, 1.4.1
-
Fix Understood
-
x86
-
windows_2000
Name: gm110360 Date: 08/01/2002
FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 Server
Version 5.0.2195 Service Pack 2 Build 2195
A DESCRIPTION OF THE PROBLEM :
Moving the last column within a JTable while column is
selected causes selection change events (valueChanged)to
refer to non-existent column (and yes, I do supply a code
fix).
REGRESSION. Last worked in version 1.3.1
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Listen to selection changes in a JTable column and try
to access the table's column using event.getLastColumn()
2. Select the last column by clicking onto one of its
fields (works even when column selection is not activated)
3. Move the last column to the left
EXPECTED VERSUS ACTUAL BEHAVIOR :
The selection change event caused by moving the column
should be received BEFORE the moving column is temporarily
removed (in order to reinsert it at a new position) from
the table's column model.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.ArrayIndexOutOfBoundsException: 4 >= 4
at java.util.Vector.elementAt(Vector.java:427)
at javax.swing.table.DefaultTableColumnModel.getColumn
(DefaultTableColumnModel.java:277)
at TableBugDemo$1.valueChanged(TableBugDemo.java:88)
at javax.swing.DefaultListSelectionModel.fireValueChanged
(DefaultListSelectionModel.java:187)
at javax.swing.DefaultListSelectionModel.fireValueChanged
(DefaultListSelectionModel.java:167)
at javax.swing.DefaultListSelectionModel.fireValueChanged
(DefaultListSelectionModel.java:214)
at javax.swing.DefaultListSelectionModel.removeIndexInterval
(DefaultListSelectionModel.java:544)
at javax.swing.table.DefaultTableColumnModel.moveColumn
(DefaultTableColumnModel.java:180)
at
javax.swing.plaf.basic.BasicTableHeaderUI$MouseInputHandler.mouseDragged
(BasicTableHeaderUI.java:191)
at java.awt.AWTEventMulticaster.mouseDragged
(AWTEventMulticaster.java:257)
at java.awt.Component.processMouseMotionEvent(Component.java:5069)
at javax.swing.JComponent.processMouseMotionEvent(JComponent.java:2763)
at java.awt.Component.processEvent(Component.java:4822)
at java.awt.Container.processEvent(Container.java:1380)
at java.awt.Component.dispatchEventImpl(Component.java:3526)
at java.awt.Container.dispatchEventImpl(Container.java:1437)
at java.awt.Component.dispatchEvent(Component.java:3367)
at java.awt.LightweightDispatcher.retargetMouseEvent
(Container.java:3214)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:2946)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:2859)
at java.awt.Container.dispatchEventImpl(Container.java:1423)
at java.awt.Window.dispatchEventImpl(Window.java:1566)
at java.awt.Component.dispatchEvent(Component.java:3367)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:445)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy
(EventDispatchThread.java:190)
at java.awt.EventDispatchThread.pumpEventsForHierarchy
(EventDispatchThread.java:144)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:130)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:98)
Trying to access Column 4...
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
/**
* TableBugDemo (derived from SimpleTableDemo)
* demonstrates two different bugs within J2SE 1.4.0-b92
* that may easily be fixed:
*
* 1. TableCellEditor not removed when leaving JTable for
* second and subsequent time(s).
*
* 2. getLastIndex points to non-existent column in
* ListSelectionListener.valueChanged when last column
* is moved while being selected.
*
* ###@###.### 09-jun-02
*/
public class TableBugDemo extends JFrame {
private final JTable table;
private final JScrollPane scrollPane;
private final JPanel panel;
private final JTextField textField;
private final TableColumnModel tcm;
private final ListSelectionModel tcsm;
public TableBugDemo() {
super("TableBugDemo");
Object[][] data = {
{"Mary", "Campione",
"Snowboarding", new Integer(5), new Boolean(false)},
{"Alison", "Huml",
"Rowing", new Integer(3), new Boolean(true)},
{"Kathy", "Walrath",
"Chasing toddlers", new Integer(2), new Boolean(false)},
{"Mark", "Andrews",
"Speed reading", new Integer(20), new Boolean(true)},
{"Angela", "Lih",
"Teaching high school", new Integer(4), new Boolean(false)}
};
String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Move me after clicking false"};
table = new JTable(data, columnNames);
table.setPreferredScrollableViewportSize(new Dimension(800, 90));
table.setCellSelectionEnabled(true); // Cosmetic only, errors anyway
//Create the scroll pane and add the table to it.
scrollPane = new JScrollPane(table);
//Create a panel to hold the table's scrollpane and a textfield
panel = new JPanel(new BorderLayout());
//Add the scrollpane
getContentPane().add(scrollPane, BorderLayout.CENTER);
//Create and add a textfield to demonstrate focus change behaviour
textField = new JTextField("Click here after double-clicking Mary " +
"to cause Mary's editor to be removed. " +
"Then repeat procedure again to find " +
" that Mary now remains in edit state.");
getContentPane().add(textField, BorderLayout.SOUTH);
// Get the table's column model
tcm = table.getColumnModel();
// and it's selction model as well
tcsm = tcm.getSelectionModel();
// listenen to column selection changes
tcsm.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
final int colNo = e.getLastIndex();
System.out.println("Trying to access Column " + colNo + "...");
// and now: java.lang.ArrayIndexOutOfBoundsException: 4 >= 4
// when last column is moved while being selected
final TableColumn tc = tcm.getColumn(colNo);
System.out.println("... named " + tc.getHeaderValue());
}
});
}
public static void main(String[] args) {
TableBugDemo frame = new TableBugDemo();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // 1.4
frame.pack();
frame.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
This is both a code fix and a workaround (when used
properly subclassing
javax.swing.table.DefaultTableColumnModel):
public void moveColumn(int columnIndex, int newIndex)
within class in javax.swing.table.DefaultTableColumnModel
...
aColumn = (TableColumn)tableColumns.elementAt(columnIndex);
tableColumns.removeElementAt(columnIndex);
boolean selected = selectionModel.isSelectedIndex
(columnIndex);
selectionModel.removeIndexInterval(columnIndex,columnIndex);
tableColumns.insertElementAt(aColumn, newIndex);
selectionModel.insertIndexInterval(newIndex, 1, true);
...
should be changed to
...
aColumn = (TableColumn)tableColumns.elementAt(columnIndex);
// not yet tableColumns.removeElementAt(columnIndex);
boolean selected = selectionModel.isSelectedIndex
(columnIndex);
selectionModel.removeIndexInterval(columnIndex,columnIndex);
tableColumns.removeElementAt(columnIndex); // now
tableColumns.insertElementAt(aColumn, newIndex);
selectionModel.insertIndexInterval(newIndex, 1, true);
...
Release Regression From : 1.3.1_04
The above release value was the last known release where this
bug was known to work. Since then there has been a regression.
(Review ID: 148156)
======================================================================
FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 Server
Version 5.0.2195 Service Pack 2 Build 2195
A DESCRIPTION OF THE PROBLEM :
Moving the last column within a JTable while column is
selected causes selection change events (valueChanged)to
refer to non-existent column (and yes, I do supply a code
fix).
REGRESSION. Last worked in version 1.3.1
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Listen to selection changes in a JTable column and try
to access the table's column using event.getLastColumn()
2. Select the last column by clicking onto one of its
fields (works even when column selection is not activated)
3. Move the last column to the left
EXPECTED VERSUS ACTUAL BEHAVIOR :
The selection change event caused by moving the column
should be received BEFORE the moving column is temporarily
removed (in order to reinsert it at a new position) from
the table's column model.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.ArrayIndexOutOfBoundsException: 4 >= 4
at java.util.Vector.elementAt(Vector.java:427)
at javax.swing.table.DefaultTableColumnModel.getColumn
(DefaultTableColumnModel.java:277)
at TableBugDemo$1.valueChanged(TableBugDemo.java:88)
at javax.swing.DefaultListSelectionModel.fireValueChanged
(DefaultListSelectionModel.java:187)
at javax.swing.DefaultListSelectionModel.fireValueChanged
(DefaultListSelectionModel.java:167)
at javax.swing.DefaultListSelectionModel.fireValueChanged
(DefaultListSelectionModel.java:214)
at javax.swing.DefaultListSelectionModel.removeIndexInterval
(DefaultListSelectionModel.java:544)
at javax.swing.table.DefaultTableColumnModel.moveColumn
(DefaultTableColumnModel.java:180)
at
javax.swing.plaf.basic.BasicTableHeaderUI$MouseInputHandler.mouseDragged
(BasicTableHeaderUI.java:191)
at java.awt.AWTEventMulticaster.mouseDragged
(AWTEventMulticaster.java:257)
at java.awt.Component.processMouseMotionEvent(Component.java:5069)
at javax.swing.JComponent.processMouseMotionEvent(JComponent.java:2763)
at java.awt.Component.processEvent(Component.java:4822)
at java.awt.Container.processEvent(Container.java:1380)
at java.awt.Component.dispatchEventImpl(Component.java:3526)
at java.awt.Container.dispatchEventImpl(Container.java:1437)
at java.awt.Component.dispatchEvent(Component.java:3367)
at java.awt.LightweightDispatcher.retargetMouseEvent
(Container.java:3214)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:2946)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:2859)
at java.awt.Container.dispatchEventImpl(Container.java:1423)
at java.awt.Window.dispatchEventImpl(Window.java:1566)
at java.awt.Component.dispatchEvent(Component.java:3367)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:445)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy
(EventDispatchThread.java:190)
at java.awt.EventDispatchThread.pumpEventsForHierarchy
(EventDispatchThread.java:144)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:130)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:98)
Trying to access Column 4...
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
/**
* TableBugDemo (derived from SimpleTableDemo)
* demonstrates two different bugs within J2SE 1.4.0-b92
* that may easily be fixed:
*
* 1. TableCellEditor not removed when leaving JTable for
* second and subsequent time(s).
*
* 2. getLastIndex points to non-existent column in
* ListSelectionListener.valueChanged when last column
* is moved while being selected.
*
* ###@###.### 09-jun-02
*/
public class TableBugDemo extends JFrame {
private final JTable table;
private final JScrollPane scrollPane;
private final JPanel panel;
private final JTextField textField;
private final TableColumnModel tcm;
private final ListSelectionModel tcsm;
public TableBugDemo() {
super("TableBugDemo");
Object[][] data = {
{"Mary", "Campione",
"Snowboarding", new Integer(5), new Boolean(false)},
{"Alison", "Huml",
"Rowing", new Integer(3), new Boolean(true)},
{"Kathy", "Walrath",
"Chasing toddlers", new Integer(2), new Boolean(false)},
{"Mark", "Andrews",
"Speed reading", new Integer(20), new Boolean(true)},
{"Angela", "Lih",
"Teaching high school", new Integer(4), new Boolean(false)}
};
String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Move me after clicking false"};
table = new JTable(data, columnNames);
table.setPreferredScrollableViewportSize(new Dimension(800, 90));
table.setCellSelectionEnabled(true); // Cosmetic only, errors anyway
//Create the scroll pane and add the table to it.
scrollPane = new JScrollPane(table);
//Create a panel to hold the table's scrollpane and a textfield
panel = new JPanel(new BorderLayout());
//Add the scrollpane
getContentPane().add(scrollPane, BorderLayout.CENTER);
//Create and add a textfield to demonstrate focus change behaviour
textField = new JTextField("Click here after double-clicking Mary " +
"to cause Mary's editor to be removed. " +
"Then repeat procedure again to find " +
" that Mary now remains in edit state.");
getContentPane().add(textField, BorderLayout.SOUTH);
// Get the table's column model
tcm = table.getColumnModel();
// and it's selction model as well
tcsm = tcm.getSelectionModel();
// listenen to column selection changes
tcsm.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
final int colNo = e.getLastIndex();
System.out.println("Trying to access Column " + colNo + "...");
// and now: java.lang.ArrayIndexOutOfBoundsException: 4 >= 4
// when last column is moved while being selected
final TableColumn tc = tcm.getColumn(colNo);
System.out.println("... named " + tc.getHeaderValue());
}
});
}
public static void main(String[] args) {
TableBugDemo frame = new TableBugDemo();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // 1.4
frame.pack();
frame.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
This is both a code fix and a workaround (when used
properly subclassing
javax.swing.table.DefaultTableColumnModel):
public void moveColumn(int columnIndex, int newIndex)
within class in javax.swing.table.DefaultTableColumnModel
...
aColumn = (TableColumn)tableColumns.elementAt(columnIndex);
tableColumns.removeElementAt(columnIndex);
boolean selected = selectionModel.isSelectedIndex
(columnIndex);
selectionModel.removeIndexInterval(columnIndex,columnIndex);
tableColumns.insertElementAt(aColumn, newIndex);
selectionModel.insertIndexInterval(newIndex, 1, true);
...
should be changed to
...
aColumn = (TableColumn)tableColumns.elementAt(columnIndex);
// not yet tableColumns.removeElementAt(columnIndex);
boolean selected = selectionModel.isSelectedIndex
(columnIndex);
selectionModel.removeIndexInterval(columnIndex,columnIndex);
tableColumns.removeElementAt(columnIndex); // now
tableColumns.insertElementAt(aColumn, newIndex);
selectionModel.insertIndexInterval(newIndex, 1, true);
...
Release Regression From : 1.3.1_04
The above release value was the last known release where this
bug was known to work. Since then there has been a regression.
(Review ID: 148156)
======================================================================