使用GridBagLayout正确渲染

问题描述 投票:0回答:2

在所附的屏幕截图中,我有一个

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

如果我这样做,

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

我还尝试将

JLabel
JTexField
包装在
JPanel
中,将
JSchrollPane
包装在另一个
JPanel
中,然后将这 2 个
JPanels
分别添加到
JFrame
中,如下所示

findStudentFrame.add(panelWithLabelAndTextField)
findStudentFrame.add(paneLWithShcrollPane)

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

我最终也认为

GridBagLayout
可能不是这项任务的正确选择,我尝试混合使用
GridBagLayout
FlowLayout
。它给出了更好的结果,但仍然不令人满意。但我认为最好学习用
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();
    }

}
java swing layout-manager
2个回答
1
投票

当您尝试使用单个布局管理器为每个人做所有事情时,您试图对所有事情使用相同的工具,例如用螺丝刀钉钉子。在这里,就像在上一个问题中一样,您应该嵌套 JPanel,每个 JPanel 使用自己的最佳用途布局管理器。例如,您可以使用:

  • 顶部 JPanel 的 BoxLayout 或 GridLayout,带有 JLabel 和 JTextField,
  • 主 JPanel 的 BorderLayout
  • 将 JScrollPane 放入主 JPanel 中的
    BorderLayout.CENTER
    位置
  • 并将顶部 JPanel 放置在
    BorderLayout.PAGE_START
    位置。

然后尝试你的布局,直到它看起来更好。

旁注:

  • 不要设置文本组件的大小或首选大小,因为这可能会破坏其应有的功能。设置文本组件的列(或行)。

0
投票

private Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

不是获取显示屏“可视”区域的最佳方法,它不会考虑大多数操作系统上的停靠栏/菜单栏等可能会导致问题的尺寸或位置。

就我个人而言,我会避免使用

setPreferredSize

,这可能会对您的布局产生未来的影响。

这个...

tFieldAddStudFirstName.setSize(textFieldWidth, textFieldHeight);

也无关紧要。

关于您的问题...

首先,

gbcFindStud.weightx = 1.0;

给我带来了问题。相反,对于

Email
标签,我只会使用...
gbcFindStud.anchor = GridBagConstraints.EAST;
gbcFindStud.gridx = 0;
gbcFindStud.gridy = 0;
gbcFindStud.insets = new Insets(5, 5, 5, 5);

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

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

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

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

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

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

这里重要的部分是
gbcFindStud.gridwidth = GridBagConstraints.REMAINDER

。这确保表将展开所有剩余的列。我还添加了

gbcFindStud.weighty = 1
以确保它将填充剩余的垂直空间(并将其他元素推到视图的顶部)
这现在生成...

您仍然需要输入

All Students

标签,但根据我上面提供的信息,您应该能够弄清楚。不要忘记参考

如何使用GridBagLayout
可运行的示例...

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); } } }

© www.soinside.com 2019 - 2024. All rights reserved.