Java 与JScrollPane组合使用的getClipBounds错误

Java 与JScrollPane组合使用的getClipBounds错误,java,swing,jscrollpane,java-2d,clip,Java,Swing,Jscrollpane,Java 2d,Clip,也许我遇到了一个bug,或者更可能是做错了什么;) 我尝试使用JScrollPanel翻译用户绘制的JPanel的内容。在面板内部的图形中,我希望通过GraphicsclassgetClipBounds方法访问可见区域,以提高渲染性能 搜索SO会得到很多关于JScrollPane的结果,但没有一个提到剪辑边界的问题。谷歌也一样 用户绘制的面板 主机架设置 复制 只需运行代码,移动其中一个滚动条并检查System.out的控制台输出。下图显示了在x轴上滚动条 实际系统输出结果 这产生了以下结果

也许我遇到了一个bug,或者更可能是做错了什么;) 我尝试使用
JScrollPanel
翻译用户绘制的
JPanel
的内容。在面板内部的图形中,我希望通过
Graphics
class
getClipBounds
方法访问可见区域,以提高渲染性能

搜索SO会得到很多关于
JScrollPane
的结果,但没有一个提到剪辑边界的问题。谷歌也一样

用户绘制的面板 主机架设置 复制 只需运行代码,移动其中一个滚动条并检查
System.out
的控制台输出。下图显示了在x轴上滚动条

实际
系统输出
结果 这产生了以下结果

java.awt.Rectangle[x=0,y=0,width=416,height=244]
java.awt.Rectangle[x=416,y=0,width=16,height=244]
java.awt.Rectangle[x=432,y=0,width=15,height=244]
java.awt.Rectangle[x=447,y=0,width=16,height=244]
java.awt.Rectangle[x=463,y=0,width=15,height=244]
预期结果 我希望边界的宽度保持不变。但它从416变为16

现在的问题是 有人知道为什么会发生这种情况,或者如何避免这种情况吗

讨论的是 一种可能的解决方法是查找视图端口的视图边界。但是如果可能的话,我希望避免
内容
类进行任何这样的查找。另一种选择是将信息传递到
Content
类中,但我也希望避免这种情况

我希望边界的宽度保持不变

为什么??这很简单,很难解释,但让我试试

当您滚动时,如果您缓慢滚动,JPanel只会出现一小部分新内容

生成的输出绝对正确:

java.awt.Rectangle[x=0,y=0,width=416,height=244]
控件第一次显示时,您需要完全重新绘制它

java.awt.Rectangle[x=416,y=0,width=16,height=244]
您向右滚动了16个像素,因此只能重新绘制控件的窄条

您必须了解这些坐标与控件相关,控件的大小设置为2000x2000像素

尝试滚动使用此代码创建的窗口,您将看到我所说的内容:

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

public class ScrollPaneRepaintDemo extends JPanel {
    public ScrollPaneRepaintDemo() {
        setPreferredSize(new Dimension(2000,2000));
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new ScrollPaneRepaintDemo()));
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    @Override protected void paintComponent(Graphics g) {
        Rectangle clip = g.getClipBounds();
        g.setColor(new Color(new Random().nextInt()));
        g.fillRect(clip.x, clip.y, clip.width, clip.height);
    }
}

顺便说一句,由于JPanel的内部实现,它可以正常工作。如果改为扩展JComponent,则整个视口将被剪裁。我还补充说,JPanel在调整大小时完全重新绘制,其优化仅用于滚动;
图形
上下文的某些元素可能会随着绘制链的每次行程而改变。这可能有助于批判性地检查依赖剪辑区域的必要性。@trashgood哦,我会看看它并重新评估。。。
java.awt.Rectangle[x=0,y=0,width=416,height=244]
java.awt.Rectangle[x=416,y=0,width=16,height=244]
java.awt.Rectangle[x=432,y=0,width=15,height=244]
java.awt.Rectangle[x=447,y=0,width=16,height=244]
java.awt.Rectangle[x=463,y=0,width=15,height=244]
import javax.swing.*;
import java.awt.*;
import java.util.Random;

public class ScrollPaneRepaintDemo extends JPanel {
    public ScrollPaneRepaintDemo() {
        setPreferredSize(new Dimension(2000,2000));
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new ScrollPaneRepaintDemo()));
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    @Override protected void paintComponent(Graphics g) {
        Rectangle clip = g.getClipBounds();
        g.setColor(new Color(new Random().nextInt()));
        g.fillRect(clip.x, clip.y, clip.width, clip.height);
    }
}