我正在使用带有一些JLabel和JTextFields的JPanel作为JTree中的编辑器和渲染器。
用户可以单击任何JTextField并修改文本。一切正常。
我所缺少的是如何在用户输入时动态调整(增长)JTextField。
下面是一个说明问题的小样本程序。点击ie" colors"并输入一些额外的字符。 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);
}
}
}
答案 0 :(得分: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);
答案 1 :(得分:3)
为方便起见,这里使用JTextField而不是类似于接受的解决方案的JTextArea的解决方案,使用以下信息:change the size of JTextField on KeyPress
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);