Java IoT Authors: Sematext Blog, Yeshim Deniz, Zakia Bouachraoui, Dana Gardner, 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:

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 {
} catch(java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");

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()) {
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
When Enterprises started adopting Hadoop-based Big Data environments over the last ten years, they were mainly on-premise deployments. Organizations would spin up and manage large Hadoop clusters, where they would funnel exabytes or petabytes of unstructured data.However, over the last few years the economics of maintaining this enormous infrastructure compared with the elastic scalability of viable cloud options has changed this equation. The growth of cloud storage, cloud-managed big data e...
Your applications have evolved, your computing needs are changing, and your servers have become more and more dense. But your data center hasn't changed so you can't get the benefits of cheaper, better, smaller, faster... until now. Colovore is Silicon Valley's premier provider of high-density colocation solutions that are a perfect fit for companies operating modern, high-performance hardware. No other Bay Area colo provider can match our density, operating efficiency, and ease of scalability.
ScaleMP is the leader in virtualization for in-memory high-end computing, providing higher performance and lower total cost of ownership as compared with traditional shared-memory systems. The company's innovative Versatile SMP (vSMP) architecture aggregates multiple x86 systems into a single virtual x86 system, delivering an industry-standard, high-end shared-memory computer. Using software to replace custom hardware and components, ScaleMP offers a new, revolutionary computing paradigm. vSMP F...
At CloudEXPO Silicon Valley, June 24-26, 2019, Digital Transformation (DX) is a major focus with expanded DevOpsSUMMIT and FinTechEXPO programs within the DXWorldEXPO agenda. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive over the long term. A total of 88% of Fortune 500 companies from a generation ago are now out of business. Only 12% still survive. Similar percentages are found throug...
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...
Atmosera delivers modern cloud services that maximize the advantages of cloud-based infrastructures. Offering private, hybrid, and public cloud solutions, Atmosera works closely with customers to engineer, deploy, and operate cloud architectures with advanced services that deliver strategic business outcomes. Atmosera's expertise simplifies the process of cloud transformation and our 20+ years of experience managing complex IT environments provides our customers with the confidence and trust tha...
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...
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.
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...
The graph represents a network of 1,329 Twitter users whose recent tweets contained "#DevOps", or who were replied to or mentioned in those tweets, taken from a data set limited to a maximum of 18,000 tweets. The network was obtained from Twitter on Thursday, 10 January 2019 at 23:50 UTC. The tweets in the network were tweeted over the 7-hour, 6-minute period from Thursday, 10 January 2019 at 16:29 UTC to Thursday, 10 January 2019 at 23:36 UTC. Additional tweets that were mentioned in this...