JAVA Swing Table Example
In this example we will learn how to create a Table using JTable component in Swing. Data can be viewed or edited using the JTable component. JScrollPane is widely used to display the data. Model Implementation can be achieved using either AbstractDataModel or DefaultDataModel class. AbstractDataModel by default provides the implementation of most of the methods of TableModel interface. We will look into the meaning of various other terms as we proceed.
2. JAVA Swing Table Example
Prerequisite
This example is developed on Eclipse therefore a compatible Eclipse IDE is required to be installed on the system.
We also need WindowBuilder tool to be installed on Eclipse IDE for the easiness of the work. To learn how to install WindowBuilder tool please visit the Setup section 2.1 of the following link click here.
2.1 JAVA Swing Table
Create a new JAVA project lets say swing_1
- Go to src→ right click→ New→ Other→ WindowBuilder→ select Swing Designer→ Application Window
Enter the name of the application(eg. SwingTableExample ) and click finish.
This will create SwingTableExample.java file and will provide Source and Design tab.
3. Code
The Table exhibits the following property
- The entire row is highlighted if an individual cell is clicked.
- Vertical or horizontal scroll bar appears on decreasing the window size.
- A column can be dragged and moved to anywhere in the frame.
- A cell can be edited by double clicking on it
In this example we will create a table using JTable which contains a student’s academic record containing 6 column and 5 rows. We will thoroughly visit the code and learn how to create a table.
package swing_1; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; import java.awt.Dimension; import java.awt.GridLayout; private static void createAndShowGUI() < //Create and set up the window. JFrame frame = new JFrame("TableDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. SwingTableExample newContentPane = new SwingTableExample(); newContentPane.setOpaque(true); //content panes must be opaque frame.setContentPane(newContentPane); //Display the window. frame.pack(); frame.setVisible(true); >
The above code creates a Frame which holds the ContentPane and all other components. Here we are creating an object i.e, newContentPane of class SwingTableExample. The SwingTableExample class is described below.
public class SwingTableExample extends JPanel < private boolean DEBUG = false; public SwingTableExample() < super(new GridLayout(1,0)); JTable table = new JTable(new MyTableModel()); table.setPreferredScrollableViewportSize(new Dimension(500, 70)); table.setFillsViewportHeight(true); //Create the scroll pane and add the table to it. JScrollPane scrollPane = new JScrollPane(table); //Add the scroll pane to this panel. add(scrollPane); >
SwingTableExample extends the JPanel class and adds GridLayout to its window Pane. A table is created in the constructor of SwingTableExample class using JTable class which again creates a custom TableModel using AbstractTableModel when instantiated i.e, new MyTableModel() in this case.
Table can be created by using different JTable constructors. Below are the type of constructors.
JTable() Constructs a default JTable that is initialized with a default data model, a default column model, and a default selection model.
JTable(int numRows, int numColumns) Constructs a JTable with numRows and numColumns of empty cells using DefaultTableModel.
JTable(Object[][] rowData, Object[] columnNames) Constructs a JTable to display the values in the two dimensional array, rowData, with column names, columnNames.
JTable(TableModel dm) Constructs a JTable that is initialized with dm as the data model, a default column model, and a default selection model.
JTable(TableModel dm, TableColumnModel cm) Constructs a JTable that is initialized with dm as the data model, cm as the column model, and a default selection model.
JTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) Constructs a JTable that is initialized with dm as the data model, cm as the column model, and sm as the selection model.
JTable(Vector rowData, Vector columnNames) Constructs a JTable to display the values in the Vector of Vectors, rowData, with column names, columnNames.
setPreferredScrollableViewportSize(Dimension size) sets the preferred size of the viewport for this table.
void setFillsViewportHeight(boolean fillsViewportHeight) sets whether or not this table is always made large enough to fill the height of an enclosing viewport. If the preferred height of the table is smaller than the viewport, then the table will be stretched to fill the viewport. In other words, this ensures the table is never smaller than the viewport. The default for this property is false.
ScrollPane is created and the table is added to it. Finally, ScrollPane is added to the Panel.
Class MyTableModel describes the content of the data and implements the methods such as, getRowCount() , getColumnCount() , getValueAt(int row, int column) etc.
class MyTableModel extends AbstractTableModel < String[] columnNames = ; Object[][] data = < , , , , >; public int getColumnCount() < return columnNames.length; >public int getRowCount() < return data.length; >public String getColumnName(int col) < return columnNames[col]; >public Object getValueAt(int row, int col) < return data[row][col]; >public Class getColumnClass(int c) < return getValueAt(0, c).getClass(); >public boolean isCellEditable(int row, int col) < //Note that the data/cell address is constant, //no matter where the cell appears onscreen. if (col < 1) < return false; >else < return true; >> public void setValueAt(Object value, int row, int col) < data[row][col] = value; fireTableCellUpdated(row, col); >>
Here columnNames is the header or name of the column. Object data store the content of the array in two dimensional array. In this Example every cell is editable except the Name column cell as we have fixed the Name column.
getColumnClass() returns the class of each cell and is required to be implemented if we need to see checkboxex in the last column. This method is used by JTable .
getColumnCount() returns the count of the columns present in the table. getRowCount() returns the number of rows present in the table. isCellEditable returns a Boolean value i.e true or false if a cell is editable or not respectively. setValueAt(int row, int col) sets the value of cell present at the mentioned row and column. This method is implemented when you want to change the value of the cell of a table.
After execution of the code Table will look like this:
The table can be edited by double clicking on the cell and replacing the old value with the new one. For instance here we have the value of 2 row and 2 column, i.e, degree of smaira from B.Sc to B.Com. Image is shown below.
4. Download
This was an example of creation of JAVA Swing Table.
Code table in java
A code table is a list of closely related items, each of which has minimal substructure.
- a list of countries (or other geographical category)
- the list of credit cards accepted by a web site — Mastercard, Visa, etc.
- the number of items shown to the user in a search result — 10, 50, 100
Code tables are often presented in drop down lists, as in:
(Radio buttons or other presentation styles may also be appropriate, according to the needs of each case.)
Code Table Structure
Most applications use a relational database. Code tables usually represent the simplest kinds of tables that you can model in a database. Here are some example code tables, as defined by SQL CREATE TABLE statements:
Number of items shown in a search result:
CREATE TABLE NumResults ( Id TINYINT UNSIGNED NOT NULL AUTO_INCREMENT, NumItems TINYINT UNSIGNED UNIQUE NOT NULL, PRIMARY KEY (Id) ) TYPE=InnoDB;
List of countries supported by an application:
CREATE TABLE Country ( Id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT, Text VARCHAR(50)UNIQUE NOT NULL, ShortText VARCHAR(2)UNIQUE NOT NULL, PRIMARY KEY (Id) ) TYPE=InnoDB;
The same list of countries, but with a field added to control sort order:
CREATE TABLE Country ( Id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT, OrderWith MEDIUMINT UNIQUE UNSIGNED NOT NULL, Text VARCHAR(50)UNIQUE NOT NULL, ShortText VARCHAR(2)UNIQUE NOT NULL, PRIMARY KEY (Id) ) TYPE=InnoDB;
It’s often useful to picture each row in a code table as representing a set of aliases for a single idea. One alias can be more appropriate than another, according to the context in which it’s used. For example, in a report which tries to squeeze as much information as possible onto pages of fixed width, short abbreviations are often useful. When presenting a drop-down list to an end user, it may be more desirable to show a longer description, instead of an abbreviation.
So, you may decide to represent an item in a code table using what amounts to several aliases for the same item:
- a numeric id
- the ‘regular’ text, usually seen by the user
- a short abbreviation used when appropriate
- some other alias appropriate to a given case
For this idea to make sense, each of the above fields would need a UNIQUE constraint, and each would need to be non-null.
Code Table Evolution
As shown above, code tables don’t have a specific, definitive structure. You aren’t locked into a specific style. A single application often has many code tables, but those code tables don’t necessarily share the exact same form. Also, it’s not uncommon for a code table to start its life in a simple form, and then later grow into something more elaborate. In this sense, code tables are roughly similar to Java’s enumeration types, which can start out being very simple. Since enumerations are also classes, you can add more structure to them later, if needed.
In-Memory Caching
Code tables often represent relatively static data. Since the data doesn’t change very often, it usually makes sense to consider reading in all code tables once upon startup. Then, each time a code table is needed, the in-memory representations of the code tables are referenced directly, instead of repeatedly going back to the database. This usually improves application performance.
In-Memory Joins
If code tables are cached in memory after startup, then you will often be able to move logic formerly implemented by a database JOIN operation into in-memory operations in Java instead. (This is an exception to the rule of not performing database tasks in code.) There are two advantages to this:
- it will likely improve performance.
- your SQL statements will be simpler, since the JOIN s can be left out
SELECT Name, Number, PositionName FROM Team JOIN Position ON PositionFK = Position.Id WHERE Team.Id = ?
Alternatively, the JOIN might be dropped in favor of returning the ‘raw’ PositionFK identifier, instead of the PositionName text, as in :
SELECT Name, Number, PositionFK FROM Team WHERE Team.Id = ?
Of course, the PositionFK identifier would need to be translated into text (in Java-land) before presenting the result to the user.
Id For Code, Text For User
The fact that a code table item is essentially a collection of aliases for a single idea can be put to use in the following way. In Java-land, it’s best to identify items using internal, static codes, instead of the text visible to the user. Forms in web applications are a good example of this:
Here, the text (‘Chocolate’) is shown to the user in a drop-down, but the value submitted to the server is actually a numeric id (‘1’), as controlled by the value attribute of the option tag. This separates two things nicely. The text may change for many reasons (change the spelling, add translations into another language), but such changes will not ripple into Java, since Java-land uses numeric codes, not the text. (Some object to exposing database primary keys to the end user like this. But in this case, it doesn’t seem to do any harm.)
Sorting
Sorting of code tables can be tricky. If the sort is alphabetical, then that’s simple to implement. However, sorts aren’t always alphabetical. Sometimes they depend on arbitrary rules. For example, if an application is used only in Australia, a list of countries having Australia and New Zealand at the beginning may be required. In such cases, one option is to define a column in the underlying code table which explicitly defines the sort order.
The sort order can also be affected by whether an application is multilingual. If a code table is sorted alphabetically in each language, then the order of presentation to the user will usually not be the same in all languages.
Monster Code Tables
Some applications put all of their code tables into a single «monster» code table. The monster code table has two primary keys — one to identify the code table, and one to identify the value within the code table. This seems to be an inferior design:
- it lumps together items which aren’t logically related to each other. It’s almost always a mistake to put implementation details before meaning. That’s a bad sign.
- foreign keys to code tables are no longer possible. Since foreign keys are the heart and soul of a relational database, this is a major drawback.
- since some foreign keys are absent, the clarity of a database’s structure (and related SQL statements) is significantly reduced.
- when a single code table has special needs, then it usually can’t fit into the structure of the monster code table.
- code tables can’t evolve independently and still remain in the monster code table.
- JOINs to monster code tables are usually doubled. What used to be a single join becomes 2 joins — one join to define the code table, another to define the value within the code table.
- in large SQL statements, the large number of joins can rapidly become annoying.
Java Practices 3.012
© 2023 John O’Hanley
Source Code | Contact | License | RSS
Individual code snippets have a BSD license
Over 1,000,000 unique IPs last year
Last updated 2023-01-03
— In Memoriam : Bill Dirani —