我有一个应用程序,它根据用户输入更改JFrame的整个内容。我这样做是通过删除包含当前组件的JPanel并将其替换为带有新组件的新JPanel。 之后,其中一个组件需要获得焦点,JScrollpane应滚动到此组件。在大多数情况下,这是正常的。 现在,一个场景导致添加了JPanel,其本身包含500多个组件。渲染这需要一些时间,似乎在一个点处调用scrollRectToVisible(),其中UI未完全呈现。如果我调试我实际上可以看到它首先滚动到正确的位置,但随后进一步渲染完成并且组件再次移出视口。
所以当渲染完全完成时,我正在尝试找到一个名为Listener的调用器。我尝试使用ComponentListener和AnchestorListener。两人都没有收到我期待的大部分事件。但即使他们这样做,也会在屏幕上显示任何UI更改之前调用回调方法。
我在EDT中交换了JPanels,然后在JFrame上调用了validate()。之后我不再处理任何代码。但是,如果我在最后执行的行中设置断点并更进一步,则UI在屏幕上没有更改。 EDT正在积极做某事(我假设渲染用户界面)。我希望在EDT完成渲染时收到通知。
我试过的另一件事: 如果我创建另一个只是休眠几秒钟的线程(直到UI被明确渲染)并调用scrollRectToVisible()然后,一切正常。
我很抱歉不提供SSCCE。我试过了,但似乎相当复杂。我真的很感激如何能够获得有关用户完全呈现和可见的用户界面的通知。
由于
答案 0 :(得分:1)
如果我创建另一个只能休眠几秒钟的线程(直到UI被明确渲染)并调用scrollRectToVisible(),那么一切正常。
而不是睡眠,只需将scrollRectToVisibl()代码包装在SwingUtilities.invokeLater()中。这会将代码添加到EDT的末尾,因此应该在所有其他渲染之后对其进行处理。
答案 1 :(得分:0)
添加属性更改侦听器:
jPanel.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(final PropertyChangeEvent evt) {
System.out.println(evt);
}
});
产生类似的东西:
java.beans.PropertyChangeEvent[propertyName=ancestor; oldValue=null; newValue=javax.swing.JPanel[null.contentPane,0,0,0x0,invalid,layout=javax.swing.JRootPane$1,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]; propagationId=null; source=javax.swing.JPanel[,0,0,0x0,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]]
答案 2 :(得分:-1)
也许JComponent.addNotify()是你需要的。 如果重写该方法,请确保同时调用super.addNotifty()!