Search code examples
javaswinggraphics2d

JScrollPane not show content after scroll in swing


Hi I need to display a large content(its graphical data) of data in single, so I tried following code.

    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);

this is my 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);
    }

}
}

but problem is that when I am scrolling window I cannot see full content as I expected it should print 100 numbers but not printed actually, can any one correct me?

see the result here

result


Solution

  • I recommend that you avoid mixing AWT and Swing components together (or if you absolutely must do this, then you have to make sure you understand the pitfalls and fully jump through all the necessary hoops.

    Myself, I'd extend JPanel, I'd be sure that its preferredSize was where I want it, since this will determine how big it will be within the JScrollPane.

    For example:

    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);
        }
    
    }