Java Swing - полупрозрачные компоненты, вызывающие артефакты - PullRequest
3 голосов
/ 12 февраля 2011

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

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

Вот где моя проблема:

При отправке информации из поля ввода в окно чата, навигации по списку друзей или прокрутке окна чата остаются странные артефакты. Эти артефакты иногда являются полупрозрачными «призраками» кнопки «Отправить», иногда частью меню или старого текста. Мне кажется, что весь кадр не перерисовывается должным образом, но я не уверен, как это работает.

Для компонентов, которые реализуют JTextComponent, я устанавливаю их цвет выделения полупрозрачным. Для других компонентов я устанавливаю прозрачный фон. У меня есть функция setTranslucency (Component com), которая смотрит на компонент, устанавливает его прозрачность в зависимости от того, что это такое, затем видит, является ли он каким-либо контейнером, и рекурсивно устанавливает прозрачность каждого элемента.

Теперь способ, который я нашел, чтобы решить эту проблему, это перетянуть окно из поля зрения (например, свернуть или перетащить окно за пределы экрана и обратно).

Итак,

1) Есть ли способ заставить все окно обновляться так, как оно происходит, когда я перетаскиваю его за пределы экрана или минимизирую его?

или

2) Я делаю это неправильно в первую очередь? Если да, то как бы это исправить?

Вот изображение для справки:

http://i.stack.imgur.com/4J9GJ.png

Ответы [ 3 ]

3 голосов
/ 13 февраля 2011

Вы должны сообщить Swing, что компоненты полупрозрачны, поэтому он также рисует фон при перекрашивании измененных компонентов. Для этого ваши компоненты должны возвращать false из метода isOpaque() (это может быть достигнуто с помощью setOpaque(false), когда никакой подкласс не перезаписывает isOpaque, чтобы сделать что-то еще).

При этом все должно работать без перерисовки всего вручную, как предлагали другие ответы. (Я уже делал это один раз.)

Редактировать: Причина этого в том, что Swing использует оптимизированный алгоритм перерисовки, перерисовывая только те компоненты, которые действительно нуждаются в перерисовке (например, JTextField после некоторого ввода) или компоненты перед такими До тех пор, пока они непрозрачны. Когда компонент, нуждающийся в перекрашивании, непрозрачен (= заполняет все пространство непрозрачным цветом), также необходимо перекрасить компоненты, находящиеся за ними.

0 голосов
/ 12 февраля 2011

Попробуйте JFrame.repaint(). Это должно работать. Если вы хотите индивидуальное проектирование вашего JFrame, вам придется переопределить paint() метод JFrame. Кроме того, если вы хотите, чтобы каждый компонент был специально разработан, вам придется переопределить метод paint() каждого из ваших компонентов графического интерфейса. Пара вещей, на которые стоит обратить внимание:

  1. Вам не нужно вызывать paint() для любого компонента графического интерфейса. Вам нужно всего лишь позвонить repaint().
  2. Если вы переопределяете другие компоненты графического интерфейса [JButton, JTextField ...], вам не нужно вызывать их метод repaint(). Родитель Container [JFrame, JPanel ...] repaint() выполнит эту работу.
0 голосов
/ 12 февраля 2011

myComponent.revalidate ();
myComponent.repaint ();
Не уверен, что он "форсирует" перерисовку, но просит об этом, когда это возможно.

...