Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.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 如果两个组件尺寸相同且全屏显示,则JLayeredPane不绘制低组件_Java_Swing - Fatal编程技术网

Java 如果两个组件尺寸相同且全屏显示,则JLayeredPane不绘制低组件

Java 如果两个组件尺寸相同且全屏显示,则JLayeredPane不绘制低组件,java,swing,Java,Swing,JLayeredPane如果两个组件尺寸相同且全屏显示,则不绘制低组件 软件工作原理: JFrame当一个不透明组件与另一个组件重叠时,有意跳过绘制完全遮挡的组件。只有当组件被错误地声明为不透明时,这才可能成为一个问题。因此,当您实现自己的组件绘制透明图像时,它们应该实现返回false的isOpaque()方法 有趣的是,我仍然可以使用以下代码重现透明组件的重新绘制问题: JFrame f = new JFrame("Test"); JLayeredPane pane = f.getLayere

JLayeredPane
如果两个组件尺寸相同且全屏显示,则不绘制低组件

软件工作原理:


JFrame当一个不透明组件与另一个组件重叠时,有意跳过绘制完全遮挡的组件。只有当组件被错误地声明为不透明时,这才可能成为一个问题。因此,当您实现自己的组件绘制透明图像时,它们应该实现返回
false
isOpaque()
方法

有趣的是,我仍然可以使用以下代码重现透明组件的重新绘制问题:

JFrame f = new JFrame("Test");
JLayeredPane pane = f.getLayeredPane();
JButton b = new JButton("Normal Text");
b.setHorizontalTextPosition(SwingConstants.LEFT);
b.setBounds(20, 20, 300, 100);
JLabel l = new JLabel("Overlay");
l.setHorizontalTextPosition(SwingConstants.RIGHT);
l.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
l.setBounds(20, 20, 300, 100);
l.setOpaque(false);
pane.add(l);
pane.add(b);
f.setSize(350, 200);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
在这里,文本“覆盖”最初可能会出现,也可能不会出现,但一旦按钮的某个属性发生变化(例如,接收焦点或单击),文本就会消失

问题在于以下属性:

System.out.println(pane.isOptimizedDrawingEnabled());
将打印
true
。“优化绘图”意味着某些子对象在某些情况下可能无法渲染。正如上面所说:

如果此组件平铺其子组件,则返回true,也就是说,如果它可以保证子组件不会重叠

当然,
JLayeredPane
永远不会平铺子对象,而是将它们堆叠在一起,并且永远不能保证它们不会重叠。然而,出于某种原因,Swing开发人员决定实现以下逻辑:

private void validateOptimizedDrawing() {
    boolean layeredComponentFound = false;
    synchronized(getTreeLock()) {
        Integer layer;

        for (Component c : getComponents()) {
            layer = null;

            if(SunToolkit.isInstanceOf(c, "javax.swing.JInternalFrame") ||
                   (c instanceof JComponent &&
                    (layer = (Integer)((JComponent)c).
                                 getClientProperty(LAYER_PROPERTY)) != null))
            {
                if(layer != null && layer.equals(FRAME_CONTENT_LAYER))
                    continue;
                layeredComponentFound = true;
                break;
            }
        }
    }

    if(layeredComponentFound)
        optimizedDrawingPossible = false;
    else
        optimizedDrawingPossible = true;
}
因此,每当组件不是
JComponent
实例或不具有
LAYER\u属性
属性时(如上例所示,使用默认层时总是如此),该窗格决定可以进行优化绘制,尽管实际布局逻辑中没有任何更改

所以当我们改变的时候

pane.add(l);
pane.add(b);

问题将消失,如
System.out.println(pane.isOptimizedDrawingEnabled())将立即打印
false


当心自动包装。当您使用
窗格时,添加(l,JLayeredPane.DEFAULT_LAYER+1)或只是
窗格。添加(l,1)
,它将调用
add(Component,int index)
而不是所需的
add(Component,Object constraints)

在覆盖中是否调用super的paintComponent方法?顶级JPanel是否不透明?您的“repaint()循环”Swing线程安全吗?A在这里会有很大帮助。我可以确认,如果组件具有相同的边界(位置、大小)并且是不透明的,则不会调用较低的
paintComponent()
。如果没有明显可见的较低部分,可能也是如此。我怀疑这不仅仅是JLayeredPane。。。只有20行代码…@CarlosHeuberger嗯,当组件不透明时,完全模糊的组件是故意不涂漆的。有趣的是,即使是透明组件也有重新绘制
JLayeredPane
的问题。非常感谢!我通常删除super.paintComponent();所以我没有想到这一点。我通过调用setOpaque(false)修复了它;在构造函数中。你的回答很有帮助!
System.out.println(pane.isOptimizedDrawingEnabled());
private void validateOptimizedDrawing() {
    boolean layeredComponentFound = false;
    synchronized(getTreeLock()) {
        Integer layer;

        for (Component c : getComponents()) {
            layer = null;

            if(SunToolkit.isInstanceOf(c, "javax.swing.JInternalFrame") ||
                   (c instanceof JComponent &&
                    (layer = (Integer)((JComponent)c).
                                 getClientProperty(LAYER_PROPERTY)) != null))
            {
                if(layer != null && layer.equals(FRAME_CONTENT_LAYER))
                    continue;
                layeredComponentFound = true;
                break;
            }
        }
    }

    if(layeredComponentFound)
        optimizedDrawingPossible = false;
    else
        optimizedDrawingPossible = true;
}
pane.add(l);
pane.add(b);
Object myLayer = JLayeredPane.DEFAULT_LAYER+1;
pane.add(l, myLayer);
pane.add(b, myLayer);