У меня есть приложение, которое использует отключенные 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); }