Search code examples
javaswingjtablejbutton

Java JTable changes when click on JButton


I have a database with tables. I passed the name of the tables into the buttons. When you click, you need a table with fields and filling to appear. The problem is that I have a new table added every time I click on the button.

Can someone please say me how to do it? Thanks in advance!

public class App extends JPanel {

static List<FieldElement> fields = new ArrayList<>();
static List<Map<String, Object>> data = new ArrayList<>();
static JTable jTable = new JTable();

public static void createGUI() throws SQLException {

    TableContent tableContent = new TableContent();
    JFrame frame = new JFrame();
    MetadataHelper databaseMetadata = new MetadataHelper();
    List<ButtonElement> elements = databaseMetadata.showTables();
    JPanel panel = new JPanel();

    JPanel buttons = new JPanel(new GridLayout(0, 1));
    for (ButtonElement buttonElements : elements) {
        JButton jButton = new JButton(buttonElements.getTablesInMigrateSchema());
        buttons.add(jButton);
        jButton.addActionListener(new ActionListener() {
            @SneakyThrows
            @Override
            public void actionPerformed(ActionEvent e) {
                fields = tableContent.getDatabaseMetadata().showFields(buttonElements.getTablesInMigrateSchema());
                data = tableContent.getDatabaseMetadata().selectAll(buttonElements.getTablesInMigrateSchema());
                Object[][] objectRows = data.stream().map(m -> m.values().toArray()).toArray(Object[][]::new);
                jTable = new JTable(objectRows, fields.toArray());
                panel.add(new JScrollPane(jTable));
                frame.revalidate();
                frame.repaint();
                
            }
        });

    }

    panel.add(buttons, BorderLayout.EAST);
    frame.add(panel);
    frame.setTitle("SwingSandbox");
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();

}

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        @SneakyThrows
        public void run() {
            JFrame.setDefaultLookAndFeelDecorated(true);
            createGUI();
        }
    });
}

}enter image description here


Solution

  • One easy possibility is to store the JScrollPane in a variable (which holds your table that you want to remove):

    static JTable jTable = new JTable();
    static JScrollPane jScrollPane;
    

    And then in your actionPerformed method:

    public void actionPerformed(ActionEvent e) {
     ...
                    if (jScrollPane != null) {
                      panel.remove(jScrollPane);
                    }
                    jTable = new JTable(objectRows, fields.toArray());
                    jScrollPane = new JScrollPane(jTable);
                    panel.add(jScrollPane);
                    frame.revalidate();
                    frame.repaint();
                    
                }