更改JTextField的按键时的大小(change the size of JTextField

2019-07-30 16:10发布

我必须为用户在keyPressed事件扩大JTextField的大小进入textfield.please文字给我一些想法如何实现这一目标?

提前致谢

Answer 1:

好吧,跳吧:-)

让我们假设问题是

如何调整JTextField的宽度总是适合其内容的宽度?

通常的合作者

  • 在它们的PREF大小,网络连接的FlowLayout大小及其子项的布局管理
  • JTextField中报告其PREF大小安装到内容
  • 自动调整大小神奇预期

简单的例子:

JTextField field = new JTextField("something");
JComponent parent = new JPanel(); // has FlowLayout by default
parent.add(field);
frame.add(parent);
// just to ensure it's bigger 
frame.setSize(400, 400);

键入......却没有任何反应:尺寸保持在初始大小。 这是惊喜:由于某种原因,该字段的自动验证简单doesnt't发生。 事实上,该领域在接收到变更通知手动重新验证(注:只有正确键入侦听这里是一个的DocumentListener)不改变该领域以及:

final JTextField field = new JTextField("something");
DocumentListener l = new DocumentListener() {

    private void updateField(JTextField field)
        // has no effect
        field.revalidate();
    }


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

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

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

field.getDocument().addDocumentListener(l);
JComponent parent = new JPanel(); // has FlowLayout by default
parent.add(field);
frame.add(parent);
// just to ensure it's bigger 
frame.setSize(400, 400);

@Gagandeep巴厘岛发现,这是一个需要重新验证

private void updateField(JTextField field) {
    field.getParent().revalidate();
}

意外的,所以接下来的问题是臭名昭著的,为什么 ? 在这里:为什么不无效泡了容器层次结构,直到它找到一个validateRoot添加? 答案是在API文档:

呼吁重新验证的是来自文本字段本身内将通过验证文本字段,除非文本字段包含在JViewport中,在这种情况下,该返回false来处理。

或者换句话说:它没有冒泡,因为该领域本身就是一个validateRoot添加。 这让其他的选项覆盖和无条件地返回false:

JTextField field = new JTextField("something") {

    @Override
    public boolean isValidateRoot() {
        return false;
    }
};
JComponent parent = new JPanel(); // has FlowLayout by default
parent.add(field);
frame.add(parent);
// just to ensure it's bigger 
frame.setSize(400, 400);

为此付出的代价,是滚动不工作 - 这是不是一个大问题,在这种背景下,作为文本总是适合进入该领域。 或者稍微更智能实现,而如果实际宽度小于把选项返回true。



Answer 2:

我能想到的最好的办法是一个加CaretListener到JTextField关注,并与在长度的变化Document ,你Increase/Decrease的说,列JTextField通过调用它的setColumns(...) ,这inturn将Increase/Decrease的尺寸JTextField

这里有一个例子向您展示,如何实现这一点:

import java.awt.*;
import javax.swing.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

public class JTextFieldColumnExample
{
    private int columns = 1;
    private JTextField tfield;

    private void displayGUI()
    {
        JFrame frame =  new JFrame("JTextField Columns Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JPanel contentPane = new JPanel();
        tfield = new JTextField();
        tfield.setColumns(columns);
        tfield.addCaretListener(new CaretListener()
        {
            public void caretUpdate(CaretEvent ce)
            {
                int len = tfield.getDocument().getLength();
                if (len > columns)
                    tfield.setColumns(++columns);
                else
                {
                    if (--columns != 0)
                        tfield.setColumns(columns);
                    else
                    {
                        columns = 1;
                        tfield.setColumns(columns);
                    }   
                }   
                contentPane.revalidate();
                contentPane.repaint();
            }
        });

        contentPane.add(tfield);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new JTextFieldColumnExample().displayGUI();
            }
        });
    }
}


Answer 3:

1) never to use KeyListener for JTextComponent, use DocumentListener, nothing else

2) you can to use FontMetrics, TextLayout, SwingUtilities

3) after resize you have to notify LayoutManager,

4) if is there only JTextField then to use pack() for Top-Level Container,

5) otherwise (in the case that there is more than one JPanel nested other JComponents) you have to re_layout whole Container with revalidate()and repaint() then

  • call pack() to the Top-Level Container if you want to resize continiously with its contens

  • don't call pack() to the Top-Level Container if you don't want to resize, but required usage of JScrollPane

6) in the case that value of String could be very long, then to use proper JTextComponent with supporting multiline output to the GUI, to use JTextArea (in JScrollPane) rather than plain JTextField



Answer 4:

取决于如果您使用的是布局管理与否。 如果没有,附加KeyListenerJTextFieldkeyRelease你需要计算的字符串(像素)的长度,并确定现场需要更新

addDocumentListener(new DocumentListener() {

    public void changedUpdate(DocumentEvent e) {
        updateField();
    }

    public void insertUpdate(DocumentEvent e) {
        updateField();
    }

    public void removeUpdate(DocumentEvent e) {
        updateField();
    }

    public void updateField() {

        FontMetrics fm = getFontMetrics(getFont());
        String text = getText();

        int length = fm.stringWidth(text);

        Dimension size = getPreferredSize();
        Insets insets = getInsets();
        if (length < min) {

            size.width = min;

        } else {

            size.width = length + (insets.left + insets.right);

        }

        setSize(size);
        invalidate();
        repaint();

    }

});

可能是一个更明智的解决方案可能是:

addDocumentListener(new DocumentListener() {

    public void changedUpdate(DocumentEvent e) {
        updateField();
    }

    public void insertUpdate(DocumentEvent e) {
        updateField();
    }

    public void removeUpdate(DocumentEvent e) {
        updateField();
    }

    public void updateField() {

        setColumns(getText().length());

    }

});

我还要注意些什么克列奥帕特拉&mKorbel不得不说。 虽然KeyListener似乎是一个不错的主意,有正义的许多情况的,它不会被通知- setText是主要的一个。



文章来源: change the size of JTextField on KeyPress