我试图绘制比JFrame大的图形,并使用JScrollPane滚动整个图形。我创建了一个包含两行的简单示例。出现滚动条,但不显示图形。

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class Test extends JPanel{

public static void main(String... args) {
    Test test = new Test();
    JFrame frame = new JFrame();
    JPanel panel = new JPanel();
    panel.add(test);
    JScrollPane scrollPane = new JScrollPane(panel);
    scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    scrollPane.setBounds(0, 0, 1350, 700);
    JPanel contentPane = new JPanel(null);
    contentPane.setPreferredSize(new Dimension(1400, 700));
    contentPane.add(scrollPane);
    frame.setContentPane(contentPane);
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setVisible(true);
}

@Override
protected void paintComponent(Graphics g)
{
    Graphics2D g2 = (Graphics2D)g;

    g2.drawLine(30,30,30,3000);
    g2.drawLine(30, 400, 500, 3000);
}
}

最佳答案

欢迎来到一个精彩的例子,说明为什么null布局很烂...

避免使用null布局,像素完美布局是现代ui设计中的一种幻觉。有太多因素会影响组件的单个大小,您无法控制。 Swing旨在与布局经理为核心一起工作,舍弃这些问题不会导致问题和问题的终结,您将花费越来越多的时间来尝试纠正

另请参阅Why is it frowned upon to use a null layout in SWING?以获取更多详细信息...

基本问题是JScrollPane有一个JViewport,它实际上包含您的组件。 JViewport使用组件大小调整提示来确定应该多大,而JScrollPane使用JViewport做出的决定来确定是否需要显示滚动条。

JViewport正在查看您的组件,并已决定(因为您未另行告知)它的大小应为0x0

您可以通过在您的组件LineBorder中添加setBorder(new LineBorder(Color.RED));来证明这一点,您也不会看到它(或者,如果看到,它将是一个红色的小方块)

首先覆盖getPrefferedSize面板的Test方法并返回一些合适的大小

接下来,在执行任何自定义绘画之前,请调用super.paintComponent,否则您将得到一些令人敬畏但令人讨厌的绘画瑕疵...



import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test extends JPanel {

    public static void main(String... args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                Test test = new Test();
                JFrame frame = new JFrame();
                JScrollPane scrollPane = new JScrollPane(test);
                frame.add(scrollPane);
                frame.pack();
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(3000, 3000);
    }



    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        g2.drawLine(30, 30, 30, 3000);
        g2.drawLine(30, 400, 500, 3000);
    }
}


接下来,您可能要看一下Scrollable interface,因此您可以控制JViewport的默认大小,这样它就不会尝试填满整个屏幕。

查看Implementing a Scrolling-Savvy Client了解更多详细信息

10-04 21:35