我遇到了一些LayoutManager
问题(我相信)。我为自己做了一个小项目,我在下面复制了我的问题。问题在于,当我使窗口甚至比原始尺寸更小(在x或y方向上,并不重要)时,整个JScrollPane
会崩溃,直到桌子不再是可见。
我希望JPanel
根据JFrame
重新调整大小,而JScrollPane
不会崩溃。我已经在边框上添加了颜色来说明问题。
我已经查找了各种问题来解决这个问题,但答案变化很大,我找不到适合我问题的解决方案。我对LayoutManagers有一个大致的了解,但显然还不够广泛,无法解决这个问题。感谢您提前提供任何帮助。
帧正常:
框架较小(折叠/消失表):
框架更大(没问题):
代码(SSCCE):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MainWindow extends JFrame {
private JPanel EmployeePanel;
private JButton add, remove, edit;
private JTable EmployeeTable;
private JScrollPane EmployeeTableScrollPane;
private JMenuBar menu;
private JMenu file;
private JMenuItem exit;
private String[] columns = {"First Name", "Last Name", "Initials"};
private String[][] data = {
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"}
};
public MainWindow(){
//Set title
super("Scheduler");
//Set LaF
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//Set JFrame properties
this.setSize(new Dimension(800,600));
this.setMinimumSize(new Dimension(300,300));
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
this.setLayout(new BorderLayout());
//Initialize JComponents
EmployeeTable = new JTable(data, columns){
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
EmployeeTableScrollPane = new JScrollPane(EmployeeTable);
add = new JButton("Add");
remove = new JButton("Remove");
edit = new JButton("Edit");
menu = new JMenuBar();
file = new JMenu("File");
exit = new JMenuItem("Exit");
//Set MenuBar
file.add(exit);
menu.add(file);
this.setJMenuBar(menu);
exit.addActionListener(new ActionListener(){
//Don't mind the method i use for now to close the application
@Override
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
});
GridBagConstraints constraints = new GridBagConstraints();
EmployeePanel = new JPanel(new GridBagLayout());
//Add JScrollPane
constraints.weightx = 1;
constraints.weighty = 1;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridwidth = 3;
constraints.gridheight = 1;
constraints.anchor = constraints.NORTH;
constraints.fill = constraints.HORIZONTAL;
EmployeePanel.add(EmployeeTableScrollPane, constraints);
//Add Buttons
constraints.gridx = 0;
constraints.gridy = 1;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = constraints.SOUTH;
constraints.fill = constraints.HORIZONTAL;
EmployeePanel.add(add, constraints);
constraints.gridx = 1;
constraints.gridy = 1;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = constraints.SOUTH;
constraints.fill = constraints.HORIZONTAL;
EmployeePanel.add(edit, constraints);
constraints.gridx = 2;
constraints.gridy = 1;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = constraints.SOUTH;
constraints.fill = constraints.HORIZONTAL;
EmployeePanel.add(remove, constraints);
//Add EmployeePanel
this.add(EmployeePanel, BorderLayout.CENTER);
EmployeeTableScrollPane.setBorder(BorderFactory.createLineBorder(Color.YELLOW));
EmployeeTable.setBorder(BorderFactory.createLineBorder(Color.BLUE));
this.validate();
this.pack();
}
public static void main(String[] args){
new MainWindow();
}
}
答案 0 :(得分:1)
在元素周围使用BorderLayout
。
还要确保在滚动窗格上设置“首选尺寸”属性。当没有设置此属性时,框架和面板调整大小时,我有奇怪的行为(窗格/字段折叠/消失)。
答案 1 :(得分:1)
对于滚动窗格,请更改
constraints.fill = constraints.HORIZONTAL;
到
constraints.fill = constraints.BOTH;
评论中提到的第二个问题是固定的 通过添加
constraints.weighty = 0;
按钮。
完整的固定示例:
package com.zetcode;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
public class MainWindow extends JFrame {
private JPanel EmployeePanel;
private JButton add, remove, edit;
private JTable EmployeeTable;
private JScrollPane EmployeeTableScrollPane;
private JMenuBar menu;
private JMenu file;
private JMenuItem exit;
private final String[] columns = {"First Name", "Last Name", "Initials"};
private String[][] data = {
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"},
{"First Name", "Last Name", "Initials"}
};
public MainWindow(){
//Set title
super("Scheduler");
initUI();
}
private void initUI() {
createMenuBar();
//Set JFrame properties
//setSize(new Dimension(800,600));
//setMinimumSize(new Dimension(300,300));
//setLayout(new BorderLayout());
//Initialize JComponents
EmployeeTable = new JTable(data, columns){
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
EmployeeTableScrollPane = new JScrollPane(EmployeeTable);
add = new JButton("Add");
remove = new JButton("Remove");
edit = new JButton("Edit");
GridBagConstraints constraints = new GridBagConstraints();
EmployeePanel = new JPanel(new GridBagLayout());
//Add JScrollPane
constraints.weightx = 1;
constraints.weighty = 1;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridwidth = 3;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.NORTH;
constraints.fill = GridBagConstraints.BOTH;
EmployeePanel.add(EmployeeTableScrollPane, constraints);
//Add Buttons
constraints.gridx = 0;
constraints.gridy = 1;
constraints.weighty = 0;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.SOUTH;
constraints.fill = GridBagConstraints.HORIZONTAL;
EmployeePanel.add(add, constraints);
constraints.gridx = 1;
constraints.gridy = 1;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.SOUTH;
constraints.fill = GridBagConstraints.HORIZONTAL;
EmployeePanel.add(edit, constraints);
constraints.gridx = 2;
constraints.gridy = 1;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.SOUTH;
constraints.fill = GridBagConstraints.HORIZONTAL;
EmployeePanel.add(remove, constraints);
//Add EmployeePanel
this.add(EmployeePanel, BorderLayout.CENTER);
EmployeeTableScrollPane.setBorder(BorderFactory.createLineBorder(Color.YELLOW));
EmployeeTable.setBorder(BorderFactory.createLineBorder(Color.BLUE));
//this.validate();
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void createMenuBar() {
menu = new JMenuBar();
file = new JMenu("File");
exit = new JMenuItem("Exit");
//Set MenuBar
file.add(exit);
menu.add(file);
setJMenuBar(menu);
}
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MainWindow ex = new MainWindow();
ex.setVisible(true);
}
});
}
}
已解决的问题:
无需致电this.validate();
您同时打电话
setSize(new Dimension(800,600));
和
pack();
无论是打电话给另一方,pack()
都是首选方式。
无需致电
setLayout(new BorderLayout());
BorderLayout
是框架内容窗格的默认布局。
应该在EDT(事件调度线程)上启动应用程序:
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MigLayoutMainWindow ex = new MigLayoutMainWindow();
ex.setVisible(true);
}
});
最后,我会选择MigLayout
或GroupLayout
经理
GridBagLayout
经理。它们更强大,更灵活。
答案 2 :(得分:0)
我有一个与滚动窗格类似的东西,我发现让它工作的方法是手动计算高度,然后覆盖高度属性。我采用这种方法,因为我想要构建的部分内容保持相同的高度,无论窗口如何调整大小。滚动窗格很有趣。