Java Jtable spreadsheet like format - java

I have problems regarding implementing JTable, specifically the AbstractTableModel. I can create and show data from JTable but my current scenario is different from my usually scenario.
What I want to do is to make my JTable accept an input from user and I want to put other components inside the JTable
Lets say for every row there is a JComboBox, JTextField and a JCheckBox, however when I start to implement the JTable model (AbstractTableModel) I don't know how can I put those components to my JTable?
Since the method getValue from AbstractTableModel return type is of object data types. Do you have any workaround for this kind of problems and by the ways I hate using DefaultTableModel since it lacks flexibility as much as possible I want an AbstractTableModel :) help is really appreciated.

You should definitely start with How to Use Tables and study the examples there. While a JTable ins't a spreadsheet, you can calculate derived values in your table's model. This example shows how to use a JComboBox to update other cells in the same row, and these examples similarly contrast the two TableModel implementations you mention. Finally, you can use an available ScriptEngine to evaluate simple arithmetic expressions. For example, the example below prints 42.0.
ScriptEngine engine = mgr.getEngineByExtension("js");
try {
System.out.println(engine.eval("5 * 8 + 2"));
} catch (ScriptException ex) {
ex.printStackTrace(System.err);
}

Related

Using JTable to display ResultSet

I'm learning about JDBC with GUI. I can do that the GUI display the data in SQL one by one. Then i want to display the data in table just like the result when i execute in SQL. I saw that many people use two Vector to add data to JTable. I wonder is there anything else apart from Vector that I can do to add data to JTable.I really want to add some images in my post but i can't so sorry if it's uncovinient for everyone. Thanks for reading.
I wonder is there anything else apart from Vector that I can do to add data to JTable.
The DefaultTableModel uses Vectors because it makes the TableModel dynamic. That is you can easily add or remove rows/columns from the model.
If you don't want to use a Vector then you can create a custom TableModel to store the data any way that you want.
Check out Row Table Model. It gives an example
of how to create a custom TableModel using an ArrayList for the data
of to write a generic TableModel that is reusable

Simple Example of a Table in SWT

My last project I created a Singleton class and used Swing, to create my TableModel and then add the populated table to my base dialog class.
My new project however, I have to use SWT instead of Swing. I am afraid I know little to nothing about SWT.
I want to be able to create a Table class (SelectionsTable.java). In the table class I want to be able to create a simple table that has 4 colums and populates row values from a arraylist.
I will worry about how to pass the table to my BaseDialog class later.
Any Help is greatly appreciated.
There are really good code snippets directly from eclipse here. The one that is most interesting for you should be this one: create a table (columns, headers, lines). It shows how to create a table with multiple columns, headers and lines.
Since you seem fairy familiar with java, you should be able to figure out how to use this for your purpose.
If you want to have a proper TableViewer with ContentProvider, have a look at this excellent tutorial by Vogella.
ContentProvider is like a model that provides input for TableViewer. ( Model for Table)
LabelProvider is a class that provides image and text that you will display in a Table Cell. ( similar to getValueAt() in Swing)
create TableViwer in your dialog
create TableViewerColumn (each column) for tableviewer and set LabelProvider() on TableViewerColumn. LabelProvider.getImage() LabelProvider.getText() will be called for each row object that content provider provides on this column.
set viewer.setContentProvider()
This is how it works: TableViewer first gets input from its content provider. lets say your content provider is returning List of RowObjects. For each RowObject, the label providers on each TableViewerColumn will be invoked to dispaly image and text in that particular cell location ( like colIndex, RowIndex in Swing).

How to add columns/rows to an existing empty JTable?

I am developing a software for which I need a basic Java Swing UI. I am using Netbeans which enables me to drag and drop UI component. However there is a final result table that I need to display using code.
In my UI using trhe IDE I created a JTabbedPane, inside which I added an empty JTable (no rows nor columns) called finalOutputTable. Now I want at runtime to fill this table, let's say with columns: x, y and rows: row1, row2 & row3.
How can I do that by coding?
You need to make a custom TableModel that will allow you to support this functionality. JTable is just there to display the table on the GUI. The TableModel has all the business logic of what the data is and how each cell should act. To do this you will have to step away from the GUI-Builder and write actual code.
Tutorial: Creating a Table Model
inside which i added an empty JTable (no rows nor columns) called "finalOutputTable".
You need to add the data to the TableModel. Then you use:
table.setModel(...);
to display the data. You may also need to revalidate() the panel containing the table if you didn't reserve space for the table when you created the form.
How can i do that by coding?
See the Laying Out Components Within a Container lesson of the Java Tutorial.
You can also use a TableModel witch does all that hard work for you.
https://github.com/MarkyVasconcelos/Towel/wiki/ObjectTableModel

Updating JTable after inline edit

I have 2 classes, one to make a frame and the other to handle and implement the interface TableModel. When editing cells inline and updating the values in the class that implements TableModel I then need to refresh the table to show the updated data (as the table needs to auto sort thus when I inline edit a cell the rows may need to be re-ordered). The problem I'm having is after updating the data I can't figure out how to refresh the table, I've tried a hacky way of refreshing it when you click off the cell or press enter but I feel there could be a more elegant solution, any ideas?
The TableModel is responsible for invoking the fireTableCellChanged(...) method when data is changed in the model. Sorting will then happen automatically.
Read the JTable API and follow the link to the Swing tutorial on How to Use Tables for more information about TableModels and sorting.
I suggest you just use the DefaultTableModel so you don't have to worry about this since it implements all the TableModel methods.

Editable JTable Tutorial

Are there any good books or website that go over creating a JTable? I want to make one column editable. I would like to actually put a inherited JCheckBox component (that we created here) into one of the table columns instead of just having the table put JCheckBox in based on it being an editable boolean field.
I have the JFC Swing Tutorial Second Edition book but I just would like to know if there are other examples I could look at and learn how to deal with the tables better. The book seems to just take the java 'trail' online and put it in the book.
I am re-reading the stuff though, just curious if anyone has found something that might help out more.
To make a column editable you have to override the isCellEditable method in the TableModel. Creating a TableModel is fairly easy if you inherit AbstractTableModel and I'd recommend it for all but the most simple JTables.
However, adapting the TableModel is only part of what you need to do. To actually get a custom component in the JTable, you need to set a custom cell renderer. To use an interactive custom component, you need to set a custom cell editor. In some cases, it's enough to use slightly modificated versions of the default classes for this.
Editors
If you already have got a custom component is easily done using delegation: Create a new class implementing TableCellEditor, and return a new instance of the component in the getCellEditorComponent method. The paramaters to this method include the current value as well as the cell coordinates, a link back to the table and wether or not the cell is selected.
The TableCellEditor also has a method that is called when the user commits a change to the cell contents (where you can validate user input and adjust the model) or cancels an edit. Be sure to call the stopEditing() method on your editor if you ever programmatically abort editing, otherwise the editor component will remain on screen -- this once took me like 2 hours to debug.
Note that within a JTable editors and only editors receive events! Displaying a button can be done using a renderer. But to get a functioning button, you need to implement an editor with the correct EventListeners registered. Registering a listener on a renderer does nothing.
Renderers
Implementing a renderer is not strictly necessary for what you describe in your question, but you typically end up doing it anyway, if only for minor modifications. Renderers, unlike editors, are speed critical. The getTableCellRendererComponent of a renderer is called once for every cell in the table! The component returned by a renderer is only used to paint the cell, not for interaction, and thus can be "reused" for the next cell. In other words, you should adjust the component (e.g. using setText(...) or setFont(...) if it is a TextComponent) in the renderer, you should not instantiate a new one -- that's an easy way to cripple the performance.
Caveats
Note that for renderers and editors to work, you need to tell the JTable when to use a certain renderer/editor. There are basically two ways to do this. You can set the default cell renderer/editor for a certain type using the respective JTable methods. For this way to work, your TableModel needs to return exactly this type in the getColumnClass(...) method! The default table model will not do this for you, it always returns Object.class. I'm sure that one has stumped a lot of people.
The other way to set the editor/renderer is by explicitly setting it on the column itself, that is, by getting the TableColumn via the getTableColumn(...) method of the JTable. This is a lot more elaborate, however, it's also the only way to have two different renderers/editors for a single class. E.g. your model might have two columns of class String which are rendered in entirely different ways, maybe once using a JLabel/DefaultRenderer and the other using a JButton to access a more elaborate editor.
JTable with its custom renderers and editors is extremely versatile, but it is also a lot to take in, and there are a lot of things to do wrong. Good luck!
How to Use Tables in The Swing Tutorial is mandatory reading for anyone customising JTables. In particular, read and reread Concepts: Editors and Renderers because it typically takes a while for it to "click". The examples on custom renderers and editors are also very worthwhile.
The class you want to look into extending to create your own behavior is DefaultTableModel. That will allow you to define your own behavior. A decent tutorial can be found on sun's site.
This tutorial from the java lobby is easy to follow. The online Swing trail for JTable that you reference indicates that it has been updated. Did you scan through the whole thing for possible better (isn't newer always better) information?
If you are trying to use a simple JTable with 1 column editable and you know the column location you could always use default table model and overload the isCellEditable call.
something like this :
myTable.setModel(new DefaultTableModel(){
#Override
public boolean isCellEditable(int row, int column) {
if (column == x) {
return true;
} else
return false;
}
});
And for the check box create a renderer class
MyCheckBoxRenderer extends JCheckBox implements TableCellRenderer
Some useful classes are:
Package javax.swing.table :
TableModel - Interface for a tablemodel
AbstractTableModel - Nice class to extend for creating your own table with custom data structures
DefaultTableModel - Default table model which can deal with arrays[] and Vectors
To disable editing on any cell you need to override the isCellEditable(int row, int col) method
in your table Model, you should override "isCellEditable" and "setValueAt" functions, like below.
Column 4 is the column for editable cells.
Then when you double click the cell and type something,
setValueAt() will be called and save the value to the tableModel's DO,field col4.
public ArrayList<XXXDO> tbmData = new ArrayList<XXXDO>(); //arraylist for data in table
#Override
public boolean isCellEditable(int row, int col) {
if (col == 4) {
return true;
} else {
return false;
}
}
#Override
public void setValueAt(Object value, int row, int col) {
if ((row >= 0) && (row < this.tbmData.size()) && (col >= 0) && (col < this.colNm.length)) {
if (col == 4) {
tbmData.get(row).col4= (String) value;
}
fireTableCellUpdated(row, col);
} else {
}
}

Categories