Java Swing:当组件*完成*调整大小时做一些事情 [英] Java Swing: Do something when a component has *finished* resizing

查看:31
本文介绍了Java Swing:当组件*完成*调整大小时做一些事情的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于这个有点不清楚的问题表示歉意 - 想不出更好的表达方式.

Apologies for the somewhat unclear question - couldn't think of a better way of putting it.

我使用 JXTaskPane(来自 Swing 实验室扩展 API)以显示一些信息.

I use a JXTaskPane (from the Swing labs extension API) to display some information.

用户可以点击"展开面板的标题.JXTaskPane 位于容器 JPanel 中,然后将其添加到 JFrame(我的主应用程序窗口)中.

The user can "click" the title to expand the panel. The JXTaskPane is in a container JPanel, which is then added to a JFrame, my main application window.

我希望我的应用程序窗口调整为展开的任务窗格的大小.为了实现这一点,我在容器 JPanel 中添加了一个组件侦听器,它将大小设置为现在展开的面板.

I want my application window to resize to the size of the expanded task pane. To achieve this, I added a component listener to my container JPanel which would set size to the now expanded panel.

panel.addComponentListener(new ComponentListener()
{   
    public void componentResized(ComponentEvent e)
    {
        Dimension newSize = ((JXTaskPane)e.getSource()).getSize();
        reSizeFrame(newSize);
    }
}

private void reSizeFrame(Dimension newSize)
{   
    if ((newSize.height < maxSize.height) && (newSize.width < maxSize.width))
    {
        containerPanel.setSize(newSize);
        appFrame.setSize(containerPanel.getSize());
        appFrame.pack();
    }
}

问题是 componentResized 方法在任务窗格展开时被调用,因此 resizeFrame 方法被调用了很多次,在屏幕上看起来很糟糕.

The problem is that the componentResized method is called as the task pane expands, as a result the resizeFrame method is called lots of times, and looks really awful on the screen.

如何检测 JXTaskpane 何时完成调整大小?我想到了两种方法:

How can I detect when the JXTaskpane has finished resizing? I thought of two approaches:

  • 将 resizeFrame() 方法放在 SwingUtilities.invokeLate(..) 调用中.

  • Put the resizeFrame() method in a SwingUtilities.invokeLate(..) call.

放入一个计时器 resizeFrame 调用,因此任何后续调用在计时器触发之前都不会执行任何操作.这应该为面板调整大小提供足够的时间.

Put in a timer resizeFrame call, so any subsequent calls do not do anything until the timer fires. This should give enough time for the panel to resize.

最好的方法是什么?

此外 - 这是我的第一个严肃 Java GUI 应用程序,经过多年的服务器端程序.StackOverflow 非常有帮助.所以谢谢!

Also - This is my first serious Java GUI app after years of server side program. StackOverflow has been very helpful. So thanks!

推荐答案

我知道你已经选择了一个答案,但是覆盖 Paint 方法绝对是不正确的,虽然你可能能够在适当的地方破解一些东西,但它不会很理想.

I know you've already selected an answer, but overriding the paint method is definitely not correct, and while you may be able to hack something in place, it won't be ideal.

查看 JXTaskPane 并特别查看 setExpanded()(第 387 行),您可以看到它调用 JXCollapsiblePane.setCollapsed(...) 然后为扩展触发属性更改事件.该属性上的侦听器将不正确,因为它会在动画完成之前触发.所以,如果你进入 JXCollapsiblePane 并查看 setCollapsed(...)(第 470 行),您会看到如果它是动画的,它会设置参数并启动计时器.我们想知道动画何时结束,因此在该文件中,查看动画器(第 620 行,特别是 652-667),它显示当动画结束时,它会触发 ANIMATION_STATE_KEY 的属性更改,值为collapsed"或扩展".这是您真正想要的活动.但是,您无权访问 JXCollapsiblePane,因此返回 JXTaskPane 并搜索 ANIMATION_STATE_KEY,您会找到第 208 行,这表明 JXTaskPane 在 JXCollapsiblePane.ANIMATION_STATE_KEY 上创建了一个侦听器,并将其作为自己的事件重新触发.

Looking at the source for JXTaskPane and specifically looking in setExpanded() (line 387), you can see it calls JXCollapsiblePane.setCollapsed(...) and then fires a property change event for expanded. A listener on that property won't be correct, because it'll fire before the animation is complete. So, if you go into JXCollapsiblePane and look at setCollapsed(...) (line 470) you'll see that if it's animated, it sets the paramaters and starts a timer. We want to know when the animation ends, so in that file, look at the animator (line 620, and specifically 652-667), which shows that when the animation ends, it fires a property change for ANIMATION_STATE_KEY with a value of "collapsed" or "expanded". This is the event you actually want. However, you don't have access to JXCollapsiblePane, so go back to JXTaskPane and search for ANIMATION_STATE_KEY, and you find line 208, which shows that JXTaskPane creates a listener on JXCollapsiblePane.ANIMATION_STATE_KEY and refires it as it's own event.

由于您确实可以访问 JXTaskPane,因此您可以侦听该事件,因此...

Since you do have access to JXTaskPane, you can listen for that event, so doing ...

taskPane.addPropertyChangeListener(JXCollapsiblePane.ANIMATION_STATE_KEY, new PropertyChangeListener() {
  public void propertyChange(PropertyChangeEvent e) {
    if(e.getNewValue().equals("expanded") {
      ...
    }
    else if(e.getNewValue().equals("collapsed") {
      ...
    }
  }
}

应该在您想要的时候准确地获取您的活动.

should get your event exactly when you want it.

在 Swing 中监听事件的正确方法是通过属性监听器.不幸的是,找出正确属性和值的唯一方法是挖掘源代码.

The correct way to listen for events in Swing is through property listeners. Unfortunately, the only way to find out what the correct properties and values are is by digging through source code.

这篇关于Java Swing:当组件*完成*调整大小时做一些事情的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆