我应该使用哪些设置来解决此GridBagLayout调整大小问题?

时间:2016-01-19 02:33:18

标签: java swing jpanel jscrollpane gridbaglayout

我一直在寻找并尝试解决我在GridBagLayout调整大小时遇到​​的问题,但无济于事。问题是:

  1. 我向下拖动JDialog窗口的底部使其更高;搜索面板(下面屏幕截图中的面板)不断增加,只需添加其内容不需要的空白区域(我不希望这个浪费的空间远离其下方的滚动表)。

  2. 如果我移动窗口的右侧使其稍微变窄,即使我的屏幕和窗口显示其全高,滚动面板也会变得太短;出现一个垂直滚动条(我不喜欢垂直滚动的面板,只是水平滚动。)

  3. 我的JDialog保存在右上角部分的下方,使用下面的布局管理器和约束:

    JPanel      level 1         uses GridBagLayout Setting 1 (see below)
    JScrollPane level 2         uses GridBagLayout Setting 1  
    JPanel      level 3         uses GridBagLayout Setting 2
    JPanel      level 4         uses GridBagLayout Setting 2
    JPanel      level 5         uses GridBagLayout Setting 2
    JPanel      level 5         uses GridBagLayout Setting 2
    

    GridBagLayout.GridBagConstraints(c)

    设置1:

    c.fill = GridBagConstraints.BOTH;
    c.weightx = 99.0;
    c.weighty = 99.0;
    

    设置2:

    c.fill = GridBagConstraints.NONE;
    c.weightx = 1.0;
    c.weighty = 1.0;
    

    最初,如果我不使用JDialog,这是我的JScrollPane

    enter image description here

    如果我拖动窗口使其变大,JPanel的大小(这是我在使用JScrollPane之前使用它来使其水平滚动)仍保持原样。我想实现相同的行为,只是我想让它可以水平滚动。

    我应该使用什么布局管理器来解决此调整大小问题?如果我必须真正使用GridBagLayout,我应该使用哪些约束/设置?我非常感谢任何建议。谢谢!

    更新1 ------------------------------------------ ------------

    请检查下面的示例代码方案。两个可滚动面板(RED和BLUE)都使用GridBagConstraints.BOTHweightxweighty等于99.0。我希望红色面板的高度足以包含文本字段。我也希望当拖动对话框使窗口变大时,红色面板的高度保持不变。请注意,在实际屏幕中,两个面板的内容数量可能会更改(存在添加/减少按钮),因此,设置最小面板大小(用于调整大小)将无济于事。请告知我应该怎么做这个案子。谢谢!

    package cfr.view.search;
    
    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    
    import javax.swing.JDialog;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextField;
    import javax.swing.border.EmptyBorder;
    
    public class GBLSample extends JDialog {
    
        private JPanel contentPane;
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        GBLSample frame = new GBLSample();
                        frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        /**
         * Create the frame.
         */
        public GBLSample() {
            setBounds(100, 100, 350, 400);
            contentPane = new JPanel();
            contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
            setContentPane(contentPane);
            GridBagLayout gbl_contentPane = new GridBagLayout();
            contentPane.setLayout(gbl_contentPane);
    
            // RED PANEL ------------------------------------------------ 
            JScrollPane sp1 = new JScrollPane();
            GridBagConstraints gbc1 = new GridBagConstraints();
            gbc1.fill = GridBagConstraints.BOTH;
            gbc1.weightx = 99.0;
            gbc1.weighty = 99.0;
            contentPane.add(sp1, gbc1);
    
            JPanel redPanel = new JPanel();
            redPanel.setBackground(Color.RED);
            JTextField field = new JTextField(20);
            GridBagConstraints gbc2 = new GridBagConstraints();
            gbc2.anchor = GridBagConstraints.PAGE_START;
            gbc2.fill = GridBagConstraints.NONE;
            contentPane.add(field, gbc2);
    
            redPanel.add(field);
            sp1.setViewportView(redPanel);
    
            // BLUE PANEL ------------------------------------------------ 
            JScrollPane sp2 = new JScrollPane();
            GridBagConstraints gbc3 = new GridBagConstraints();
            gbc3.fill = GridBagConstraints.BOTH;
            gbc3.gridx = 0;
            gbc3.gridy = 1;
            gbc3.weightx = 99.0;
            gbc3.weighty = 99.0;
            contentPane.add(sp2, gbc3);
    
            JPanel bluePanel = new JPanel();
            bluePanel.setBackground(Color.BLUE);
            sp2.setViewportView(bluePanel);
        }
    }
    

    更新2 ------------------------------------------ ------------

    JPanel的大小调整仍然与上面的#1相同。 问题1

    enter image description here

4 个答案:

答案 0 :(得分:1)

试试这段代码:

package test;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;

public class GridBagLayoutSample extends JFrame {

private JPanel contentPane;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                GridBagLayoutSample frame = new GridBagLayoutSample();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public GridBagLayoutSample() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    GridBagLayout gbl_contentPane = new GridBagLayout();
    gbl_contentPane.columnWidths = new int[]{0, 0};
    gbl_contentPane.rowHeights = new int[]{50, 0, 0};
    //the 1.0 value in columnWeights let redPanel and scrollPane (that contain bleuPanel) grow horizontally
    //the 1.0 value is in the first index so it affect the first column
    //you still need to use a valid value for gbc_redPanel.fill and gbc_scrollPane.fill;
    gbl_contentPane.columnWeights = new double[]{1.0, Double.MIN_VALUE};
    //the 0.0 value of rowWeights => components in first row will not grow
    //the 0.0 value of rowWeights => components in second row will grow
    gbl_contentPane.rowWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
    contentPane.setLayout(gbl_contentPane);

    JPanel redPanel = new JPanel();
    redPanel.setBackground(Color.RED);
    GridBagConstraints gbc_redPanel = new GridBagConstraints();
    gbc_redPanel.insets = new Insets(0, 0, 5, 0);
    gbc_redPanel.fill = GridBagConstraints.BOTH;
    gbc_redPanel.gridx = 0;
    gbc_redPanel.gridy = 0;
    contentPane.add(redPanel, gbc_redPanel);

    JScrollPane scrollPane = new JScrollPane();
    GridBagConstraints gbc_scrollPane = new GridBagConstraints();
    gbc_scrollPane.fill = GridBagConstraints.BOTH;
    gbc_scrollPane.gridx = 0;
    gbc_scrollPane.gridy = 1;
    contentPane.add(scrollPane, gbc_scrollPane);

    JPanel bleuPanel = new JPanel();
    bleuPanel.setBackground(Color.BLUE);
    //scrollpane work with the preferred size of the component in the viewportView
    //try to change this values
    bleuPanel.setPreferredSize(new Dimension(400, 400));
    scrollPane.setViewportView(bleuPanel);
}

}

将此添加到您的代码

gbl_contentPane.rowHeights = new int[]{40, 0, 0};
gbl_contentPane.rowWeights = new double[]{0.0,0.0, 1.0, Double.MIN_VALUE};
gbc1.gridx = 0;
gbc1.gridy = 0;

并删除此

gbc1.weightx = 99.0;
gbc1.weighty = 99.0;

答案 1 :(得分:1)

  

我一直在寻找并尝试解决我在GridBagLayout调整大小时遇到​​的问题,但无济于事。

欢迎使用GridBagLayout

首先要注意的是

        JPanel redPanel = new JPanel();
        redPanel.setBackground(Color.RED);
        JTextField field = new JTextField(20);
//      GridBagConstraints gbc2 = new GridBagConstraints();
//      gbc2.anchor = GridBagConstraints.PAGE_START;
//      gbc2.fill = GridBagConstraints.NONE;
//      contentPane.add(field, gbc2);

        redPanel.add(field);
        sp1.setViewportView(redPanel);

您正在将文本字段添加到内容窗格,然后再将其添加到面板,这将覆盖您之前的分配(一个组件只能属于一个容器)。我评论出了无效的线条。如何在红色面板中布置文本字段的选择与选择如何在内容窗格中布置红色面板完全不同。

  

我希望红色面板的高度足以包含文本字段。

由布局管理员负责。但是,如果手动调整窗口大小以使面板没有足够的空间,则只要面板位于JScrollPane中,就会显示滚动条。您可以尝试@Override面板的getMinimumSize getPreferredSize,但不是所有布局管理员都尊重它。我相信。

无论如何,我根本不知道为什么你需要红色面板的滚动窗格。

  

我也希望当拖动对话框使窗口变大时,红色面板的高度保持不变。

然后您应将其weighty设置为0

注意:不要根据Java命名约定在非最终变量名中使用下划线(_gbl_contentPane应为{{1 }})。

修改

以下是动态更改gblContentPane的分配大小的示例。为简单起见,我将redPanel用于内容窗格(也由Dan O建议)。

BorderLayout

这个想法是通过给底部的一个组件赋予所有权重来添加面板底部的所有额外空间(同样可以使用最右边的组件对x轴进行)。当显示滚动条时,面板会重新计算其高度并将滚动条的高度添加到自身(到最底部的组件),然后滚动条不会隐藏任何内容。

答案 2 :(得分:1)

也许GridBagLayout可能不适合您当前的用户界面,而BorderLayout会更好用吗?将红色面板放在BorderLayout.NORTH中,然后将蓝色面板放在BorderLayout.CENTER中。在调整对话框大小时,CENTER区域中的组件会增大和缩小,而红色面板的preferredSize将作为+/-项目得到尊重。

答案 3 :(得分:0)

不幸的是,系统覆盖的JPanel.getMinimumSize()中存在一个错误,导致我的搜索面板被压缩而不存在。我已经能够在不使用系统的自定义布局管理器更改任何设置的情况下找到它的修复程序。不过,非常感谢你的所有答案和帮助。