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

发布于 2024-08-19 16:16:24 字数 543 浏览 5 评论 0原文

我使用的是 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());

非常感谢任何帮助! -克雷格

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

旧夏天 2024-08-26 16:16:24

尝试从 paintComponent(Graphics g) 而不是 paint(Graphics g) 进行覆盖。
PaintComponent 是您必须重写以进行服装绘制的方法。

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

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.

烂人 2024-08-26 16:16:24

看起来您正在取得进展,但您可能希望看到 教程示例也是如此。

Martijn Courteaux 的分析是正确的:您应该重写 paintComponent()。另外,混合使用 AWT 和 Swing 组件也是一个坏主意。 在 AWT 和 Swing 中绘制<中讨论了这两种想法/a>.

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

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

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);
            }
        });
    }
}
椵侞 2024-08-26 16:16:24

好吧,我已经想出了一个简单的答案。
打电话,而是

scrollPane.add(containerCanvas);

我不是

new JScrollPane(containerCanvas);

打电话,这在某种意义上是有效的。但是,现在不允许显示 JScrollPane 栏。我不知道为什么会这样,但目前正在调查。但至少组件又开始绘制了。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文