Автоматическое обновление Jtable от JPanel до затмения Jframe - PullRequest
0 голосов
/ 04 июля 2018

У меня есть база данных JTable из моего класса JPanel, и я хочу использовать ее в своем классе JFRame

И я хочу автообновление JTable, нажав несколько кнопок
Это не ошибка, но он не хочет автообновления, если я не помещу Jframe в класс Jpanel, который создаст новый фрейм

вот мой JPanel

 public class TUsers extends JPanel {

    private static final long serialVersionUID = 1L;  

    String [] header = {"Id","name","address"};
    JTable BTab = new JTable(); 
    JScrollPane scrPnl = new JScrollPane();
    public Object [][] table = null;

     TUsers(){
        Dbcon dc = new Dbcon();
        Connection psql = dc.getConnection();
        try 
        {
            Statement stmt = psql.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
            String sql = "SELECT * FROM public.patrons ORDER BY id ASC";
            ResultSet res = stmt.executeQuery(sql);
            ResultSetMetaData meta = res.getMetaData();
            int y  = meta.getColumnCount();
            int x = 0;
            while(res.next())
            {
                y = res.getRow();
            }
            table = new Object[x][y];
            int n = 0;
            res.beforeFirst();
            while(res.next())
            {
                table[n][0]=res.getString("Id");
                table[n][1]=res.getString("name");
                table[n][2]=res.getString("address");
                x++;
            }
            scrPnl.setViewportView(BTab);
            BTab.setModel(new DefaultTableModel(table, header));
            TableColumnModel table = BTab.getColumnModel();

            table.getColumn(0).setPreferredWidth(2);
            table.getColumn(1).setPreferredWidth(100);
            table.getColumn(2).setPreferredWidth(180);

            scrPnl.setPreferredSize(new Dimension(350, 120));

            add(scrPnl, BorderLayout.CENTER);
            revalidate();
            repaint();
            stmt.close();
            res.close();

вот из моего класса JFrame

  public class AddUser extends JFrame {
    TUsers t = new TUsers();


AddUser()
{
    setTitle("Admin");
    setLocation(400,400);
    setSize(400, 400);
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

}

    void Layout()
  {
   getContentPane().add(t).setBounds(10, 225, 350, 150);
   //if i delete this it wont show the table

    setVisible(true);
  } 



    void EventHandle() 
   {
  b_crt.addActionListener(new ActionListener() 
    {
        public void actionPerformed(ActionEvent e)
        {
            Dbcon dc = new Dbcon();
            Connection psql = dc.getConnection();
            try
            {
                Statement stmt = psql.createStatement();
                String sql = "INSERT INTO public.patrons VALUES ('"
                            +t_id.getText()+"','"
                            +t_usrnm.getText()+"','"
                            +t_adrs.getText()+"');";
                int i = stmt.executeUpdate(sql);
                if(i == i) 
                {
                    JOptionPane.showMessageDialog(null, "Success");
                }
                Clear();
            }
            catch(Exception x)
            {
                JOptionPane.showMessageDialog(null, x.getMessage());
            }

            TUsers t = new TUsers();

         }
        });
   }
}   

я уже поставил
repaint () и revalidate () на моем JPanel, но это не работает

1 Ответ

0 голосов
/ 04 июля 2018

Хорошо, давайте сделаем шаг назад и переосмыслим ваш TUsers класс.

Текущая реализация имеет побочный эффект загрузки информации базы данных как часть фазы инициализации классов. В этом есть пара проблем, основная проблема в том, что вы не можете обновить таблицу, не создав новый экземпляр.

Лучшим подходом может быть простое создание базового пользовательского интерфейса в конструкторе, а затем предоставление отдельного метода "load", который повторно загружает данные из базы данных, возможно, что-то вроде ...

public class TUsers extends JPanel {

    private static final long serialVersionUID = 1L;

    String[] header = {"Id", "name", "address"};
    JTable BTab = new JTable();
    JScrollPane scrPnl = new JScrollPane();

    TUsers() {
        // Build the UI
        setLayout(new BorderLayout());
        DefaultTableModel model = new DefaultTableModel(header, 0);
        BTab = new JTable(model);
        scrPnl.setViewportView(BTab);
        add(scrPnl);
    }

    public void loadData() throws SQLException {
        Dbcon dc = new Dbcon();
        String sql = "SELECT * FROM public.patrons ORDER BY id ASC";
        try (Connection psql = dc.getConnection();
                Statement stmt = psql.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                ResultSet res = stmt.executeQuery(sql)) {
            DefaultTableModel model = new DefaultTableModel(header, 0);
            while (res.next()) {
                String[] rowData = new String[3];
                rowData[0] = res.getString("Id");
                rowData[1] = res.getString("name");
                rowData[2] = res.getString("address");
                model.addRow(rowData);
            }
            BTab.setModel(model);
            BTab.getColumn(0).setPreferredWidth(2);
            BTab.getColumn(1).setPreferredWidth(100);
            BTab.getColumn(2).setPreferredWidth(180);
        }
    }
}

Просто убедитесь, что вы звоните loadData в какой-то момент, иначе он покажет пустую таблицу.

Теперь, когда вы захотите, вы можете позвонить loadData и обновить таблицу ...

public class AddUser extends JFrame {

    TUsers t = new TUsers();

    AddUser() {
        setTitle("Admin");
        setLocation(400, 400);
        setSize(400, 400);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        // When does t get added??
    }

    void Layout() {
        getContentPane().add(t).setBounds(10, 225, 350, 150);
        //if i delete this it wont show the table
        // This is a symptom of a different problem
        setVisible(true);
    }

    void EventHandle() {
        b_crt.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Dbcon dc = new Dbcon();
                String sql = "INSERT INTO public.patrons VALUES ('"
                        + t_id.getText() + "','"
                        + t_usrnm.getText() + "','"
                        + t_adrs.getText() + "');";
                try (Connection psql = dc.getConnection();
                        Statement stmt = psql.createStatement()) {
                    int i = stmt.executeUpdate(sql);
                    if (i == i) {
                        JOptionPane.showMessageDialog(null, "Success");
                    }
                    t.loadData();
                } catch (Exception x) {
                    JOptionPane.showMessageDialog(null, x.getMessage());
                }

            }
        });
    }
}

И пока я обращаю ваше внимание, позвольте представить вам пару маленьких друзей ...

PreapredStatement

PreparedStatement защищает вас от возможных проблем с внедрением SQL и поддерживает ряд различных типов данных, избавляя вас от необходимости пытаться выяснить, как преобразовать их для разных баз данных

См. Как использовать PreparedStatement для более подробной информации

void EventHandle() {
    b_crt.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Dbcon dc = new Dbcon();
            String sql = "INSERT INTO public.patrons VALUES (?, ?, ?)";
            try (Connection psql = dc.getConnection();
                    PreparedStatement stmt = psql.prepareStatement(sql)) {
                stmt.setString(1, t_id.getText());
                stmt.setString(2, t_usrnm.getText());
                stmt.setString(3, t_adrs.getText());
                int i = stmt.executeUpdate(sql);
                if (i == i) {
                    JOptionPane.showMessageDialog(null, "Success");
                }
                t.loadData();
            } catch (Exception x) {
                JOptionPane.showMessageDialog(null, x.getMessage());
            }

        }
    });
}

примерочный с-ресурсами

Управление ресурсами - очень важная задача, которая может быть сложной. Вы рискуете оставить ресурсы открытыми в случае сбоя одной из многих операций. Лучшее решение - использовать доступную поддержку «автоматического закрытия»

Вы увидите это в приведенном выше коде, но вы также можете прочитать Заявление о попытках использования ресурсов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...