【问题标题】:Automatically re-sizing a component within a GridBagLayout自动调整 GridBagLayout 中组件的大小
【发布时间】:2015-07-21 03:47:15
【问题描述】:

在这段代码中,我在GridBagLayout 中有一个面板,其中包含一个JLabel 和一个JTextField

import java.awt.*;
import javax.swing.*;

public class Simple
{
    JFrame simpleWindow = new JFrame("Simple MCVE");

    JPanel  simplePanel = new JPanel();

    JLabel lblSimple;
    JTextField txtSimple;

    public void numberConvertGUI()
    {
        simpleWindow.setBounds(10, 10, 420, 80);

        simpleWindow.setMinimumSize(new Dimension(420, 80));

        simpleWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        simpleWindow.setLayout(new GridLayout(1,1));

        createSimplePanel();

        simpleWindow.getContentPane().add(simplePanel);

        simpleWindow.setVisible(true);
    }

    public void createSimplePanel()
    {
        simplePanel.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();

        lblSimple = new JLabel();
        c.weightx = 0.0;
        c.weighty = 1.0;
        c.fill = GridBagConstraints.BOTH;
        c.insets = new Insets(0,2,0,2);
        c.gridx = 0;
        c.gridy = 0;
        c.ipady = 0;
        lblSimple.setText("Next to me is a JTextField: ");
        lblSimple.setHorizontalAlignment(JLabel.RIGHT);
        simplePanel.add(lblSimple, c);

        txtSimple = new JTextField();
        c.weightx = 0.5;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.ipady = 5;
        c.gridx = 1;
        c.gridy = 0;
        c.insets = new Insets(0,2,0,2);
        simplePanel.add(txtSimple, c);
    }

    public static void main(String[] args)
    {
        Simple s = new Simple();
        s.numberConvertGUI();
    }
}

我希望能够根据输入的数据量自动调整文本字段的大小。例如,当字符串“如何在到达它的边缘时自动调整这个组件的大小?”在 JTextField 中输入它看起来像这样。

但是,当我输入字符串时,我希望 JTextBoxJFrame 自动重新调整大小以生成看起来有点像这样的东西。

唯一的问题是我不知道有什么可以让我这样做。对于完成这项任务的任何帮助,我将不胜感激。

编辑

当组件自动调整大小时,我还希望该组件有一个最大大小。这样,当输入更多数据时,组件将不会不断调整某人计算机显示器的大小

【问题讨论】:

  • 将 DocumentListener 添加到 JTextField,计算 JTextField 中的字符串长度或列数,以获取 JTextField 的 getPreferredSIze 或 Dimension,然后调用重新验证并重新绘制到 JFrame(也许这两个通知器必须包装到 invokeLater 中)

标签: java swing layout-manager gridbaglayout autoresize


【解决方案1】:

Swing 中没有提供执行此操作的内置功能。

您需要做的是在文本字段后面的文档中添加DocumentListener,并在添加或删除文本时收到通知。

然后您需要为文本字段计算所需的新大小(这本身可能很棘手 - 您可能需要使用 FontMetrics)并重新调整控件的大小以匹配。此时您可以轻松实现的最大尺寸,只需查看您要调整的尺寸与您希望允许的最大尺寸相比。

有关DocumentListener 的信息,请参见此处: https://docs.oracle.com/javase/tutorial/uiswing/events/documentlistener.html

有关FontMetrics 的信息,请参见此处: https://docs.oracle.com/javase/tutorial/2d/text/measuringtext.html

【讨论】:

  • 谢谢你,我刚刚使用 fontmetrics 和文档侦听器让它工作
【解决方案2】:

将我的布局更改为MigLayout 后,我设法让我的代码按照我的意愿去做。对于阅读本文并对如何执行此操作感兴趣的任何人,请参阅下面的代码。

import java.awt.*;
import javax.swing.*;
import java.lang.Object.*;
import javax.swing.event.*;
import javax.swing.text.*;
import net.miginfocom.swing.MigLayout;

public class Simple
{
    JFrame simpleWindow = new JFrame("Simple MCVE");

    JPanel  simplePanel = new JPanel();

    JLabel lblTitle;
    JLabel lblSimple;
    JTextField txtSimple;

    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    String []fontFamilies = ge.getAvailableFontFamilyNames();

    int adv;
    int widthOftxtSimple;
    int i;
    int xDimension;

    public static int GetScreenWorkingWidth() 
    {
        return java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width;
    }

    int maxSize = GetScreenWorkingWidth()-50;

    public void numberConvertGUI()
    {
        simpleWindow.setBounds(10, 10, 800, 100);

        simpleWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        simpleWindow.setResizable(false);

        simpleWindow.setLayout(new GridLayout(1,1));

        createSimplePanel();

        simpleWindow.getContentPane().add(simplePanel);

        simpleWindow.setVisible(true);
    }

    public void createSimplePanel()
    {
        MigLayout layout = new MigLayout("" , "[][grow]");
        simplePanel.setLayout(layout);

        lblTitle = new JLabel();
        lblTitle.setText("This is a Title");
        simplePanel.add(lblTitle, "wrap, align center,span 2");

        lblSimple = new JLabel();
        lblSimple.setText("Next to me is a JTextField: ");
        simplePanel.add(lblSimple);

        String sMPMConstraints = "width 615::"+maxSize;
        txtSimple = new JTextField();
        simplePanel.add(txtSimple, "grow, "+sMPMConstraints);

        myDocumentListener();
    }

    public void myDocumentListener()
    {
        Document doc = txtSimple.getDocument(); 
        DocumentListener listener = new DocumentListener()
        {
            @Override
            public void insertUpdate(DocumentEvent e)
            {
                System.out.println("Insert");
                String simpleString = txtSimple.getText();
                Graphics graphics = txtSimple.getGraphics();
                Font test = txtSimple.getFont();
                FontMetrics metrics = graphics.getFontMetrics(test);
                adv = metrics.stringWidth(simpleString);
                System.out.println("The width of the string is: "+adv);
                widthOftxtSimple = txtSimple.getWidth();
                System.out.println("The width of the JTextField is: "+widthOftxtSimple);
                if(xDimension<maxSize)
                {
                    System.out.println("The x dimension is shorter than the max size which is: "+maxSize);
                    if(widthOftxtSimple-20<adv)
                    {
                        i = 615-20-adv; //615 in this case is the original length of the text box
                        //change for different text boxes
                        System.out.println("Value of i is: "+i);
                        xDimension = 800-i;
                        System.out.println("Value of xDimension is: "+xDimension);
                        simpleWindow.setBounds(10, 10, xDimension, 100);
                    }
                }

                else
                {
                    System.out.println("The x dimension is longer than the max size which is: "+maxSize);
                    simpleWindow.setBounds(10, 10, maxSize, 100);
                    String lastCharSize = simpleString.charAt(simpleString.length() - 1)+"";
                    int adv2 = metrics.stringWidth(lastCharSize);
                    xDimension = xDimension+adv2;
                }
            }

            @Override
            public void removeUpdate(DocumentEvent e)
            {
                System.out.println("Remove");
                String simpleString = txtSimple.getText();
                Graphics graphics = txtSimple.getGraphics();
                Font test = txtSimple.getFont();
                FontMetrics metrics = graphics.getFontMetrics(test);
                widthOftxtSimple = txtSimple.getWidth();
                System.out.println("The width of the JTextField is: "+widthOftxtSimple);
                System.out.println("Value of xDimension is: "+xDimension);
                if(xDimension<maxSize)
                {
                    if(xDimension>800) //Original length of the JFrame
                    {
                        System.out.println("last char = " + simpleString.charAt(simpleString.length() - 1));
                        String lastCharSize = simpleString.charAt(simpleString.length() - 1)+"";
                        int adv2 = metrics.stringWidth(lastCharSize);
                        int newX = xDimension-adv2;
                        simpleWindow.setBounds(10, 10, newX, 100);
                        xDimension = newX;
                        if(xDimension<800)
                        {
                            simpleWindow.setBounds(10, 10, 800, 100);
                        }
                    }
                }

                else
                {
                    System.out.println("last char = " + simpleString.charAt(simpleString.length() - 1));
                    String lastCharSize = simpleString.charAt(simpleString.length() - 1)+"";
                    int adv2 = metrics.stringWidth(lastCharSize);
                    int new3 = xDimension-adv2;
                    System.out.println("This is the else statement");
                    System.out.println("The new `xDimension` will be:"+ new3);
                    xDimension = new3;
                }
            }

            @Override
            public void changedUpdate(DocumentEvent e)
            {
                System.out.println("Change");
            }
        };
        doc.addDocumentListener(listener);
    }

    public static void main(String[] args)
    {
        Simple s = new Simple();
        s.numberConvertGUI();
    }
}

要正确编译,您需要下载 MigLayout package

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    • 2012-03-26
    • 2014-11-05
    • 2014-02-20
    相关资源
    最近更新 更多