Reputation: 203
I am trying to customize a JTree to have a dark background and light foreground. My problem can be seen in the screenshot below:
What I end up with, is a partially customized background (the white is intended to be also black). The problem seems to occur on Ubuntu Linux 12.04 with OpenJDK 7. On Windows or Mac it looks ok. Also, if I switch to cross platform look and feel, it is ok. Below is the sample code:
package com.tt.examples;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.tree.DefaultTreeCellRenderer;
@SuppressWarnings("serial")
public class TreeExample extends JFrame {
private TreeExample() {
setTitle("TreeExample");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(320, 240);
setLayout(new GridLayout(1, 1));
JTree tree = new JTree();
tree.setBackground(Color.BLACK);
tree.setCellRenderer(new CustomTreeCellRenderer());
JScrollPane scrollPane = new JScrollPane(tree);
scrollPane.setBackground(Color.BLACK);
add(scrollPane);
setVisible(true);
}
private class CustomTreeCellRenderer extends DefaultTreeCellRenderer {
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
setBackground(Color.BLACK);
setBackgroundNonSelectionColor(Color.BLACK);
setBackgroundSelectionColor(Color.GRAY);
setBorderSelectionColor(Color.GRAY);
setForeground(Color.WHITE);
return (this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
// UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace(System.err);
}
new TreeExample();
}
});
}
}
Update: Tested on latest Linux Mint with Oracle JDK 7 and 8, and seems to show ok (as intended) there.
Update: Tested also on Ubuntu 12.04 with Oracle JDK 8 (update 25), but still no luck, so it seems it's not the JDK.
Upvotes: 2
Views: 680
Reputation: 9818
Using a SynthStyle
seems to work OK for me on Ubuntu 14.04 with OpenJDK 64-Bit(1.7.0_65):
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.plaf.synth.*;
public class TreeExample2 extends JFrame {
private TreeExample2() {
setTitle("TreeExample2");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JTree tree = new JTree();
//tree.setBackground(Color.BLACK);
tree.setOpaque(false);
tree.setCellRenderer(new CustomTreeCellRenderer());
JScrollPane scrollPane = new JScrollPane(tree);
scrollPane.getViewport().setBackground(Color.BLACK);
add(scrollPane);
setSize(320, 240);
setVisible(true);
}
private class CustomTreeCellRenderer extends DefaultTreeCellRenderer {
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
setBackground(Color.BLACK);
setBackgroundNonSelectionColor(Color.BLACK);
setBackgroundSelectionColor(Color.GRAY);
setBorderSelectionColor(Color.GRAY);
setForeground(Color.WHITE);
return (this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
// UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SynthLookAndFeel.setStyleFactory(new MySynthStyleFactory(
SynthLookAndFeel.getStyleFactory()));
} catch (Exception e) {
e.printStackTrace(System.err);
}
new TreeExample2();
}
});
}
}
class MySynthStyleFactory extends SynthStyleFactory {
private final SynthStyleFactory wrappedFactory;
public MySynthStyleFactory(SynthStyleFactory factory) {
super();
this.wrappedFactory = factory;
}
@Override public SynthStyle getStyle(JComponent c, Region id) {
SynthStyle s = wrappedFactory.getStyle(c, id);
if (id == Region.TREE_CELL) {
s = new TranslucentSynthSytle(s);
}
return s;
}
}
class TranslucentSynthSytle extends SynthStyle {
private final SynthStyle style;
public TranslucentSynthSytle(SynthStyle style) {
super();
this.style = style;
}
@Override public Object get(SynthContext context, Object key) {
return style.get(context, key);
}
@Override public boolean getBoolean(SynthContext context, Object key, boolean defaultValue) {
return style.getBoolean(context, key, defaultValue);
}
@Override public Color getColor(SynthContext context, ColorType type) {
return style.getColor(context, type);
}
@Override public Font getFont(SynthContext context) {
return style.getFont(context);
}
@Override public SynthGraphicsUtils getGraphicsUtils(SynthContext context) {
return style.getGraphicsUtils(context);
}
@Override public Icon getIcon(SynthContext context, Object key) {
return style.getIcon(context, key);
}
@Override public Insets getInsets(SynthContext context, Insets insets) {
return style.getInsets(context, insets);
}
@Override public int getInt(SynthContext context, Object key, int defaultValue) {
return style.getInt(context, key, defaultValue);
}
@Override public SynthPainter getPainter(SynthContext context) {
//return style.getPainter(context);
return new SynthPainter() { /* do nothing */ };
}
@Override public String getString(SynthContext context,
Object key, String defaultValue) {
return style.getString(context, key, defaultValue);
}
@Override public void installDefaults(SynthContext context) {
style.installDefaults(context);
}
@Override public void uninstallDefaults(SynthContext context) {
style.uninstallDefaults(context);
}
@Override public boolean isOpaque(SynthContext context) {
return style.isOpaque(context);
}
@Override public Color getColorForState(SynthContext context, ColorType type) {
return null;
}
@Override public Font getFontForState(SynthContext context) {
return null;
}
}
Upvotes: 1