Java 在JPanel上使用JScrollPane时不会显示它

Java 在JPanel上使用JScrollPane时不会显示它,java,swing,jpanel,jscrollpane,layout-manager,Java,Swing,Jpanel,Jscrollpane,Layout Manager,我已经试了几个小时想找到一个解决这个问题的方法,但是我没有成功。下面是一个示例代码: import java.awt.BorderLayout; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SwingUtilities

我已经试了几个小时想找到一个解决这个问题的方法,但是我没有成功。下面是一个示例代码:

import java.awt.BorderLayout;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class Example extends JFrame
{
    private static final long serialVersionUID = 1L;

    public Example()
    {
        JPanel contentPane = (JPanel) getContentPane();
        contentPane.setLayout(new BorderLayout());

        JPanel panTop = new JPanel(new BorderLayout());
        //JPanel panBottom = new JPanel(new BorderLayout());

        JPanel panTopCenter = new JPanel();
        //JPanel panTopLeft = new JPanel();
        //JPanel panTopRight = new JPanel();

        panTop.add(panTopCenter, BorderLayout.CENTER);
        //panTop.add(panTopLeft, BorderLayout.WEST);
        //panTop.add(panTopRight, BorderLayout.EAST);

        contentPane.add(panTop, BorderLayout.CENTER);
        //contentPane.add(panBottom, BorderLayout.SOUTH);

        JPanel pan = new JPanel();
        pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS));
        for(int i = 0; i < 50; i++) pan.add(new JButton("Button " + i));
        JScrollPane scrollPane = new JScrollPane(pan);
        panTopCenter.add(scrollPane);

        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {           
            @Override
            public void run()
            {
                new Example();
            }
        });
    }
}
导入java.awt.BorderLayout;
导入javax.swing.BoxLayout;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.SwingUtilities;
公共类示例扩展了JFrame
{
私有静态最终长serialVersionUID=1L;
公共示例()
{
JPanel contentPane=(JPanel)getContentPane();
setLayout(新的BorderLayout());
JPanel panTop=newjpanel(newborderlayout());
//JPanel panBottom=newjpanel(newborderlayout());
JPanel panTopCenter=新的JPanel();
//JPanel panTopLeft=新的JPanel();
//JPanel panTopRight=新的JPanel();
添加(panTopCenter、BorderLayout.CENTER);
//panTop.add(panTopLeft,BorderLayout.WEST);
//panTop.add(panTopRight,BorderLayout.EAST);
添加(panTop,BorderLayout.CENTER);
//添加(panBottom,BorderLayout.SOUTH);
JPanel pan=新的JPanel();
平移.设置布局(新的框布局(平移,框布局.Y_轴));
对于(inti=0;i<50;i++)pan.add(新的JButton(“按钮”+i));
JScrollPane scrollPane=新的JScrollPane(pan);
panTopCenter.add(滚动窗格);
包装();
setLocationRelativeTo(空);
setVisible(真);
}
公共静态void main(字符串[]args)
{
SwingUtilities.invokeLater(新的Runnable()
{           
@凌驾
公开募捐
{
新例子();
}
});
}
}
快照:


如果容器或顶级容器中的
JScrollPane
是单个
JComponent
,则必须设置首选大小

scrollPane.setPreferredSize(new Dimension(100,500));

最好对同一类型的
JComponent
s使用
GridLayout

我必须始终这样设置视口的首选大小

import java.awt.*;
import javax.swing.*;

public class Example extends JFrame {

    public Example() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Box box = new Box(BoxLayout.Y_AXIS);
        for (int i = 0; i < 50; i++) {
            box.add(new JButton("Button " + i));
        }
        JScrollPane sp = new JScrollPane(box);
        Dimension d = new Dimension(box.getComponent(0).getPreferredSize());
        sp.getVerticalScrollBar().setUnitIncrement(d.height);
        d.height *= 10; // Show at least 10 buttons
        sp.getViewport().setPreferredSize(d);

        add(sp, BorderLayout.CENTER);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                Example e = new Example();
            }
        });
    }
}
import java.awt.*;
导入javax.swing.*;
公共类示例扩展了JFrame{
公共示例(){
setDefaultCloseOperation(关闭时退出);
长方体=新长方体(长方体布局Y_轴);
对于(int i=0;i<50;i++){
添加(新的JButton(“按钮”+i));
}
JScrollPane sp=新的JScrollPane(框);
维度d=新维度(box.getComponent(0.getPreferredSize());
sp.getVerticalScrollBar().setUnitIncrement(d.高度);
d、 高度*=10;//显示至少10个按钮
sp.getViewport().setPreferredSize(d);
添加(sp,BorderLayout.CENTER);
包装();
setLocationRelativeTo(空);
setVisible(真);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
示例e=新示例();
}
});
}
}

不要设置任何尺寸!如果进行了此更改,将显示滚动条

JPanel panTopCenter = new JPanel(new GridLayout());

基本问题是
FlowLayout
将以显示组件所需的最小尺寸显示组件,对于滚动窗格,即(决定为)0x0。通过使用构造函数中没有参数的
GridLayout
,并添加滚动窗格作为唯一组件,它将被迫填充可用空间。

最好的解决方案是使用SwingX,它是准标准的,实现了
可滚动的

,但当我这样做时,
panTopCenter
将具有静态大小,并且在放大JFrame大小时不会动态放大。我认为您可以更改视口的大小,例如。啊,类似于
setVisibleRowCount()
JList
所做的操作,如图所示。不要使用
BoxLayout
,请尝试
GridLayout
,如图所示,由于在
GridLayout
中,所有
JButton
的大小都是相同的,这与
BoxLayout
不同,BoxLayout的大小是由其内部的文本决定的。您还可以实现
Scrollable
+1iiuc,问题在于生成的视口首选大小不易操作,并且(可能)依赖于L&F。我主张实现
getPreferredScrollableViewportSize()
@trashgod我可以看到可能需要设置首选视口大小的情况,但对于“设置任意大小”我总是非常谨慎。这是我在用尽其他可能的可能性之后才考虑的问题。@我承认,我不太理解这个问题+1,因为可能是正确的answer@mKorbel“我不太明白这个问题”这是一个答案在于细节的问题,而这些细节目前还不清楚。我通常会在GUI的其余部分使用元素来形成“合理的大小”(基于列/行等),并在GUI的另一个区域使用这些大小提示来显示“我们有很多这样的”类型的组件/元素的可滚动组件(或列表)。事实上,即使使用列表(
JList
),我们也可以建议行大小,这样也会有所帮助。aaaachhh我看到了,当然我的坏'cos
1)
默认情况下,在创建我的答案之前从问题中删除balast
2)
只返回到关于L&F、UIManager和最后一个2M比较Java7的问题(,但以有限的形式工作,如示例)
3)
从未使用过FlowLayout/BoxLayout