java - 让 JTextField 自动调整大小
问题描述
我想显示一个由用户编辑的 JTextField 的二维数组。初始化(带文本)后,它们以良好的尺寸显示。当 Text 是 editet 时,它们不会调整大小。我将它们放在 JPanel 中,并在 JSrolePane 中使用 GridbagLayout。尝试“手动”调整它们的大小,因此在接收事件时调用 .setPrefferedSize,但很难获得不同 letterSize 的 TextLength 准确原因。所有的 JTextField 都显示在一行中,所以我可能对 GridBagConstraints 有什么误解。(以前用过 JTable 但不喜欢)。
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.weighty = 0.1;
c.weightx = 0.1;
c.fill = GridBagConstraints.BOTH;
for(int row=0; row<initText.length; row++) {
for(int col=0; col<initText[row].length; col++) {
jTextFields[row][col] = new JTextField(initText[row][col]);
jTextFields[row][col].getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent arg0) {
}
@Override
public void insertUpdate(DocumentEvent dE) {
int row = -1;
int col = -1;
for(int i=0; i<jTextFields.length; i++) {
for(int ii=0; ii<jTextFields[i].length; ii++) {
if(jTextFields[i][ii].getDocument()==dE.getDocument()) {
row=i;
col=ii;
break;
}
}
if(col!=-1) {
break;
}
}
//Tried it so to make resize "by Hand" but initalisation size is better
jTextFields[row][col].setPreferredSize(new Dimension(jTextFields[row][col].getText().length()*jTextFields[row][col].getPreferredSize().height, jTextFields[row][col].getPreferredSize().height));
System.out.println("insertUpdate in cell "+row+" "+col);
Main.gui.frame.repaint();
}
@Override
public void changedUpdate(DocumentEvent arg0) {
// TODO Auto-generated method stub
}
});
c.gridx = col;
c.gridy = row;
innerContentPane.add(jTextFields[row][col], c);
}
}
contentPane = new JScrollPane(innerContentPane);
frame.repaint();
解决方案
您不想继续重置组件的首选大小。让每个组件确定自己的首选尺寸。
相反,您想调用布局管理器,以便可以重新计算每个组件的大小并调整面板的布局。一种简单的方法是revalidate()
使用包含文本字段的面板。
我不喜欢具有多级循环代码的多级循环代码。您可以通过创建一个由所有文档共享的通用 DocumentListener 来简化您的代码。
此外,您的代码仅处理添加文本的情况。如果删除文本怎么办,文本字段的大小不应该缩小吗?
应用上述所有建议,逻辑将类似于:
// Create shared DocumentListener
DocumentListener dl = new DocumentListener()
{
@Override
public void removeUpdate(DocumentEvent de)
{
resizeTextField(de);
}
@Override
public void insertUpdate(DocumentEvent de)
{
resizeTextField(de);
}
@Override
public void changedUpdate(DocumentEvent de) {}
private void resizeTextField(DocumentEvent de)
{
innerContentPane.revalidate();
}
};
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
//c.weighty = 0.1;
//c.weightx = 0.1;
//c.fill = GridBagConstraints.BOTH;
// Create text fields and add listener to the Document
for(int row = 0; row < 3; row++)
{
for(int col = 0; col <3; col++)
{
JTextField textField = new JTextField("0");
textFields[row][col] = textField;
textField.getDocument().addDocumentListener(dl);
c.gridx = col;
c.gridy = row;
innerContentPane.add(textField, c);
}
}
注意 DocumentListener 也应该被创建为一个内部类,以使代码更加简洁。
所有的 JTextFields 都显示在一行中,所以我可能对 GridBagConstraints 有什么误解
JPanel 的默认布局管理器是 FlowLayout。如果要使用,则需要将布局设置为 GridBagLayout:
innerContentPane.setLayout( new GridBagLayout() );
GridBagConstraints c = new GridBagConstraints();
否则 GridBagConstraints 对 FlowLayout 没有任何意义。
阅读有关布局管理器的 Swing 教程部分以获取更多信息。
推荐阅读
- cmake - CMake:将共享库与具有相对路径的其他库链接以进行分发
- sql - 如何在 SQL Server 的不同表中使用筛选器
- php - 如何远程访问“Infomaniak”数据库服务器
- php - 将 Laravel 安装从子文件夹移动到子域而不破坏子文件夹 URL
- methods - 您可以将函数存储在变量中吗?
- jquery - 如何很好地居中垂直滑动文本
- c# - 用DES算法加密明文
- javascript - 如何在 sap.m.MessageBox onClose 方法中使用全局变量?
- angular - 由于模拟,在返回可观察对象之前调用可观察对象时如何在角度/茉莉花中测试可观察对象
- keras - 在keras中对多重损失求和