The JTable

The JTable class is used to display arrays of data. We found that the GUI object was very useful when we discussed how to integrate a database in Java in Chapter 16. Let's look at a sample application that will display a table of data. Note that this example requires two source files, one for the actual application and the other to handle the table.

Code Listing 16: Using the JTable

start example

JTableExample.java

import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*;     public class JTableExample extends JFrame implements ActionListener {     public static void main(String[] argv)     {         JTableExample mainApp = new JTableExample();     }          public JTableExample()     {         super("JTable Example");         setBounds(0, 0, 450, 350);         getContentPane().setLayout(null);         setDefaultCloseOperation(EXIT_ON_CLOSE);                         table = new JTable(10, 3);         table.setBounds(10, 10, 420, 200);                     tableHandler = new TableHandler();         table.setModel(tableHandler);                         // Create three JTextField...         textfield1 = new JTextField(15);         textfield1.setLocation(10, 220);         textfield1.setSize(textfield1.getPreferredSize());                  textfield2 = new JTextField(15);         textfield2.setLocation(10, 250);         textfield2.setSize(textfield2.getPreferredSize());                  textfield3 = new JTextField(15);         textfield3.setLocation(10, 280);         textfield3.setSize(textfield3.getPreferredSize());                  // Create the button...         addButton = new JButton("Add Data to Table");         addButton.setLocation(200, 220);         addButton.setSize(addButton.getPreferredSize());                  // Add the action listeners...         addButton.addActionListener(this);                                             // Add the objects to the content pane...         getContentPane().add(table);         getContentPane().add(textfield1);         getContentPane().add(textfield2);         getContentPane().add(textfield3);         getContentPane().add(addButton);                  setVisible(true);     }          public void actionPerformed(ActionEvent e)     {         if(e.getSource() == addButton)         {             // Check there is text in the 'textfield'             if(textfield1.getText().compareTo("") != 0 &&                textfield2.getText().compareTo("") != 0 &&                textfield3.getText().compareTo("") != 0)             {                 // Then add the three fields to the JTable                 tableHandler.addRowToTable(textfield1.getText(),                                            textfield2.getText(),                                            textfield3.getText());                                  // Clear the textfields...                 textfield1.setText("");                 textfield2.setText("");                 textfield3.setText("");             }         }     }          JTable table;     TableHandler tableHandler;     JTextField textfield1;     JTextField textfield2;     JTextField textfield3;     JButton addButton; }

TableHandler.java

import javax.swing.table.*; import java.util.*;     class TableHandler extends AbstractTableModel {     public TableHandler()     {         dataRows = new Vector(); // set up the vector      }          public void addRowToTable(String a, String b, String c)     {         String[] rowData = new String[3];                                     rowData[0] = a;         rowData[1] = b;         rowData[2] = c;                  dataRows.addElement(rowData);   // Add the data to a vector                      fireTableChanged(null); // Tell the table there is new data     }          public int getColumnCount()     {         return 3;     }          public int getRowCount()     {         if(dataRows != null)         {             return dataRows.size();         }         else         {             return -1;         }     }         public Object getValueAt(int row, int column)     {         if(dataRows != null)         {             return ((String[])(dataRows.elementAt(row)))[column];         }         else         {             return null;         }     }             private Vector dataRows;   // Vector to contain the rows of data }
end example

When we run the example and add some sample data into the table using the three text fields and the button, the following should be visible:

click to expand
Figure 20: Using the JTable

Let's first look at our TableHandler class before we look at how we implemented it into the main class. Our TableHandler class extends the AbstractTableModel class, which is used by JTables to control how the data is stored for the table. The purpose of our TableHandler class is to allow functionality to the JTable, such as the addRowToTable method that we created to allow a row of data to be inserted easily into the table. Let's look at all the methods in the TableHandler one by one, so we can understand how it works.

  • The constructor

    public TableHandler() {     dataRows = new Vector(); // set up the vector  }

    The constructor only creates a new vector object, which is stored in the dataRows reference. This vector is used to hold all of our table data (i.e., the rows and columns).

  • The addRowToTable method

    public void addRowToTable(String a, String b, String c) {         String[] rowData = new String[3];                                     rowData[0] = a;         rowData[1] = b;         rowData[2] = c;                  dataRows.addElement(rowData);   // Add the data to a vector                      fireTableChanged(null);  // Tell the table there is new data }

    The addRowToTable method allows us to easily add rows to our table by taking in three string parameters, which represent the three columns in the new table row. First we assign each of the three strings (a, b, and c) to an array of three strings called rowData. Once this is done, we add the reference to the array of three strings to our dataRows vector, which we initialized in the constructor. Finally, we call a method of the AbstractTableModel, which we have extended, called fireTableChanged. This method notifies the table that the data inside the table has changed. We will see how the table updates its data in the getValueAt method. If the table is large, the parameter in the fireTableChanged method, which is null in the example, should tell exactly what rows or columns are updated so that the table view is not completely updated unnecessarily.

  • The getColumnCount method

    public int getColumnCount() {         return 3; } 

    The getColumnCount method does exactly what it says; it simply returns the number of the columns in our table. We have hard-coded this value to be 3, but this can be worked out dynamically if required. Note that this method is part of the abstract class that we are extending and therefore must be implemented.

  • The getRowCount method

    public int getRowCount() {         if(dataRows != null)         {             return dataRows.size();         }         else         {             return -1;         } }

    The getRowCount method simply returns the number of rows currently in the table by retrieving the size of our dataRows vector. If the dataRows vector is null, the function returns –1. Note that this method is also part of the AbstractTableModel that we are extending and consequently must be implemented.

  • The getValueAt method

    public Object getValueAt(int row, int column) {     if(dataRows != null)     {         return ((String[])(dataRows.elementAt(row)))[column];     }     else     {         return null;     } }

The getValueAt method is where the magic happens when we try to update the information in our table. This method is called by the JTable to retrieve the data that should be in each of its columns and rows once the fireTableChanged method is called. All this method does is return the string that is stored at the row and column that is specified by the two parameters the method takes (i.e., the integer's row and column). Note that this function is also part of the abstract class that we are extending; hence it must also be implemented. Note also, though, that if this function is not implemented correctly, no data will be visible in your table.

Now that we have looked at the TableHandler class, let's look at how it is implemented in our main JTableExample class. First we have created the JTable object with the following code segment:

table = new JTable(10, 3); table.setBounds(10, 10, 420, 200);

Note that the JTable constructor parameters represent the number of rows and columns that you wish to be visible on the screen.

Once the object is created, we then create an instance of our TableHandler class and store the reference in a variable called tableHandler. Then, once this is done, we call the setModel method of our table object to set its model to be our TableHandler class. This can be seen in the following code segment:

tableHandler = new TableHandler(); table.setModel(tableHandler);

Finally, if we look at the code where we handle the button click, we can see that all we have to do is retrieve the text that the user has entered into the text fields and pass them into the addRowToTable method, which is a member of our tableHandler object. Our table will automatically update after we call this method, as the addRowToTable method calls the fireTableChanged method after it has updated the vector in the TableHandler class. The use of the addRowToTable method can be seen in the following code snippet:

tableHandler.addRowToTable(textfield1.getText(),                            textfield2.getText(),                            textfield3.getText());



Java 1.4 Game Programming
Java 1.4 Game Programming (Wordware Game and Graphics Library)
ISBN: 1556229631
EAN: 2147483647
Year: 2003
Pages: 237

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net