Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.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 为什么这个JLabel会不断地重新喷漆?_Java_Swing_Paint - Fatal编程技术网

Java 为什么这个JLabel会不断地重新喷漆?

Java 为什么这个JLabel会不断地重新喷漆?,java,swing,paint,Java,Swing,Paint,我有一个项目,当它存在时,似乎会不断地重新绘制,导致CPU在我的任何窗口中都会出现峰值。它直接继承自JLabel,与屏幕上的其他JLabel不同,它具有红色背景和边框。我不知道为什么它会有足够的不同,以不断地重新油漆。调用堆栈如下所示: Thread [AWT-EventQueue-1] (Suspended (breakpoint at line 260 in sItem)) sItem.paint(Graphics) line: 260 sItem(JComponent)

我有一个项目,当它存在时,似乎会不断地重新绘制,导致CPU在我的任何窗口中都会出现峰值。它直接继承自JLabel,与屏幕上的其他JLabel不同,它具有红色背景和边框。我不知道为什么它会有足够的不同,以不断地重新油漆。调用堆栈如下所示:

Thread [AWT-EventQueue-1] (Suspended (breakpoint at line 260 in sItem)) 
    sItem.paint(Graphics) line: 260 
    sItem(JComponent).paintToOffscreen(Graphics, int, int, int, int, int, int) line: 5124   
    RepaintManager$PaintManager.paintDoubleBuffered(JComponent, Image, Graphics, int, int, int, int) line: 1475 
    RepaintManager$PaintManager.paint(JComponent, JComponent, Graphics, int, int, int, int) line: 1406  
    RepaintManager.paint(JComponent, JComponent, Graphics, int, int, int, int) line: 1220   
    sItem(JComponent)._paintImmediately(int, int, int, int) line: 5072  
    sItem(JComponent).paintImmediately(int, int, int, int) line: 4882   
    RepaintManager.paintDirtyRegions(Map<Component,Rectangle>) line: 803    
    RepaintManager.paintDirtyRegions() line: 714    
    RepaintManager.seqPaintDirtyRegions() line: 694 [local variables unavailable]   
    SystemEventQueueUtilities$ComponentWorkRequest.run() line: 128  
    InvocationEvent.dispatch() line: 209    
    summitEventQueue(EventQueue).dispatchEvent(AWTEvent) line: 597  
    summitEventQueue(SummitHackableEventQueue).dispatchEvent(AWTEvent) line: 26 
    summitEventQueue.dispatchEvent(AWTEvent) line: 62   
    EventDispatchThread.pumpOneEventForFilters(int) line: 269   
    EventDispatchThread.pumpEventsForFilter(int, Conditional, EventFilter) line: 184    
    EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component) line: 174   
    EventDispatchThread.pumpEvents(int, Conditional) line: 169  
    EventDispatchThread.pumpEvents(Conditional) line: 161   
    EventDispatchThread.run() line: 122 [local variables unavailable]   
bgColor = OurColors.clrWindowTextAlert;
textColor = Color.white;
setBackground(bgColor);
setOpaque(true);
setSize(150, getHeight());
Border border_warning = BorderFactory.createCompoundBorder(
        BorderFactory.createMatteBorder(1, 1, 1, 1, OurColors.clrXBoxBorder),
        Global.border_left_margin);
setBorder(border_warning);
它显然做得更多,但特定的块只存在于导致尖峰/连续重绘的标签中


你知道为什么它会不断地重新绘制这个标签吗?

很多代码都不见了,但我会有一个有根据的猜测

类的“唯一”部分可能位于负责呈现标签的代码部分中。如果这是真的,那么调用所有这些setXXX()方法可能会使对象变脏,这意味着它需要重新绘制,这将再次输入这段代码,然后使用公共接口更新小部件,这将使对象变脏,导致循环重复

最终,这样的事情将消耗所有的空闲周期,导致CPU为一个显然没有多大作用的标签设置最大值

尝试在渲染循环之外的位置设置适当的值。这些项中的大多数看起来都可以在构造函数中设置

---确认是订单后进行编辑(…)---

设置新边框可能会触发小部件边界框的重新计算,因为边框可能比前一个边框大或小。新边框可能包含与旧边框不同的屏幕显示(升高、降低等)

这些项都不需要在渲染部分设置,但我敢打赌,对于其他项,将进行一次初步检查,以查看新项
是否等于(…)
旧项。如果是这样,则(作为优化)不会设置脏位,也不会向渲染引擎发出刷新请求


有了边框,这样的检查必须覆盖多个元素,包括一些由字节码编译的元素(实际的绘图说明)。由于在考虑边界时检查相等性不再是一个简单的优化,很可能他们根本不尝试检查相等性,而只是将小部件标记为重新绘制。

缺少很多代码,但我会根据实际情况进行猜测

类的“唯一”部分可能位于负责呈现标签的代码部分中。如果这是真的,那么调用所有这些setXXX()方法可能会使对象变脏,这意味着它需要重新绘制,这将再次输入这段代码,然后使用公共接口更新小部件,这将使对象变脏,导致循环重复

最终,这样的事情将消耗所有的空闲周期,导致CPU为一个显然没有多大作用的标签设置最大值

尝试在渲染循环之外的位置设置适当的值。这些项中的大多数看起来都可以在构造函数中设置

---确认是订单后进行编辑(…)---

设置新边框可能会触发小部件边界框的重新计算,因为边框可能比前一个边框大或小。新边框可能包含与旧边框不同的屏幕显示(升高、降低等)

这些项都不需要在渲染部分设置,但我敢打赌,对于其他项,将进行一次初步检查,以查看新项
是否等于(…)
旧项。如果是这样,则(作为优化)不会设置脏位,也不会向渲染引擎发出刷新请求


有了边框,这样的检查必须覆盖多个元素,包括一些由字节码编译的元素(实际的绘图说明)。由于在考虑边界时检查是否相等不再是一个简单的优化,很可能他们根本不尝试检查是否相等,只是将小部件标记为重新绘制。

这是边界。在每次绘制循环期间创建边框会使其不断重新绘制。如果我只创建一次边界作为类范围的私有对象,并在绘制循环中设置它,它将正确地设置边界,并且不会连续地重新绘制。如果有人知道为什么会有不同,我也会很感激你提供的信息。请随意评论,我会在可能的时候接受我的答案,或者添加一个冗长的新答案,我也会接受你的答案。

这是边界。在每次绘制循环期间创建边框会使其不断重新绘制。如果我只创建一次边界作为类范围的私有对象,并在绘制循环中设置它,它将正确地设置边界,并且不会连续地重新绘制。如果有人知道为什么会有不同,我也会很感激你提供的信息。请随意对此发表评论,我会在可能的时候接受我的答案,或者添加一个冗长的新答案,我也会接受你的答案。

请参阅JComponent.setBorder()中的代码。它使用简单的比较来比较新旧边界,因为这是两个不同的对象,所以总是返回false。如果条件保持不变,则将重新绘制零部件。因此,无限循环


作为一般规则-不要在组件的绘制方法中调用任何setter。正如您所看到的,设置边界将导致无限重绘循环。这可能发生在任何其他设置中,如果不是在这个版本的VM中,可能发生在下一个版本中。正确的方法是在模型更改时更改组件(视图)的属性,并让Swing确定何时重新绘制组件,或者自己调用repaint()。

请参阅JComponent.setboorder()中的代码。它使用简单的比较来比较新旧边界,因为这是两个不同的对象,所以总是返回false。如果