java - 可滚动 JTextField 的大小问题

标签 java swing jscrollpane jtextfield scrollable

我有一个包含很多文本字段的表单,其中一些文本字段可能包含很长的字符串。为了让它工作,我使用以下代码使这些文本字段可滚动:

JScrollPane scroll = new JScrollPane(textField);
scroll.setPreferredSize(new Dimension((int)textField.getPreferredSize().getWidth(), (int)textField.getPreferredSize().getHeight() * 2));

然后我使用 GridBagLayout 将滚动条放入我的表单中。

我的示例中的第二行是滚动条显示所必需的。但它有缺点。当我调整窗口大小以适应文本字段中的整个文本时,滚动消失,只留下比其他文本字段高两倍的文本字段,这看起来很荒谬。 我怎样才能使这一切正常工作并在滚动条隐藏后显示正常大小的文本字段?

编辑:

您可以使用以下作为演示代码来重现该问题:

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

public class ScrollTextDemo extends JFrame{

public  ScrollTextDemo(){
    super();
    this.setPreferredSize(new Dimension(500, 300));
    JPanel panel = new JPanel();
    panel.setLayout(new GridBagLayout());
    JTextField textField = new JTextField("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
    textField.setCursor(new Cursor(0));
    textField.setEditable(false);
    JScrollPane scroll = new JScrollPane(textField);
    scroll.setPreferredSize(new Dimension(70, 40) );
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridx = 1;
    gbc.gridy = 1;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.weightx = 0.5;
    gbc.insets = new Insets(5, 5, 0, 5);
    panel.add(scroll,gbc);
    //let's add one more text field without scroll bar to compare
    JTextField textField2 = new JTextField("abc");
    gbc = new GridBagConstraints();
    gbc.gridx = 1;
    gbc.gridy = 2;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.weightx = 0.5;
    gbc.insets = new Insets(5, 5, 0, 5);
    panel.add(textField2,gbc);
    this.add(panel);
} 

public static void main(String args[]){
    ScrollTextDemo demo = new ScrollTextDemo();
    demo.pack();
    demo.setVisible(true);
}
}

最佳答案

为此,在没有好的SSCCE ,我认为你没有提供任何用于填充的约束,它用于

当组件的显示区域大于组件请求的大小时使用,以确定是否以及如何调整组件的大小。有效值(定义为 GridBagConstraints 常量)包括 NONE(默认值)、HORIZONTAL(使组件足够宽以水平填充其显示区域,但不更改其高度)、VERTICAL(使组件足够高以垂直填充其显示区域,但不要改变它的宽度)和两者(让组件完全填满它的显示区域)。

所以你必须在你的 GridBagConstraints 中添加这样的东西

constraintsGridBag.fill = GridBagConstraints.HORIZONTAL;

这只会允许它水平扩展,而不是双向扩展。

** 编辑:至于添加的代码**

切勿为 Swing 中的任何组件指定 setPreferredSize(...)。让您正在使用的布局管理器来处理。删除所有 setPreferredSize(...) 东西,将让它在调整大小时保持正常大小。

*编辑 2:*

代码告诉你我在说什么:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;

import java.awt.event.*;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

public class GridBagTest extends JFrame
{
    private JPanel topPanel;
    private JPanel bottomPanel;

    public GridBagTest()
    {
        setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();      
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        //gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 1.0;
        gbc.weighty = 0.8;

        // Setting TOP PANEL.
        topPanel  = new JPanel();
        topPanel.setLayout(new GridBagLayout());
        GridBagConstraints constraintsTopPanel = new GridBagConstraints();
        constraintsTopPanel.gridwidth = 2; // Specifies that this component will take two columns.
        constraintsTopPanel.gridheight = 1; // specifies that the component will take one row.
        /*
         *  fill with HORIZONTAL, means the component upon resize, will
         * only expand along the X-Axis.
         */
        constraintsTopPanel.fill = GridBagConstraints.NONE;
        constraintsTopPanel.insets = new Insets(5, 5, 5, 5);
        constraintsTopPanel.ipadx = 2;
        constraintsTopPanel.ipady = 2;
        constraintsTopPanel.weightx = 0.3;
        constraintsTopPanel.weighty = 0.2;

        constraintsTopPanel.gridx = 0;
        constraintsTopPanel.gridy = 0;
        JTextField tfield1 = new JTextField("kajslkajfkl dsjlafj lksdj akljsd lfkajflkdj lkaj flkdjalk jflkaj lkfdsj salkj flkaj flkja dslkfjal ksjdflka jlfjd aflsdj", 10);
        topPanel.add(tfield1, constraintsTopPanel);

        constraintsTopPanel.gridx = 2;
        constraintsTopPanel.gridy = 0;
        final JTextField tfield2 = new JTextField("kajslkajfkl dsjlafj lksdj akljsd lfkajflkdj lkaj flkdjalk jflkaj lkfdsj salkj flkaj flkja dslkfjal ksjdflka jlfjd aflsdj", 10);              
        topPanel.add(tfield2, constraintsTopPanel);

        constraintsTopPanel.gridx = 4;
        constraintsTopPanel.gridy = 0;
        JTextField tfield3 = new JTextField("kajslkajfkl dsjlafj lksdj akljsd lfkajflkdj lkaj flkdjalk jflkaj lkfdsj salkj flkaj flkja dslkfjal ksjdflka jlfjd aflsdj", 10);
        topPanel.add(tfield3, constraintsTopPanel);

        topPanel.setBackground(Color.WHITE);
        add(topPanel, gbc);

        constraintsTopPanel.gridx = 0;
        constraintsTopPanel.gridy = 2;
        constraintsTopPanel.gridwidth = 6; // Specifies that this component will take two columns.
        constraintsTopPanel.gridheight = 1; // specifies that the component will take one row.

        JButton button = new JButton("REMOVE");
        button.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                topPanel.remove(tfield2);
                topPanel.revalidate();
                topPanel.repaint();
            }
        });
        topPanel.add(button, constraintsTopPanel);

        //Setting BOTTOM PANEL.
        bottomPanel = new JPanel();
        bottomPanel.setLayout(new BorderLayout());
        bottomPanel.setBackground(Color.DARK_GRAY);     
        JLabel label3 = new JLabel("I am a new JLABEL for the bottom JPanel", JLabel.CENTER);
        label3.setForeground(Color.WHITE);
        bottomPanel.add(label3, BorderLayout.CENTER);       
        gbc.weighty = 0.2;      
        add(bottomPanel, gbc);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        pack();
        setVisible(true);
    }

    public static void main(String... args)
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    new GridBagTest();
                }
            });
    }
}

关于java - 可滚动 JTextField 的大小问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9492214/

相关文章:

java - 如何在音频均衡器中添加立体声、高音选项?

java.lang.VerifyError 使用 kotlin 创建 gradle 任务

Java-找不到符号(swing)

java - 在 JPanel 上绘制多个 JComponent 不起作用

javascript - 如何使终端可滚动?

java - 我的 JScrollPane 不会在 JPanel 上垂直滚动

java - 多个 JLabel 不打印在屏幕上

java - jack 森非法参数异常 : Can not handle managed/back reference

java - 在java swing中同步滚动N个jtables

javascript - Jscrollpane 分页