gpt4 book ai didi

java - setVisible() 和正在绘制的组件之间会发生什么?

转载 作者:行者123 更新时间:2023-12-04 00:33:52 27 4
gpt4 key购买 nike

我有一个 JScrollPane包含 JPanel然后包含一些自定义组件,它们是 JPanel 的扩展(它们都是同一类型)。此 JScrollPane 在包含 JFrame 之前设置为不可见显示。

当用户选择 JCheckBox我用 setVisible()显示滚动 Pane 。但是,第一次显示 Pane 时,在调用 setVisible() 和绘制 Pane 之间存在明显的延迟。如果用户取消选中并重新选中该复选框,则会立即绘制 Pane 。

我的自定义组件已经构建并添加到面板中。他们是ComponentListener s 但除了 componentResized() 之外还有空的实现.他们还有一个自定义 paintComponent()方法,但该方法内的断点显示延迟发生在调用 this 之前,因此这不是缓慢绘制的情况。

JScrollPane 或 JPanel 都没有任何其他监听器。 setVisible()paintComponent() 之间还发生了什么?我还可以从哪些地方确定延迟的原因?


编辑:试图创建和 MCVEKevin Workman的建议下我发现我的问题与我想象的略有不同。似乎如果没有其他任何事情发生,滚动 Pane 将永远不会被绘制。

在我的最小示例(见下文)中,在我调整框架大小之前,该项目不会显示。在初始显示之后 setVisible() 立即应用,就像在完整程序中一样。以下是演示问题的示例代码:

public class VisibilityDelayExample extends JFrame {

private JPanel contentPane;
private JCheckBox chckbxAdvancedView;
private JScrollPane scrollPane;

/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
VisibilityDelayExample frame = new VisibilityDelayExample();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Create the frame.
*/
public VisibilityDelayExample() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);

chckbxAdvancedView = new JCheckBox("Advanced View");
chckbxAdvancedView.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent arg0) {
System.err.println("Property Changed");
if(chckbxAdvancedView.isSelected() != scrollPane.isVisible()){
scrollPane.setVisible(chckbxAdvancedView.isSelected());
scrollPane.invalidate();
scrollPane.repaint();
VisibilityDelayExample.this.invalidate();
VisibilityDelayExample.this.repaint();
}
}
});
contentPane.add(chckbxAdvancedView, BorderLayout.NORTH);

scrollPane = new JScrollPane();
scrollPane.setVisible(false);
contentPane.add(scrollPane, BorderLayout.CENTER);

JPanel panel = new JPanel();
scrollPane.setViewportView(panel);
for(int j = 0; j < 100;j++){
panel.add(new JLabel("Label " + j));
}
}

}

现在的问题是,在调整大小期间发生了什么导致 setVisible() 生效,我怎样才能让它立即生效?

最佳答案

Now the question is, what is happening during a resize that is causing

当您调整框架大小时,将调用布局管理器,以便将滚动 Pane 的大小从 (0, 0) 更改为适当的值。

how can I cause it to happen instantly?

当您从可见的 GUI 添加/删除组件时,您需要在父容器上使用 revalidate()repaint()。我知道您没有添加组件,但效果是一样的,因为它没有有效的大小。

// scrollPane.revalidate();
// scrollPane.repaint();
// VisibilityDelayExample.this.invalidate();
// VisibilityDelayExample.this.repaint();
contentPane.revalidate();
contentPane.repaint();

关于java - setVisible() 和正在绘制的组件之间会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22387773/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com