我在这个论坛(例如this one)上阅读了一些已回答的问题,强烈建议您避免使用setXXXSize()方法来调整swing应用程序中组件的大小。
因此,要解决我的问题,我想知道如何最佳调整JScrollPane的大小,以避免其父面板在没有任何控件的情况下增加其大小。
在写一些代码之前,我想描述一下实际情况,因为我将发布一个“玩具示例”。
在我的JFrame中,我当前正在为内容窗格使用边框布局。在BorderLayout.CENTER处有一个JPanel,我在其中做一些自定义绘制。
在BorderLayout.EAST处,有一个JPanel(例如eastPanel)在另一个面板中包含一些组件(此面板将在BorderLayout.NORTH处添加到eastPanel),并在JScrollPane中包含一个JTable(在BorderLayout.CENTER处添加到eastPanel)。该表将有很多行。
由于我希望eastPanel的高度与centerPanel的高度相同,因此我需要某种方法来避免JScrollPane增大其大小,以便尝试显示尽可能多的行。
现在,除了在包含滚动窗格的eastPanel上调用setPreferredSize之外,我无法找到其他解决方案,但是我不得不承认我讨厌这种解决方案。
样例代码
在此代码示例中,我在EastPanel的北部和JScrollPane内部添加了一些随机标签,因为我的目的是发布简短的代码示例。
但是,情况与我上面描述的情况非常相似。
如果不使用以下“糟糕的”代码行,就无法解决我的问题:
eastPanel.setPreferredSize(new Dimension(eastPanel.getPreferredSize().width, centerPanel.getPreferredSize().height));
对于这种简单情况,我想避免使用更复杂的布局。我想念什么吗?另外,设置该空白边框是设置面板尺寸的一种可接受的方法,我将在该面板上进行一些自定义绘画?
代码:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class Test
{
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new TestFrame().setVisible(true);
}
catch(Exception exception) {
JOptionPane.showMessageDialog(null, "Fatal error while initialiing application", "Error", JOptionPane.ERROR_MESSAGE);
}
}
});
}
}
class TestFrame extends JFrame
{
public TestFrame() {
super("Test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel pane = new JPanel(new BorderLayout(20, 0));
pane.setBorder(new EmptyBorder(20, 20, 20, 20));
JPanel centerPanel = new JPanel();
centerPanel.setBackground(Color.WHITE);
centerPanel.setBorder(new EmptyBorder(400, 400, 0, 0));
// centerPanel.setPreferredSize(new Dimension(400, 400));
JPanel eastPanel = new JPanel(new BorderLayout(0, 20));
JPanel labelsContainer = new JPanel(new GridLayout(0, 1));
for(int i=0;i<7;i++) labelsContainer.add(new JLabel(String.valueOf(i)));
eastPanel.add(labelsContainer, BorderLayout.NORTH);
JPanel moreLabelsContainer = new JPanel(new GridLayout(0, 1));
for(int i=7;i<70;i++) moreLabelsContainer.add(new JLabel(String.valueOf(i)));
JScrollPane scroll = new JScrollPane(moreLabelsContainer, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
eastPanel.add(scroll, BorderLayout.CENTER);
eastPanel.setPreferredSize(new Dimension(eastPanel.getPreferredSize().width, centerPanel.getPreferredSize().height));
pane.add(centerPanel, BorderLayout.CENTER);
pane.add(eastPanel, BorderLayout.EAST);
setContentPane(pane);
pack();
setLocationRelativeTo(null);
}
}
谢谢你的帮助 !
最佳答案
我不知道会根据面板中特定组件的高度来限制面板高度的布局管理器。
一种方法是自定义包含两个子组件的父面板的行为。
该代码可能类似于:
@Override
public Dimension getPreferredSize()
{
Dimension d = super.getPreferredSize();
BorderLayout layout = (BorderLayout)getLayout();
Component center = layout.getLayoutComponent(BorderLayout.CENTER);
int centerHeight = center.getPreferreidSize().height;
if (d.height > centerHeight)
d.height = centerHeight;
return d;
}
这种方法将允许基于中心的组件动态计算高度。
另一种选择是编写自己的布局管理器。然后,您可以在布局管理器中控制这种类型的逻辑。
另外,设置该空白边框是设置面板尺寸的一种可接受的方法,我将在该面板上进行一些自定义绘画?
我重写
getPreferredSize()
以返回适当的尺寸。通过使用EmptyBorder,您将无法在面板上添加真正的边框,因此我不推荐这样做。