【问题标题】:How to refresh JTree after add or delete row in JTable在 JTable 中添加或删除行后如何刷新 JTree
【发布时间】:2014-07-21 08:58:03
【问题描述】:

我正在尝试使用 JTree 和 JTable 为电影数据库制作 GUI。但是我有问题,当我想从 JTable 添加或删除一些行时,我不知道如何在 JTree 中显示这种变化。我尝试添加kategorieFilmu.add(node)kategorieFilmu.remove(row),但它不起作用。我还尝试使用panelJTree.repaint 刷新JTree。

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;
      }

表模型:

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);
    }
}

如果有任何帮助,我将不胜感激。

【问题讨论】:

  • 又是通知器,不需要 reload()

标签: java swing jtable jtree


【解决方案1】:

如果您修改了此模型所依赖的 TreeNode,请尝试使用 DefaultTreeModel#reload() 并调用此方法。该模型将通知其所有侦听器该模型在给定节点下发生了更改。

示例代码:

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

注意:

  • 以同样的方式只重新加载更新节点的直接父节点。
  • 我相信您正在使用DefaultTreeModelJTree 添加和删除节点,正如@MadProgrammer 在下面的cmets 中所建议的那样。

有关使用DefaultTreeModel 的更多信息和示例,请参阅How to Use Trees in The Java Tutorial。特别看Dynamically Changing a Tree部分。

在刷新JTree 时找到更多解决方案herehere

【讨论】:

  • 到了一半,重新加载强制重新加载整个树,折叠当前展开的节点。您可以使用任何可用的突变方法,例如 insertNodeInto、nodeChanged 或 rmoveNodeFromParent ;)
  • @MadProgrammer 我同意,但它只能在编辑/插入节点的直接父节点上刷新。不需要总是在根节点上调用它。
  • 视情况而定。如果您所做的只是进行操作,以便更好地使用模型操作方法,如果您正在以重要的方式更改模型,那么确定,重新加载它
  • @MadProgrammer 是的,我非常同意你的看法。
  • .getRoot() 不应该在第一行
猜你喜欢
  • 2012-04-09
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多