2015-02-24 3 views
3

Мне интересно об этом в течение довольно долгого времени.Почему setContentPane() не содержит repaint()?

Я обычно создаю свои программы SWING, имея JFrame с JPanel, содержащий содержимое окна, установленное в качестве области содержимого на setContentPane(). Когда я хочу, чтобы мой контент был заменен другим (например, для получения новой маски после нажатия кнопки), я снова вызываю setContentPane() и заменяю панель содержимого другой панелью. Но каждый раз, когда я это делаю, мне нужно позвонить repaint() после setContentPane(), чтобы сделать видимым изменение, поэтому я создал собственный класс, который я использую для создания фреймов. Этот класс расширяет JFrame и переопределение setContentPane() так:

@Override 
public void setContentPane(Container c) { 
    super.setContentPane(c); 
    revalidate(); 
    repaint(); 
} 

Почему это не реализовано в JFrame классе по умолчанию? Может быть, у меня плохой побочный эффект?

+0

Какой менеджер макетов вы используете? –

+1

Зачем? Вообще говоря, вы должны установить и покинуть область содержимого как есть. Вы также можете внести дополнительные изменения в пользовательский интерфейс, который вы не хотите планировать перерисовку, пока вы не закончите ... – MadProgrammer

+0

Вы также просите, чтобы вернуться к более чем 15 годам умов разработчиков, которые разработал и написал API. Там требования были совершенно определенно отличны от наших сегодня, просто посмотрите на разницу в концепции JavaFX, например – MadProgrammer

ответ

4

Я думаю, что по той же причине он не вызывается после добавления или удаления компонентов из Container. Настройка области содержимого будет такой же, как добавление компонентов к уже существующей. Иерархия компонентов становится недействительной, поэтому вы должны позвонить revalidate() и repaint().

И причина, почему он не вызывается автоматически, предлагается в документации Container.validate():

Проверка контейнера может быть весьма трудоемкой операцией. По соображениям производительности разработчик может отложить проверку иерархии до завершения набора операций, связанных с макетом, например. после добавления всех детей в контейнер.

Но это только моя догадка.

+0

Хорошо, но я всегда создаю свою полностью сделанную маску в панели сначала, и когда я закончил, я установил эту панель как область содержимого моего JFrame в конце. Поэтому я бы просто назвал это один раз за действие пользователя. Я не могу представить себе чистый способ использования setContentPane() по-другому. Я думал, для этого и предназначен. – Froxx

+1

Вы можете установить область содержимого, а затем добавить к ней компоненты. В этом нет ничего плохого. Как и 'Container.add', вы можете называть' setContentPane' всякий раз, когда захотите. Нет правила, что его всегда следует называть последним. –

+0

Хм ... Да, это так. Я просто думаю, что это самый лучший способ сделать это шаг за шагом, и моим последним шагом будет setContentPane() каждый раз. Но все в порядке, я принимаю это ...;) Но при использовании setContentPane(), как и я, должно быть хорошо использовать мой метод из стартового поста, правильно? Я не вижу никакого побочного эффекта. – Froxx

Смежные вопросы