JDK-4330950 : Lost newly entered data in the cell when resizing column width
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 2_beta,1.3.0,1.3.1,1.4.1,6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS:
    generic,solaris_2.6,solaris_8,windows_nt,windows_2000,windows_xp generic,solaris_2.6,solaris_8,windows_nt,windows_2000,windows_xp
  • CPU: generic,x86,sparc
  • Submitted: 2000-04-17
  • Updated: 2010-10-13
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b114Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Description
Name: skT45625			Date: 04/17/2000


java version "1.3.0rc2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0rc2-Y)
Java HotSpot(TM) Client VM (build 1.3.0rc2-Y, mixed mode)

Run TableExample4 in the demo/TableExample directory. double click on a cell and
modify the text in the cell. While the cell is still in the editing mode. click
a column header cell or resize a column. The newly entered data will be gone.
(Review ID: 103784) 
======================================================================
Contribution provided by java.net member leouser:


A DESCRIPTION OF THE FIX :
BUG ID: 4330950 lost newly entered data in the cell when resizing column width.
FILES AFFECTED: javax.swing.JTable
JDK VERSION
jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin

Discusion(embeded in test case as well):
/**
 * BUG ID: 4330950 lost newly entered data in the cell when resizing column width.
 * The problem is that one size does not fit all.  There is alot of complaining
 * in the bug report about what happens. The problem in defining what happens
 * one way is suddenly there is a group of people who are left out.  To try
 * and make the excluded ones happy we come to JTable.ColumnEditorBehavior.
 * ColumnEditorBehavior is an enum that currently defines 3 behaviors that
 * make sense when faced with column manipulation: revert, save and continue.
 * Im not sure whatever behaviors people need: if these don't cut the muster
 * maybe a better solution would be to allow a pluggable behavior defining
 * class.  But with that people are going to complain that they have to define
 * a class to get what they want.  To answer these folks we may add another
 * option: CUSTOM.  When CUSTOM would be used the JTable would look to a custom
 * handler to deal with what should happen.  If this solution is taken we
 * may want to wait to add that mechanism.  It may prove to be an unneeded tool.
 * WHY ARE MOVING COLUMNS WITH SAVE AND CONTINUE THE SAME?
 * Well, because they both enable the same behavior.  Once you move a column
 * you can start editing again by typing.  I guess you could complain that
 * visually they should be distinct... .  Ideally it would be great that
 * clicking on the header didn't knock out the editing session for CONTINUE
 * but there is not a good way to determine when editing should stop during
 * movement. If you use the index measurement from != to the value stored
 * in the cell goes to the swapped column/row!  If we try to do it based off
 * of changing values in getCellRect, this doesn't help either... I saw
 * the same value returned over and over until the column moved.  At least
 * we can differentiate on the resizing behavior.
 *
 * ANTI-RATIONALE:
 * 1. Adds 2 new public methods and an enum to the interface of JTable.  Could
 * break existing clients that are expecting this behavior.  This is why
 * I set the default behavior to REVERT.
 *
 * Testing Strategy:
 * 1. Create 3 JFrames with JTables in them.  Each JTable has one of the different
 * behaviors.  Play with the behaviors to see how they differ.  See if they
 * break anything.
 * We are not doing a tradition JUnit style test here because you have to
 * see the results of the interaction.  I guess we could programmatically
 * try to move things around but what we want is a test of behavior based off
 * of user interaction.
 *
 * FILES AFFECTED: javax.swing.JTable
 * JDK VERSION
 * jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin
 *
 * test ran succesfully on a SUSE 7.3 Linux distribution
 *
 * Brian Harry
 * ###@###.###
 * Jan 20, 2006
 */

UNIFIED DIFF:
--- /home/nstuff/java6/jdk1.6.0/javax/swing/JTable.java	Thu Dec 15 02:17:37 2005
+++ /home/javarefs/javax/swing/JTable.java	Fri Jan 20 15:00:49 2006
@@ -231,6 +231,35 @@
         FIT_WIDTH
     }
 
+    /**
+     * Defines the behavior of the editor when columns
+     * are manipulated: resized, clicked on or moved.
+     *
+     * @see #getColumnEditorBehavior
+     * @see #setColumnEditorBehavior
+     */
+    public enum ColumnEditorBehavior{
+        
+        /**
+         * When the column is resized or clicked on,
+	 * revert to the starting value and stop editing.
+         */
+        REVERT,
+
+        /**
+         * When the column is resized, moved or clicked on,
+	 * save the editors contents and stop editing.
+         */
+        SAVE,
+
+        /**
+         * When the column is resized, continue with the editing.
+         * If moved or clicked on, act as {@code SAVE}.
+         */
+        CONTINUE
+
+    }
+
 
 //
 // Instance Variables
@@ -331,6 +360,9 @@
     /** The background color of selected cells. */
     protected Color selectionBackground;
 
+    /** The {@code ColumnEditorBehavior} property. */
+    protected ColumnEditorBehavior ceBehavior = ColumnEditorBehavior.REVERT;
+
 //
 // Private state
 //
@@ -2598,6 +2630,13 @@
     }
 
     /**
+     * Returns the {@code ColumnEditorBehavior} property.
+     *
+     * @return the {@code ColumnEditorBehavior} enum
+     */
+    public ColumnEditorBehavior getColumnEditorBehavior(){ return ceBehavior; }
+
+    /**
      * Returns the name of the column appearing in the view at
      * column position <code>column</code>.
      *
@@ -3671,6 +3710,15 @@
     }
 
     /**
+     * Sets the {@code ColumnEditorBehavior} property.
+     *
+     * @param ceb the new {@code ColumnEditorBehavior}.
+     */
+    public void setColumnEditorBehavior(ColumnEditorBehavior ceb){
+	ceBehavior = ceb;
+    }
+
+    /**
      * Returns the <code>TableColumnModel</code> that contains all column information
      * of this table.
      *
@@ -4503,7 +4551,11 @@
     public void columnMoved(TableColumnModelEvent e) {
         // If I'm currently editing, then I should stop editing
         if (isEditing()) {
-            removeEditor();
+            ColumnEditorBehavior ceb = getColumnEditorBehavior();
+            if(ceb == ColumnEditorBehavior.REVERT)
+                removeEditor();
+            else
+                cellEditor.stopCellEditing();
         }
         repaint();
     }
@@ -4520,9 +4572,7 @@
      * @see TableColumnModelListener
      */
     public void columnMarginChanged(ChangeEvent e) {
-	if (isEditing()) {
-            removeEditor();
-        }
+	processCEBehavior();
 	TableColumn resizingColumn = getResizingColumn();
 	// Need to do this here, before the parent's
 	// layout manager calls getPreferredSize().
@@ -4530,6 +4580,23 @@
 	    resizingColumn.setPreferredWidth(resizingColumn.getWidth());
 	}
 	resizeAndRepaint();
+    }
+
+    private void processCEBehavior(){
+	ColumnEditorBehavior ceb = getColumnEditorBehavior();
+	if(isEditing()){
+	    switch(ceb){
+	        case REVERT:
+		    removeEditor();
+	            break;
+                case SAVE:
+		    if(cellEditor != null)
+			cellEditor.stopCellEditing();
+	            break;
+	        case CONTINUE:
+	            break;
+	    }
+	}
     }
 
     private int limit(int i, int a, int b) {


JUnit TESTCASE :
import javax.swing.*;
import java.awt.*;

/**
 * BUG ID: 4330950 lost newly entered data in the cell when resizing column width.
 * The problem is that one size does not fit all.  There is alot of complaining
 * in the bug report about what happens. The problem in defining what happens
 * one way is suddenly there is a group of people who are left out.  To try
 * and make the excluded ones happy we come to JTable.ColumnEditorBehavior.
 * ColumnEditorBehavior is an enum that currently defines 3 behaviors that
 * make sense when faced with column manipulation: revert, save and continue.
 * Im not sure whatever behaviors people need: if these don't cut the muster
 * maybe a better solution would be to allow a pluggable behavior defining
 * class.  But with that people are going to complain that they have to define
 * a class to get what they want.  To answer these folks we may add another
 * option: CUSTOM.  When CUSTOM would be used the JTable would look to a custom
 * handler to deal with what should happen.  If this solution is taken we
 * may want to wait to add that mechanism.  It may prove to be an unneeded tool.
 * WHY ARE MOVING COLUMNS WITH SAVE AND CONTINUE THE SAME?
 * Well, because they both enable the same behavior.  Once you move a column
 * you can start editing again by typing.  I guess you could complain that
 * visually they should be distinct... .  Ideally it would be great that
 * clicking on the header didn't knock out the editing session for CONTINUE
 * but there is not a good way to determine when editing should stop during
 * movement. If you use the index measurement from != to the value stored
 * in the cell goes to the swapped column/row!  If we try to do it based off
 * of changing values in getCellRect, this doesn't help either... I saw
 * the same value returned over and over until the column moved.  At least
 * we can differentiate on the resizing behavior.
 *
 * ANTI-RATIONALE:
 * 1. Adds 2 new public methods and an enum to the interface of JTable.  Could
 * break existing clients that are expecting this behavior.  This is why
 * I set the default behavior to REVERT.
 *
 * Testing Strategy:
 * 1. Create 3 JFrames with JTables in them.  Each JTable has one of the different
 * behaviors.  Play with the behaviors to see how they differ.  See if they
 * break anything.
 * We are not doing a tradition JUnit style test here because you have to
 * see the results of the interaction.  I guess we could programmatically
 * try to move things around but what we want is a test of behavior based off
 * of user interaction.
 *
 * FILES AFFECTED: javax.swing.JTable
 * JDK VERSION
 * jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin
 *
 * test ran succesfully on a SUSE 7.3 Linux distribution
 *
 * Brian Harry
 * ###@###.###
 * Jan 20, 2006
 */
public class TestJTLostData{


    public static class GUIBuilder implements Runnable{

	public void run(){
	    
	    JFrame jf1 = createJTable(JTable.ColumnEditorBehavior.REVERT,0,0);
	    Dimension b1 = jf1.getSize();
	    int x2 = 0 + b1.width;
	    int y2 = 0 + b1.height;
	    JFrame jf2 = createJTable(JTable.ColumnEditorBehavior.SAVE,x2,0);
	    JFrame jf3 = createJTable(JTable.ColumnEditorBehavior.CONTINUE,0,y2);
	    

	}
	
	public JFrame createJTable(JTable.ColumnEditorBehavior ceb, int x, int y){

	    JFrame jf = new JFrame();
	    jf.setTitle(ceb.toString());
	    Object[][] data = new Object[10][10];
	    Object[] cnames = new Object[10];
	    for(int i = 0; i < 10; i++){
		cnames[i] = String.valueOf(i);
		for(int i2 = 0; i2 < 10; i2++)
		    data[i][i2] = i2;
	    }

	    JTable jt = new JTable(data, cnames);
	    jt.setColumnEditorBehavior(ceb);
	    JScrollPane jsp = new JScrollPane(jt);
	    jf.add(jsp);
	    jf.pack();
	    jf.setLocation(x,y);
	    jf.setVisible(true);
	    return jf;
	}

    }



    public static void main(String ... args){

        SwingUtilities.invokeLater(new GUIBuilder());

    }


}


FIX FOR BUG NUMBER:
4330950

Comments
EVALUATION Contribution-forum:https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?forumID=1463&messageID=10981
23-01-2006

EVALUATION Wow, there are so many similar issues that things are getting really confusing. Here's the deal - This bug is open to track a single issue: The fact that a cell being edited loses its changes when clicking on the JTable column headers. This happens because removeEditor is being called (withou calling cancelEditing or stopEditing). Another similar issue exists involving CellEditorRemover which removes the editor when a component outside the JTable is clicked. This issue is now being tracked by 4709394. Apologies for changing the bug numbers again. ###@###.### 2002-07-11
11-07-2002