Linux上的JTree背景颜色,具有系统外观

时间:2014-10-19 20:04:31

标签: java linux swing jtree

我正在尝试自定义一个具有深色背景和浅色前景的JTree。我的问题可以在下面的截图中看到:

JTree with partially customized background

我最终得到的是部分定制的背景(白色也是黑色)。在使用OpenJDK 7的Ubuntu Linux 12.04上似乎出现了这个问题。在Windows或Mac上看起来没问题。此外,如果我切换到跨平台的外观和感觉,它是好的。以下是示例代码:

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();
            }
        });
    }

}

更新:使用Oracle JDK 7和8测试最新的Linux Mint,并且似乎在那里显示正常(按预期)。

更新:在使用Oracle JDK 8(更新25)的Ubuntu 12.04上进行了测试,但仍然没有运气,所以它似乎不是JDK。

1 个答案:

答案 0 :(得分:1)

在使用OpenJDK 64位(1.7.0_65)的Ubuntu 14.04上使用SynthStyle似乎对我有效:

enter image description here

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;
  }
}