If I want to use a JTable in Java it seems to me for adding rows and doing alters from behind a button or so I always have to use a TableModel (this could be the default one or one created by your own) But my question is: Why do we have to use this. I can't find this in any of the posts I saw. Can someone explain how this works and why it is necessary? And why we can't just add rows to the JTable without a model.
It seems to me that if you want to just show a few records but at creation you don't know all the rows yet it would be easier to just do something like a table.add() to add the row.
You can create the table with data inside without a model attached to it. So why not add data?
Or am I just wrong and can you add also data without a model?
The TableModel interface defines the minimum methods needed by a JTable (view) to render its content (model). AbstractTableModel is an abstract implementation that provides the event plumbing and leaves just three methods that must be overridden. DefaultTableModel goes on to include an internal data model based on Vector and convenient methods to alter that internal model. See Creating a Table Model for a comparison and these contrasting examples.
Related
I have been wondering why a jTable hasn't got an .addRow() method by default. Why do you have to set a Model before this is possible?
JTable table = new JTable();
table.addRow();
The above is not possible, however:
JTable table2 = new JTable();
table2.setModel(new DefaultTableModel());
table2.addRow(...);
After setting the new model, it IS possible - why?
First of all, by default, the TableModel is not mutable (other then being able to, potentially, modify the existing data), that is, there are no methods within TableModel that provide any means to add or delete rows.
It is up to implementations of TableModel to decide if that functionality is possible. Take a look at TableModel for details about what the default interface provides
Secondly, it is the responsibility of the model to manage the data. It makes no sense for the table to suddenly provide add/delete functionality, when that functionality may or may not exist. Modifications to the data should be done directly via the model - IMHO
Thirdly, there is no JTable#addRow method
I have two radiobuttons(Say rbtn_Asia,rbtn_Europe)and one JTable. When I select rbtn_Asia, table must contains Asia's data. Similarly when I select rbtn_Europe, table must contains Europe's data. (Asia's data and Europe's data is in same database which will be updated periodically). I have implemented upto this.
My problem is like this: Consider the following case: I have selected rbtn_Asia and obviously table will contain Asia's data. Now let database has got two new tuples of Asia, how can I update the JTable dynamically without selecting the rbtn_Asia once again (because rbtn_Asia is already in selected state).
In your button handler, update your implementation of TableModel, which should then fire the appropriate event. A structure that supports clear() such as Map, shown here, is convenient. More examples may be found here.
So I am working on a GUI that involves working with tables that can be sorted. I am noticing that when I sort a table, and I select a row from the newly sorted table, the selected row index of that row points to the data row from before the sort. I understand that this is because the view has changed, but the model has not; thus, you have the need for convertRowIndexToModel. It is also to my understanding that one can automatically update the view based on changes to the model by firing TableModelEvent's.
So here is my question: is it possible to automatically update the TableModel, based on changes to the view, so that I would not have to worry about converting the view index to table index?
All the default table code does this automatically so you don't need to worry about this. That is if you reference the model by using the table.getValueAt(...) and table.setValueAt(...) methods then you won't have a problem.
Only code that you write that tries to access the TableModel directly will have a problem. In this case thats what the convertXXX(...) methods are for.
I would assume that I should use a jTable. I tried this, but I can't for the life of me figure out how to append, insert and delete rows without a ton of overrides and complicated code. I find it hard to believe that Oracle doesn't have an easier way to do it.
Here's the premise. I have a few arrayLists. Each contain n amount of items and I want to be able to add these items' properties in the form of strings to the jtable and once i surpass a certain number of rows, I want the jTable to scroll.
So that's the reason I need to be able to add and remove rows.
As discussed in How to Use Tables: Creating a Table Model, DefaultTableModel has convenient methods to add, insert and remove rows. Simply update your model using any of these methods and your view will be updated accordingly.
Addendum: There's an example here.
Take a look at GlazedLists. It makes working with dynamically changing data and sowing it in JTables/JLists/JTrees, etc, very simple.
How do I enable JTable icons and behaviors for sorting table rows by a column, without letting it use a comparison predicate to do the sorting? That is to say, how do I tell the table headers to show the arrow for ascending/descending sort order in the column being used, and get it to call appropriate methods when sort order/column change?
I am trying to create an (editable, filterable, sortable) JTable backed by an SQL query or view. The rows may not fit in memory, and may not map cleanly to java objects, so I want to do all sorting/filtering within SQL. I have already written the code for changing a query to accommodate sorting by column, filtering by values, and visible columns.
To use this, I am planning to write a JTableModel based on a ResultSet with TYPE_SCROLL_SENSITIVE, and CONCUR_UPDATABLE, so changes to the DB get propagated to the ResultSet. I will periodically (several times a second) force a refresh of the visible JTable from the ResultSet, so changes to the database become visible to the user. User changes to the table will be passed to the updateable ResultSet after validation.
I've looked a little bit at how sorting is done normally, but most implementations seems to rely on the JTable creating a javax.swing.RowSorter with a Comparator predicate, or on maintaining a sorted list of rows that fires events when changed. So, my questions:
ORM frameworks are NOT an answer to this question, because the data do not map well to entity objects. Also, the DBMS I am using is H2.
EDIT: Sortable JTable libraries based on applying Comparators or sorting predicates to row objects are also unsuitable, unfortunately. I do not believe I will be able to hold all objects in memory in order to perform sorting. This problem prevents me from using the SwingX JXTables, GlazedLists, or similar libraries. I wish I could, but I can't. Period.
** I will be dealing with many thousand rows, potentially millions, with numerous columns. Yes, I really DO need to use SQL to do the sorting and filtering.**
Questions: (in descending importance)
How do I show indicators for which column is used to sort rows?
How do I get the JTable to fire appropriate events when the column headers are LEFT-clicked to change sort order?
Is there an easier way to force the JTable to update when the database changes?
Is there a library that would make all this considerably easier (connecting DB queries or views and JTables)?
Am I going to run into horrible, horrible problems when I design the system like this?
I have never used it myself but JIDE Data Grids provides a DatabaseTableModel that provides filtering and sorting support using SQL WHERE and ORDER BY.
In answer to 1 and 2, check out SwingX, which already includes a table class with built-in sorting (and filtering). You may be able to adapt this.
Am I going to run into horrible, horrible problems when I design the system like this?
From experience, yes. I worked on a project almost exactly the same as this, where someone had designed a JTable that supposedly 'magically' bound to a database table. This coupled display logic and database access together in one big horrible mess, which we replaced entirely with reflection-driven table models and separate record CRUD operations.
You say that ORM is not the answer...
If the format of the data doesn't change, then it's worth considering anyway. Your 'entity' classes need not represent real-world entities.
If (as I suspect) your entity format changes, it might be worth considering:
A flexible map-based Record class which stores records as key-value pairs;
Dynamically-built table models for your display logic, built by querying record keys, plugged into SwingX tables to get sort and filter for free;
A similarly-designed Repository class which encapsulates your database access separately from the table itself, responsible for loading and saving Records. This acts as an adapter between your updateable ResultSet and the view (although I'd check whether using a ResultSet this way is going to require an open database connection whilst data is visible...).
This separation into 'a table that displays and sorts records' and 'a repository that manages the data' means:
You can reuse the table for non-database-bound data;
You can display database-bound records in things other than tables;
You won't go mad trying to build and test the thing :)
You should be able to subclass javax.swing.RowSorter in order to create a row sorter that does the sorting in the database. From the API docs:
"RowSorter implementations typically don't have a one-to-one mapping with the underlying model, but they can. For example, if a database does the sorting, toggleSortOrder might call through to the database (on a background thread), and override the mapping methods to return the argument that is passed in."
http://docs.oracle.com/javase/6/docs/api/javax/swing/RowSorter.html
Leaving aside the database stuff there's a class called SortableTable that's a part of JIDE Grids. It displays the sorting with a little ^ or v in the table header, and supports sorting by more than 1 column (1v, 2v, etc.).