Java 在同一JTree中使用两个不同对象时,JTree和CellEditor无法正常工作

Java 在同一JTree中使用两个不同对象时,JTree和CellEditor无法正常工作,java,swing,jtree,Java,Swing,Jtree,我目前在JTree的单元格编辑器中遇到问题。我的JTree中有两个不同的对象,用户和书籍 因此,用户是Bianca,书籍是节点。这些节点内的标签(眼睛、油漆标签和垃圾桶)也可以单击。但是,当我设置单元格编辑器时,它会给我一个null异常。我想这是因为我在处理两个不同的对象,所以无法正确设置单元格编辑器。这是我认为存在问题的具体方法: public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isS

我目前在JTree的单元格编辑器中遇到问题。我的JTree中有两个不同的对象,用户和书籍

因此,用户是Bianca,书籍是节点。这些节点内的标签(眼睛、油漆标签和垃圾桶)也可以单击。但是,当我设置单元格编辑器时,它会给我一个null异常。我想这是因为我在处理两个不同的对象,所以无法正确设置单元格编辑器。这是我认为存在问题的具体方法:

public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded,
        boolean leaf, int row) {
    Component returnValue = null;
    System.out.println("loo");
    if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
        Object userObject = ((DefaultMutableTreeNode) value)
                .getUserObject();
        System.out.println("b");
        if(userObject instanceof Book){
            Book feature = (Book) userObject;
            title.setText(feature.getTitulo());
            renderer.setEnabled(tree.isEnabled());
            returnValue = renderer;
            System.out.println("hi!!");
        }
    }
    if (returnValue == null) {
        System.out.println("hi1");
        returnValue = defaultEditor.getTreeCellEditorComponent(tree, value, isSelected, expanded, leaf, row);
        System.out.println(defaultEditor);

    } 
    return returnValue;
}
当节点的类型不是Book时,我不知道如何返回DefaultCellEditor

如果有人想复制问题,下面是我的全部代码:

public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded,
        boolean leaf, int row) {
    Component returnValue = null;
    System.out.println("loo");
    if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
        Object userObject = ((DefaultMutableTreeNode) value)
                .getUserObject();
        System.out.println("b");
        if(userObject instanceof Book){
            Book feature = (Book) userObject;
            title.setText(feature.getTitulo());
            renderer.setEnabled(tree.isEnabled());
            returnValue = renderer;
            System.out.println("hi!!");
        }
    }
    if (returnValue == null) {
        System.out.println("hi1");
        returnValue = defaultEditor.getTreeCellEditorComponent(tree, value, isSelected, expanded, leaf, row);
        System.out.println(defaultEditor);

    } 
    return returnValue;
}
教材:

public class Book {
    String titulo;

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }
    public Book(String titulo){
        this.titulo = titulo;
    }
}
类用户

public class User {
    String nomeUser;

    public String getNomeUser() {
        return nomeUser;
    }

    public void setNomeUser(String nomeUser) {
        this.nomeUser = nomeUser;
    }
    public User(String nome){
        this.nomeUser = nome;
    }
}
类Render(用于设置JTree的单元编辑器和单元渲染)

类JTreeOfObject

public class JTreeOfObjects {


    public static TreeCellRenderer renderer;
    private JFrame frame;
    public static JTree tree;
    private DefaultTreeModel model;
    private DefaultMutableTreeNode parent;
    JLabel nomeRadar;
    JLabel btnVisible;
    JLabel btnPaint;
    JLabel btnTrash;
    public static TreeCellEditor currentStyle;
    public void initialize() throws IOException{
        frame = new JFrame("Árvore de Navegação");
        parent = new DefaultMutableTreeNode("Library",true);
        //DefaultMutableTreeNode undefined = new DefaultMutableTreeNode("Indefinida");
        //undefined.add(new DefaultMutableTreeNode("!"));
        System.out.println(parent.getUserObject());

        //parent.add(undefined);
        tree = new JTree(parent);
        System.out.println("Current"+tree.getCellEditor());
        //currentStyle = tree.getCellEditor();
        renderer  = new Render.NodeCellRenderer();
        model = (DefaultTreeModel) tree.getModel();

        tree.setEditable(true);
        tree.setCellRenderer(renderer);
        tree.setCellEditor(new Render.ButtonCellEditor());
        //frame.getContentPane().add(tree);
        nomeRadar = new JLabel();
        btnVisible = new JLabel();
        btnPaint = new JLabel();
        btnTrash = new JLabel(); 
        InputStream visible = getClass().getResourceAsStream("/eye_visible-16.png");
        InputStream invisible = getClass().getResourceAsStream("/eye_invisible-16.png");
        InputStream paint = getClass().getResourceAsStream("/paint-16.png");
        InputStream trash = getClass().getResourceAsStream("/trash-16.png");
        btnVisible.setIcon(new ImageIcon(ImageIO.read(visible)));
        btnPaint.setIcon(new ImageIcon(ImageIO.read(paint)));
        btnTrash.setIcon(new ImageIcon(ImageIO.read(trash)));
        frame.getContentPane().add(btnPaint);
        frame.getContentPane().add(btnVisible);
        frame.getContentPane().add(btnTrash);
        frame.getContentPane().add(tree);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setUndecorated(true);
        frame.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
        frame.setSize(200, 200);
        frame.setVisible(true);

    }
    public void adicionarNoCamada(String nomePessoa){
        //DefaultTreeModel model = (DefaultTreeModel)tree.getModel();

        DefaultMutableTreeNode noCamada = new DefaultMutableTreeNode(nomePessoa);
        parent.add(noCamada);


    }
    public void adicionarLivro(String nomeCamada,Book feature) throws IOException{
        //tree.get
        DefaultMutableTreeNode node = null;
        Enumeration e = parent.breadthFirstEnumeration();
        while(e.hasMoreElements()){
            node = (DefaultMutableTreeNode) e.nextElement();
            if(nomeCamada.equals(node.getUserObject().toString())){
                node.add(new DefaultMutableTreeNode(feature));
                break;
            }
            else{

            }
        }
        tree.setCellEditor(new Render.ButtonCellEditor());
    }

}
类主应用程序

public class MainApp {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        Book b1 = new Book("The Book of Life");
        Book b2 = new Book ("The Book of Death");
        User u1 = new User("Bianca");
        JTreeOfObjects object = new JTreeOfObjects();
        object.initialize();
        object.adicionarNoCamada(u1.getNomeUser());
        object.adicionarLivro(u1.getNomeUser(), b1);
        object.adicionarLivro(u1.getNomeUser(), b2);

    }

}

任何帮助都将不胜感激。它不是重复的,因为我知道如何修复NullPointer异常(必须恢复对象)。我只是不知道在TreeCellEditor的情况下返回什么,如何返回其默认值。

您可能需要覆盖
CellEditor#isCellEditable(…)
CellEditor#getCellEditorValue()
,但我不确定这是否能满足您的要求

  @Override public boolean isCellEditable(EventObject e) {
    Object source = e.getSource();
    if (!(source instanceof JTree) || !(e instanceof MouseEvent)) {
      return false;
    }
    JTree tree = (JTree) source;
    Point p = ((MouseEvent) e).getPoint();
    Object node = tree.getPathForLocation(p.x, p.y).getLastPathComponent();
    if (!(node instanceof DefaultMutableTreeNode)) {
      return false;
    }
    Object userObject = ((DefaultMutableTreeNode) node).getUserObject();
    if (!(userObject instanceof Book)) {
      return false;
    }
    return super.isCellEditable(e);
  }

  @Override
  public Object getCellEditorValue() {
    return new Book(renderer.nomeRadar.getText());
  }
下面是一个简单的例子:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.tree.*;

public class MainApp2 {
  public JComponent makeUI() {
    JTree tree = new JTree(makeModel());
    tree.setEditable(true);
    tree.setCellRenderer(new NodeCellRenderer());
    tree.setCellEditor(new ButtonCellEditor());

    JPanel p = new JPanel(new BorderLayout());
    p.add(new JScrollPane(tree));
    return p;
  }
  private static DefaultMutableTreeNode makeModel() {
    Book b1 = new Book("The Book of Life");
    Book b2 = new Book("The Book of Death");
    User u1 = new User("Bianca");

    DefaultMutableTreeNode noCamada = new DefaultMutableTreeNode(u1);
    noCamada.add(new DefaultMutableTreeNode(b1));
    noCamada.add(new DefaultMutableTreeNode(b2));

    DefaultMutableTreeNode root = new DefaultMutableTreeNode("Library", true);
    root.add(noCamada);
    return root;
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame("Arvore de Navegacao");
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new MainApp2().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

class NodePanel extends JPanel {
  public final JLabel nomeRadar = new JLabel();
  public final JLabel btnVisible = new JLabel(new ColorIcon(Color.RED));
  public final JLabel btnPaint = new JLabel(new ColorIcon(Color.GREEN));
  public final JLabel btnTrash = new JLabel(new ColorIcon(Color.BLUE));
  protected NodePanel() {
    super(new FlowLayout(FlowLayout.LEADING, 5, 5));
    add(nomeRadar);
    add(btnVisible);
    add(btnPaint);
    add(btnTrash);
  }
}

class NodeCellRenderer implements TreeCellRenderer {
  private final DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
  private final NodePanel renderer = new NodePanel();

  @Override public Component getTreeCellRendererComponent(
      JTree tree, Object value, boolean selected, boolean expanded,
      boolean leaf, int row, boolean hasFocus) {
    Component returnValue = null;
    if (value instanceof DefaultMutableTreeNode) {
      Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
      if (userObject instanceof Book) {
        Book feature = (Book) userObject;
        renderer.nomeRadar.setText(feature.getTitulo());
        returnValue = renderer;
      }
    }
    if (returnValue == null) {
      returnValue = defaultRenderer.getTreeCellRendererComponent(
          tree, value, selected, expanded, leaf, row, hasFocus);
    }
    return returnValue;
  }
}

class ButtonCellEditor extends AbstractCellEditor implements TreeCellEditor {
  private final DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
  private final NodePanel renderer = new NodePanel();

  public ButtonCellEditor() {
    renderer.setBackground(Color.ORANGE);
    renderer.nomeRadar.addMouseListener(new MouseAdapter() {
      @Override public void mousePressed(MouseEvent e) {
        System.out.println("clicou no nome");
        stopCellEditing();
      }
    });
    renderer.btnVisible.addMouseListener(new MouseAdapter() {
      @Override public void mousePressed(MouseEvent e) {
        System.out.println("clicou no olho");
        stopCellEditing();
      }
    });
    renderer.btnPaint.addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        System.out.println("clicou no paint");
        stopCellEditing();
      }
    });
    renderer.btnTrash.addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        System.out.println("clicou no trash");
        stopCellEditing();
      }
    });
    renderer.addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        System.out.println("renderer");
        stopCellEditing();
      }
    });
  }

  @Override public boolean isCellEditable(EventObject e) {
    Object source = e.getSource();
    if (!(source instanceof JTree) || !(e instanceof MouseEvent)) {
      return false;
    }
    JTree tree = (JTree) source;
    Point p = ((MouseEvent) e).getPoint();
    TreePath path = tree.getPathForLocation(p.x, p.y);
    if (Objects.isNull(path)) {
      return false;
    }
    Object node = path.getLastPathComponent();
    if (!(node instanceof DefaultMutableTreeNode)) {
      return false;
    }
    Object userObject = ((DefaultMutableTreeNode) node).getUserObject();
    if (!(userObject instanceof Book)) {
      return false;
    }
    return super.isCellEditable(e);
  }

  @Override
  public Object getCellEditorValue() {
    return new Book(renderer.nomeRadar.getText());
  }

  @Override
  public Component getTreeCellEditorComponent(
      JTree tree, Object value, boolean isSelected, boolean expanded,
      boolean leaf, int row) {
    Component returnValue = null;
    if (value instanceof DefaultMutableTreeNode) {
      Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
      if (userObject instanceof Book) {
        Book feature = (Book) userObject;
        renderer.nomeRadar.setText(feature.getTitulo());
        returnValue = renderer;
      }
    }
    if (returnValue == null) {
      returnValue = defaultRenderer.getTreeCellRendererComponent(
          tree, value, isSelected, expanded, leaf, row, true);
    }
    return returnValue;
  }
}

class Book {
  String titulo;
  public String getTitulo() {
    return titulo;
  }
  public void setTitulo(String titulo) {
    this.titulo = titulo;
  }
  public Book(String titulo) {
    this.titulo = titulo;
  }
}

class User {
  String nomeUser;
  public String getNomeUser() {
    return nomeUser;
  }
  public void setNomeUser(String nomeUser) {
    this.nomeUser = nomeUser;
  }
  public User(String nome) {
    this.nomeUser = nome;
  }
  @Override public String toString() {
    return nomeUser;
  }
}

class ColorIcon implements Icon {
  private final Color color;
  protected ColorIcon(Color color) {
    this.color = color;
  }
  @Override public void paintIcon(Component c, Graphics g, int x, int y) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.translate(x, y);
    g2.setPaint(color);
    g2.fillRect(0, 0, getIconWidth(), getIconHeight());
    g2.dispose();
  }
  @Override public int getIconWidth() {
    return 16;
  }
  @Override public int getIconHeight() {
    return 16;
  }
}

这为解决这个问题提供了很多线索。我会做进一步的测试并更新答案。谢谢!!