1

サイズが可変JTreeTreeCellEditorがあります (エディター内の 1 つのコンポーネントで値を選択すると、追加のコンポーネントが表示されます)。エディターが最初に表示されるときは、正しいサイズです。ただし、優先サイズを大きくする追加のコンポーネントが表示される場合、エディターは拡大されず、その内容はクリップされます。

エディターのサイズを設定するとサイズが変更されることがわかりましたが、推奨サイズが変更されたときに自動的にサイズを変更する方法が必要です。

JTextFieldを使用してエディタをシミュレートする例を次に示します。ボタンをクリックすると、テキスト フィールドの優先サイズが大きくなりますが、私のエディターでは、これはエディター コンポーネント内からトリガーされ、ツリー セル エディター以外のコンテキストで使用されるため、サイズを明示的に設定したくありません。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JTree;

public class Test extends JFrame {
    @Override
    public void setVisible(boolean b) {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JTree tree = new JTree();
        tree.setEditable(true);
        final JTextField field = new JTextField();
        tree.setCellEditor(new DefaultCellEditor(field));

        JButton button = new JButton(new AbstractAction("Make CellEditor Wider") {
            @Override
            public void actionPerformed(ActionEvent e) {
                Dimension size = field.getPreferredSize();
                size.width += 50;
                field.setPreferredSize(size);
                field.setSize(size); // This forces the tree to show the correct size
            }
        });

        setLayout(new BorderLayout());
        add(tree, BorderLayout.CENTER);
        add(button, BorderLayout.SOUTH);
        setSize(500, 500);
        super.setVisible(b);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test().setVisible(true);
            }
        });
    }
}
4

1 に答える 1

1

基本的に、ツリー (より正確にはその ui-delegate) は、同じノードのレンダラー コンポーネントとは異なるサイズのエディター コンポーネントを処理できますが、単一ノードの編集プロセスの存続期間中にサイズが変更されないことを前提としています。 . UI

  • 編集開始時のエディタ コンポーネントのサイズと位置
  • エディター コンポーネントの下のノード位置の更新をトリガーします (必要な場合)。

エディターの存続期間中の変更の場合、カスタム コントローラーはそれらの変更 (および/またはそれらをトリガーするもの) をリッスンしてから、両方のタスクをリッスンする必要があります。以下は、コンテンツに応じた prefSize を持つ textField と、documentChanges をリッスンして必要に応じて動作するコントローラーです。

// both height and width depend on content
final JTextField field = new JTextField() {

    @Override
    public Dimension getPreferredSize() {
        Dimension dim = super.getPreferredSize();
        int length = getText().length();
        dim.width += length * 10;
        dim.height += length * 2;
        return dim;
    }

};
// controller listens to changes to dynamically takes over the ui's job 
DocumentListener l = new DocumentListener() {

    protected void validateEditor(final JTextField field) {
        // the selectionModel's rowMapper is-a AbstractLayoutCache
        // BEWARE: implementation detail!
        TreeSelectionModel model = tree.getSelectionModel();
        // invalidate all cached node sizes/locations
        ((AbstractLayoutCache) model.getRowMapper()).invalidateSizes();
        // just a fancy cover method for revalidate/repaint
        tree.treeDidChange();
        // manually set the component's size
        field.setSize(field.getPreferredSize());
    }
    @Override
    public void insertUpdate(DocumentEvent e) {
        validateEditor(field);
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        validateEditor(field);
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
    }

};
field.getDocument().addDocumentListener(l);
于 2013-10-11T09:32:56.723 に答える