Nimbus Look&Feel und seine Eigenarten

Zugegeben, das Nimbus Look&Feel unter Java schaut schon gut aus – ja ich bekenne mich dazu, daß ich es gerne mag. Aber leider hat Nimbus schon so seine Problemchen. Ich würde sie mal als Kinderkrankheiten bezeichnen. Trotzdem versuche ich Nimbus in neue Applikationen einzubinden und mit den Problemen klar zu kommen.

Große Verwirrung bereitet hierbei der Hintergrund vom JEditorPane/JTextPane, welcher sich nicht mehr so verhält, wie es bisher von Swing gewohnt war. Wer es nicht glaubt, braucht nur mal mit den Stichworten Nimbus und Background zu googlen. Ich habe die Probleme übrigens auch schon bei der JTextArea gehabt. Die Tipps hier gelten analog.

Zwei Workarounds hätte ich hier anzubieten:

1. Transparenter Hintergrund im Textfeld

Viele GUI-Entwickler setzen gerne mindestens die JTextArea ein, wenn es darum geht, einen längeren Text in der Applikation darzustellen. Die JTextArea kann den Text automatisch nach Wörtern umbrechen, was eine enorme Arbeitserleichterung ist.

Wenn es darum geht, einzelne Textstellen gesondert zu formatieren, kommt man sogar gar nicht um ein JEditorPane bzw. ein JTextPane umhin. Es gibt coole Erweiterungen, womit man sogar Quelltexte highlighten kann, genau wie die Codeabschnitte in diesem Artikel.

Nun werden dieses Textkomponenten oft gerne auf eine GUI gesetzt, um ähnlich wie ein Label einfach nur den Text im Vordergrund anzuzeigen und den Hintergrund durchscheinen zu lassen. Bisher hatte man das mit Swing so gemacht:

// ...
JTextPane pane = new JTextPane();
pane.setText(myText);
pane.setOpaque(false);
add(pane);
// ...

Probiert man dies mit Nimbus aus, so stellt man fest, das es nicht mehr funktioniert. Der Textbereich wird mit weißem Hintergrund dargestellt.

Das liegt daran, daß die Methode setOpaque(...) nicht definiert, daß etwas durchsichtig ist. Sie sagt nur, daß die Komponente nicht vollständig undurchsichtige Teile enthält. Doch wie das geschieht, das legt die Komponente selbst fest.

Der Workaround für dieses Problem besteht nun darin, daß man die Hintergrundfarbe zusätzlich auf eine vollständig durchsichtige Farbe setzt. Das sieht dann etwas so aus:

// ...
JTextPane pane = new JTextPane();
pane.setText(myText);
pane.setOpaque(false);
pane.setBackground(new Color(0,0,0,0));
add(pane);
// ...

Zur Erinnerung: Definiert man eine neue Farbe mit vier Parametern, so gibt der letzte Parameter den Alphawert an. Jener Wert definiert, wie stark die Farbe durchsichtig ist. Der Wert 255 bzw. 1.0 sagt, daß die Farbe vollständig undurchsichtig (opaque) ist. Ein Wert von 0 bzw. 0.0 läßt die Farbe vollständig durchsichtig/transparent erscheinen. Alle Werte dazwischen lassen die Farbe unterschiedlich stark durchscheinen.

Mit dem obigen Trick funktioniert die Transparenz wieder. Dies wirkt umso eigenartiger, betrachtet man das nächste Problem.

2. Farbiger Hintergrund im Textfeld

Es wirkt paradox, aber setzt man eine andere Farbe als Hintergrund, um z. B. das Textfeld gesondert hervorzuheben, so wird dies ignoriert. Ein Programm, bei dem ich verschiedentlich Hintergrundfarben setzte, um spezielle Zustände zu unterscheiden, verlor deutlich an Aussagekraft. Aber selbst, wenn man dies nicht nutzt, es ist schon ärgerlich, setzt man ein JEditorPane mit setEnabled(false) auf nicht eingeschaltet um anzudeuten, daß der Benutzer eben hier nichts eintippen kann. Anstatt daß sich das  Feld in einem gewohnten Grau färbt, bleibt es weiß.

Dieses Verhalten würde ich als klaren Bug bezeichnen. Hier hilft nur ein kleiner Umweg – unter Berücksichtigung von Trick 1 oben – um wieder eine Hintergrundfarbe setzen zu können.

// ...
JTextPane pane = new JTextPane();
pane.setText(myText);
pane.setOpaque(false);
pane.setBackground(new Color(0,0,0,0));

JScrollPane scroller = new JScrollPane(pane);
scroller.getViewport().setBackground(Color.YELLOW);
add(scroller);
// ...

Der Trick besteht darin, die Textkomponente in einer anderen Panel-Komponente einzubetten. Die Textkomponente wird dann wie im ersten Trick oben vollständig transparent gesetzt, während die Hintergrundfarbe – hier gelb – in der dahinter liegenden Panel-Komponente gesetzt ist.

Dies ist meist sogar automatisch gegeben, da die Textkomponenten oft in Scrollpanes eingebettet werden, um längere Texte scrollen zu können – passen sie nicht mehr auf den Bildschirm. Man kann aber auch einfach ein normales JPanel nehmen und die Textkompente als einzigste Komponente z. B. in einem Borderlayout mittig einsetzen.

Hinweis:

Die hier vorgestellten Tipps beziehen sich auf Nimbus, wie es in Java 6 ausgeliefert wird. Nimbus befindet sich noch in der Entwicklung. Es kann gut sein, das künftige Versionen diese Eigenarten nicht mehr haben.

Sollte ich noch auf weitere Probleme stoßen und Workarounds für sie finden, werde ich weitere Teile dieses Artikels schreiben.

1 Responses to Nimbus Look&Feel und seine Eigenarten

  1. […] diejenigen die dasselbe Problem haben: ich hab mal ein wenig gegoogelt und dieses hier gefunden Nimbus Look&Feel und seine Eigenarten SolutionCrawler Kinderkrankheiten vom Nimbus, denke ich. Aber jetzt funktioniert es […]