JTable single click edit, vs double click action problem

Hi everyone,

I have a small problem which hopefully has a solution! I have a JTable which represents a bunch of objects, that when double clicked opens an editor which permits us to view the information related to the objects.

One of the JTable's columns has in each row, the subject/title of the object it represents.

I have a MouseAdapter on the table which currently successfully captures the double-click to open event. I'd like to add a second event, that permits the cell editor to fire, if the user single clicks the row when it was already selected.

Problem:

elseif( e.getClickCount() == 1 && table.isRowSelected( row ) ){

System.out.println( e.getClickCount() );

int column = table.columnAtPoint( e.getPoint() );

table.editCellAt( row, column );

table.setEditingRow( row );

table.setEditingColumn( column );

table.repaint();

}

This code seems to intercept the doubleclick event! It would appear that the doubleclick selects the row after the first click, and not after the second.

How then can I achieve the functionality desired?

Regards.

Alex

[1322 byte] By [Saevena] at [2007-10-3 10:04:33]
# 1
I think a much better approach would be to override JTable.editCellAt(int row, int column, EventObject e)
dberanskya at 2007-7-15 5:23:41 > top of Java-index,Desktop,Core GUI APIs...
# 2

Unless I'm complete beside the point here, It's not the edit event that's the problem, it's that the table needs to respond differently based on click count. Unfortunately, if you add a simple

System.out.println( e.getClickCount() );

You will see:

1

2

On a doubleclick. If anyone has an actual solution, it would be most appreciated.

Saevena at 2007-7-15 5:23:41 > top of Java-index,Desktop,Core GUI APIs...
# 3

there was an "actual" solution in that. I just didn't spell it out. anyway, here it is:

public class TestTable extends JFrame {

public static void main(String[] args) {

JFrame app = new TestTable();

app.pack();

app.setVisible(true);

}

public TestTable() throws HeadlessException {

JTable table = new JTable(new Object[][]{{"John", "Smith", new Date()},

{"James", "Bond", new Date()},

{"Steven", "Bryde", new Date()}},

new Object[]{"A", "B", "C"}) {

{

((DefaultCellEditor) getDefaultEditor(String.class)).setClickCountToStart(1);

}

public boolean editCellAt(int row, int column, EventObject e) {

if(isEditing()) {

getCellEditor().stopCellEditing();

}

if (e instanceof MouseEvent) {

JTable table = (JTable) e.getSource();

MouseEvent mEvent = ((MouseEvent) e);

if (mEvent.getClickCount() == 2) {

JOptionPane.showMessageDialog(table, "Edit Properties");

return false;

} else if (!table.isRowSelected(row)) {

return false;

} else {

return super.editCellAt(row, column, e);

}

}

return false;

}

};

setContentPane(new JScrollPane(table));

}

}

dberanskya at 2007-7-15 5:23:41 > top of Java-index,Desktop,Core GUI APIs...
# 4

Turns out you weren't so far off base, I'll give you a duke dollar for mentioning that function name! :)

Here was the complete solution:

In the JTable mouseadapter, only capture double clicks, and issue this to prevent screwy edit behavior (ie. cancel edit on row selection when edit isn't terminated)

((DefaultCellEditor)table.getDefaultEditor(String.class)).cancelCellEditing();

On the JTable itself, issue:

((DefaultCellEditor)getDefaultEditor(String.class)).setClickCountToStart(1);

putClientProperty( "terminateEditOnFocusLost", Boolean.TRUE );

Next, override the editCellAt event in the JTable

public boolean editCellAt(int row, int col, EventObject e){

if( e instanceof MouseEvent ){

if( ((MouseEvent)e).getClickCount() == 1 && this.isRowSelected( row ) )

super.editCellAt( row, col, e );

}

return false;

}

I hope this helps someone in the future!

Saevena at 2007-7-15 5:23:41 > top of Java-index,Desktop,Core GUI APIs...
# 5

Events should not have multiple meanings. Not only is it difficult to code, but it is difficult for users to understand. The default behaviour for a table is:

a) single click selects the row

b) double click places the cell in edit mode (if the cell is editable)

When a cell is editable, then the double click doesn't get passed to the MouseListener. Since you say you have code that opens an editor on a double click, this implies that you have made all your cell non-editable. If this is the case, then invoking editCellAt(...) won't work because the cell is non-editable.

One solution is to make the cells editable and then also change the setClickCountToStart to 3. This means the user will need to triple click the cell to start the editor. Or the user can use the F2 key to invoke the editor.

camickra at 2007-7-15 5:23:41 > top of Java-index,Desktop,Core GUI APIs...
# 6

> Turns out you weren't so far off base,

imagine that! :)

>

> Here was the complete solution:

you have a part of your code sitting in a mouse event listener and another part in an overriden editCellAt() function. These two pieces together comprise the custom behavior you want. This isn't good design (especially if someone else will end up maintaining the code). I'd recommend consolidating as much of the code into a single location as possible (the editCellAt() function).

dberanskya at 2007-7-15 5:23:41 > top of Java-index,Desktop,Core GUI APIs...
# 7
I would otherwise agree with you both, but the mouseclick handler does 'other' things that aren't necessarily triggered by the listener, and are tied to press/release events.
Saevena at 2007-7-15 5:23:41 > top of Java-index,Desktop,Core GUI APIs...