Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何调整Swing窗口的大小而不闪烁?_Java_Swing_Resize_Flicker_Jwindow - Fatal编程技术网

Java 如何调整Swing窗口的大小而不闪烁?

Java 如何调整Swing窗口的大小而不闪烁?,java,swing,resize,flicker,jwindow,Java,Swing,Resize,Flicker,Jwindow,我正在尝试基于JWindow创建一个自定义UI,以选择要共享的屏幕区域。我已经扩展了JWindow,并添加了代码,使其可调整大小,并使用AWTUtilities.setWindowsShape()来“剪切”窗口的中心 当运行代码时,当窗口在负x和y方向(即向上和向左)调整大小时,我感觉到闪烁。似乎正在发生的是,在更新组件之前,窗口已调整大小并绘制。下面是代码的简化版本。运行时,可使用顶部面板向上和向左调整窗口大小。窗口的背景设置为绿色,以清楚显示我不希望显示的像素的位置 编辑:使用Compone

我正在尝试基于
JWindow
创建一个自定义UI,以选择要共享的屏幕区域。我已经扩展了
JWindow
,并添加了代码,使其可调整大小,并使用
AWTUtilities.setWindowsShape()
来“剪切”窗口的中心

当运行代码时,当窗口在负x和y方向(即向上和向左)调整大小时,我感觉到闪烁。似乎正在发生的是,在更新组件之前,窗口已调整大小并绘制。下面是代码的简化版本。运行时,可使用顶部面板向上和向左调整窗口大小。窗口的背景设置为绿色,以清楚显示我不希望显示的像素的位置

编辑:使用
ComponentListener
改进了代码以正确塑造窗口的形状,并在底部添加了一个虚拟组件以进一步演示闪烁(同时更新了屏幕截图)

重写的
paint()
方法可以用作断点,或者可以在此处取消注释
线程.sleep()
,以便在更新发生时提供更清晰的视图

我的问题似乎源于
setBounds()
方法,该方法导致在布局之前将窗口绘制到屏幕上


调整大小之前的窗口,如其外观所示:


窗口在放大(向上和向左)的过程中,如重写的
paint()
method)处的断点所示:


窗口在调整大小时变小(向下和向右),如重写的
paint()
method)处的断点所示:


当然,这些截图是在激烈的鼠标拖动运动中拍摄的,但即使是更温和的鼠标拖动,闪烁也会变得相当恼人

“resize to Large”屏幕截图上的绿色区域显示了在完成任何绘制/布局之前绘制的新背景,这似乎发生在底层的
ComponentPeer
或本机窗口管理器中。“调整大小到更小”屏幕截图上的蓝色区域显示
JPanel
的背景被推到视图中,但现在已过时。这在Linux(Ubuntu)和Windows XP下发生

在对屏幕进行任何更改之前,是否有人找到方法使
窗口
JWindow
调整到后台缓冲区,从而避免这种闪烁效应?也许有一个
java.awt….
system属性可以设置来避免这种情况,但我找不到


编辑#2:注释掉调用
awutilities.setWindowsShape()
(并且可以选择取消
线程的注释。sleep(10)
行在
paint()
)中),然后用力拖动顶部面板,以便清楚地看到闪烁的性质


编辑#3:有人能够在Windows 7或Mac OSX上的Sun Java下测试这种行为吗

我刚刚试过你的例子。在调整窗口大小时,我确实看到了一些小的抖动。我试图替换从
setBounds()
开始的代码片段,并在
AWTUtilities.setWindowShape(这是newShape)结束

setSize(newBounds.width, newBounds.height);

然后看到电影消失了。因此,我建议您使用此解决方案,除非您有任何特殊原因使用
setBounds

另一种方法可能是在绘制之前等待用户完成拖动/调整大小。可能使用边界框向用户显示窗口的大小,直到其调整大小事件完成


我注意到很多窗口应用程序要么采用这种方法,要么处理闪烁。我尝试过的所有应用程序都有同样的问题(非Java),因此问题可能只是图形子系统,而不是Swing本身。

我承认这不是一个特别有用的答案,但了解Swing的确切含义可能会有所帮助

看,Swing自己做所有的工作,除了从操作系统中获得一点空间之外。所有的绘图、小部件等都是Java代码。与其说它运行得太慢,不如说它没有2D图形卡加速和操作系统渲染技巧的好处

还记得DirectDraw吗?现在什么东西都有,窗户也很光滑。但是,如果你曾经因为某种原因(比如说,XP安装没有驱动程序)而抓到一台没有它的计算机,你就会注意到这种类型的减速

使用Swing,因为它管理自己的所有空间,所以操作系统无法执行任何这些渲染技巧来帮助您

有人可能会提出一些优化方案来解决您计算机上的问题,但我担心这并不能真正解决基本问题—Swing速度很慢,不能更快

您应该研究本机工具包。AWT还可以,但是缺少了很多小部件/等等。它是本机的,内置的,所以如果您需要的话,它应该足够快。我偏爱SWT,这正是Eclipse、Vuze(以及其他人)所使用的。它结合了AWT的本地特性和Swing的易用性和功能,当然,它可以在任何地方运行


编辑:在阅读了更多您的评论后,很明显您完全理解了窗口是如何发生的-我不想表现为居高临下。不仅如此,你对调整尺寸更感兴趣,我的评论与此无关。我仍然推荐SWT,因为它是本机代码,速度更快,但这与上面的答案不同。

@willjcroz:+1,这是一个非常巧妙的问题。对所有人说:请不要在没有对问题进行投票的情况下对任何答案进行投票。我也想知道同一个问题的答案——我讨厌这个问题很多年了,但从来没有找到一个简单的解决办法。在Windows7上测试,虽然我没有得到和你完全相同的效果,但我得到了非常相似的东西。调整artefac的大小
setSize(newBounds.width, newBounds.height);