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 / General / January 2006

Tip: Looking for answers? Try searching our database.

Swing - JTable, CellEditors and terminateEditOnFocusLost

Thread view: 
dbaldes - 09 Jan 2006 09:15 GMT
Hello,

I have a JTable with some custom editors. I set the
"terminateEditOnFocusLost" property to have editors get removed
properly when the user "leaves" the table. The problem arises when the
user is editing a cell of the table and then clicks on another cell to
edit that one:

- editing of the cell currently being edited is stopped (good)
- the editor of the new cell is loaded (getEditorComponent called)
(good)
- JTable loses focus for some reason to somewhere (probably bad)
- JTable stops editing of the newly clicked cell (due to
terminateEditOnFocusLost i guess) (bad)

So the user has to click a second time on the new cell to edit it,
cause the editor was stopped right after being loaded on the first
click..

Without "terminateEditOnFocusLost" the behaviour is also strange: on
most Editors (simple text fields f.e.) it works well (problem described
above does not arise) , but on a custom ComboBox editor the combobox
pops up and closes again on the first click, BUT only when the cell
editor used before was also the combobox editor.. so the user has to
click a second time on the combobox to get the drop down list. When the
user was editing another column (with other editor) before, the
combobox pops up its drop down list and stays open on the first click
as I expect it to.

What i want is: 1. the behaviour of terminateEditOnFocusLost without
editors being removed when i click to edit a cell and 2. the combobox
to pop up and stay open on 1st click in any case

I already tried overriding "shouldSelectCell" in the editors (which is
not called any more, i read somewhere) because I suspected it to be
related to focusing, and messing around with JTable.requestFocus, and
the "focusable" property of the JTable is true - I did not get it to
work properly up to now.

Can you help me with this problem?

Thanks in advance!

Regards,
Daniel
zero - 09 Jan 2006 13:24 GMT
> Hello,
>
[quoted text clipped - 41 lines]
> Regards,
> Daniel

Do you have an online example that we could experiment with, and a short,
compilable example (see http://www.mindprod.com/jgloss/sscce.html)

Signature

Beware the False Authority Syndrome

dbaldes - 09 Jan 2006 15:55 GMT
Hi,

"unfortunately" i did not manage to reproduce the odd behaviour with
the editors being removed im my sscce, but the combobox problem
(described in paragraph "Without terminateEditOnFocusLost") arises here
(with and without that property set). I will further investigate and
try to reproduce the problem with editors being removed; In the
meantime the following serves as sample for the ComboBox problem (which
might be in some way related to the editors-being-removed-problem).

How to reproduce the problem with the sample code:

1. click on cell with "ab" in it
-> combobox appears and pops open
2. select some value
-> combobox closes its dropdown and displays new value
3. click on cell with "bb" in it
-> new combobox appears, but is closed
 (i do not see the box pop open and close again; i think it is due to
the example
  running faster due to the rather simple list content)

Whenever the combobox editor is active, clicking on another cell with
the combobox editor gives the described behaviour. When another or no
editor is active, the combobox pops open as it is supposed to.

any help is greatly appreciated.

---8X-------------------------------------
import java.awt.BorderLayout;
import java.awt.Component;

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

public class TestMain {

 public static void main(String[] args) {
   JTable table = new JTable(
     new String[][] { { "aa", "ab" }, { "ba", "bb" } },
     new String[] { "A", "B"} );
   table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

   table.getColumnModel().getColumn(1).setCellEditor(
     new CustomEditor());

   JFrame frame = new JFrame();
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.getContentPane().add(table, BorderLayout.CENTER);
   frame.getContentPane().add(new JTextField(), BorderLayout.SOUTH);
   frame.setSize(400,300);
   frame.setVisible(true);
 }

 private static class CustomEditor
   extends AbstractCellEditor
   implements TableCellEditor {

   private JComboBox cbComponent;

   public CustomEditor() {
     cbComponent = new JComboBox(new String[] { "xx", "yy", "zz" } );
   }

   public Component getTableCellEditorComponent(JTable table,
     Object value, boolean isSelected, int row, int column) {
     return cbComponent;
   }

   public Object getCellEditorValue() {
     return cbComponent.getSelectedItem();
   }
 }
}
dbaldes - 09 Jan 2006 16:08 GMT
Hi again,

I just managed to reproduce the problem. The difference of the
following code to the example above is that the ComboBox is inside a
JPanel, and the JPanel is returned as editor (i do this to get the
combobox centered vertically in higher rows in my application).

Repeat the steps in the posting before to reproduce the problem:
Clicking on a combobox cell (here the rightmost column) when a ComboBox
is already open results in the new editor being loaded, stopped and
removed immediately.

Maybe the Table passes focus to the JPanel, the panel then passes focus
to the ComboBox and the JTable then deems the focus to be lost?

------8X-----------------------------------
import java.awt.BorderLayout;
import java.awt.Component;

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

public class TestMain {

 public static void main(String[] args) {

   JTable table = new JTable(
     new String[][] { { "aa", "ab" }, { "ba", "bb" } },
     new String[] { "A", "B"} );
   table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

   table.getColumnModel().getColumn(1).setCellEditor(
     new CustomEditor());

   JFrame frame = new JFrame();
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.getContentPane().add(table, BorderLayout.CENTER);
   frame.getContentPane().add(new JTextField(), BorderLayout.SOUTH);
   frame.setSize(400,300);
   frame.setVisible(true);
 }

 private static class CustomEditor
   extends AbstractCellEditor
   implements TableCellEditor {

   private JPanel panel;
   private JComboBox cbComponent;

   public CustomEditor() {
     panel = new JPanel(new BorderLayout());
     cbComponent = new JComboBox(new String[] { "xx", "yy", "zz" } );
     panel.add(cbComponent, BorderLayout.CENTER);
   }

   public Component getTableCellEditorComponent(JTable table,
     Object value, boolean isSelected, int row, int column) {
     return panel;
   }

   public Object getCellEditorValue() {
     return cbComponent.getSelectedItem();
   }
 }
}
Vova Reznik - 09 Jan 2006 17:04 GMT
>   private static class CustomEditor
>     extends AbstractCellEditor
>     implements TableCellEditor {

Did you find that your CustomEditor implements CellEditor twice?
As sub of AbstractCellEditor and sub of TableCellEditor.

Try this:
private static class CustomEditor extends DefaultCellEditor  {

        private JPanel        panel;
        private static final JComboBox    cbComponent = new JComboBox(new
String[] { "xx", "yy", "zz" });

        public CustomEditor() {
            super(cbComponent);
            panel = new JPanel(new BorderLayout());           
            panel.add(cbComponent, BorderLayout.CENTER);
        }

        public Component getTableCellEditorComponent(JTable table,
                Object value, boolean isSelected, int row, int column) {
            return panel;
        }

        public Object getCellEditorValue() {
            return cbComponent.getSelectedItem();
        }       
    }
dbaldes - 09 Jan 2006 17:21 GMT
Hi,

it does not implement it twice. AbstractCellEditor implements
CellEditor, and my Subclass implements remaining methods of
TableCellEditor. This works well and is not related to the problem.
Your code does not change the behaviour (it just adds useless
functionality to the editor).
zero - 09 Jan 2006 22:50 GMT
"dbaldes" <daniel.baldes@gmail.com> wrote in news:1136822935.645822.196620
@g47g2000cwa.googlegroups.com:

> Clicking on a combobox cell (here the rightmost column) when a ComboBox
> is already open results in the new editor being loaded, stopped and
> removed immediately.

Ok, I think I have an acceptable solution.

Your main problem is that the editing is never actually stopped, because
your CustomEditor never calls fireEditingStopped.  You could add this in an
itemListener or actionListener on the combo box, but those both have flaws
(specifically when opening and closing the combo box without changing the
selected value).  The solution is to use a PopupMenuListener.

Add this to CustomEditor's constructor:

cbComponent.addPopupMenuListener(new PopupMenuListener()
  {
     public void popupMenuCanceled(PopupMenuEvent e)
     {
        fireEditingCanceled();
     }

     public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
     {
        fireEditingStopped();
     }

     public void popupMenuWillBecomeVisible(PopupMenuEvent e)
     {
     }
  });

This code will cancel or stop the editing when appropriate.

I believe you don't need the terminateEditOnFocusLost property, but do some
testing to be sure.

Signature

Beware the False Authority Syndrome

zero - 09 Jan 2006 22:56 GMT
> Your main problem is that the editing is never actually stopped,
> because your CustomEditor never calls fireEditingStopped.

btw, all these problems are caused by the fact that you use the same
CustomEditor for every cell in the column, and this CustomEditor re-uses
the same JComboBox.  If you would have a separate instance of CustomEditor
for each cell, or recreate the JComboBox, I think you would have far less
problems.  But of course this does use more memory.

Signature

Beware the False Authority Syndrome

dbaldes - 10 Jan 2006 08:15 GMT
Hi,

the default implementation of AbstractCellEditor calls
fireEditingStopped() (and cancelled). My "true" application does it
itself. (on stopCellEditing/cancelCellEditing, which is called by the
table implementation; those methods are called when i leave the editing
cell)
Reusing Components is the intention of the whole
TableCellEditor/Renderer model, i think..

But your code resolved the problem for me, so thanks a lot!

Regards,
Daniel
dbaldes - 10 Jan 2006 08:20 GMT
Hi, erm, wait,

it solves the problem for my combobox editors, which is a great step in
the right direction, but... I also have other editos (textfield,
lists..), so if anyone knows a more general solution I would be glad.

I'll try to add listeners and call fireEditingStopped/Cancelled myself,
but I think there should be a way which works with the default
behaviour (table implementation calls editor.stopCellEditing(), editor
calls fireEditingStopped() ..)

thanks in advance..

Daniel


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.