设置 JScrollPane.getViewPort() 的背景时没有任何反应

Nothing happens when setting the background of JScrollPane.getViewPort()

我有一个 JPanel 布局设置为空,背景为白色。然后我将 JPanel 添加到 JScrollPane.

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class TestJScollPane extends JPanel {

    private static final long serialVersionUID = 1L;

    public TestJScollPane() {
        initUI();
    }

    private void initUI()
    {
        JScrollPane scrollPane = new JScrollPane();
        scrollPane.getViewport().setBackground(Color.GRAY);
        scrollPane.setBounds(1, 1, 200, 200);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

        setBorder(BorderFactory.createEtchedBorder(Color.GREEN, Color.MAGENTA));
        setBackground(Color.WHITE);
        setLayout(null);

        JFrame frame = new JFrame();
        scrollPane.setViewportView(this);
        frame.add(scrollPane);

        frame.setLayout(null);
        frame.setVisible(true);
        frame.setSize(800, 500);
        frame.getContentPane().setBackground(Color.BLACK);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    @Override
    public Dimension getPreferredSize() {

        return new Dimension(30,30);
    }

    public static void main(String[] args)
    {
        new TestJScollPane();
    }
}

我的场景是我有一个缩放工具,如果我缩小 JPanel 并且它所有绘制的形状都使用 AffineTransform 缩放。所以我希望如果我缩小,JScrollPane 的背景是灰色,但实际是白色。

抱歉,我添加了一个示例。实际上,这不是我创建的实际代码,所以我可以提供一个示例供大家帮助。

我将 JPanel 的首选大小设置为 30x30,因此我希望 JScrollPane 的背景会变得可见,但事实并非如此。

在此先感谢您的帮助。

默认情况下,面板的大小适合视口,因此您不会看到视口的背景。

您需要实现 JPanel 的 Scrollable 接口来告诉滚动窗格您希望面板以其首选大小显示。

或者,您可以使用 Scrollable Panel 而不是自己实现 Scrollable 界面,默认情况下,它会以首选大小显示面板。

您的代码更改为:

ScrollablePanel panel = new ScrollablePanel();
panel.setPreferredSize( new Dimension(30, 30) );
panel.setBorder(BorderFactory.createEtchedBorder(Color.GREEN, Color.MAGENTA));
panel.setBackground(Color.WHITE);
//panel.setLayout(null);
scrollPane.setViewportView(panel);
//scrollPane.setViewportView(this);

变化:

scrollPane.setViewportView(this);

类似于:

JPanel centerPanel = new JPanel(new GridBagLayout());
centerPanel.add(this);
scrollPane.setViewportView(centerPanel);

A GridBagLayout(默认情况下,除非另有配置)将遵循子组件的首选大小,并且不会拉伸它们以填充 'cell'。另一方面,滚动窗格会将内容拉伸到(至少)填充可见区域。

结果:

但说真的,放弃使用 null 布局。如果使用现有布局(内置或第三方)或布局组合无法实现效果,则它必须具有如此深奥的定位约束,值得自定义布局管理器。