Java Swing: Сделайте что-то, когда компонент будет иметь *законченный* изменение размеров

Извинения за несколько неясный вопрос - не могли думать о лучшем способе поместить его.

Я использую 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 был очень полезен. Так Спасибо!

8
задан javanna 18 December 2011 в 20:18
поделиться

3 ответа

Я знаю, что вы уже выбрали ответ, но переопределение метода рисования определенно неверно, и хотя вы можете взломать что-то на месте, это не будет идеально.

Посмотрев на источник 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 - использовать прослушиватели свойств. К сожалению, единственный способ узнать правильные свойства и значения - это покопаться в исходном коде.

9
ответ дан 5 December 2019 в 15:22
поделиться

Как предложение, вы пытались переопределить метод рисования, сначала вызвав super, а затем поместив свой код изменения размера в конец этого, если (и только если) размер существенно изменился.

1
ответ дан 5 December 2019 в 15:22
поделиться

Я не знаком с JXTaskPane, но моя первая реакция - возможно, вы обрабатываете неправильное событие. Вы хотите, чтобы размер кадра изменялся, когда пользователь щелкает заголовок - так почему бы не обработать это событие (возможно, используя EventQueue.invokeLater () для изменения размера кадра после изменения размера панели задач)?

Но если это не так. работать, и вам нужно использовать подход, который вы обрисовали выше, используя javax.swing.Timer, вероятно, лучше всего. Установите его на 200 миллисекунд или около того и просто перезапустите () каждый раз, когда срабатывает componentResized ().

1
ответ дан 5 December 2019 в 15:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: