gpt4 book ai didi

java - getClipBounds 与 JScrollPane 结合使用错误

转载 作者:行者123 更新时间:2023-12-01 12:50:40 28 4
gpt4 key购买 nike

也许我遇到了错误或更可能做错了什么;)我尝试使用 JScrollPanel 翻译用户绘制的 JPanel 的内容。在面板内部,我想通过 Graphics 类的 getClipBounds 方法访问可见区域,以提高渲染性能。

搜索 SO 会带来很多涉及 JScrollPane 的结果,但没有提到剪辑边界的问题。谷歌也一样。

用户绘制的面板

import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;

public class Content extends JPanel {
@Override
protected void paintChildren(Graphics g) {
super.paintChildren(g);
// intense clip bounds dependent rendering here
System.out.println(g.getClipBounds());
}
@Override
public Dimension getPreferredSize() {
return new Dimension(2000,2000);
}
}

主框架设置

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;

public class ClipBoundsIssue {
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ClipBoundsIssue window = new ClipBoundsIssue();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public ClipBoundsIssue() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane scrollPane = new JScrollPane();
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
Content content = new Content();
scrollPane.setViewportView(content);
}
}

重现

只需运行代码,移动滚动条之一并检查 System.out 的控制台输出。下图描绘了在 x 轴上滚动条形图。

moved scrollbar on x axis

实际System.out结果

产生以下结果

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。

现在的问题是

有谁知道为什么会发生这种情况,或者如何避免这种情况?

废弃的WA

一个可能的解决方法是查找视口(viewport)的 View 边界。但如果可能的话,我想避免 Content 类进行任何此类查找。另一种选择是将信息传递到 Content 类中,但我也想避免这样做。

最佳答案

I would have expected to have the width of the bounds to keep the same.

为什么?它太简单了,很难解释,但让我尝试一下。

当您滚动时,如果缓慢滚动,则仅出现 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,则整个视口(viewport)将被裁剪。我还补充说,JPanel 在调整大小时会完全重新绘制,其优化仅针对滚动。

关于java - getClipBounds 与 JScrollPane 结合使用错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24233722/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com