我都在彼此的一個JPanel設置爲一個網格佈局下面一系列的組件。 我需要暫時隱藏組件,但setVisible(false)
不會削減它,因爲組件所在的空隙仍然存在。隱形組件仍然佔用空間的JPanel
是否有一個快速簡便的方法來做到這一點?或者我必須保存JPanel的狀態,刪除組件,然後恢復它?
SSCCE:
[GridLayout2.java]
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Insets;
public class GridLayout2 extends GridLayout
{
public GridLayout2() {
this(1, 0, 0, 0);
}
public GridLayout2(int rows, int cols) {
this(rows, cols, 0, 0);
}
public GridLayout2(int rows, int cols, int hgap, int vgap) {
super(rows, cols, hgap, vgap);
}
public Dimension preferredLayoutSize(Container parent) {
//System.err.println("preferredLayoutSize");
synchronized (parent.getTreeLock()) {
Insets insets = parent.getInsets();
int ncomponents = parent.getComponentCount();
int nrows = getRows();
int ncols = getColumns();
if (nrows > 0) {
ncols = (ncomponents + nrows - 1)/nrows;
}
else {
nrows = (ncomponents + ncols - 1)/ncols;
}
int[] w = new int[ncols];
int[] h = new int[nrows];
for (int i = 0; i < ncomponents; i ++) {
int r = i/ncols;
int c = i % ncols;
Component comp = parent.getComponent(i);
Dimension d = comp.getPreferredSize();
if (w[c] < d.width) {
w[c] = d.width;
}
if (h[r] < d.height) {
h[r] = d.height;
}
}
int nw = 0;
for (int j = 0; j < ncols; j ++) {
nw += w[j];
}
int nh = 0;
for (int i = 0; i < nrows; i ++) {
nh += h[i];
}
return new Dimension(insets.left + insets.right + nw + (ncols-1)*getHgap(),
insets.top + insets.bottom + nh + (nrows-1)*getVgap());
}
}
public Dimension minimumLayoutSize(Container parent) {
System.err.println("minimumLayoutSize");
synchronized (parent.getTreeLock()) {
Insets insets = parent.getInsets();
int ncomponents = parent.getComponentCount();
int nrows = getRows();
int ncols = getColumns();
if (nrows > 0) {
ncols = (ncomponents + nrows - 1)/nrows;
}
else {
nrows = (ncomponents + ncols - 1)/ncols;
}
int[] w = new int[ncols];
int[] h = new int[nrows];
for (int i = 0; i < ncomponents; i ++) {
int r = i/ncols;
int c = i % ncols;
Component comp = parent.getComponent(i);
Dimension d = comp.getMinimumSize();
if (w[c] < d.width) {
w[c] = d.width;
}
if (h[r] < d.height) {
h[r] = d.height;
}
}
int nw = 0;
for (int j = 0; j < ncols; j ++) {
nw += w[j];
}
int nh = 0;
for (int i = 0; i < nrows; i ++) {
nh += h[i];
}
return new Dimension(insets.left + insets.right + nw + (ncols-1)*getHgap(),
insets.top + insets.bottom + nh + (nrows-1)*getVgap());
}
}
public void layoutContainer(Container parent) {
//System.err.println("layoutContainer");
synchronized (parent.getTreeLock()) {
Insets insets = parent.getInsets();
int ncomponents = parent.getComponentCount();
int nrows = getRows();
int ncols = getColumns();
if (ncomponents == 0) {
return;
}
if (nrows > 0) {
ncols = (ncomponents + nrows - 1)/nrows;
}
else {
nrows = (ncomponents + ncols - 1)/ncols;
}
int hgap = getHgap();
int vgap = getVgap();
// scaling factors
Dimension pd = preferredLayoutSize(parent);
double sw = (1.0 * parent.getWidth())/pd.width;
double sh = (1.0 * parent.getHeight())/pd.height;
// scale
int[] w = new int[ncols];
int[] h = new int[nrows];
for (int i = 0; i < ncomponents; i ++) {
int r = i/ncols;
int c = i % ncols;
Component comp = parent.getComponent(i);
Dimension d = comp.getPreferredSize();
d.width = (int) (sw * d.width);
d.height = (int) (sh * d.height);
if (w[c] < d.width) {
w[c] = d.width;
}
if (h[r] < d.height) {
h[r] = d.height;
}
}
for (int c = 0, x = insets.left; c < ncols; C++) {
for (int r = 0, y = insets.top; r < nrows; r ++) {
int i = r * ncols + c;
if (i < ncomponents) {
parent.getComponent(i).setBounds(x, y, w[c], h[r]);
}
y += h[r] + vgap;
}
x += w[c] + hgap;
}
}
}
}
[SSCCE.java]
import java.awt.Color;
import javax.swing.*;
import javax.swing.border.*;
public class SSCCE extends JFrame{
JPanel innerPane = new JPanel();
JScrollPane scr = new JScrollPane(innerPane);
public static void main(String[] args) {
new SSCCE();
}
public SSCCE() {
setSize(400, 800);
innerPane.setLayout(new GridLayout2(0, 1));
add(scr);
for (int i = 0; i < 30; i++)
{
innerPane.add(getPane());
}
setVisible(true);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
for (int i = 0; i < 30; i++)
{
if (i%2==0)
innerPane.getComponent(i).setVisible(false);
}
}
private JPanel getPane()
{
JPanel ret = new JPanel();
JLabel lbl = new JLabel("This is a pane.");
ret.add(lbl);
ret.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
ret.setBackground(Color.gray);
return ret;
}
}
您的問題*可能*是由於您使用網格佈局中可以就此網格點取決於它如何建立開放的,但心裏很不舒服,我只是在猜測這就是全部人能做到給予迄今給出的信息。如果您很快就沒有得到正確的答案,我建議您創建併發布[SSCCE](http://sscce.org),供我們測試,修改和幫助修復。 –
您可能想看看比GridLayout功能強大的第三方LayoutManagers,它取決於您需要的佈局(看起來您僅暴露了部分問題)。我建議你看看DesignGridLayout,它可以處理你想要的東西(但是使用特定的API);其主要優勢是其學習曲線非常短(與其他LayoutManagers相比)。 – jfpoilpret