1

Short Version: Given a JTable with a TableModel that extends DefaultTableModel, can I select all the text in a cell with the class String without the use of a CellEditor?

Long Version: I have made a TableModel which extends DefaultTableModel and should only have selectable rows be editable. Here's the relevant parts:

class MyTableModel extends DefaultTableModel {

    private List<String> columnNames;
    private List<List<String>> strings;

    /** editable stores the columns which we're allowed to change */
    private List<Integer> editable;

    public MyTableModel (List<String> columnNames, List<List<String>> 
            strings, List<Integer> editable) {
        this.columnNames = columnNames;
        this.strings = strings;
        this.editable = editable;
    }

    public Object getValueAt(int row, int col) {
        return strings.get(col).get(row);
        return null;
    }

    public void setValueAt(Object value, int row, int col) {
        strings.get(col).set(row, (String) value);
        fireTableCellUpdated(row, col);
    }

    public boolean isCellEditable(int row, int col) {
        return canEdit(col);
    }

    /**
     * This method looks like it should be lumped into isCellEditable()
     * But there's unique behavior I plan on having later for the first
     * column and this will let my code down the road be much cleaner.
     **/ 
    public boolean canEdit(int col) {
        return col != 0 && editable.indexOf(col) != -1;
    }
}

As far as understand, the DefaultTableModel treats cells populated with Strings as JTextFields. Our use of this table is to populate it with two columns. An uneditable column with filenames (as Strings), followed by an editable empty column of Strings. When an editable cell is selected, I'd like it to set its text the text of the filename before it, then select all the text (later the user executes a command that has an optional String field for each file, so if a filename's associated editable cell isn't empty, it uses that value. We don't want the user to have to retype the entire filename every time they set this, but also want to give them the ability to quickly do so if they want).

The table has a MouseListener which sees if an editable cell was clicked on, and if it was, it also fills in the cell with the file's name before it.

table.addMouseListener(new MouseAdapter() {
    public void mouseReleased(MouseEvent e) {       
        JTable table = ((JTable) e.getSource());
        MyTableModel model = (MyTableModel)table.getModel();
        int row = table.rowAtPoint(e.getPoint());
        int col = table.columnAtPoint(e.getPoint());

        if(tableModel.canEdit(col))
            tableModel.setValueAt(
                tableModel.getValueAt(row, col - 1), row, col);
    }
});

This works fine, but I cannot get the text to be selected. I can't seem to find a method which returns the component of a cell, and I've added a CellEditor I found online, but it doesn't change anything.

class MyCellEditor extends DefaultCellEditor {

    public MyCellEditor(JTextField textField) {
        super(textField);

        textField.addFocusListener(new FocusAdapter()  {
            public void focusGained(FocusEvent e ) {
                textField.selectAll();
            }
        });
    }
}

Added to the table with this:

for(int i = 0; i < table.getRowCount(); i++)
    table.setCellEditor(new MyCellEditor(new
              JTextField((String)table.getValueAt(i, 2))));

Things would be much easier if there were a way to omit the CellEditor altogether, but if there's something I've done like mess up the order these listeners process events, I don't mind including it. What I want to avoid is needing to write some huge CellEditor or massively overhaul any code just to add a tiny bit of convenience.

Lord Farquaad
  • 712
  • 1
  • 12
  • 33
  • 1
    *"Here's the relevant parts:"* For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson Jul 15 '16 at 15:59
  • *"X works fine, but.."* (sigh) Wish I had a dollar for every time I've read words like that.. – Andrew Thompson Jul 15 '16 at 16:01
  • "The more code there is to go through, the less likely people can find your problem. Streamline your example in one of two ways: Restart from scratch. Create a new program, adding in only what is needed to see the problem. This can be faster for vast systems where you think you already know the source of the problem. Also useful if you can't post the original code publicly for legal or ethical reasons. Divide and conquer. When you have a small amount of code, but the source of the problem is entirely unclear, start removing code a bit at a time until the problem disappears – then...." – Lord Farquaad Jul 15 '16 at 16:05
  • Why are you quoting the MCVE document to me? I was there when I wrote the first draft of it, and am quite familiar with the content.. – Andrew Thompson Jul 15 '16 at 16:23
  • I just don't see how I didn't follow it. I've seen you post it before and it's actually what I used to reformat my code for SO. I truly do appreciate you helping me form better questions, that's a super important thing, I'm just a bit confused about what I should've changed. – Lord Farquaad Jul 15 '16 at 16:56
  • @LordFarquaad `just a bit confused about what I should've changed` - how do we compile and test the code you posted? – camickr Jul 15 '16 at 17:13
  • That's fair, but my actual code is way longer than what I've posted, and the data for the tables gets piped in through a socket, so it would've been really difficult to create a self-contained version that didn't seem too long/inconvenient to read. I was hoping to reach some compromise by posting what I thought explained the problem without throwing too much code at people. Should I always prioritize completeness over minimalization? – Lord Farquaad Jul 15 '16 at 17:26
  • @AndrewThompson I've read up more on the SO meta boards and I see now how important the C in MCVe is, so I'm sorry for being snarky and quoting that back to you. However, I still don't understand what to do when you can't offer a complete example without posting a tremendous amount of code. Are there situations when posting code snippets is acceptable? Sorry, I know that's a really rookie question, but I am a rookie and I'd love to be able to contribute to SO better. – Lord Farquaad Jul 15 '16 at 19:19
  • *"..the data for the tables gets piped in through a socket"* Hard code some data within the source code. *"..that didn't seem too long/inconvenient to read."* An MCVE can be up to 200 lines of code, which will cover the vast majority of problems. *"Are there situations when posting code snippets is acceptable?"* 'Acceptable' is such a nebulous term. Let's put it this way. I think you'll get better & faster responses (on average) with an MCVE. But there are cases when a problem can be solved based on the title, or code snippets provided. This Q&A is an example of the latter. – Andrew Thompson Jul 16 '16 at 02:21

1 Answers1

3

Try wrapping the selectAll() statement in a SwingUtilities.invokeLater(...).

See: how do I simulate "onStartCellEditing" for DefaultCellEditor

for a general example of selecting text in any cell when cell editing is started:

Community
  • 1
  • 1
camickr
  • 321,443
  • 19
  • 166
  • 288
  • Thank you so much! I just copy and pasted the overrided function right after "= new JTable(){" ,and it worked like a charm! One more question though. Selecting the box lets me edit straight into it, and it has all the text selected, but it doesn't actually highlight it. I still have to doubleclick to get in and set my cursor. I tried adding grabFocus() before or after selectAll(), but neither worked. This is a pretty small issue, but our users aren't phenomenally computer-savvy, so I'm thinking that highlighing the text would help them a lot. – Lord Farquaad Jul 15 '16 at 16:50
  • Scratch that. I switched from grabFocus() to requestFocusInWindow() then added an explicit call to editCell(row, col) at the end of my mouseReleased() function on the table and it's working perfectly! Thanks again for all the help! – Lord Farquaad Jul 15 '16 at 17:06