【问题标题】:Rendering a JTree leaf with a JPanel containing an editable JTextArea使用包含可编辑 JTextArea 的 JPanel 渲染 JTree 叶
【发布时间】:2012-09-02 18:34:12
【问题描述】:

我正在尝试渲染一个 JTree 叶以具有一个包含可编辑 JTextArea 的 JPanel,以便用户可以输入文本并能够在添加文本时向下滚动,

并且还使用包装器来限制文本的宽度,使其向下延伸以允许更多空间而不是左右滚动。

到目前为止,我已经实现了以下内容,但它看起来很奇怪,当我运行代码时,好像有两个叶子,默认一个和渲染上。任何类型的帮助都将受到高度赞赏。

我只想知道我想做的事情是否可以实现,如果不能,我可以在哪里修改。

我不想更改图标,只更改叶子。

import java.awt.Component;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ItemEvent;
import java.util.EventObject;
import javax.swing.*;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;

/**
 *
 * @author Razaractor
 */
class LeafRenderer extends AbstractCellEditor implements
        TreeCellRenderer, TreeCellEditor {

    //Text area to be place on JPanel
    JTextArea text = new JTextArea();
    DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();

    @Override
    public Object getCellEditorValue() {
        return text.getText();
    }

    @Override
    public boolean isCellEditable(final EventObject event) {
        return true;
    }

    @Override
    public Component getTreeCellRendererComponent(
            final JTree tree, final Object value,
            final boolean selected,
            final boolean expanded,
            final boolean leaf,
            final int row,
            final boolean hasFocus) {
        //Default leaf
        Component render = nonLeafRenderer.getTreeCellRendererComponent(tree,
                value, selected, expanded, leaf, row, hasFocus);
        if (selected && leaf) {
            final JPanel panel = new JPanel();
            BoxLayout layout = new BoxLayout(panel, BoxLayout.X_AXIS);
            panel.setLayout(layout);
            text.setColumns(20);
            text.setLineWrap(true);
            text.setRows(5);
            text.setWrapStyleWord(true);
            text = new JTextArea(String.valueOf(value));
            text.addComponentListener(new ComponentListener() {

                @Override
                public void componentResized(ComponentEvent e) {
                    panel.setSize(panel.getPreferredSize());
                }

                @Override
                public void componentShown(ComponentEvent e) {
                }

                @Override
                public void componentMoved(ComponentEvent e) {
                }

                @Override
                public void componentHidden(ComponentEvent e) {
                }
            });
            JScrollPane scroll = new JScrollPane(text);
            panel.add(scroll);
            render = panel;
            return panel;
        }
        return render;
    }

    @Override
    public Component getTreeCellEditorComponent(
            final JTree tree,
            final Object value,
            final boolean isSelected,
            final boolean expanded,
            final boolean leaf,
            final int row) {
        Component editor = nonLeafRenderer.getTreeCellRendererComponent(tree,
                value, true, expanded, leaf, row, true);
        final JPanel p = new JPanel();
        if (editor instanceof JPanel) {
            editor = (JPanel) editor;
        }
        return editor;
    }

    public void itemStateChanged(ItemEvent itemEvent) {
        if (stopCellEditing()) {
            fireEditingStopped();
        }
    }
}

【问题讨论】:

  • 有三个选择 1) 发布关于 JTree 的问题,然后您可以继续使用 Renderer 和 Editor,2) 发布 SSCCE 演示您的问题 3) 顺其自然,然后我们也一样,但也许是雷声:-)
  • @ Keppil,感谢您的建议,我刚刚设法发布了它。 @ mKorbel,我会选择选项 2。:^D
  • 另见TablePopupEditor,它实现了TreeCellEditor

标签: java swing editor jtree jtextarea


【解决方案1】:

我不知道您真正想要实现什么,但请尝试这些更改。

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ItemEvent;
import java.util.EventObject;
import javax.swing.*;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;

/**
 *
 * @author Razaractor
 */
class LeafRenderer extends AbstractCellEditor implements
        TreeCellRenderer, TreeCellEditor {

    //Text area to be place on JPanel
    JTextArea text = new JTextArea();
    DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();

    @Override
    public Object getCellEditorValue() {
        return text.getText();
    }

    @Override
    public boolean isCellEditable(final EventObject event) {
        return true;
    }

    @Override
    public Component getTreeCellRendererComponent(
            final JTree tree, final Object value,
            final boolean selected,
            final boolean expanded,
            final boolean leaf,
            final int row,
            final boolean hasFocus) {
        //Default leaf
        Component render = nonLeafRenderer.getTreeCellRendererComponent(tree,
                value, selected, expanded, leaf, row, hasFocus);
        if (selected && leaf) {
            final JPanel panel = new JPanel();
            BoxLayout layout = new BoxLayout(panel, BoxLayout.X_AXIS);
            panel.setLayout(layout);
            //Changed code
            //moved from
            text = new JTextArea(String.valueOf(value));
            text.setColumns(20);
            text.setLineWrap(true);
            text.setRows(5);
            text.setWrapStyleWord(true);
            //here. You were creating just ordinary JTextArea.
            text.addComponentListener(new ComponentListener() {

                @Override
                public void componentResized(ComponentEvent e) {
                    panel.setSize(panel.getPreferredSize());
                }

                @Override
                public void componentShown(ComponentEvent e) {
                }

                @Override
                public void componentMoved(ComponentEvent e) {
                }

                @Override
                public void componentHidden(ComponentEvent e) {
                }
            });
            JScrollPane scroll = new JScrollPane(text);
            //changed Code
            //if you want to hide scrollbars uncomment one of these
            //scroll.getVerticalScrollBar().setPreferredSize(new Dimension(0, 0));
            //scroll.getHorizontalScrollBar().setPreferredSize(new Dimension(0, 0));
            panel.add(scroll);
            render = panel;
            return panel;
        }
        return render;
    }

    @Override
    public Component getTreeCellEditorComponent(
            final JTree tree,
            final Object value,
            final boolean isSelected,
            final boolean expanded,
            final boolean leaf,
            final int row) {
        Component editor = nonLeafRenderer.getTreeCellRendererComponent(tree,
                value, true, expanded, leaf, row, true);
        final JPanel p = new JPanel();
        if (editor instanceof JPanel) {
            editor = (JPanel) editor;
        }
        return editor;
    }

    public void itemStateChanged(ItemEvent itemEvent) {
        if (stopCellEditing()) {
            fireEditingStopped();
        }
    }
}

【讨论】:

  • 我的目标是让 JPanel 与 JTextArea 替换 JTree 具有的默认可编辑叶子。所以我不确定我正在实施的实际上是实现我想要的东西所需要的。并且感谢它现在拥有它的滚动条校正。我想返回一个包含 JTextArea 的 JPanel,以允许用户通过结束行来限制文本上下滚动,这样它就不会是长的水平线。
  • 我只是设法摆脱了默认的叶子外观,我删除了选定的条件,现在只有叶子。现在我有了我想要的叶子喜欢的东西,就像我发布的第二张图片一样,我在必须在 JTextArea 中输入文本时遇到问题,因此它通过使用包装器来结束行,但它仍然使用默认的编辑器输入样式,即它不会结束行。我该怎么办?谢谢
  • 尝试在面板中设置 JTree 可编辑 (jtree.setEditable(true)) 和 JTextArea 可聚焦 (text.setFocusable(true))
  • 我已经将 JTree 设置为可编辑,我尝试了 setFocusable(true) 但它仍然没有响应,我可能会尝试 requestFocus(),thanx Riso
猜你喜欢
  • 1970-01-01
  • 2015-10-29
  • 2011-10-31
  • 2020-07-18
  • 1970-01-01
  • 1970-01-01
  • 2011-01-04
  • 1970-01-01
  • 2018-03-17
相关资源
最近更新 更多