使用 GridBagLayout 正确渲染

Sta*_*tes 1 java swing layout-manager

在所附的屏幕截图中,我有一个JLabel,JTextField和一个JTabel包裹在JSchrollPane. 首先,JLabelJTextField 漂浮在中间很远的地方。上面有很大的空间。我想关闭那个空间。其次,我希望JTable/JSchrollPane填充整个宽度。它只占宽度的一半。并且它不显示表包含的 3 行。

如果我这样做,则会panFindStudent.add(table, gbcFindStud);显示行,但它看起来仍然不漂亮。我想使用JSchrollPane, 以便在表包含许多行/列时可以滚动

我还尝试将JLabel和包装JTexField在 aJPanel中,将 包装JSchrollPane在另一个 中JPanel,然后将这两个JPanels分别添加到JFrame像这样的

findStudentFrame.add(panelWithLabelAndTextField)
findStudentFrame.add(paneLWithShcrollPane)
Run Code Online (Sandbox Code Playgroud)

但这样做,似乎只添加了最后一个面板,而不是第一个面板

我最终也认为这GridBagLayout可能不是这项任务的正确选择,我尝试混合使用GridBagLayoutFlowLayout。它给出了更好的结果,但仍然不令人满意。但我认为最好学习用 解决这个问题GridBagLayout,以便我学习正确使用它。欢迎您提出建议,让我的结果/看起来更好。我已在底部添加了整个代码,因此您可以运行它并更改它。谢谢

在此输入图像描述

我想要与此类似的东西 在此输入图像描述

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

public class SwingPractice2 {
    
    private JFrame findStudentFrame;
    private JPanel panFindStudent, panTableResults;
    private JLabel labelAddStudEmail;
    private JTextField tFieldAddStudFirstName;
    
    private int textFieldWidth = 20,
            textFieldHeight = 10;
    
    private Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 

    private int frameWidth = screenSize.width/4, 
            frameHeight = screenSize.height/3;
    
    public SwingPractice2() {
        findStudentFrame = new JFrame();
        //findStudentFrame.setLayout(new GridLayout(2, 1));
        //findStudentFrame.setSize(frameWidth, frameHeight);
        //addStudentFrame.setSize(frameWidth, frameHeight);
        panFindStudent = new JPanel(new GridBagLayout());
        panFindStudent.setPreferredSize(new Dimension(frameWidth, frameHeight));
        panFindStudent.setBorder(BorderFactory.createTitledBorder("Students"));
        
        labelAddStudEmail = new JLabel("Email");    
        tFieldAddStudFirstName = new JTextField();
        tFieldAddStudFirstName.setSize(textFieldWidth, textFieldHeight);
        
        panTableResults = new JPanel(new FlowLayout());
    }

    public void showStudentGUI() {
        GridBagConstraints gbcFindStud = new GridBagConstraints();
        gbcFindStud.anchor = GridBagConstraints.NORTHWEST;      
        gbcFindStud.gridx = 0;
        gbcFindStud.gridy = 0;
        gbcFindStud.weightx = 1.0;
        gbcFindStud.fill = GridBagConstraints.HORIZONTAL;
        gbcFindStud.insets = new Insets(5, 5, 5, 5);
        
        panFindStudent.add(labelAddStudEmail, gbcFindStud);
                
        gbcFindStud.gridx++;
        gbcFindStud.anchor = GridBagConstraints.NORTHEAST;
        panFindStudent.add(tFieldAddStudFirstName, gbcFindStud);
        
        String[] tableCols = new String[] {
            "ID", "First name", "Last name" 
        };
        
        String data[][] = {
                {"1", "Marcus", "Johnson" }, 
                {"2", "Miko", "Jameson"},
                {"2", "Kate", "Anderson"}
        };
        
        JTable table = new JTable(data, tableCols);     
        //table.setBounds(30, 40, 200, 300);
        
        JScrollPane jsp = new JScrollPane(table);   
        //jsp.setBounds(30, 40, 300, 300);
        
        gbcFindStud.gridx = 0;
        gbcFindStud.gridy = 1;
        gbcFindStud.fill = GridBagConstraints.HORIZONTAL;
        gbcFindStud.anchor = GridBagConstraints.CENTER;
                
        panFindStudent.add(jsp, gbcFindStud);
        
        findStudentFrame.add(panFindStudent);
        //findStudentFrame.add(jsp);
        findStudentFrame.pack();
        findStudentFrame.setVisible(true);
    }
    
    public static void main(String[] args) {
        new SwingPractice2().showStudentGUI();
    }

}
Run Code Online (Sandbox Code Playgroud)

Mad*_*mer 5

首先,一些建议...

private Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Run Code Online (Sandbox Code Playgroud)

不是获得显示器“可视”区域的最佳方法,它不会考虑大多数操作系统上的停靠栏/菜单栏之类的东西的大小或位置,这可能会导致您出现问题。

就我个人而言,我会避免使用setPreferredSize,这可能会对您的布局产生未来的影响。

这...

tFieldAddStudFirstName.setSize(textFieldWidth, textFieldHeight);
Run Code Online (Sandbox Code Playgroud)

也是无关紧要的。

关于你的问题...

首先,gbcFindStud.weightx = 1.0;给我带来了问题。相反,对于Email标签,我只会使用...

gbcFindStud.anchor = GridBagConstraints.EAST;
gbcFindStud.gridx = 0;
gbcFindStud.gridy = 0;
gbcFindStud.insets = new Insets(5, 5, 5, 5);
Run Code Online (Sandbox Code Playgroud)

这可以确保标签只有所需的大小,为什么?因为您希望文本字段与其对齐,以便两个元素之间存在视觉相关性。

对于文本字段,我会使用...

gbcFindStud.gridx++;
gbcFindStud.fill = GridBagConstraints.HORIZONTAL;
gbcFindStud.weightx = 1.0;
panFindStudent.add(tFieldAddStudFirstName, gbcFindStud);
Run Code Online (Sandbox Code Playgroud)

这确保了文本字段水平填充所有剩余空间,不确定某些电子邮件可能有多大错误,但能够一眼阅读您输入的内容是很好的。

对于桌子,我会使用...

gbcFindStud.gridx = 0;
gbcFindStud.gridy = 1;
gbcFindStud.gridwidth = GridBagConstraints.REMAINDER;
gbcFindStud.fill = GridBagConstraints.BOTH;
gbcFindStud.weighty = 1;
Run Code Online (Sandbox Code Playgroud)

这里重要的部分是gbcFindStud.gridwidth = GridBagConstraints.REMAINDER。这确保表将展开所有剩余的列。我还添加了gbcFindStud.weighty = 1确保它将填充剩余的垂直空间(并将其他元素推到视图的顶部)

现在这会生成...

在此输入图像描述

您仍然需要输入All Students标签,但是根据我上面提供的信息,您应该能够弄清楚。不要忘记参考如何使用 GridBagLayout

不要忘记,您可以使用多个容器,使用不同的布局管理器。

例如,电子邮件标签和文本字段可以是一个单独的容器,然后可以使用 将其添加到容器中BorderLayout,从而简化逻辑。

可运行的例子...

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new SwingPractice2().showStudentGUI();
            }
        });
    }

    public class SwingPractice2 {

        private JFrame findStudentFrame;
        private JPanel panFindStudent, panTableResults;
        private JLabel labelAddStudEmail;
        private JTextField tFieldAddStudFirstName;

        public SwingPractice2() {
            findStudentFrame = new JFrame();
            panFindStudent = new JPanel(new GridBagLayout());
            panFindStudent.setBorder(BorderFactory.createTitledBorder("Students"));

            labelAddStudEmail = new JLabel("Email");
            tFieldAddStudFirstName = new JTextField();
        }

        public void showStudentGUI() {
            GridBagConstraints gbcFindStud = new GridBagConstraints();
            gbcFindStud.anchor = GridBagConstraints.EAST;
            gbcFindStud.gridx = 0;
            gbcFindStud.gridy = 0;
            gbcFindStud.insets = new Insets(5, 5, 5, 5);

            panFindStudent.add(labelAddStudEmail, gbcFindStud);

            gbcFindStud.gridx++;
            gbcFindStud.fill = GridBagConstraints.HORIZONTAL;
            gbcFindStud.weightx = 1.0;
            panFindStudent.add(tFieldAddStudFirstName, gbcFindStud);

            String[] tableCols = new String[]{
                "ID", "First name", "Last name"
            };

            String data[][] = {
                {"1", "Marcus", "Johnson"},
                {"2", "Miko", "Jameson"},
                {"2", "Kate", "Anderson"}
            };

            JTable table = new JTable(data, tableCols);

            JScrollPane jsp = new JScrollPane(table);

            gbcFindStud.gridx = 0;
            gbcFindStud.gridy = 1;
            gbcFindStud.gridwidth = GridBagConstraints.REMAINDER;
            gbcFindStud.fill = GridBagConstraints.BOTH;
            gbcFindStud.weighty = 1;

            panFindStudent.add(jsp, gbcFindStud);

            findStudentFrame.add(panFindStudent);
            findStudentFrame.pack();
            findStudentFrame.setVisible(true);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)