Java repaint()方法只能工作一次

Java repaint()方法只能工作一次,java,swing,repaint,Java,Swing,Repaint,我目前正在从事一个gui项目,该项目正在管理一个sql数据库。我目前正在添加、删除日志并显示mysql中存在的表。问题是,面板上的“添加”和“删除”按钮应该在添加或删除记录时重新绘制/刷新该面板上的表,但是在测试时,我发现“重新绘制”方法在第一次使用按钮后不会刷新表。什么会导致这个问题?提前谢谢 public JTabbedPane addComponentToPane() { //Container pane = new Container(); JTabbed

我目前正在从事一个gui项目,该项目正在管理一个sql数据库。我目前正在添加、删除日志并显示mysql中存在的表。问题是,面板上的“添加”和“删除”按钮应该在添加或删除记录时重新绘制/刷新该面板上的表,但是在测试时,我发现“重新绘制”方法在第一次使用按钮后不会刷新表。什么会导致这个问题?提前谢谢

public JTabbedPane addComponentToPane() {
        //Container pane = new Container();
        JTabbedPane tabbedPane = new JTabbedPane();

        JPanel card1 = new JPanel();
        JPanel card2 = new JPanel();
        JPanel card3 = new JPanel();
        JPanel card4 = new JPanel();
        JPanel card5 = new JPanel();
        JPanel card6 = new JPanel();
        JPanel card7 = new JPanel();
        JPanel card8 = new JPanel();

        card1.setLayout(new BorderLayout());
        card2.setLayout(new BorderLayout());
        card3.setLayout(new BorderLayout());
        card4.setLayout(new BorderLayout());
        card5.setLayout(new BorderLayout());
        card6.setLayout(new BorderLayout());
        card7.setLayout(new BorderLayout());
        card8.setLayout(new BorderLayout());

        JScrollPane actor = new JScrollPane(createTables("actor"));

        card1.add(actor, BorderLayout.CENTER);
        card3.add(createTables("address"), BorderLayout.CENTER);
        card4.add(createTables("category"), BorderLayout.CENTER);
        card5.add(createTables("city"), BorderLayout.CENTER);
        card6.add(createTables("country"), BorderLayout.CENTER);
        card7.add(createTables("customer"), BorderLayout.CENTER);
        card8.add(createTables("film"), BorderLayout.CENTER);

        JButton button = new JButton("Yeni Kayıt");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                addRecord("actor");                
                card1.remove(actor);
                card1.add(createTables("actor"), BorderLayout.CENTER);
                card1.validate();
                card1.repaint();                
            }
        });
        JButton delButton = new JButton("Kayıt sil");
        delButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                delRecord("actor");
                card1.remove(actor);
                card1.add(createTables("actor"), BorderLayout.CENTER);
                card1.validate();
                card1.repaint();
            }
        });``

        card1.add(button, BorderLayout.SOUTH);
        card1.add(delButton, BorderLayout.EAST);

        tabbedPane.addTab("Şirketler", null, card1, "şirket tanımları");
        tabbedPane.addTab("Sorumlular", card2);
        tabbedPane.addTab("Varlık Grupları", card3);
        tabbedPane.addTab("Bilgi Varlıkları", card4);
        tabbedPane.addTab("Varlık Değerleri", card5);
        tabbedPane.addTab("Açıklıklar", card6);
        tabbedPane.addTab("Tehditler", card7);
        tabbedPane.addTab("Ek-A", card8);

        //pane.add(tabbedPane, BorderLayout.CENTER);
        return tabbedPane;
    }
createtables方法从sql表创建Jtable

private JScrollPane createTables(String tablename) {
        Connection con = null;
        Statement statement = null;
        ResultSet result = null;
        String query;
        JScrollPane jsp = null;

        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/sakila", "root", "root");
            statement = con.createStatement();
            query = "select * from " + tablename;
            result = statement.executeQuery(query);
            ResultSetMetaData rsmt = result.getMetaData();
            int columnCount = rsmt.getColumnCount();
            Vector column = new Vector(columnCount);
            for (int i = 1; i <= columnCount; i++) {
                column.add(rsmt.getColumnName(i));
            }
            Vector data = new Vector();
            Vector row = new Vector();
            while (result.next()) {
                row = new Vector(columnCount);
                for (int i = 1; i <= columnCount; i++) {
                    row.add(result.getString(i));
                }
                data.add(row);
            }
            defTableModel = new DefaultTableModel(data, column);
            table = new JTable(defTableModel) {
                @Override
                public boolean isCellEditable(int row, int column) {
                    return false;
                }
            ;
            };
            //table.setAutoCreateRowSorter(true);
            TableRowFilterSupport.forTable(table).searchable(true).apply();
            table.setRowSelectionAllowed(true);

            jsp = new JScrollPane(table);

        }
        catch (Exception e) {
            e.printStackTrace();
            // JOptionPane.showMessageDialog(null, "ERROR");
        }
        finally {
            try {
                statement.close();
                result.close();
                con.close();
            }
            catch (Exception e) {
                //JOptionPane.showMessageDialog(null, "ERROR CLOSE");
            }
        }

        return jsp;
    }

我可以看到代码中有几个不一致之处:

未将actor变量设置为操作侦听器中添加的组件。 第一次添加新的JScrollPanecreateTablesactor时,然后只添加createTablesactor。
1可能是导致问题的原因。

我认为问题在于对参与者的引用:

card1.remove(actor);
card1.add(createTables("actor"), BorderLayout.CENTER);
在这里,变量actor在card1中没有更多的引用。为了不丢失此引用,您应该在两种actionPerformed方法中执行以下操作:

card1.remove(actor);
actor = new JScrollPane(createTables("actor"));
card1.add(actor, BorderLayout.CENTER);

您可以尝试调用revalidate;重新油漆;而不是验证;重新油漆;我已经试过了,但是谢谢你的建议。你能发布你的createTables函数吗?更好的是,您能发布一个吗?我已经添加了createTables函数。更新表时应该不需要显式调用repaint。更改表格模型,表格将更新。发布一个or。这不是问题所在。我必须这样做,因为我必须在数据库更改时重新创建表。如果我再次添加actor变量,则不会再次调用该函数,并且会添加旧表,因为它不是动态的。@Sertage说得更清楚了。如果您不能使用actor,因为它需要是final,那么您可以将其设置为类的成员变量,或者在action listener中使用removeAll而不是remove。我认为将actor变量设置为成员变量并不是一个合适的解决方案,因为这只是一种情况,removeAll函数还可以从面板中删除不必要的按钮。你能想出一个方法,我可以删除只是表?谢谢。一种黑客方法是使用getComponents并在面板中搜索表。我使用了这段代码,它可以工作。只是为了进一步使用:Component[]components=card1.getComponents;forComponent组件:如果组件实例为JScrollPane card1.removecomponent,则为组件;我想你已经发现了问题所在,但我仍然没有解决方案,因为我在尝试引用actor变量时出错,说从内部类引用的局部变量必须是final这是一个愚蠢的问题,但使变量final是可行的选项吗?