开发者

Cast Object to JTable?

I am trying to implement a ListSelectionListener for some of my JTables. Simply (at the moment) the ListSelectionListener is supposed to simply return the text of the cell that was selected.

My program design has several JTables and I would like to have one ListSelectionListener work for them all. In the valueChanged event of the ListSelectionListener I thought it was possible to do something like:

private class SelectionHandler implements ListSelectionListener {
    public void valueChanged(ListSelectionEvent e)
    {
        JTable table = (JTable)e.getSource();                                                         

        String data = (String) table.getValueAt(table.getSelectedRow(), 0);

        // Print data
    }
}

Behind the scenes I have used the following code to get the SelectionHandler working with the table in question:

fbTable.setCellSelectionEnabled(true);
ListSelectionModel cellSM = fbTable.getSelectionModel();
cellSM.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
cellSelectionModel.addListSelectionListener(selectionHandler);

When I run the program I get a ClassCastException error:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.DefaultListSelectionModel cannot be cast to javax.swing.JTable
        at cardboardfantasy.CardboardFantasyView$SelectionHandler.valueChanged(CardboardFantasyView.java:360)

开发者_开发问答// This is the line in question: JTable table = (JTable)e.getSource();

Is there a way to do something like this? One solution I thought of was to compare the source of the event (e.getSource()) to all my JTables to see if they were equivalent (big if block) and then just calling .getValueAt inside that block but that would making the code in the future difficult if tables were to be added or removed.


Either debug your code in your IDE, set a breakpoint and see what the type of e.getTarget() is:

Object source = e.getSource();
JTable table = (JTable)source; // breakpoint on this line and inspect the variable 'source'
String data = (String) table.getValueAt(table.getSelectedRow(), 0);

Or if debugging is not possible for whatever reason do this:

Object source = e.getSource();
System.out.println(source.getClass());

But: debugging using System.out.println is evil. your debugger is your friend.


As the error implies, the source object in question is a DefaultListSelectionModel not a JTable. This makes sense since the source of the event (that is, the object which fired the event) was the selection model object, not the table. Also, models in themselves make no assumptions about what type of object is using them as a model so there is no way to get a reference to the table via the selection model.


Pass the JTable instance to your selection handler. As long as the handler listens on one table, you'll be able to use that instance instead of relying on the information from the event.


I think there are two main solutions:

  • Use a JList and register the listener not with model but directly with the list. Then, if the list is contained by a table you could just ask for the list's (Component) parent to find the responsible table
  • Override DefaultListSelectionModel to (for example) take an additional argument in the constructor, which would be a JTable instance (every table will need a new instance of that model). You would save that instance in an instance variable and could then operate directly on the table when an event occurrs

I do not think that either of these solutions is ideal. I have the feeling that you could make your life easier by using some pattern or idiom to get around having to know which table the source was. But to give you any clues there we'd have to see a lot more of your code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜