我遇到了一些 LayoutManager
问题(我相信)。我正在为自己做一个小项目,我在下面复制了我的问题。问题是,当我使窗口比原始大小小一个像素(在 x 或 y 方向上,无关紧要)时,整个 JScrollPane
就会崩溃,以至于表格不存在更长可见。
我希望 JPanel
根据 JFrame
重新调整大小,而不会使 JScrollPane
折叠。我在边框上添加了颜色来说明问题。
我查了各种问题来解决这个问题,但答案相差很大,我没有找到适合我的问题的解决方案。我对布局管理器有一个大致的了解,但显然还不够广泛,无法弄清楚这一点。感谢您提前提供的任何帮助。
帧正常:
框架较小(折叠/消失的 table ):
框架更大(没问题):
代码(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();
}
}
最佳答案
对于滚动 Pane ,更改
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
是框架内容 Pane 的默认布局。
应用程序应在 EDT(事件调度线程)上启动:
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MigLayoutMainWindow ex = new MigLayoutMainWindow();
ex.setVisible(true);
}
});
最后,我会使用 MigLayout
或 GroupLayout
管理器
GridBagLayout 管理器的。它们更强大、更灵活。
关于java - 调整 JFrame 大小后 JScrollPane 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25018084/