Swing - JTable, CellEditors and terminateEditOnFocusLost

Discussion in 'Java' started by dbaldes, Jan 9, 2006.

  1. dbaldes

    dbaldes Guest

    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
    dbaldes, Jan 9, 2006
    #1
    1. Advertising

  2. dbaldes

    zero Guest

    "dbaldes" <> wrote in
    news::

    > 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
    >


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

    --
    Beware the False Authority Syndrome
    zero, Jan 9, 2006
    #2
    1. Advertising

  3. dbaldes

    dbaldes Guest

    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, Jan 9, 2006
    #3
  4. dbaldes

    dbaldes Guest

    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();
    }
    }
    }
    dbaldes, Jan 9, 2006
    #4
  5. dbaldes

    Vova Reznik Guest

    dbaldes wrote:

    > 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();
    }
    }
    Vova Reznik, Jan 9, 2006
    #5
  6. dbaldes

    dbaldes Guest

    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).
    dbaldes, Jan 9, 2006
    #6
  7. dbaldes

    zero Guest

    "dbaldes" <> 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.

    --
    Beware the False Authority Syndrome
    zero, Jan 9, 2006
    #7
  8. dbaldes

    zero Guest

    zero <> wrote in
    news:Xns9746F28AA9A5Azerothishi@195.130.132.70:

    >
    > 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.



    --
    Beware the False Authority Syndrome
    zero, Jan 9, 2006
    #8
  9. dbaldes

    dbaldes Guest

    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, Jan 10, 2006
    #9
  10. dbaldes

    dbaldes Guest

    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
    dbaldes, Jan 10, 2006
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Florent Coué

    How to do a good use of JTable Swing ?

    Florent Coué, Sep 9, 2003, in forum: Java
    Replies:
    1
    Views:
    5,349
    Thomas Weidenfeller
    Sep 9, 2003
  2. Tivo Escobar
    Replies:
    1
    Views:
    7,309
    manusa
    Apr 12, 2007
  3. dbaldes
    Replies:
    0
    Views:
    3,439
    dbaldes
    Jan 9, 2006
  4. Tintin92
    Replies:
    1
    Views:
    1,693
    Andrew Thompson
    Feb 14, 2007
  5. Haircuts Are Important
    Replies:
    3
    Views:
    312
    Haircuts Are Important
    Jun 4, 2013
Loading...

Share This Page