6

JTree のエディターおよびレンダラーとして、いくつかの JLabels と JTextFields を持つ JPanel を使用しています。

ユーザーは任意の JTextField をクリックしてテキストを変更できます。すべて正常に動作します。

私が見逃しているのは、ユーザーが入力しているときに JTextField を動的にサイズ変更 (拡大) する方法だけです。

問題を説明する小さなサンプル プログラムの下。「色」をクリックして、追加の文字を入力します。JTextField は予想どおりのサイズを維持しますが、テキストに合わせて拡大縮小したいと考えています。

さまざまなレイアウト マネージャーを試し、JTextField と JPanel の preferredSize を計算し、invalidate() と JPanel と Tree などを呼び出しましたが、成功しませんでした。

何か案は?

import java.awt.Component;
import java.util.EventObject;

import javax.swing.AbstractCellEditor;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;

public class Tree {

    public static void main(final String[] args) {
        new Tree().grow();
    }

    private void grow() {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JTree tree = new JTree();
        tree.setEditable(true);
        tree.setCellRenderer(new SomeTreeCellRenderer());
        tree.setCellEditor(new SomeTreeCellRenderer());

        frame.add(new JScrollPane(tree));

        frame.pack();
        frame.setSize(400, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private class SomeTreeCellRenderer extends AbstractCellEditor implements 
            TreeCellRenderer, TreeCellEditor {

        @Override
        public Object getCellEditorValue() {
            return null;
        }

        @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) {

            final JPanel panel = new JPanel();
            final BoxLayout layout = new BoxLayout(panel, BoxLayout.X_AXIS);
            panel.setLayout(layout);

            panel.add(new JLabel("Some text: "));
            panel.add(new JTextArea(String.valueOf(value)));

            return panel;
        }

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

            return getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, false);
        }

    }

}
4

2 に答える 2

3

何が起こっているのかというと、あなたを所有しているコンテナにpanelはレイアウトマネージャが割り当てられていpanelないので、テキスト領域のサイズが変更されているときに、はサイズ変更されていません。これに対する簡単な修正は、テキスト領域のサイズが変更されるたびにパネルのサイズを設定することです。したがって、これを直接行う代わりに:

        panel.add(new JTextArea(String.valueOf(value)));

あなたはこれを行うことができます:

        JTextArea ta = new JTextArea(String.valueOf(value));
        ta.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) {}
        });

        panel.add(ta);
于 2012-08-02T16:30:57.533 に答える
3

便宜上、JTextArea の代わりに JTextField を使用するソリューションを、次の情報を使用して受け入れられたソリューションと同様に示します

final JPanel panel = new JPanel();
final BoxLayout layout = new BoxLayout(panel, BoxLayout.X_AXIS);
panel.setLayout(layout);

panel.add(new JLabel("Some text: "));

final JTextField field = new JTextField(String.valueOf(value));
final DocumentListener documentListener = new DocumentListener() {

    private void updatePanel() {
        panel.revalidate();
        panel.setSize(panel.getPreferredSize());
    }

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

    @Override
    public void insertUpdate(DocumentEvent e) {
        updatePanel();
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
    }
};

field.getDocument().addDocumentListener(documentListener);

panel.add(field);
于 2012-08-02T17:20:57.507 に答える