0

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.

Petr Šrámek
  • 435
  • 7
  • 26

1 Answers1

4

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.

Community
  • 1
  • 1
Braj
  • 46,415
  • 5
  • 60
  • 76
  • 2
    Half way there, reload forces the entire tree to be reloaded, collapsing currently expanded nodes. You could use any of the available mutation methods, like insertNodeInto, nodeChanged or rmoveNodeFromParent for example ;) – MadProgrammer May 31 '14 at 21:00
  • @MadProgrammer I agree but It can be refresh on the immediate parent of edited/inserted node only. There is no need to call it on root node always. – Braj May 31 '14 at 21:03
  • 1
    It depends. If all you are doing is manipulating so e of the des better to use the model manipulation methods, if you're changing the model in a significant manner, then sure, reload it – MadProgrammer May 31 '14 at 21:09
  • @MadProgrammer yes I strongly agree with you. – Braj May 31 '14 at 21:27
  • .getRoot() should not be there in the first line – mountrix Oct 02 '18 at 22:31