JScrollPane 滚动后不显示内容

JScrollPane not show content after scroll in swing

您好,我需要在单个数据中显示大量内容(其图形数据),所以我尝试了以下代码。

    canvas.setPreferredSize(new Dimension(3000, 300));
    canvas.setBackground(Color.blue);

    JScrollPane jsp = new JScrollPane(canvas);

    setPreferredSize(new Dimension(600, 500));
    setLayout(new GridLayout(1, 0, 5, 0));

    jsp.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
        @Override
        public void adjustmentValueChanged(AdjustmentEvent e) {
            System.out.println(e.getValue());
            repaint();
        }
    });

    add(jsp);

这是我的 MyCanvas class

class MyCanvas extends Canvas {

@Override
public void paint(Graphics g) {
    super.paint(g);
    System.out.println("paint");
    g.setColor(Color.YELLOW);

    for (int i = 0; i < 100; i++) {
        g.drawString(""+i, i*30, 100);
    //  g.drawLine(10, 10, 20, 20);
    }

}
}

但问题是当我滚动时 window 我无法看到完整内容,因为我预期它应该打印 100 个数字但实际上没有打印,任何人都可以纠正我吗?

在此处查看结果

我建议您避免将 AWT 和 Swing 组件混合在一起(或者如果您绝对必须这样做,那么您必须确保您理解这些陷阱并完全跳过所有必要的箍。

我自己,我会扩展 JPanel,我会确定它的 preferredSize 是我想要的,因为这将决定它在 JScrollPane 中的大小。

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.*;

@SuppressWarnings("serial")
public class MyScrollExample extends JPanel {
    private static final int MAX = 100;
    private MyPanel myPanel = new MyPanel(MAX);

    public MyScrollExample() {
        JScrollPane scrollPane = new JScrollPane(myPanel);
        scrollPane.getViewport().setPreferredSize(new Dimension(600, 200));
        add(scrollPane);
    }

    private static void createAndShowGui() {
        MyScrollExample mainPanel = new MyScrollExample();

        JFrame frame = new JFrame("MyScrollExample");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

@SuppressWarnings("serial")
class MyPanel extends JPanel {
    private static final Color BG = Color.BLUE;
    private static final Color FG = Color.YELLOW;
    private static final int WIDTH_GAP = 30;
    private static final int HEIGHT_GAP = 100;
    private int max;

    public MyPanel(int max) {
        setBackground(BG);
        this.max = max;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(FG);

        for (int i = 0; i < max; i++) {
            g.drawString("" + i, i * WIDTH_GAP, HEIGHT_GAP);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        int w = (WIDTH_GAP + 1) * max; 
        int h = HEIGHT_GAP * 3;
        return new Dimension(w, h);
    }

}