8

私は Java アプリケーションを WindowsLookAndFeel から Nimbus に移行する作業を行ってきましたが、Nimbus の弱点にもかかわらず、ほぼ成功しています。私のユーザーは全体的に Nimbus LaF を気に入っていますが、一部の詳細が気に入らなかったため、このサイトの以前の質問を参照して変更したものもあります。例: 私は、LeafIcon、ClosedIcon、および OpenIcon を Windows LaF (彼らが気に入っていた) からコピーし、それらを Nimbus バージョンで使用して、LaF の優れた組み合わせを実現しました。

最後の (?) 問題に行き詰まりました。

適切なノード表示を作成するために、サブクラス化された DefaultCellRenderer を持つ JTree があります。これは、WindowsLookAndFeel で正常に動作します。

問題: WindowsLaF でノードを選択すると、ノードのテキストが強調表示され、効果が視覚的にわかりやすくなります。Nimbus では、ノードが選択されると、(テキストの幅だけでなく) ツリー ウィンドウの幅に沿った (かなり暗い) 色のバーで強調表示が行われ、その効果は当惑させられます。

したがって、Nimbus LaF での JTree ノードの強調表示の WindowsLaF 処理が必要です (つまり、色付きの背景はテキストの幅のみで、できればより良い色を選択できます)。これは、適切な並べ替え Painter を "Tree:TreeCell[Focused+Selected].backgroundPainter" に割り当てる必要があることを意味していると思われますが、書き方がわかりません。

提案は大歓迎です。


編集

Java 7 で奇妙な選択ノードのハイライトを確認してください!

ここに画像の説明を入力

public class TreeBorder {
    public static void main( String[] args ) {
        try{
            for( UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels() ) {
                if( "Nimbus".equals( info.getName() ) ) {
                    UIManager.setLookAndFeel( info.getClassName() );
                    break;
                }
            }
        } catch( Exception e ) {
            e.printStackTrace();
        }
        SwingUtilities.invokeLater( new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setLocationRelativeTo( null );
                f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                f.getContentPane().add( getJTree() );
                f.pack();
                f.setVisible( true );
            }
            private JTree getJTree() {
                JTree jTree = new JTree();
                jTree.setCellRenderer( new LocalRenderer() );
                return jTree;
            }
        } );
    }

    private static class LocalRenderer extends DefaultTreeCellRenderer {
        @Override
        public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasfocus ) {
            DefaultTreeCellRenderer result = (DefaultTreeCellRenderer)super.getTreeCellRendererComponent( tree, value, sel, expanded, leaf, row, hasfocus );
                if( true ) {
                    result.setFont( new JLabel().getFont() );
                    Icon icon = UIManager.getIcon("FileView.floppyDriveIcon");
                    result.setIcon( icon );
                }
            return(result);
        }
    }
}
4

1 に答える 1

6

編集

「Tree.selectionBackground」キーは、JTreeのハイライトを制御するものです。これは、TreeCellRendererレベルではなく、ツリーレベルで実行されます(これが、管理が少し混乱する理由です)。このコードは、ハイライトを制御できるツリーを取得します。

private JTree getJTree() {

    JTree jTree = new JTree();
    jTree.setOpaque(true);
    jTree.setBackground(Color.white);
    UIDefaults paneDefaults = new UIDefaults();
    paneDefaults.put("Tree.selectionBackground",null);

    JTextPane pane = new JTextPane();
    jTree.putClientProperty("Nimbus.Overrides",paneDefaults);
    jTree.putClientProperty("Nimbus.Overrides.InheritDefaults",false);

    jTree.setCellRenderer( new LocalRenderer() );
    return jTree;
}

そして、これがハイライトを赤に変更する例です。アイコンの背景も強調表示されることに注意してください。これは、ニンバス以外のL&Fのデフォルトの動作でもあります。アイコンを強調表示したくない場合は、デフォルトのJLabelよりも優れたものを使用してTreeCellをレンダリングする必要があります。

    public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasfocus ) {
        DefaultTreeCellRenderer result = (DefaultTreeCellRenderer)super.getTreeCellRendererComponent( tree, value, sel, expanded, leaf, row, hasfocus );
        result.setOpaque(true);
            if( true ) {
                result.setFont( new JLabel().getFont() );
                Icon icon = UIManager.getIcon("FileView.floppyDriveIcon");
                result.setIcon( icon );
            }
            if(sel){
                result.setBackground(Color.red);
            } else{
                result.setBackground(Color.white);
            }
        return(result);
    }

元の回答

これを修正する最も簡単な方法の1つは、選択した背景色を透明に設定することです。問題は、ラベルの背景をペイントしようとしていることです。これには、JTreeの選択で使用されるクールなニンバスペインタがありません。したがって、この行をgetTreeCellRendererComponentメソッドに追加します。

result.setBackgroundSelectionColor(new Color(0,0,0,0));

もう1つのオプションは、TreeCellRendererの背景にニンバスペインターを使用することですが、この状況ではやり過ぎのようです。

于 2012-12-17T15:31:01.820 に答える