Welcome!

Java IoT Authors: Pat Romanski, Zakia Bouachraoui, Elizabeth White, Mehdi Daoudi, Liz McMillan

Related Topics: Java IoT

Java IoT: Article

Mastering the JTable

Mastering the JTable

JBuilder Data Express controls enable JBuilder developers to use prebuilt objects to provide the user with an interface in which to view and manipulate data. For the most part, the use of Data Express components simplifies our task of programming data access functionality into our applets/applications. One drawback of using these components is that you're restricted to using only functions and changing properties that are supported by that specific control. In other words, although JBuilder simplifies your task, you can use only prewritten functionality.

What if you wanted total control over your data? What if you wanted to control every aspect of how your data is formatted, displayed, edited, and up- dated? The answer to this is knowing how to use the native Java JTable. Mastering the use of this class is your key to exercising total control over data within your applet/application - albeit with a considerable tradeoff in added complexity.

Over the next few issues I'll cover the use of the JTable and help you master this powerful Java component.

The JTable
Before Data Express there was the JTable, a Java Swing Component with the Swing JComponent as its immediate ancestor. The JTable is used primarily to provide users with a way to view and manipulate data in a columnar (or grid) format. With this functionality, users are allowed to edit and scroll through many records of data rather than editing one record at a time.

Although the JTable can obtain its data from many sources, it's most useful when it holds data retrieved from a database via JDBC. Interestingly, the JTable is the only native Java control that can be populated directly from JDBC that allows the user to manipulate data in a columnar format. As you might guess, the JTable is an extremely complex component - in my opinion, the most complex in the entire Java language. Since books can be written on its use, it's amazing that the JTable is the most underdocumented or written about Java component. Even the best of Java books barely give it a mention. I hope to help change all that.

Understanding the Basics
Like most things in Java, matters appear more difficult than they really are. So it seems with the JTable. Understanding its functionality first requires understanding related classes. As you'll soon learn, with all of its robust functionality the JTable relies on other Java classes to perform most of the work. Often the relationship between these related classes is a source of confusion; understanding it is key to understanding the JTable. Learning it can be daunting, but it's made easier if spoon-fed one piece at a time.

The first class that needs to be understood is the JTable itself. This class contains a two-dimensional view of the data to be displayed. In other words, when the user is looking at the GUI, what he or she sees is the JTable class. Simple uses of the JTable are relatively easy to set up. However, in complex applications use of the JTable without any of its supporting classes is very limited. For example, if you need to automatically populate the JTable with rows and columns from a JDBC data source, the use of a JTable alone will not suffice.

If used alone, the data contained within a JTable needs to be passed as an array of objects or as a vector to the JTable constructor. This may be okay if you want the JTable to contain static values. More than likely you'll want the data to come from a database. In a nutshell the JTable contains the visual portion of the data and generally doesn't control where it comes from or how it behaves (e.g., what happens if it changes). If you have the data ahead of time and want to simply display it to the user (without regard to changes in data) use the simple JTable constructors listed below:

JTable()
This constructs a "basic" JTable that's initialized with a default table model, a default column model, and a default selection model (these classes will be discussed later in this series). This constructor is of limited use because the number of rows and columns haven't been specified. Also, the JTable receives limited functionality because the default models will be used. Since you haven't built custom models (or don't yet know how!), don't expect the default models to do much. This constructor isn't used very often, so I won't offer a code example.

JTable(int numberofRows,int numberofColumns)
This constructs a JTable with numberofRows and numberofColumns of empty cells using the default models. Since no column names can be specified in the constructor, Java will produce generic ones in the form "A", "B", "C", "D", and so on. Ironically, you can add and remove columns after the table has been constructed, but you can't add or remove rows. Like the first constructor, this one doesn't directly accept data.

The code in Listing 1 illustrates the use of this constructor. In the listing, the class constructor builds a JTable (with three rows and two columns) and adds it to a JScrollPane. When a JTable is added to a JScrollPane, the JScrollPane automatically obtains the JTable's header, which displays the column names, and puts it on top of the table. When the user scrolls down, the table's header remains visible at the top of the viewing area. Next, the program's main method places the JScrollPane on a JFrame via a constructor call. Finally, the program uses the setValueAt method to set the value for a single cell in the JTable. Three names and ages are added. Here's the syntax for setValueAt:

public void setValueAt(object value, int row, int column)

  • Value: The new value to be placed in the cell
  • row: The row in the JTable to be changed
  • column: The column in the JTable to be changed
Notice that the setValueAt method doesn't care what data type the value is. In the above example I used the same method to set names (strings) and ages (integers). You may think that the setValueAt is an overloaded method. It isn't. It takes the value argument as type Object so the programmer doesn't have to differentiate between data types. Also rows and columns start at the number "0", not "1".

As noted earlier, data can't be included in the constructor JTable- (rows, columns). However, this isn't to prevent you from crafting creative schemes in your data-getting endeavors. The previous example illustrates that the setValueAt method can be used to set the value of a single cell within a JTable. So why can't the data come from a database rather than a hard-coded value? Well, it can. The current constructor doesn't support the use of database data but nothing is preventing you from doing the legwork yourself.

Consider the program in Listing 2. This listing is similar to the previous one, the main difference being that the data within the setValueAt method comes from data in a database. The focus of this series of articles is on the use of JTables and not necessarily JDBC. However, the code does warrant a brief explanation. For the sake of brevity I'll discuss only the differences from the first example.

try {
Class.forName("sun.jdbc.odbc.Jdbc
OdbcDriver");
} catch(java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}

This first block of code loads the "Level 1" Java database driver. The Level 1 driver is often called the JDBC-ODBC Bridge and is used to connect to local databases that support the ODBC interface.

String url = "jdbc:odbc:bradygirls";
Ex1Con= DriverManager.getConnection(url, "", "");
Ex1Stmt = Ex1Con.createStatement();
Ex1rs = Ex1Stmt.executeQuery( "SELECT name, age FROM bradygirls ORDER BY name");

Next, the string containing the URL is built; jdbc:odbc: is specified because the JDBC-ODBC bridge is being used. :bradygirls is the name of the ODBC data source. Note: For this to work, an ODBC data source named bradygirls must be set up on your local machine. This can be achieved via the control panel on Windows machines. In my case, I'm using an MS Access database.

After the database connection has been established a statement class is created, then an executeQuery method is fired. This method takes a string containing a valid SQL statement for an argument. The results of the SQL statement are read into a ResultSet class. Now we're ready to read the contents of the result set and put the data into our JTable.

int li_row = 0;
while (Ex1rs.next()) {
myTable.setValueAt(Ex1rs.getString(1),li_row,0);
myTable.setValueAt(Ex1rs.getNumber(2),li_row,1);
li_row ++;
} // while

The above while block will loop through the result set one row at a time and populate the JTable. The methods used to extract data from the result set are commonly called the getXXXX() methods (with the XXXX being the data type of the column in the result set).

Notice that the first column in a result set is column "1". This is a direct contrast to the first column being "0" in a JTable. This discrepancy can be confusing for a while, but you'll get used to it. Believe me, it's not the only discrepancy you'll find in Java!

Although the above example uses a database to populate the JTable, keep in mind that it's provided as a work-around (instead of using Table Models). Table Models (discussed later) provide a better way to automatically populate a JTable directly from a database. But until you understand Table Models, this code example should keep you pretty busy - especially if you're new to JDBC. The results of the above program are displayed in Figure 1.

JTable(Object[][],rowscolData,Object[] columnNames)

Unlike the previous two constructors, this one is used when the rows, columns, and headings are known at the time the JTable is instantiated. Data for the rows and columns are passed in a two-dimensional array of objects. The column headings are passed as a single array of objects. (FYI: There's a similar constructor that uses vectors in place of objects.) The following code snippet uses arrays of objects to instantiate and populate a JTable.

Object[] [] data =
{ {"Marsha", new Integer(18)},
{"Jan", new Integer(17)},
{"Cindy", new Integer(16)} };
String[] colNames = {"First Name","Age");
JTable myTable = new JTable(data,colNames);

All of the simple constructors discussed here are easy to use. However, as I mentioned, these constructors also have a few significant limitations. For example, they automatically make every cell (and row) editable. This is misleading to the user because if you're allowed to edit a value, you're implying that changes can be saved; and remember, the JTable isn't even connected to a database. Furthermore, all of the simple constructors treat all data types as strings. This can be annoying in two ways. First, when aligning data, strings are generally left-aligned and numbers are right-aligned. Since the JTable treats everything as a string, the ages of the Brady Girls (Figure 1) appear to be aligned incorrectly. Second, the JTable has the ability to use other edit styles besides the ones that handle only text. For example, if a value to place into a cell is Boolean, the JTable has the ability to display the data in a check box. After all, a Boolean has only two values, so a check box seems appropriate. However, if you use one of the JTable constructors listed previously, a Boolean column will be displayed as a string. Finally, the largest limitation is that they don't automatically "link" the JTable to a database. Although there are a few limited ways to get around this, one way is to read database columns into an array of objects or vectors, then pass those objects to the JTable constructor. A better way is to implement your own custom table model, which will be next month's focus.

Default Behavior
Whatever constructor you use, be aware of the following default behavior:

  • All columns in the JTable begin with equal widths, and the columns automatically fill the entire width of the JTable.
  • If the container is resized (made larger), all the cells within the JTable become larger, expanding to fill any extra space.
  • When a cell is selected (usually by double-clicking on it), the entire row becomes selected. The cell that was double-clicked becomes highlighted.
  • Users can rearrange columns by dragging or dropping them to the left or to the right.
  • Columns are resizable by dragging the column header to the left or to the right. This doesn't adjust the size of the JTable itself; the other columns will automatically resize to fill in unused space. Columns can be set to a default size by calling the setPreferredWidth() method for the column model. More on column models next month.
Some Fun with JTables
The program in Table 1 contains additional methods on a JTable that can be used to modify its appearance.

Coming Up Next Issue
As you can see, the JTable controls how the data is presented but has little control over how it's populated. This job is the responsibility of the TableModel, which defines where the data comes from, what the user is allowed to do with it, and what happens if it changes. This model is a Java class you create that extends the Java class AbstractTableModel. This class is fairly complex and can be a bit puzzling. I'll cover it in more detail in the next issue.

Another large piece of the puzzle is the TableModelListener. Its job is to execute when any of the data has changed in the TableModel. A TableModelListener is implemented whenever you create a class extending the Java class TableModelListener, or it can be implemented in an inner class. Of course, the functionality provided by the listener is completely up to you. Many programmers place code to update the database within a TableModelListener.

More Stories By Bob Hendry

Bob Hendry is a PowerBuilder instructor for Envision Software Systems and a frequent speaker at national and international PowerBuilder conferences. He specializes in PFC development and has written two books on the subject, including Programming with the PFC 6.0.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


IoT & Smart Cities Stories
In an age of borderless networks, security for the cloud and security for the corporate network can no longer be separated. Security teams are now presented with the challenge of monitoring and controlling access to these cloud environments, at the same time that developers quickly spin up new cloud instances and executives push forwards new initiatives. The vulnerabilities created by migration to the cloud, such as misconfigurations and compromised credentials, require that security teams t...
The platform combines the strengths of Singtel's extensive, intelligent network capabilities with Microsoft's cloud expertise to create a unique solution that sets new standards for IoT applications," said Mr Diomedes Kastanis, Head of IoT at Singtel. "Our solution provides speed, transparency and flexibility, paving the way for a more pervasive use of IoT to accelerate enterprises' digitalisation efforts. AI-powered intelligent connectivity over Microsoft Azure will be the fastest connected pat...
AI and machine learning disruption for Enterprises started happening in the areas such as IT operations management (ITOPs) and Cloud management and SaaS apps. In 2019 CIOs will see disruptive solutions for Cloud & Devops, AI/ML driven IT Ops and Cloud Ops. Customers want AI-driven multi-cloud operations for monitoring, detection, prevention of disruptions. Disruptions cause revenue loss, unhappy users, impacts brand reputation etc.
CloudEXPO has been the M&A capital for Cloud companies for more than a decade with memorable acquisition news stories which came out of CloudEXPO expo floor. DevOpsSUMMIT New York faculty member Greg Bledsoe shared his views on IBM's Red Hat acquisition live from NASDAQ floor. Acquisition news was announced during CloudEXPO New York which took place November 12-13, 2019 in New York City.
As you know, enterprise IT conversation over the past year have often centered upon the open-source Kubernetes container orchestration system. In fact, Kubernetes has emerged as the key technology -- and even primary platform -- of cloud migrations for a wide variety of organizations. Kubernetes is critical to forward-looking enterprises that continue to push their IT infrastructures toward maximum functionality, scalability, and flexibility. As they do so, IT professionals are also embr...
BMC has unmatched experience in IT management, supporting 92 of the Forbes Global 100, and earning recognition as an ITSM Gartner Magic Quadrant Leader for five years running. Our solutions offer speed, agility, and efficiency to tackle business challenges in the areas of service management, automation, operations, and the mainframe.
@CloudEXPO and @ExpoDX, two of the most influential technology events in the world, have hosted hundreds of sponsors and exhibitors since our launch 10 years ago. @CloudEXPO and @ExpoDX New York and Silicon Valley provide a full year of face-to-face marketing opportunities for your company. Each sponsorship and exhibit package comes with pre and post-show marketing programs. By sponsoring and exhibiting in New York and Silicon Valley, you reach a full complement of decision makers and buyers in ...
While the focus and objectives of IoT initiatives are many and diverse, they all share a few common attributes, and one of those is the network. Commonly, that network includes the Internet, over which there isn't any real control for performance and availability. Or is there? The current state of the art for Big Data analytics, as applied to network telemetry, offers new opportunities for improving and assuring operational integrity. In his session at @ThingsExpo, Jim Frey, Vice President of S...
In his keynote at 18th Cloud Expo, Andrew Keys, Co-Founder of ConsenSys Enterprise, provided an overview of the evolution of the Internet and the Database and the future of their combination – the Blockchain. Andrew Keys is Co-Founder of ConsenSys Enterprise. He comes to ConsenSys Enterprise with capital markets, technology and entrepreneurial experience. Previously, he worked for UBS investment bank in equities analysis. Later, he was responsible for the creation and distribution of life settl...
Two weeks ago (November 3-5), I attended the Cloud Expo Silicon Valley as a speaker, where I presented on the security and privacy due diligence requirements for cloud solutions. Cloud security is a topical issue for every CIO, CISO, and technology buyer. Decision-makers are always looking for insights on how to mitigate the security risks of implementing and using cloud solutions. Based on the presentation topics covered at the conference, as well as the general discussions heard between sessio...