17

ニンバスは見栄えがすることがよくありますが、特定の色の組み合わせでは、結果が最適ではありません。私の場合、aの背景がJPopupMenu合わないので、手動で設定したいと思います。

私はJava7を使用していますが、興味深いことに、NimbusはUIManager(のようなPopupMenu.background)のいくつかのプロパティの設定を完全に無視します。JPopupMenuしたがって、私の唯一のオプションは、そのオーバーライドのサブクラスを作成することでしたpaintComponent(...)。私は知っています、それは厄介ですが、少なくともそれはうまくいきました。

ただし、JMenuを別のメニューに追加すると、それ自体のインスタンスが埋め込まれJPopupMenu、それを自分のサブクラスに置き換える方法がわかりませんでした。

埋め込みインスタンスに独自のものを割り当ててPopupMenuUIも、結果は得られませんでした。JPopupMenuオーバーライドされたメソッドから直接継承された場合paint(...)は呼び出されましたが、何をしても何も描画されませんでした。継承元javax.swing.plaf.synth.SynthPopupMenuUI paintが呼び出されない場合、結果は私がまったく自分自身PopupMenuUIを設定しなかった場合になります。

JPopupMenuしたがって、簡単な質問は次のとおりです。Java7でL&FとしてNimbusを使用して、1つまたは(それが簡単な場合は)すべての背景色を調整するにはどうすればよいですか?

編集:コード例

次のコードと結果を見てください。

public static void main(final String[] args) {
    try {
        UIManager.setLookAndFeel(NimbusLookAndFeel.class.getCanonicalName());
        UIManager.getLookAndFeelDefaults().put("PopupMenu.background", Color.GREEN);
        UIManager.getLookAndFeelDefaults().put("Panel.background", Color.RED);
        UIManager.getLookAndFeelDefaults().put("List.background", Color.BLUE);
    } catch (ClassNotFoundException | InstantiationException
            | IllegalAccessException | UnsupportedLookAndFeelException e) {
        e.printStackTrace();
    }
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(200,200);

    JPanel panel = new JPanel(new BorderLayout());
    panel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
    JList list = new JList();
    panel.add(list);

    frame.getContentPane().add(panel);

    JPopupMenu menu = new JPopupMenu();
    menu.add(new JMenuItem("A"));
    menu.add(new JMenuItem("B"));
    menu.add(new JMenuItem("C"));

    frame.setVisible(true);
    menu.show(frame, 50, 50);
}

UIManager.put(key, value)L&Fを設定するUIManager.getLookAndFeelDefautls().put(key,value) 前に使用する必要があると言う人もいますが、私にとっては結果は得られません(つまり、デフォルトの色はまったく変更されません)。上記のコードは少なくとも以下をもたらします:

最初のスクリーンショット

を使用すると、同じことが起こります(何も意味しません)JPopupMenu.setBackground(...)。これは、ニンバスが内部ペインターを使用しているためです。内部ペインターは、ニンバスの原色から色を計算し、コンポーネントのプロパティを無視します。この例では、回避策として以下を使用できます。

JPopupMenu menu = new JPopupMenu() {
    @Override
    public void paintComponent(final Graphics g) {
        g.setColor(Color.GREEN);
        g.fillRect(0,0,getWidth(), getHeight());
    }
};

これは

SecondScreen

ただし、この回避策は、JMenuそれ自体がラップするを挿入した場合は機能しませJPopupMenuん。オーバーライドすることはできません。

JMenu jmenu = new JMenu("D");
jmenu.add(new JMenuItem("E"));
menu.add(jmenu);

予想通り、与える:

3番目の画面

JPopupMenuこれはを使用して取得できますJMenu.getPopupMenu()が、設定することはできません。の独自のサブクラスでこのメソッドをオーバーライドしても、ゲッターを使用せずにのラップされたインスタンスにアクセスするように見えるためJMenu、結果は得られません。JMenuJPopupMenu

4

3 に答える 3

9

これを行う1つの方法は、個々のJMenuItemの背景に色を付けて、不透明にすることです。

JMenuItem a = new JMenuItem("A");
a.setOpaque(true);
a.setBackground(Color.GREEN);

次に、メニュー自体に緑色の境界線を付けて、残りを塗りつぶします。

menu.setBorder(BorderFactory.createLineBorder(Color.GREEN));

そこには簡単で簡単な方法があるかもしれませんが、これは私にとってはうまくいきました。

于 2012-07-27T18:43:46.997 に答える
9
  • 両方の答えにいくつかの間違いがあります

  • 他のJComponentsとその色に影響を与えたほとんどのUIDeafaultsをオーバーライドするために必要な上記の方法

  • ニンバスには独自のペインターがあり、その一例です...

ここに画像の説明を入力してください

コードから

import com.sun.java.swing.Painter;
import java.awt.*;
import javax.swing.*;

public class MyPopupWithNimbus {

    public MyPopupWithNimbus() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(200, 200);
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        JList list = new JList();
        panel.add(list);
        frame.getContentPane().add(panel);
        JPopupMenu menu = new JPopupMenu();
        menu.add(new JMenuItem("A"));
        menu.add(new JMenuItem("B"));
        menu.add(new JMenuItem("C"));
        JMenu jmenu = new JMenu("D");
        jmenu.add(new JMenuItem("E"));
        menu.add(jmenu);
        frame.setVisible(true);
        menu.show(frame, 50, 50);
    }

    public static void main(String[] args) {

        try {
            for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(laf.getName())) {
                    UIManager.setLookAndFeel(laf.getClassName());
                    UIManager.getLookAndFeelDefaults().put("PopupMenu[Enabled].backgroundPainter",
                            new FillPainter(new Color(127, 255, 191)));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                MyPopupWithNimbus aa = new MyPopupWithNimbus();
            }
        });
    }
}

class FillPainter implements Painter<JComponent> {

    private final Color color;

    FillPainter(Color c) {
        color = c;
    }

    @Override
    public void paint(Graphics2D g, JComponent object, int width, int height) {
        g.setColor(color);
        g.fillRect(0, 0, width - 1, height - 1);
    }
}
于 2012-08-01T12:35:16.213 に答える
7

全体像ではありませんが、メニュー/アイテムの不透明度をtrueに設定すると、部分的に解決されるように見えます(@Derek Richardは、完全なアプリケーション制御で作成されたアイテムに対してすでに行ったように)。

UIDefaults ui = UIManager.getLookAndFeelDefaults();
ui.put("PopupMenu.background", GREEN);
ui.put("Menu.background", GREEN);
ui.put("Menu.opaque", true);
ui.put("MenuItem.background", GREEN);
ui.put("MenuItem.opaque", true);

など、radioButton/checkBoxなどのすべてのタイプのアイテム。

これでも上部/下部の灰色の領域が残ります-その描画の原因となっている部分がわかりません。マージンを削除すると、圧迫されたように見えるという代償を払うのに役立ちます

// this looks not so good, but without the margins above/below are still grey
ui.put("PopupMenu.contentMargins", null);

チュートリアルにはプロパティキーのリストがあります。

于 2012-07-30T09:17:43.380 に答える