Java Nimbus LAF с прозрачными текстовыми полями - PullRequest
11 голосов
/ 05 марта 2009

У меня есть приложение, которое использует отключенные JTextFields в нескольких местах, которые должны быть прозрачными - позволяя фону просвечивать вместо обычного фона текстового поля.

При запуске нового Nimbus LAF эти поля непрозрачны (несмотря на установку setOpaque (false)), и мой пользовательский интерфейс не работает. Это как если бы LAF игнорирует непрозрачное свойство. Задать цвет фона явно сложно в нескольких местах, и это менее чем оптимально из-за фоновых изображений на самом деле не работает - он все равно закрашивает свой LAF-фон по умолчанию поверх, оставляя внешний вид, похожий на рамку ( на заставке ниже задан фон, явно соответствующий изображению).

Есть идеи, как заставить Nimbus не рисовать фон для JTextField?

Примечание: мне нужен JTextField, а не JLabel, потому что мне нужен потокобезопасный setText () и возможность переноса.

Примечание. Моя запасная позиция - продолжать использовать систему LAF, но Nimbus выглядит значительно лучше.

См. Примеры изображений ниже.


Выводы

Удивление при таком поведении связано с неправильным толкованием того, что setOpaque () предназначено для этого - из сообщения об ошибке Nimbus:

Это проблема оригинального дизайна Swing и его запутанности в течение многих лет. Проблема в том, что setOpaque (false) имеет побочный эффект при выходе из LAF, который заключается в сокрытии фона, который на самом деле не предназначен для этого. Следует сказать, что компонент my может содержать прозрачные части, а Swing должен закрасить родительский компонент за ним.

К сожалению, компоненты Nimbus, по-видимому, также не поддерживают setBackground (null), который в противном случае был бы рекомендуемым способом остановки рисования фона. Установка полностью прозрачного фона кажется мне не слишком понятной.

По моему мнению, setOpaque () / isOpaque () является ошибочным публичным выбором API, который должен был быть только:

public boolean isFullyOpaque();

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

Таким образом, непрозрачность компонента не должна быть установлена ​​с помощью setOpaque (). Вместо этого что-то вроде setBackground (null) должно привести к тому, что многие компоненты «не имеют фона» и, следовательно, станут не полностью непрозрачными. Например, в идеальном мире большинство компонентов должны иметь isOpaque (), который выглядит следующим образом:

public boolean isOpaque() { return (background!=null); }

Example

alt text

Ответы [ 4 ]

17 голосов
/ 05 марта 2009

Я столкнулся с этой же проблемой на прошлой неделе, используя JTextPane. Метод setOpaque () работает должным образом при использовании любого внешнего вида, кроме нимба. По-видимому, внешний вид нимба меняет поведение, которое мы привыкли ожидать с помощью setOpaque () для многих компонентов. В зависимости от того, как вы на это смотрите, это можно считать ошибкой. Проверьте комментарии на это солнце bugid:

нимб непрозрачная ошибка

Обходной путь, который работал для меня, был:

myPane.setOpaque(false); // added by OP
myPane.setBorder(BorderFactory.createEmptyBorder());
myPane.setBackground(new Color(0,0,0,0));

Примечание от OP: Я также должен был обеспечить setOpaque (false) для JTextField, чтобы родительский фон был закрашен - просто хотел упомянуть это для других, которые следуют, если они экспериментировали с setOpaque (true), как я.

0 голосов
/ 06 марта 2009

Из Javadoc

public void setBackground (Color bg)

Устанавливает цвет фона этого компонента. Цвет фона используется только если компонент непрозрачный, и только подклассами JComponent или реализации ComponentUI. непосредственный подклассы JComponent должны переопределить paintComponent для соблюдения этого свойства.

Это зависит от внешнего вида и чувства, чтобы почтить эту собственность, некоторые могут выбрать игнорировать это.

0 голосов
/ 06 марта 2009

Я думаю, что вопрос в том, как интерпретировать «непрозрачный» и «фоновый». Для JTextfield возникает вопрос: «какие видимые части являются фоном?». Я бы определил «фон» как части ограничивающего прямоугольника, которые не нарисованы компонентом. Для «круглой» кнопки, например, это будут углы вне круга. Поэтому я бы сказал, что JTextfield не имеет видимого фона! Он имеет прямоугольную форму, и в качестве фона вы берете не фон поля, а его холст.


Опровержение от ОП

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

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

Я думаю, что это соображение приводит аргумент в пользу существующего (и неправильно понятого) значения isOpaque (). Это также приводит мой аргумент в пользу того, что setOpaque () не должен существовать и что setBackground (null) должен привести к тому, что компонент не будет рисовать фон.

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

0 голосов
/ 05 марта 2009

Привет, Software Monkey.

ммхх, как насчет установки замены подклассов пользовательского интерфейса, которая фактически соблюдает поведение setOpaque.

Я думаю, что это что-то вроде setUI или что-то в этом роде.

Вы можете взять исходный код нимба и посмотреть, что там сломано (если оно есть), создать подкласс и установить «исправленный».

Ваш звук довольно интересный, у вас есть какой-нибудь скриншот, который мы видим?

...