views:

358

answers:

3

Hi all, I was using Java JRE 1.6.7 and had a JComponent and a JScrollPane. I couldn't get double buffering to work on this which always resulted in a flicker. I had the buffering taken care of if I used a Canvas, but this resulted in problems when used in conjunction with a JScrollPane.

So I downloaded JRE 1.6.18 in hopes that one of these problems would be fixed. Well now the JComponent inside the JScrollPane is not drawing properly at all. It draws only the outside region of the JComponent, as if the JScrollPane is drawing on top of it except for the borders.

Here is an example of code that is not drawing..this results in a 1-pixel-wide white outline of the area where drawing should occur:

public void paint(Graphics arg0) {



Graphics2D graphics = (Graphics2D) arg0;

  graphics.setColor(Color.WHITE);
  graphics.fillRect(0, 0, (int) getWidth(), (int) getHeight());

Any help is greatly appreciated! -Craig

+2  A: 

try to make an override from paintComponent(Graphics g) instead of paint(Graphics g). paintComponent is the method you have to override for costum drawing.

Are you sure you can see the white rectangle, try to use red or something else you can see good.

Martijn Courteaux
HiThanks for the response. Ya, the outline is definitely there. I tried it in Red also. I also tried putting my paint code in paintComponent but I got the same result.I added the painting JComponent directly to the center of a JDialog and it paints perfectly. However, as soon as I add it to a JScrollPane and put that in the JDialog I start getting the weird drawing behavior. Here is the code where I'm adding to the dialog/scrollpane:
Craig
JScrollPane scrollPane = new JScrollPane();scrollPane.add(containerCanvas);scrollPane.setSize(containerCanvas.getSize());dialog.add(scrollPane, BorderLayout.CENTER);dialog.setVisible(true);
Craig
+1  A: 

Ok, I've come up with a slight answer. Instead of calling

scrollPane.add(containerCanvas);

I'm calling

new JScrollPane(containerCanvas);

This works in a sense. However, it now is disallowing the JScrollPane bars from showing up. I have no idea why this is, but am currently looking into it. But at least the component is drawing again.

Craig
To bring up the scrolling, just PREFERRED size, not getSize, which is what I was doing in my scrollable component.If you can't instantiate the scroll pane with the component, you can also call scrollPane.getViewport.add(component). That does the same thing.Thanks for everyone that looked at this.
Craig
+1  A: 

It looks like you're making progress, but you might like to see the tutorial examples, too.

Martijn Courteaux's analysis is correct: you should override paintComponent(). Also, it's a bad idea to mix AWT and Swing components. Both ideas are discussed in Painting in AWT and Swing.

Scrolling shouldn't cause flickering. Here's an example that scrolls a grid of components and paints a checkerboard on the background.

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

public class Scrolling extends JFrame {

    private static final int MAX = 8;
    private static final int SIZE = 480;
    private static final Color light = new Color(0x40C040);
    private static final Color dark  = new Color(0x408040);

    private static class MyPanel extends JPanel {

        public MyPanel() {
            super(true);
            this.setLayout(new GridLayout(MAX, MAX, MAX, MAX));
            this.setPreferredSize(new Dimension(SIZE, SIZE));
            for (int i = 0; i < MAX * MAX; i++) {
                this.add(new JLabel(String.valueOf(i), JLabel.HORIZONTAL));
            }
        }

        @Override
        public void paintComponent(final Graphics g) {
            int w = this.getWidth()/MAX;
            int h = this.getHeight()/MAX;
            for (int row = 0; row < MAX; row++) {
                for (int col = 0; col < MAX; col++) {
                    g.setColor((row + col) % 2 == 0 ? light : dark);
                    g.fillRect(col * w, row * h, w, h);
                }
            }
        }
    }

    public Scrolling() {

        this.setLayout(new BorderLayout());
        final MyPanel panel = new MyPanel();
        final JScrollPane scrollPane = new JScrollPane(panel);
        scrollPane.getHorizontalScrollBar().setUnitIncrement(16);
        scrollPane.getVerticalScrollBar().setUnitIncrement(16);
        this.add(scrollPane, BorderLayout.CENTER);
        this.pack();
        this.setSize(SIZE - SIZE / 3, SIZE - SIZE / 3);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
    }

    public static void main(final String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Scrolling().setVisible(true);
            }
        });
    }
}
trashgod