2013-04-02 3 views
2

У меня есть приложение, которое в зависимости от ввода пользователя меняет все содержимое JFrame. Я делаю это, удаляя JPanel, содержащий текущие компоненты, и заменяю его новым JPanel новыми компонентами. После этого один из компонентов должен получить фокус, а JScrollpane должен перейти к этому компоненту. В большинстве случаев это работает правильно. Теперь один сценарий приводит к добавлению JPanel beeing, который содержит более 500 компонентов. Рендеринг занимает некоторое время, и кажется, что scrollRectToVisible() вызывается в точке, где пользовательский интерфейс не полностью отображается. Если я отлаживаю, я могу увидеть, что он сначала прокручивается в нужную позицию, но затем выполняется дальнейший рендеринг, и компонент снова перемещается из окна просмотра.Как я могу получить уведомление, когда JPanel отображается на экране

Так что я пытался найти прослушиватель, который называется, когда рендеринг полностью выполнен. Я пробовал с ComponentListener и AnchestorListener. Оба не получили большинство событий, которые я ожидал. Но даже когда они вызывали методы обратного вызова, вызывались до того, как на экране было отображено какое-либо изменение пользовательского интерфейса.

Я заменяю JPanels в EDT и затем вызываю подтверждение() на JFrame. После этого я не обрабатываю дополнительный код. Однако, если я установил точку останова в последней выполненной строке и продвинулся дальше на один шаг, пользовательский интерфейс не изменился на экране. EDT активно что-то делает (я предполагаю, что пользовательский интерфейс). И я хотел бы получить уведомление, когда EDT закончит рендеринг.

Еще одна вещь, которую я пробовал: Если я создаю другую тему, которая просто спит в течение нескольких секунд (пока пользовательский интерфейс определенно не отображается) и вызовите scrollRectToVisible(), тогда все будет хорошо.

Прошу прощения, если вы не предоставите SSCCE. Я попытался, но это кажется довольно сложным. Я действительно ценю любую идею о том, как я могу получить уведомление о том, что пользовательский интерфейс полностью отображается и отображается пользователю.

Благодаря

ответ

1

Если я создаю еще одну тему, которая просто спит в течение нескольких секунд (до тех пор, пока интерфейс, безусловно, оказывается) и называют scrollRectToVisible(), то все работает отлично.

Вместо того, чтобы спать, просто заверните код scrollRectToVisibl() в SwingUtilities.invokeLater(). Это добавит код в конец EDT, чтобы он обрабатывался после всего другого рендеринга.

+0

Я уже попробовал, что и это не сработало. – haferblues

-1

Возможно, JComponent.addNotify() - это то, что вам нужно. Если вы переопределите этот метод, убедитесь, что вы также вызываете super.addNotifty()!

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=]] 
Смежные вопросы