java 组件变为可见时的事件
java event for when the component becomes visible
我有一个 JScrollPane 环绕着一个 JPanel,它可能包含数百个显示缩略图图像的 JLabel(每个 JLabel 一个缩略图)。出于记忆原因,我不想构建所有缩略图。我只想为可见的 JLabel 构建缩略图,并在它们的 JLabel 变得不可见时删除缩略图。当用户滚动 JPanel 时,它们变为 visible/invisible。我尝试使用 ComponentListener 实现 loading/unloading 缩略图,如下所示:
addComponentListener( new ComponentAdapter() {
@Override
public void componentShown( ComponentEvent e ) {
setIcon( new ImageIcon( getThumb() ) );
}
@Override
public void componentHidden( ComponentEvent e ) {
setIcon( null );
}
});
但这行不通。 JLabel 始终为空。我可以使用滚动事件并计算应该加载哪些缩略图,但在我这样做之前我想知道是否有更简单的解决方案。
"visible"属性不代表可见"on screen"。它仅指示组件本身是否要显示。由于组件在默认情况下是可见的,并且只有在 属性 更改时才会通知侦听器 您的侦听器永远不会收到通知。
据我所知,当组件进入显示器的可见区域时,没有专门的事件通知组件。另请注意,在标签上设置图标可能会改变其首选大小,从而破坏整个布局。这可以通过手动给标签一个固定的首选大小来解决(对于缩略图来说应该很简单)。
一种懒惰的方法是覆盖标签上的 paintComponent 并检查是否需要在 paintComponent 中加载缩略图:
protected void paintComponent(Graphics g) {
if (getIcon() == null) {
// create thumbnail
}
super.paintComponent(g);
}
这不是最好的方法,因为您的代码将 运行 在 Swings 事件分派线程中。这意味着加载缩略图的任何延迟都会阻止 UI.
的渲染
IMO 更明智的方法是 请求 加载缩略图并将实际加载推迟到后台线程。当该线程完成加载时,它可以使用 SwingUtilities.invoke(或 invokeLater)更新标签(如果我没记错的话会自动触发重绘)。
效果是卷入的标签短暂显示为空,然后在拇指可用时立即更新。
我有一个 JScrollPane 环绕着一个 JPanel,它可能包含数百个显示缩略图图像的 JLabel(每个 JLabel 一个缩略图)。出于记忆原因,我不想构建所有缩略图。我只想为可见的 JLabel 构建缩略图,并在它们的 JLabel 变得不可见时删除缩略图。当用户滚动 JPanel 时,它们变为 visible/invisible。我尝试使用 ComponentListener 实现 loading/unloading 缩略图,如下所示:
addComponentListener( new ComponentAdapter() {
@Override
public void componentShown( ComponentEvent e ) {
setIcon( new ImageIcon( getThumb() ) );
}
@Override
public void componentHidden( ComponentEvent e ) {
setIcon( null );
}
});
但这行不通。 JLabel 始终为空。我可以使用滚动事件并计算应该加载哪些缩略图,但在我这样做之前我想知道是否有更简单的解决方案。
"visible"属性不代表可见"on screen"。它仅指示组件本身是否要显示。由于组件在默认情况下是可见的,并且只有在 属性 更改时才会通知侦听器 您的侦听器永远不会收到通知。
据我所知,当组件进入显示器的可见区域时,没有专门的事件通知组件。另请注意,在标签上设置图标可能会改变其首选大小,从而破坏整个布局。这可以通过手动给标签一个固定的首选大小来解决(对于缩略图来说应该很简单)。
一种懒惰的方法是覆盖标签上的 paintComponent 并检查是否需要在 paintComponent 中加载缩略图:
protected void paintComponent(Graphics g) {
if (getIcon() == null) {
// create thumbnail
}
super.paintComponent(g);
}
这不是最好的方法,因为您的代码将 运行 在 Swings 事件分派线程中。这意味着加载缩略图的任何延迟都会阻止 UI.
的渲染IMO 更明智的方法是 请求 加载缩略图并将实际加载推迟到后台线程。当该线程完成加载时,它可以使用 SwingUtilities.invoke(或 invokeLater)更新标签(如果我没记错的话会自动触发重绘)。
效果是卷入的标签短暂显示为空,然后在拇指可用时立即更新。