Java IoT Authors: Zakia Bouachraoui, Pat Romanski, Elizabeth White, Liz McMillan, Yeshim Deniz

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
Moroccanoil®, the global leader in oil-infused beauty, is thrilled to announce the NEW Moroccanoil Color Depositing Masks, a collection of dual-benefit hair masks that deposit pure pigments while providing the treatment benefits of a deep conditioning mask. The collection consists of seven curated shades for commitment-free, beautifully-colored hair that looks and feels healthy.
The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
We all love the many benefits of natural plant oils, used as a deap treatment before shampooing, at home or at the beach, but is there an all-in-one solution for everyday intensive nutrition and modern styling?I am passionate about the benefits of natural extracts with tried-and-tested results, which I have used to develop my own brand (lemon for its acid ph, wheat germ for its fortifying action…). I wanted a product which combined caring and styling effects, and which could be used after shampo...
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...
There are many examples of disruption in consumer space – Uber disrupting the cab industry, Airbnb disrupting the hospitality industry and so on; but have you wondered who is disrupting support and operations? AISERA helps make businesses and customers successful by offering consumer-like user experience for support and operations. We have built the world’s first AI-driven IT / HR / Cloud / Customer Support and Operations solution.
Codete accelerates their clients growth through technological expertise and experience. Codite team works with organizations to meet the challenges that digitalization presents. Their clients include digital start-ups as well as established enterprises in the IT industry. To stay competitive in a highly innovative IT industry, strong R&D departments and bold spin-off initiatives is a must. Codete Data Science and Software Architects teams help corporate clients to stay up to date with the mod...
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...
Druva is the global leader in Cloud Data Protection and Management, delivering the industry's first data management-as-a-service solution that aggregates data from endpoints, servers and cloud applications and leverages the public cloud to offer a single pane of glass to enable data protection, governance and intelligence-dramatically increasing the availability and visibility of business critical information, while reducing the risk, cost and complexity of managing and protecting it. Druva's...
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.