There is a JTree based on the implemented TreeModel , which is based on a sample from the MySQL database. There are buttons, by pressing which data is added / deleted in the MySQL table. How to make the data in JTree automatically updated? The revalidate() and repaint() methods do not work. Only updateUI() works, but for some reason it is not recommended to be used (by the way, the second question is why is it not recommended?).
Code:
package catalogs; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTree; import javax.swing.ListSelectionModel; import javax.swing.event.TableModelListener; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.table.TableModel; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import main.Global; /*------Класс окна справочника товаров.------*/ public class ProductsCatalog extends JInternalFrame{ private static final long serialVersionUID = 1L; //Объявления компонент окна. private JTree groupTree; private GroupTreeModel groupTreeModel; private JScrollPane groupTreeScrlPane; private JButton btnAddGroup; private JButton btnDelGroup; private ButtonListener btnListener; private TreeListener groupTreeListener; private JTable prodTable; private ProdTableModel prodTableModel; private JScrollPane prodTableScrlPane; //Конструктор. public ProductsCatalog(){ Global.DB_NAME = "mydb"; //УДАЛИТЬ СТРОКУ //Инициализация компонент окна. //Древо групп товаров. groupTreeModel = new GroupTreeModel(); groupTree = new JTree(groupTreeModel); groupTree.setSelectionRow(0); groupTreeListener = new TreeListener(); groupTree.addTreeSelectionListener(groupTreeListener); groupTreeScrlPane = new JScrollPane(groupTree); groupTreeScrlPane.setBounds(10, 10, 150, 200); //Кнопки добавления и удаления групп товаров. btnListener = new ButtonListener(); btnAddGroup = new JButton(); ImageIcon btnAddGroupIcon = new ImageIcon("images/btnAddGroup.png"); btnAddGroup.setIcon(btnAddGroupIcon); btnAddGroup.addActionListener(btnListener); btnAddGroup.setBounds(10, 220, 30, 30); btnDelGroup = new JButton(); ImageIcon btnDelGroupIcon = new ImageIcon("images/btnDelGroup.png"); btnDelGroup.setIcon(btnDelGroupIcon); btnDelGroup.addActionListener(btnListener); btnDelGroup.setBounds(50, 220, 30, 30); //Таблица товаров. prodTableModel = new ProdTableModel(); prodTable = new JTable(prodTableModel); prodTableModel.buildTable(groupTree.getLastSelectedPathComponent()); prodTable.setAutoCreateRowSorter(true); prodTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); prodTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); prodTable.getColumnModel().getColumn(0).setPreferredWidth(25); prodTable.getColumnModel().getColumn(1).setPreferredWidth(200); prodTable.getColumnModel().getColumn(2).setPreferredWidth(25); prodTable.getColumnModel().getColumn(3).setPreferredWidth(50); prodTableScrlPane = new JScrollPane(prodTable); prodTableScrlPane.setBounds(170, 10, 500, 200); //Параметры окна. this.setTitle("Каталог товаров"); this.setClosable(true); this.setMaximizable(true); this.setIconifiable(true); this.setResizable(true); this.getContentPane().setLayout(null); this.setSize(700, 350); this.setVisible(true); this.add(groupTreeScrlPane); this.add(btnAddGroup); this.add(btnDelGroup); this.add(prodTableScrlPane); } /*------Модель дерева.------*/ private class GroupTreeModel implements TreeModel{ @Override public Object getChild(Object parent, int index) { Object[][] buf = Global.sqlQueryResult("SELECT * FROM `prod_group` WHERE `name`='"+ parent +"'"); Object parentCode = buf[0][0]; Object[][] res = Global.sqlQueryResult("SELECT * FROM `prod_group` WHERE `parent`='"+ parentCode +"'"); return res[index][1]; } @Override public int getChildCount(Object parent) { Object[][] buf = Global.sqlQueryResult("SELECT * FROM `prod_group` WHERE `name`='"+ parent +"'"); Object parentCode = buf[0][0]; Object[][] res = Global.sqlQueryResult("SELECT * FROM `prod_group` WHERE `parent`='"+ parentCode +"'"); return res.length; } @Override public int getIndexOfChild(Object parent, Object child) { Object[][] buf = Global.sqlQueryResult("SELECT * FROM `prod_group` WHERE `name`='"+ parent +"'"); Object parentCode = buf[0][0]; Object[][] res = Global.sqlQueryResult("SELECT * FROM `prod_group` WHERE `parent`='"+ parentCode +"'"); int index = 0; for(int i =0; i<res.length; i++){ if(res[i][1].equals(child)) index = i; } return index; } @Override public Object getRoot() { Object[][] res = Global.sqlQueryResult("SELECT * FROM `prod_group` WHERE `parent`='0'"); return res[0][1]; } @Override public boolean isLeaf(Object arg0) { return false; } @Override public void addTreeModelListener(TreeModelListener arg0) {} @Override public void removeTreeModelListener(TreeModelListener arg0) {} @Override public void valueForPathChanged(TreePath arg0, Object arg1) {} } /*------Слушатель изменения выбранной строки дерева групп товаров.------*/ public class TreeListener implements TreeSelectionListener{ @Override public void valueChanged(TreeSelectionEvent selection) { prodTableModel.buildTable(groupTree.getLastSelectedPathComponent()); prodTable.revalidate(); prodTable.repaint(); } } /*------Слушатель нажатия кнопок добавления/удаления групп/товаров.------*/ public class ButtonListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { //Если нажата кнопка удаления группы товаров. if(e.getSource().equals(btnDelGroup)){ //Проверяем, пуста ли папка, которую удаляем. boolean isEmpty = false; Object[][] buf = Global.sqlQueryResult("SELECT `id` FROM `prod_group` WHERE `name`='"+ groupTree.getLastSelectedPathComponent() +"'"); Object[][] buf2 = Global.sqlQueryResult("SELECT * FROM `product` WHERE `group`='"+ buf[0][0] +"'"); Object[][] buf3 = Global.sqlQueryResult("SELECT * FROM `prod_group` WHERE `parent`='"+ buf[0][0] +"'"); if(buf2.length==0 && buf3.length==0) isEmpty = true; //Если выделена группа, она пуста и мы подтверждаем удаление, тогда удаляем. if(!groupTree.isSelectionEmpty()){ if(isEmpty){ if(JOptionPane.showConfirmDialog(null, "Вы уверены?", "Подтверждение удаления", JOptionPane.YES_NO_OPTION)==0){ Global.sqlQueryVoid("DELETE FROM `prod_group` WHERE `name`='"+ groupTree.getLastSelectedPathComponent() +"'"); //groupTree.updateUI(); groupTree.setVisible(false); groupTree.revalidate(); groupTree.repaint(); groupTree.setVisible(true); } }else JOptionPane.showMessageDialog(null, "Нельзя удалить эту папку, т.к. она не пуста!", "Ошибка", JOptionPane.ERROR_MESSAGE); }else JOptionPane.showMessageDialog(null, "Вы не выбрали ни одну папку!", "Ошибка", JOptionPane.ERROR_MESSAGE); } } } /*------Модель таблицы.------*/ public class ProdTableModel implements TableModel{ //Двумерный массив данных. private Object[][] selection = null; //Метод построения двумерного массива данных, на основе которого отрисовывается таблица товаров. public void buildTable(Object group){ Object[][] buf = Global.sqlQueryResult("SELECT `id` FROM `prod_group` WHERE `name`='"+ group +"'"); selection = Global.sqlQueryResult("SELECT `id`, `name`, `unit`, `comments` FROM `product` WHERE `group`='"+ buf[0][0] +"'"); } @Override public Class<?> getColumnClass(int colInd) { return String.class; } @Override public int getColumnCount() { return 4; } @Override public String getColumnName(int colInd) { String colName =""; switch(colInd){ case 0: colName = "Код"; break; case 1: colName = "Наименование"; break; case 2: colName = "Ед. изм."; break; case 3: colName = "Комментарий"; break; } return colName; } @Override public int getRowCount() { return selection.length; } @Override public Object getValueAt(int rowInd, int colInd) { return selection[rowInd][colInd]; } @Override public void addTableModelListener(TableModelListener arg0) {} @Override public boolean isCellEditable(int arg0, int arg1) {return false;} @Override public void removeTableModelListener(TableModelListener arg0) {} @Override public void setValueAt(Object arg0, int arg1, int arg2) {} } }