Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / November 2004

Tip: Looking for answers? Try searching our database.

cut & copy function lost with custom TableCellEditor

Thread view: 
VisionSet - 26 Nov 2004 19:43 GMT
I've got my cut-copy-paste function working well now except where I have
defined my own TableCellEditors.  Paste works okay but cut & copy do
nothing.

I'm using the internal eg DefaultEditorKit.CutAction object

I'm using a DefaultCellEditor closely based on:

http://java.sun.com/docs/books/tutorial/uiswing/components/example-1dot4/Integer
Editor.java


Cut and copy are not working only where I have replaced the default cell
editor with the one above.

However, the keyboard operation eg ctrl X does work, and whats more if I do
that suddenly my DefaultEditorKit.CutAction starts to work for that cell, as
soon as I stop editing it, it won't work again until I do another ctrl X.

Wierd!

Christian, Babu... any clues?

Signature

Mike W

VisionSet - 27 Nov 2004 01:48 GMT
> Wierd!
>
> Christian, Babu... any clues?

I have the DefaultEditorKit.CutAction proxied via my own action with its own
icons etc.

From this Action I create a menuitem and a toolbar button.

Now I find the menu button works fine, but the toolbar button does not!!
It seems that for some reason the selection is being lost for the toolbar
button initiated action.

How can this be it is the same action!!

I'd post code, but how will it help, the action is the same for both button
and menu item and it proxys to the internal cut action on all text
components that is suns own implementation.

Signature

Mike W

VisionSet - 27 Nov 2004 23:59 GMT
Okay I've narrowed the problem down.
Below is compilable example.
Briefly it uses a custom CellEditor.
And a TableModel that returns Integers
(& Strings for comparison) for rendering.
The Cut action is available via menu and button.
The Cut action works in either column from the menu,
but the button only cuts text from the String type column.
Copy has the same behaviour.
Paste is not a problem.
The classes are obviously pointless,
I've stripped out the stuff that wasn't relevant.

Compile and try to cut text from both columns cell via menu and button.

TIA for any pointers.

import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.table.*;

public class CutProblem extends JFrame {

   Action cutAction = new
JTextField().getActionMap().get(DefaultEditorKit.cutAction);

   public CutProblem() throws Exception {

       JMenuBar menuBar = new JMenuBar();
       setJMenuBar(menuBar);

       JMenu menu = new JMenu("File");
       menuBar.add(menu);

       menu.add(new JMenuItem(cutAction));

       getContentPane().add(new JButton(cutAction), BorderLayout.NORTH);

       JTable table = new JTable();
       table.setDefaultEditor(Integer.class, new ProblemEditor());

       getContentPane().add(table, BorderLayout.CENTER);

       table.setModel(new MyModel(new String[] {"", ""} , 1));

       pack();
       setVisible(true);
   }

   public static void main(String[] args) throws Exception {

       new CutProblem();
   }
}

class MyModel extends DefaultTableModel {

   public MyModel(Object[] o, int r) {

       super(o, r);
   }

   public Object getValueAt(int row, int col) {

       return new Integer(42);
   }

   public Class getColumnClass(int columnIndex) {

       switch(columnIndex) {

           case 0: return Integer.class; // causes problem
           case 1: return String.class;  // no problem
           default: throw new IllegalArgumentException();
       }
   }

}

class ProblemEditor extends DefaultCellEditor {

   private JFormattedTextField ftf;

   public ProblemEditor() {
       super(new JFormattedTextField());
       ftf = (JFormattedTextField) getComponent();
   }

   //Override to invoke setValue on the formatted text field.
   public Component getTableCellEditorComponent(JTable table,
           Object value, boolean isSelected, int row, int column) {

       JFormattedTextField ftf =
           (JFormattedTextField) super.getTableCellEditorComponent(
           table, value, isSelected, row, column);

       ftf.setValue(value); // remove and okay

       return ftf;
   }
}

Signature

Mike W

Kleopatra - 28 Nov 2004 12:13 GMT
Hi Mike,

an explanation about what's going on:

> Okay I've narrowed the problem down.
> Below is compilable example.
[quoted text clipped - 4 lines]
> The Cut action works in either column from the menu,
> but the button only cuts text from the String type column.

The important difference is the editor component used in the
CellEditors: the default for the String is a JTextField, the custom for
Integer is a JFormattedTextField - the latter fires an actionEvent on
focusLost which terminates the edit while the former doesn't. Clicking
the button transfers the focus to it, at the time of executing the
cutAction, the editing component is no longer part of the component
hierarchy in the latter case, nothing to cut from...

You can do two things to verify:

a) add an accelerator to the cutAction, then typing the accelerator
keystroke while the editor content is selected will have the same effect
(cutting) on both columns

b) set the table's clientProperty "terminateOnFocusLost" to
Boolean.TRUE, then clicking the button while the editor content is
selected will have the same effect (not cutting) on both columns

(the cutting in both column when clicking the menu is because
opening/clicking a menuItem does not change the permanent focus owner)

Jeanette
VisionSet - 28 Nov 2004 13:23 GMT
> The important difference is the editor component used in the
> CellEditors: the default for the String is a JTextField, the custom for
> Integer is a JFormattedTextField - the latter fires an actionEvent on
> focusLost which terminates the edit...

I don't believe the edit is terminated on focus lost, at least that is not
the behaviour I am seeing.  When I change the table model (via a focus loss)
during a cell edit, the editing cell remains unchanged. If the edit is
terminated, surely the renderer replaces the editor, in which case the cell
should update.

Any how, can you think of any possible solutions ?

Thanks Jeanette.

--
Mike W
Kleopatra - 28 Nov 2004 18:11 GMT
> > The important difference is the editor component used in the
> > CellEditors: the default for the String is a JTextField, the custom for
[quoted text clipped - 3 lines]
> I don't believe the edit is terminated on focus lost, at least that is not
> the behaviour I am seeing.  

"believe" is the wrong category - we aren't talking about religion.

> Any how, can you think of any possible solutions ?

yes.

Jeanette
VisionSet - 28 Nov 2004 22:48 GMT
> > I don't believe the edit is terminated on focus lost, at least that is not
> > the behaviour I am seeing.
[quoted text clipped - 4 lines]
>
> yes.

Would you be as good to enlighten the disbeliever?

--
Mike W
Kleopatra - 29 Nov 2004 15:10 GMT
> > I don't believe the edit is terminated on focus lost, at least that is not
> > the behaviour I am seeing.
>
> "believe" is the wrong category - we aren't talking about religion.

Mike, my apologies - I had been jumping to conclusions (as Babu
dilligently pointed out :-)

Hmm... looks weird and kind of statistically working or not. The only
half-way predictable way to make get the cut seems to be a) set the
terminateOnFocusLost to true and b) make sure all buttons bound to any
of the text actions are not focusable and have their requestFocusEnabled
set to false.

Jeanette
Kleopatra - 28 Nov 2004 18:16 GMT
forgot this:

> If the edit is
> terminated, surely the renderer replaces the editor, in which case the cell
> should update.

ehh... how? Your model.getValueAt(..) always returns new Integer(42)...

Jeanette
VisionSet - 28 Nov 2004 22:52 GMT
> forgot this:
>
[quoted text clipped - 3 lines]
>
> ehh... how? Your model.getValueAt(..) always returns new Integer(42)...

mmmm, I *understand* that a renderer is used to show cell contents when they
are not being edited, a renderer can show Integer(42) as well as an editor
they both convert them to Strings for display purposes however they are both
implemented.  Or is my *understanding* wrong?

--
Mike W
Babu Kalakrishnan - 29 Nov 2004 13:18 GMT
> Hi Mike,
>
[quoted text clipped - 29 lines]
> (the cutting in both column when clicking the menu is because
> opening/clicking a menuItem does not change the permanent focus owner)

While you seem spot on in your analysis that the focusLost handling of
the JFormattedField is probably the culprit, I'm afraid I still don't
quite understand the behaviour. (On JDK 1.4.2_05 - Linux, you may be
testing on another version, so your observation may be different)

For instance, if I put the cell into editing mode by double-clicking,
select the contents and click on the JButton, Cut doesn't seem to work.
If on the other hand, I enter some keystrokes into the editor and then
do the same thing, it seems to suddenly perform the Cut properly. [The
source code shows an invokeLater call in the focus lost handler that
delays the action to the next EDT cycle if the contents have changed :
may be that causes this difference]

As for why Mike "believing" :-) about the table still remaining in
editing mode, I would have probably come to the same conclusion, because
it "looks" so. The string is still left justified in the field (the
renderer shows it right justified) - Only the selection seems to vanish.

Calling setRequestFocusEnabled(false) on the JButton seems to cure the
problem altogether - (which again points to the focus handling being the
probable cause of the problem).

Also I don't quite understand why the editing should get terminated with
the JFTF even when the "terminateOnFocusLost" property of the JTable is
FALSE. The JFTF does call its own commitEdit directly - but I couldn't
quite spot it firing any ActionEvents. May be I didn't read the source
too cosely.

BK
Kleopatra - 29 Nov 2004 15:37 GMT
> While you seem spot on in your analysis that the focusLost handling of
> the JFormattedField is probably the culprit, I'm afraid I still don't
> quite understand the behaviour. (On JDK 1.4.2_05 - Linux, you may be
> testing on another version, so your observation may be different)

neither do I - after re-visiting the problem :-)

> For instance, if I put the cell into editing mode by double-clicking,
> select the contents and click on the JButton, Cut doesn't seem to work.
> If on the other hand, I enter some keystrokes into the editor and then
> do the same thing, it seems to suddenly perform the Cut properly.

Hmm, then the behaviour seems to be really undeterministic - currently
the cut on the first column works the very first time after starting the
test app (unchanged except for a slightly saner model that does not
insist on the famous 42).

> [The
> source code shows an invokeLater call in the focus lost handler that
> delays the action to the next EDT cycle if the contents have changed :
> may be that causes this difference]

interestingly that handler seems to (being cautious ;) not always be
called ...

> As for why Mike "believing" :-) about the table still remaining in
> editing mode, I would have probably come to the same conclusion, because
> it "looks" so. The string is still left justified in the field (the
> renderer shows it right justified) - Only the selection seems to vanish.

yeah - I was blind.

> Calling setRequestFocusEnabled(false) on the JButton seems to cure the
> problem altogether - (which again points to the focus handling being the
> probable cause of the problem).

I'm pretty sure it's "somehow" related to focus - but can't nail it
down.

> Also I don't quite understand why the editing should get terminated with
> the JFTF even when the "terminateOnFocusLost" property of the JTable is
> FALSE. The JFTF does call its own commitEdit directly - but I couldn't
> quite spot it firing any ActionEvents. May be I didn't read the source
> too cosely.

again, I stand corrected (no actionEvents fired) - wasn't my day. Sorry
for the confusion I caused.

Jeanette
Babu Kalakrishnan - 29 Nov 2004 15:52 GMT
>>While you seem spot on in your analysis that the focusLost handling of
>>the JFormattedField is probably the culprit, I'm afraid I still don't
>>quite understand the behaviour. (On JDK 1.4.2_05 - Linux, you may be
>>testing on another version, so your observation may be different)
>
> neither do I - after re-visiting the problem :-)

Going into the realm of speculation (too lazy and too little spare time
to go and trace it down), I get a feeling it has something to do with a
code segment which says :

        if (isEdited() && e.getID() == FocusEvent.FOCUS_LOST) {
// My comments here :
        // Do something
        // Also delays the handler if some events
        // are pending to be processed
        }
        else if (!isEdited()) {
            // reformat
            setValue(getValue(), true);
        }

I wonder if that last setValue which is called when isEdited is false
(wonder why the call at all : why is a reformat reqd if it wasn't edited
?? ) causes the field to deselect the contents (as was my observation).
If there is no selection, obviously there's nothing to cut.

BK
VisionSet - 30 Nov 2004 10:56 GMT
> Going into the realm of speculation (too lazy and too little spare time
> to go and trace it down), I get a feeling it has something to do with a
[quoted text clipped - 15 lines]
> ?? ) causes the field to deselect the contents (as was my observation).
> If there is no selection, obviously there's nothing to cut.

Thanks all, the setRequestFocusEnabled solution works fine for me.

A setValue is called explicitly in my own code in the ProblemEditor class.
Removing that line solves the uncuttable problem.

--
Mike W


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.