2014-10-19 28 views
2

我想要定製一個JTree有一個黑暗的背景和光前景。我的問題可以看出,在下面的截圖:Linux上的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(); 
      } 
     }); 
    } 

} 

更新:在測試了最新的Linux Mint的與Oracle JDK 7和8,並且似乎顯示OK(按預期)那裏。

更新:在Ubuntu 12.04上使用Oracle JDK 8(更新25)進行了測試,但仍然沒有運氣,所以它看起來不是JDK。

+0

示例代碼工作正常,在OS X上也許嘗試調用:'tree.setOpaque(true)'。 – 2014-10-19 20:08:44

+0

嘗試過'tree.setOpaque(true)',但沒有區別。 – 2014-10-19 20:11:48

+0

這會令我感到驚訝,但設置LaF後試試這個:'UIManager.put(「Tree.background」,Color.BLACK);' – 2014-10-19 20:13:56

回答

1

使用SynthStyle似乎在Ubuntu 14.04爲我的工作確定與OpenJDK的64位(1.7.0_65):

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

我想你的意思是'新的TreeExample2();'。否則,我嘗試了你的代碼,但仍然是相同的結果。 – 2014-10-20 19:11:04

+0

對不起,我錯誤地混合了TreeExample和TreeExample2。我會解決這個問題。 – aterai 2014-10-21 09:07:49

+0

我最終做了升級到Ubuntu 14.04,並有相同的OpenJDK版本,但32位。上述代碼示例仍然是同樣的問題。但是,如果我在Linux Mint 17 Cinnamon(Oracle JDK 1.7.0_71)上運行它,兩者都可以。所以作爲總結,我沒有在任何組合的Ubuntu設置上工作。 – 2014-10-22 05:42:41