Извинения за несколько неясный вопрос - не могли думать о лучшем способе поместить его.
Я использую JXTaskPane (от расширения лабораторий Swing API) для отображения некоторой информации.
Пользователь может "нажать" заголовок для расширения панели. JXTaskPane находится в контейнерном JPanel, который затем добавляется к JFrame, моему окну главного приложения.
Я хочу, чтобы мое окно приложения изменило размер к размеру расширенной панели задач. Для достижения этого я добавил слушателя компонента своего контейнерного JPanel, который установит размер на теперь расширенную панель.
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 метод называют большим количеством времен и выглядит действительно ужасным на экране.
Как я могу обнаружить, когда JXTaskpane закончил изменять размер? Я думал о двух подходах:
Поместите resizeFrame () метод в SwingUtilities.invokeLate (..) звонить.
Вставьте таймер resizeFrame вызов, таким образом, любые последующие вызовы ничего не делают до огней таймера. Это должно дать достаточно времени для панели для изменения размеров.
Каков наилучший путь вперед?
Также - Это - мой первый серьезный Java приложение для GUI после лет серверной программы. StackOverflow был очень полезен. Так Спасибо!
Я знаю, что вы уже выбрали ответ, но переопределение метода рисования определенно неверно, и хотя вы можете взломать что-то на месте, это не будет идеально.
Посмотрев на источник JXTaskPane и, в частности, посмотрев на setExpanded () (строка 387), вы увидите, что он вызывает JXCollapsiblePane.setCollapsed (...), а затем запускает событие изменения свойства для раскрытия. Слушатель этого свойства будет некорректным, потому что он сработает до завершения анимации. Итак, если вы войдете в JXCollapsiblePane и посмотрите на setCollapsed (...) (строка 470), вы увидите, что если он анимирован, он устанавливает параметры и запускает таймер. Мы хотим знать, когда заканчивается анимация, поэтому в этом файле посмотрите на аниматора (строка 620 и, в частности, 652-667), который показывает, что когда анимация заканчивается, он запускает изменение свойства для ANIMATION_STATE_KEY со значением «свернуто. "или" расширенный ". Это событие, которое вы действительно хотите. Однако у вас нет доступа к JXCollapsiblePane, поэтому вернитесь к JXTaskPane и найдите ANIMATION_STATE_KEY, и вы найдете строку 208, которая показывает, что JXTaskPane создает прослушиватель на JXCollapsiblePane.ANIMATION_STATE_KEY и обновляет его как собственное событие.
Поскольку у вас есть доступ к JXTaskPane, вы можете прослушивать это событие, поэтому выполнение ...
taskPane.addPropertyChangeListener(JXCollapsiblePane.ANIMATION_STATE_KEY, new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
if(e.getNewValue().equals("expanded") {
...
}
else if(e.getNewValue().equals("collapsed") {
...
}
}
}
должно получить ваше событие именно тогда, когда вы этого хотите.
Правильный способ прослушивать события в Swing - использовать прослушиватели свойств. К сожалению, единственный способ узнать правильные свойства и значения - это покопаться в исходном коде.
Как предложение, вы пытались переопределить метод рисования, сначала вызвав super, а затем поместив свой код изменения размера в конец этого, если (и только если) размер существенно изменился.
Я не знаком с JXTaskPane, но моя первая реакция - возможно, вы обрабатываете неправильное событие. Вы хотите, чтобы размер кадра изменялся, когда пользователь щелкает заголовок - так почему бы не обработать это событие (возможно, используя EventQueue.invokeLater () для изменения размера кадра после изменения размера панели задач)?
Но если это не так. работать, и вам нужно использовать подход, который вы обрисовали выше, используя javax.swing.Timer, вероятно, лучше всего. Установите его на 200 миллисекунд или около того и просто перезапустите () каждый раз, когда срабатывает componentResized ().