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

时间:2015-06-26 22:44:14

标签: java swing jcomponent

我好奇...为什么JComponent.isLightweightComponent(Component c)方法在传递JLabel,JButton等swing组件时返回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不是轻量级组件

2 个答案:

答案 0 :(得分:1)

方法isLightweightComponent实际上并没有检查组件本身是否是轻量级的,而是检查组件是否"对等"很轻巧。 (因此,也许这种方法没有很好地命名?)

在内部,该方法检查组件的对等方是否是LightweightPeerc.getPeer() instanceof LightweightPeer的实例。看起来只有NullComponentPeerNullEmbeddedFramePeer才能实现此接口。此外,isLightweightComponent的JavaDoc可以这样说:

  

如果此组件是轻量级的,也就是说,如果它没有本机窗口系统对等方,则返回true。

从我可以收集到的内容来看,同行是一种拾取本机操作系统事件并将其路由到组件的幕后方法。

<强>更新

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

总结:isLightweightComponent仅检查组件的对等方是LightweightPeer的实例,并返回false(而不是返回null或当它无法实际确定对等体是否轻量级时,抛出异常。

答案 1 :(得分:1)

部分方法(关于AWT / SWing GUI系统属性,Dimension,isXxxXxx等)分别需要true来自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)