自定义绘制组件未在JScrollPane内部绘制

时间:2010-02-02 18:28:16

标签: java jscrollpane jcomponent

我使用的是Java JRE 1.6.7并且有一个JComponent和一个JScrollPane。我无法获得双缓冲来处理这种情况,这总是导致闪烁。如果我使用Canvas,我会对缓冲进行处理,但是当与JScrollPane结合使用时会出现问题。

所以我下载了JRE 1.6.18,希望能解决其中一个问题。那么现在JScrollPane中的JComponent根本没有正确绘制。它只绘制JComponent的外部区域,就好像JScrollPane除了边框之外在它上面绘制。

以下是未绘制的代码示例..这会导致绘图区域的1像素宽的白色轮廓:

public void paint(Graphics arg0) {



Graphics2D graphics = (Graphics2D) arg0;

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

非常感谢任何帮助! -Craig

3 个答案:

答案 0 :(得分:2)

尝试从paintComponent(Graphics g)而不是paint(Graphics g)进行覆盖。 paintComponent是您必须覆盖costum绘图的方法。

您确定可以看到白色矩形,尝试使用红色或其他您可以看到的其他东西。

答案 1 :(得分:2)

看起来你正在取得进步,但你也希望看到tutorial examples

Martijn Courteaux的分析是正确的:你应该覆盖paintComponent()。此外,混合AWT和Swing组件是一个坏主意。这两个想法都在Painting in AWT and Swing中进行了讨论。

滚动不应导致闪烁。这是一个滚动组件网格并在背景上绘制棋盘的示例。

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

答案 2 :(得分:1)

好的,我想出了一个小答案。 而不是打电话

scrollPane.add(containerCanvas);

我正在打电话

new JScrollPane(containerCanvas);

这在某种意义上是有效的。但是,现在它不允许JScrollPane栏显示出来。我不知道为什么会这样,但我现在正在研究它。但至少该组件正在重新绘制。