Search code examples
javaswingjdbcjframetablemodel

TableModel, causing duplicate Database Info in a Java JFrame


I have this method setup in a JFrame to be called when the user presses a button to "Load File"; however, when the user presses the button a second time . . . they get another table underneath the first table so all the information gets duplicated and it expands beyond my "non-resizable" frame.

How can I get it to only load the one table no matter how many times the user presses the button?

    JButton btnLoad = new JButton("Load File")

private void GetAction()
{
    ActionHandler handler = new ActionHandler();
    btnLoad.addActionListener(handler);
}

    private class ActionHandler implements ActionListener
{       
    public void actionPerformed(ActionEvent evt) 
    {
        String incmd = evt.getActionCommand();
        if (incmd.equals("Load File")) // If Load File button is pressed
            DatabaseLoad();
        else if (incmd.equals("Exit")) // If Exit button is pressed
            System.exit(0);  
    }
}
    private void DatabaseLoad()
    {
        try 
        {
            // The driver allows you to query the database with Java
            // forName dynamically loads the class for you           
            Class.forName("com.mysql.jdbc.Driver");

            // DriverManager is used to handle a set of JDBC drivers
            // getConnection establishes a connection to the database
            // You must also pass the userid and password for the database            
            String url = "jdbc:mysql://localhost:3306/charity";
            conn = DriverManager.getConnection (url,"root","password");

            // Statement objects executes a SQL query
            // createStatement returns a Statement object            
            Statement sqlState = conn.createStatement();

            // This is the query I'm sending to the database
            String selectStuff = "SELECT `name`, `charity`, `amount` FROM `charity`.`donations` ";                  

            // A ResultSet contains a table of data representing the
            // results of the query. It can not be changed and can 
            // only be read in one direction            
            rows = sqlState.executeQuery(selectStuff);

            // Temporarily holds the row results            
            Object[] tempRow;

            // next is used to iterate through the results of a query            
            while(rows.next()){

            // Gets the column values based on class type expected
            tempRow = new Object[]{rows.getString(1), rows.getString(2), rows.getDouble(3) };

            // Adds the row of data to the end of the model             
            dTableModel.addRow(tempRow);                

        }
            // Successfully loaded, message the user
            message1.setText("<html><font color='red'>Database Info Loaded</font>");
            message2.setText("");
    } 
        catch (SQLException ex) 
        {            
            // String describing the error          
            System.out.println("SQLException: " + ex.getMessage());

            // Vendor specific error code            
            System.out.println("VendorError: " + ex.getErrorCode());
        } 
        catch (ClassNotFoundException e) 
        {
            // Executes if the driver can't be found
            System.out.println("Driver Cannot be found");
            e.printStackTrace();
        }

        // Create a JTable using the custom DefaultTableModel       
        JTable table = new JTable(dTableModel);

        // Increase the font size for the cells in the table        
        table.setFont(new Font("Serif", Font.PLAIN, 16));

        // Increase the size of the cells to allow for bigger fonts        
        table.setRowHeight(table.getRowHeight()+5);

        // Allows the user to sort the data     
        table.setAutoCreateRowSorter(true);

        // right justify amount column
        TableColumn tc = table.getColumn("amount");
        RightTableCellRenderer rightRenderer = new RightTableCellRenderer();
        tc.setCellRenderer(rightRenderer);      

        // Disable auto resizing
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        // Set the width for the columns        
        TableColumn col1 = table.getColumnModel().getColumn(0);
        col1.setPreferredWidth(200);

        TableColumn col2 = table.getColumnModel().getColumn(1);
        col2.setPreferredWidth(275);

        TableColumn col3 = table.getColumnModel().getColumn(2);
        col3.setPreferredWidth(75);     

        // Put the table in a scrollpane and add scrollpane to the frame          
        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setPreferredSize(new Dimension(552, 400));
        this.add(scrollPane, BorderLayout.CENTER);
    }   

    // To change justification to the right
    class RightTableCellRenderer extends DefaultTableCellRenderer {   
          public RightTableCellRenderer() {  
            setHorizontalAlignment(JLabel.RIGHT);  
        }           
    }       

Solution

  • How can I get it to only load the one table no matter how many times the user presses the button?

    The table and scrollpane should only be created once when you build the GUI components. Then when you want to change the data you just change the model of the existing table:

    table.setModel( updatedModel );