Petr Šrámek
Petr Šrámek

Reputation: 433

How to refresh JTree after add or delete row in JTable

I'm trying to make GUI for database of movies, with JTree and JTable. But I have problem, when I want to add or delete some row from JTable, I can't figure out how show this change in JTree. I tryied add kategorieFilmu.add(node) or kategorieFilmu.remove(row), but it doesn't work. And I also try to refresh JTree with panelJTree.repaint.

JTable:

      protected JScrollPane jTable() 
      {                   
      vypisFilmu.setRowSorter(sorter);    
      sorter.setRowFilter(RowFilter.regexFilter(""));   
      vypisFilmu.setModel(spravaFilmu.getModel());        

      class ButtonEditor extends DefaultCellEditor {
        private static final long serialVersionUID = 1L;

          protected JButton button;
          private String label;
          private boolean isPushed;

          public ButtonEditor(JCheckBox checkBox) {
            super(checkBox);
            button = new JButton();
            button.setOpaque(true);
            button.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                fireEditingStopped();
              }
            });
          }

          public Component getTableCellEditorComponent(JTable table, Object value,
              boolean isSelected, int row, int column) {
            button.setText(label);
            int index = (Integer) vypisFilmu.getValueAt(row, 0);
            spravaFilmu.removeRow(index); //DELETE row
            spravaFilmu.getFilmy().add(new film("", "", 0, 0,"", false)); //ADD new - without this it trows exception, because one row is missing 
            panelJTable.repaint();
                      /*kategorieFilmu.remove(row);
            panelJTree.repaint();*/
            isPushed = true;
            return button;
          }

          public boolean stopCellEditing() {
            isPushed = false;
            return super.stopCellEditing();
          }

          protected void fireEditingStopped() {
            super.fireEditingStopped();
          }
        }

      class ButtonRenderer extends JButton implements TableCellRenderer {
        private static final long serialVersionUID = 1L;

        public ButtonRenderer() {
            setOpaque(true);
          }

          public Component getTableCellRendererComponent(JTable table, Object value,
              boolean isSelected, boolean hasFocus, int row, int column) {
            if (isSelected) {
              setForeground(table.getSelectionForeground());
              setBackground(table.getSelectionBackground());
            } else {
              setForeground(table.getForeground());
              setBackground(UIManager.getColor("Button.background"));
            }
            setText((value == null) ? "" : value.toString());
            return this;
          }
        }
      vypisFilmu.getColumn("Smazat").setCellRenderer(new ButtonRenderer());
      vypisFilmu.getColumn("Smazat").setCellEditor(new ButtonEditor(new JCheckBox()));    

      DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
      centerRenderer.setHorizontalAlignment( JLabel.CENTER );
      TableColumn column = null;


      final JScrollPane panelJTable = new JScrollPane(vypisFilmu);
      hlavniOkno.this.add(BorderLayout.CENTER, panelJTable);
      return panelJTable;
  }

JTree:

private JTree kategorieFilmu;

      protected JScrollPane jTree()
      {   
    kategorieFilmu = new JTree(root);
          add(kategorieFilmu);

          root.add(akcni);  
          root.add(animovany);
          root.add(drama);
          root.add(komedie);

          for(int i = 0; i < pocetFilmu;i++)
          {   
              if(spravaFilmu.getFilmy().get(i).getZanr().equals("Akční"))
                      {                 
                        DefaultMutableTreeNode nazevNode = new DefaultMutableTreeNode(spravaFilmu.getFilmy().get(i).getNazev());
                        akcni.add(nazevNode);
                      }
              else if(spravaFilmu.getFilmy().get(i).getZanr().equals("Animovaný"))
              {                 
                DefaultMutableTreeNode nazevNode = new DefaultMutableTreeNode(spravaFilmu.getFilmy().get(i).getNazev());
                animovany.add(nazevNode);
              }
              else if(spravaFilmu.getFilmy().get(i).getZanr().equals("Drama"))
              {                 
                DefaultMutableTreeNode nazevNode = new DefaultMutableTreeNode(spravaFilmu.getFilmy().get(i).getNazev());
                drama.add(nazevNode);
              }
              else if(spravaFilmu.getFilmy().get(i).getZanr().equals("Komedie"))
              {                 
                DefaultMutableTreeNode nazevNode = new DefaultMutableTreeNode(spravaFilmu.getFilmy().get(i).getNazev());
                komedie.add(nazevNode);
              }
              else {}
          }           


          /****** Select category ******/
          kategorieFilmu.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
              @Override
              public void valueChanged(TreeSelectionEvent e) {
                  DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) kategorieFilmu.getLastSelectedPathComponent();
                  if(selectedNode.getUserObject().toString() == "Všechny filmy")
                  {
                      sorter.setRowFilter(RowFilter.regexFilter(""));   
                      vypisFilmu.setModel(spravaFilmu.getModel()); 
                  }
                  else
                  {
                      sorter.setRowFilter(RowFilter.regexFilter(selectedNode.getUserObject().toString()));  
                      vypisFilmu.setModel(spravaFilmu.getModel());
                  }

              }
          });

          final JScrollPane panelJTree = new JScrollPane(kategorieFilmu);
          panelJTree.setPreferredSize(new Dimension(180,520));
          hlavniOkno.this.add(BorderLayout.LINE_START, panelJTree);
          return panelJTree;
      }

TableModel:

public class spravaFilmu {

    private ArrayList<film> filmy = new ArrayList<>();
    private TableModel model;

    public spravaFilmu()
    {
        // Testovací data
        filmy.add(new film("Expendables: Postradatelní", "Akční", 2010, 103,"Sylvester Stallone", true));
        filmy.add(new film("Rivalové", "Akční", 2013, 123,"Ron Howard", true));
        filmy.add(new film("Temný rytíř povstal", "Akční", 2012, 158,"Christopher Nolan", true));
        filmy.add(new film("Avengers", "Akční", 2012, 143,"Joss Whedon", false));
        filmy.add(new film("Skyfall", "Akční", 2012, 143,"Sam Mendes", true));
        filmy.add(new film("Expendables 2, The", "Akční", 2012, 103,"   Simon West ", false));
        filmy.add(new film("Iron Man 3", "Akční", 2013, 130,"Shane Black", true));
        filmy.add(new film("Raubíř Ralf", "Animovaný", 2012, 97,"Rich Moore", true));
        filmy.add(new film("LEGO® příběh", "Animovaný", 2014, 100,"Phil Lord", true));
        filmy.add(new film("Croodsovi", "Animovaný", 2013, 90,"Chris Sanders", true));
        filmy.add(new film("Ledové království", "Animovaný", 2013, 102,"Chris Buck", true));
        filmy.add(new film("Hon", "Drama", 2012, 115,"Thomas Vinterberg", true));
        filmy.add(new film("Nespoutaný Django", "Drama", 2012, 165,"Quentin Tarantino", true));
        filmy.add(new film("Grandhotel Budapešť", "Komedie", 2014, 100,"Wes Anderson", true));
        filmy.add(new film("Vlk z Wall Street", "Komedie", 2013, 180,"Martin Scorsese", true));
        filmy.add(new film("Lásky čas", "Komedie", 2013, 123,"Richard Curtis", true));
        filmy.add(new film("Stuck in Love", "Komedie", 2012, 97,"Josh Boone", false));   

        // Definice vlastního modelu JTable 
        model = new AbstractTableModel() {

            private static final long serialVersionUID = 1L;
            String[] nazvySloupcu = {"ID", "Název", "Žánr", "Rok", "Délka (min)", "Režie", "Dabing", "Smazat"};
            @Override
            public String getColumnName(int col) { return nazvySloupcu[col]; }
            @Override
            public int getRowCount() { return getFilmy().size(); }
            @Override
            public int getColumnCount() { return nazvySloupcu.length; }
            @Override
            public Object getValueAt(int row, int col) {
                film film = getFilmy().get(row);
                switch (col)
                {
                    case 0:
                        return film.getId();
                    case 1:
                        return film.getNazev();
                    case 2:
                        return film.getZanr();
                    case 3:
                        return film.getRok();
                    case 4:
                        return film.getDelka();
                    case 5:
                        return film.getRezie();
                    case 6:
                        return film.getDabing();
                    case 7:
                        return "X";
                }
                return film;
            }
            @Override
            public boolean isCellEditable(int row, int col) { return true; }

        };

    }

    public ArrayList<film> getFilmy() {
        return filmy;
    }

    public TableModel getModel() {
        return model;
    }

    public void removeRow(int index)
    {
        filmy.remove(index);
    }
}

I'll be gratefull for any help.

Upvotes: 0

Views: 2174

Answers (1)

Braj
Braj

Reputation: 46841

Try with DefaultTreeModel#reload() and invoke this method if you've modified the TreeNodes upon which this model depends. The model will notify all of its listeners that the model has changed below the given node.

Sample code:

DefaultTreeModel model = (DefaultTreeModel)tree.getModel().getRoot();
model.reload((TreeNode) model.getRoot());

Note:

  • In the same way just reload the immediate parent node of the updated node only.
  • I believe you are using DefaultTreeModel for adding and deleting the nodes from JTree as suggested by @MadProgrammer in below comments.

For further information and examples that use DefaultTreeModel, see How to Use Trees in The Java Tutorial. Specially look at Dynamically Changing a Tree section.

Find more solutions here and here on refreshing the JTree.

Upvotes: 4

Related Questions