JTree编辑器未设置变量 [英] JTree Editor not setting variables

查看:81
本文介绍了JTree编辑器未设置变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为正在开发的Swing应用程序在JTree中使用Renderer,仅当树是叶对象并且由流布局组成时,才使用自定义渲染器.一个带有图像的空标签,一个JComboBox,最后是一个包含String的标签.

I am trying to use a Renderer in a JTree for a Swing application I am developing, the custom renderer is used only when the tree is a leaf object and is composed of a flow layout. An empty label with an image, a JComboBox and finally a label that contains a String.

首先,通过HazardRenderer.java中的getTreeCellRendererComponent()方法向Renderer传递字符串值,然后在HazardComboBox.java中使用setText()方法进行设置,然后,编辑器将选择选定的渲染器实例,并使用相同的setText()方法.

Initially the Renderer is passed a string value via the getTreeCellRendererComponent() method in HazardRenderer.java it is then set using the setText() method in HazardComboBox.java the editor then takes the selected renderer instance and sets text using the same setText() method.

但是,当在HazardEditor()中调用ItemListener时,标签文本将被清除.我可以验证这一点,因为注释掉侦听器可以解决此问题,但是我要求侦听器能够告诉应用程序可靠地完成了编辑器的编辑.这个问题有什么解决方案?下面的代码;

However the label text is cleared out when the ItemListener is called within HazardEditor(). I can verify this because commenting out the listener removes the issue, but I require a listener to be able to tell the application that editing the editor has finished reliably. What is the solution to this problem? Code below;

Main.java

Main.java

public class Main {
  public JComponent makeUI() {
    JTree tree = new JTree();
    tree.setEditable(true);
    tree.setRootVisible(false);
    tree.setCellRenderer(new HazardRenderer());
    tree.setCellEditor(new HazardEditor());
    //tree.setModel() excluded for brevity
    return new JScrollPane(tree);
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new Main().makeUI());
      f.pack();
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

HazardComboBox.java

HazardComboBox.java

public class HazardComboBox extends JPanel {
    private JLabel lblLabel = new JLabel("Placeholder");
    private JComboBox comboBox = new JComboBox(HazardSelection.values());

    public HazardComboBox() {
        setBackground(Color.WHITE);
        setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));

        JLabel label = new JLabel("");
        label.setIcon(new ImageIcon(HazardComboBox.class.getResource("/javax/swing/plaf/metal/icons/ocean/file.gif")));
        add(label);

        comboBox.setBorder(new EmptyBorder(2, 5, 2, 5));
        comboBox.setBackground(Color.WHITE);
        add(comboBox);

        lblLabel.setFont(new Font("Tahoma", Font.PLAIN, 11));
        add(lblLabel);
    }

    public JComboBox getComboBox() {
        return comboBox;
    }

    public JLabel getLabel() {
        return lblLabel;
    }

    public void setText(String name) {
        getLabel().setText(name);
    }

}

HazardRenderer.java

HazardRenderer.java

public class HazardRenderer implements TreeCellRenderer {
    private HazardComboBox leafRenderer = new HazardComboBox();
    private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();

    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object hazard, boolean selected, boolean expanded, boolean leaf,
            int row, boolean hasFocus) {
        if (leaf) {
            leafRenderer.setText(hazard.toString());
            return leafRenderer;
        }
        return nonLeafRenderer.getTreeCellRendererComponent(tree, hazard, selected, expanded, leaf, row, hasFocus);
    }

}

HazardEditor.java

HazardEditor.java

public class HazardEditor extends AbstractCellEditor implements TreeCellEditor {

    private HazardRenderer renderer = new HazardRenderer();
    private HazardComboBox component;
    private DefaultMutableTreeNode treeNode;
    //private ServerInfo info;
    //private JComboBox comboBox;
    private String val;

    @Override
    public Component getTreeCellEditorComponent(JTree tree, Object value,
            boolean isSelected, boolean expanded, boolean leaf, int row) {

        val = value.toString();
        component = (HazardComboBox)renderer.getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, true);

        if(leaf) {

            treeNode = (DefaultMutableTreeNode)value;
            component.setText(val);

            //info = (ServerInfo)treeNode.getUserObject();

            //comboBox = component.getComboBox();

            ItemListener itemListener = new ItemListener() {
                public void itemStateChanged(ItemEvent arg0) {
                    component.getComboBox().removeItemListener(this);
                    fireEditingStopped();
                }
            };

            component.getComboBox().addItemListener(itemListener);
        }

        return component;
    }

    @Override
    public Object getCellEditorValue() {
        //info.setChecked(comboBox.isSelected());
        //return info;
        return null;
    }

    @Override
    public boolean isCellEditable(EventObject event) {

        if(!(event instanceof MouseEvent)) return false;

        MouseEvent mouseEvent = (MouseEvent)event;
        JTree tree = (JTree)event.getSource();

        TreePath path = tree.getPathForLocation(mouseEvent.getX(), mouseEvent.getY());

        if(path == null) return false;

        Object lastComponent = path.getLastPathComponent();

        if(lastComponent == null) return false;

        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)lastComponent;

        return treeNode.isLeaf();
    }

}

HazardSelection.java

HazardSelection.java

public enum HazardSelection {
    NOTCONSIDERED("Not Considered"), NOTAPPLICABLE("Not Applicable"), CONSIDERED("Considered"), HAZARD("Hazard");

    private String name;

    private HazardSelection (String n) {
        name = n;
    }

    @Override
    public String toString() {
        return name;
    }
}

推荐答案

问题在于有关覆盖HazardEditor.java中的getCellEditorValue()方法.您已按照以下步骤进行操作:

The problem is about overriding the getCellEditorValue() method in HazardEditor.java. You have done this as follow:

@Override
public Object getCellEditorValue() {
    //info.setChecked(comboBox.isSelected());
    //return info;
    return null;
}

因此,您将返回null,则您的Renderer会将null呈现为标签的文本.

So you are returning null, then your Renderer renders null as the label's text.

您可以按以下步骤纠正它:

You can correct it as follow:

@Override
public Object getCellEditorValue() {
    return component.getComboBox().getSelectedItem();
}

祝你好运.

这篇关于JTree编辑器未设置变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆