为什么Java swing组件显示为不轻量级,即使它们应该是轻量级的?

为什么Java swing组件显示为不轻量级,即使它们应该是轻量级的?,java,swing,jcomponent,Java,Swing,Jcomponent,我很好奇。。。为什么JComponent.isLightweightComponent(组件c)方法在传递swing组件(如JLabel、JButton等)时返回false。?根据我读到的所有内容,这些组件应该是轻量级的 这是否表明他们实际上是重量级的(绝对不应该是) 或者isLightweightComponent()方法是否以某种方式被破坏 还是我不了解isLightweightComponent()方法 请尝试以下代码以了解我的意思 import javax.swing.JButton;

我很好奇。。。为什么JComponent.isLightweightComponent(组件c)方法在传递swing组件(如JLabel、JButton等)时返回false。?根据我读到的所有内容,这些组件应该是轻量级的

这是否表明他们实际上是重量级的(绝对不应该是)

或者isLightweightComponent()方法是否以某种方式被破坏

还是我不了解isLightweightComponent()方法

请尝试以下代码以了解我的意思

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class SwingLightweightTest {

    public static void main(String[] args) {
        // why do swing components show that they not Lightweight?
        // does this mean that they are Heavywight?
        // or is the .isLightweightComponent() method broken?

        JLabel jLabel = new JLabel();
        testLightweight(jLabel);

        JButton jButton = new JButton();
        testLightweight(jButton);

        JPanel jPanel = new JPanel();
        testLightweight(jPanel);
    }

    private static void testLightweight(JComponent comp) {
        String isIsnot;

        isIsnot = JComponent.isLightweightComponent(comp) ? "IS ": "IS NOT ";
        System.out.println(comp.getUIClassID() + " \t" + isIsnot + "a lightweight component");      

    }
}
它返回以下内容:

LabelUI不是一个轻量级组件

ButtonUI不是一个轻量级组件


PanelUI不是一个轻量级组件

该方法实际上并没有检查组件本身是否轻量级,而是检查组件的“对等”是否轻量级。(因此,也许这个方法的名字不太好?)

在内部,该方法检查组件的对等体是否是LightweightPeer的实例:
c.getPeer()实例LightweightPeer
。看起来只有
NullComponentPeer
NullEmbeddedFramePeer
甚至实现了这个接口。另外,
isLightweightComponent
的JavaDoc有这样一句话:

如果此组件是轻量级的,即如果它没有本机窗口系统对等体,则返回true

据我所知,对等点是一种幕后手段,用于拾取本机操作系统事件并将其路由到组件

更新

经过进一步调查,我发现在组件可见之前,它没有对等体(
c.getPeer()
返回null),因此LightweightPeer的检查
c.getPeer()instanceof
将返回
false
(似乎表明该组件不是轻量级的,这是误导性的)。一旦组件变得可见,它将被分配一个对等方(例如,我的测试表明JLabel获得一个NullComponentPeer实例作为其对等方),因此将从调用
isLightweightComponent
返回正确的信息

总之:
isLightweightComponent
仅当组件的对等方是
LightweightPeer
的实例时才进行检查,当无法实际确定对等方是否为轻量级时,它返回
false
(而不是返回
null
或引发异常)。

方法的一部分(关于AWT/SWing GUI系统属性、维度、isXxxXxx等)所需的可见顶级容器,分别为
true
from
isEventDispatchThread
,例如

import java.awt.EventQueue;
import javax.swing.*;
import java.awt.event.*;

public class Test {

    private JFrame frame = new JFrame();
    private JPanel panel = new JPanel();
    private JLabel label = new JLabel("JLabel");
    private JButton button = new JButton("JButton");
    private String[] list = {"1", "2", "3", "4",};
    private JComboBox comb = new JComboBox(list);
    final JPopupMenu pop = new JPopupMenu();
    private Boolean bol = false;

    public Test() {
        comb.setLightWeightPopupEnabled(true);
        panel.add(label);
        panel.add(button);
        panel.add(comb);
        //
        System.out.println("before visible, out of EDT ---> "
                + (bol = pop.isLightweight()));
        System.out.println("before visible, out of EDT ---> "
                + (bol = pop.isLightweightComponent(comb)));
        pop.setLightWeightPopupEnabled(true);
        pop.add(comb);
        System.out.println("before visible, out of EDT ---> "
                + (bol = comb.isLightweight()));
        System.out.println("before visible, out of EDT ---> "
                + (bol = JComponent.isLightweightComponent(comb)));
        System.out.println("before visible, out of EDT ---> "
                + (bol = button.isLightweight()));
        System.out.println("before visible, out of EDT ---> "
                + (bol = JComponent.isLightweightComponent(button)));
        System.out.println("before visible, out of EDT ---> "
                + (bol = label.isLightweight()));
        System.out.println("before visible, out of EDT ---> "
                + (bol = JComponent.isLightweightComponent(label)));
        //
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.setVisible(true);
        frame.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                System.out.println("mousePressed");
                pop.show(e.getComponent(), e.getX(), e.getY());
                bol = false;
                System.out.println("JComponents are visible, on EDT ---> "
                        + (bol = pop.isLightweight()));
                System.out.println("JComponents are visible, on EDT ---> "
                        + (bol = pop.isLightweightComponent(comb)));
                System.out.println("JComponents are visible, on EDT ---> "
                        + (bol = comb.isLightweight()));
                System.out.println("JComponents are visible, on EDT ---> "
                        + (bol = JComponent.isLightweightComponent(comb)));
                System.out.println("JComponents are visible, on EDT ---> "
                        + (bol = button.isLightweight()));
                System.out.println("JComponents are visible, on EDT ---> "
                        + (bol = JComponent.isLightweightComponent(button)));
                System.out.println("JComponents are visible, on EDT ---> "
                        + (bol = label.isLightweight()));
                System.out.println("JComponents are visible, on EDT ---> "
                        + (bol = JComponent.isLightweightComponent(label)));
            }
        });
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }
}
有输出

run:
before visible, out of EDT ---> false
before visible, out of EDT ---> false
before visible, out of EDT ---> false
before visible, out of EDT ---> false
before visible, out of EDT ---> false
before visible, out of EDT ---> false
before visible, out of EDT ---> false
before visible, out of EDT ---> false
mousePressed
JComponents are visible, on EDT ---> true
JComponents are visible, on EDT ---> true
JComponents are visible, on EDT ---> true
JComponents are visible, on EDT ---> true
JComponents are visible, on EDT ---> true
JComponents are visible, on EDT ---> true
JComponents are visible, on EDT ---> true
JComponents are visible, on EDT ---> true
BUILD SUCCESSFUL (total time: 7 seconds)

谢谢neuronaut!我还是java的新手。还有很长的路要走。我的问题对我当前的编码来说并不重要。只是注意到主应用程序框架的一些缓慢绘制,并试图解决这个问题。我觉得如果子组件是轻量级的,它们的渲染速度会比我看到的更快(对于内部java图形上下文)。可能是因为我还没有为UI使用单独的线程,或者这是一个eclipse问题。但至少我现在可以专注于其他可能的原因,忽略轻量级的东西。谢谢!请修改或删除此答案,不同意可见的JComponents总是返回true(不包括JComboBox的JPopup)一切都取决于是否存在EDT,然后取决于JComponent是否可见not@mKorbel…不确定EDT是什么…这会是事件调度线程吗?@mKorbel@AndyBody我已经更新了我的答案,以便更清楚地了解为什么在调用可见和不可见的isLightweightComponent时,响应会有所不同e components.ok,我使用了您的示例,现在看到AWT.isLightweight()和JComponent.isLightweightComponent()在帧设置为可见时确实为JComponents返回true。我猜区别在于父帧是否可见。感谢您提供的信息!