为什么Java swing组件显示为不轻量级,即使它们应该是轻量级的?
我很好奇。。。为什么JComponent.isLightweightComponent(组件c)方法在传递swing组件(如JLabel、JButton等)时返回false。?根据我读到的所有内容,这些组件应该是轻量级的 这是否表明他们实际上是重量级的(绝对不应该是) 或者isLightweightComponent()方法是否以某种方式被破坏 还是我不了解isLightweightComponent()方法 请尝试以下代码以了解我的意思为什么Java swing组件显示为不轻量级,即使它们应该是轻量级的?,java,swing,jcomponent,Java,Swing,Jcomponent,我很好奇。。。为什么JComponent.isLightweightComponent(组件c)方法在传递swing组件(如JLabel、JButton等)时返回false。?根据我读到的所有内容,这些组件应该是轻量级的 这是否表明他们实际上是重量级的(绝对不应该是) 或者isLightweightComponent()方法是否以某种方式被破坏 还是我不了解isLightweightComponent()方法 请尝试以下代码以了解我的意思 import javax.swing.JButton;
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
fromisEventDispatchThread
,例如
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。我猜区别在于父帧是否可见。感谢您提供的信息!