3

大規模な GUI アプリケーション用のスクリプトを作成しています。メイン アプリケーション ウィンドウはシステムのを使用しLookAndFeelますが、スクリプトの GUI は Nimbus を使用したいと考えていますLookAndFeelLookAndFeelGUI作成後、元に戻したい。以下のSSCCEが機能するはずですがNullPointerException、オブジェクトを使用するとエラーが発生しComponentます。

import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;

public class GUI extends JFrame {
    private static LookAndFeel originalLookAndFeel = UIManager.getLookAndFeel();
    static {
        System.out.println("At start, look and feel is " + UIManager.getLookAndFeel().getName());
        try {
            setNimbusLookAndFeel();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        System.out.println("Look and feel changed to " + UIManager.getLookAndFeel().getName()
                + " before component creation");
    }
    private GridBagLayout gridBag = new GridBagLayout();
    private JTabbedPane tabs = new JTabbedPane();
    private JPanel selectionPanel = new JPanel(gridBag);
    private JPanel infoPanel = new JPanel(gridBag);
    private JPanel settingsPanel = new JPanel(gridBag);

    public GUI() {
        setWindowProperties();
        setUpComponents();
        addComponents();

        try {
            System.out.println("Setting to original, which is " + originalLookAndFeel.getName());
            UIManager.setLookAndFeel(originalLookAndFeel);
            System.out.println("Current look and feel is " + UIManager.getLookAndFeel().getName());
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
    }

    private void setWindowProperties() {
        setLayout(gridBag);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(new Dimension(700, 600));
        setTitle("fAmos Quester");
        setResizable(false);
        setLocationRelativeTo(null);
    }

    private static void setNimbusLookAndFeel() {
        try {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                }
            }
        } catch (Exception e) {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e2) {
            }
        }
    }

    public void setUpComponents() {
        tabs.addTab("Quest selection", selectionPanel);
        tabs.addTab("Quest info", infoPanel);
        tabs.addTab("Settings", settingsPanel);

        selectionPanel.setPreferredSize(new Dimension(650, 500));
        infoPanel.setPreferredSize(new Dimension(650, 500));
        settingsPanel.setPreferredSize(new Dimension(650, 500));
    }

    private void addComponents() {
        add(tabs);
    }

    public static void main(String[] args) {
        new GUI().setVisible(true);
    }
}
4

4 に答える 4

3

この問題は、静的ブロックで PLAF の変更を試みたことが原因で発生します。それをコンストラクターに移動すると、機能します。

import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;

public class GUI extends JFrame {
    private static LookAndFeel originalLookAndFeel = UIManager.getLookAndFeel();
    private GridBagLayout gridBag = new GridBagLayout();
    private JTabbedPane tabs = new JTabbedPane();
    private JPanel selectionPanel = new JPanel(gridBag);
    private JPanel infoPanel = new JPanel(gridBag);
    private JPanel settingsPanel = new JPanel(gridBag);

    public GUI() {
        System.out.println("At start, look and feel is " + UIManager.getLookAndFeel().getName());
        try {
            setNimbusLookAndFeel();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("Look and feel changed to " + UIManager.getLookAndFeel().getName()
                + " before component creation");

        setWindowProperties();
        setUpComponents();
        addComponents();

        try {
            System.out.println("Setting to original, which is " + originalLookAndFeel.getName());
            UIManager.setLookAndFeel(originalLookAndFeel);
            System.out.println("Current look and feel is " + UIManager.getLookAndFeel().getName());
        } catch (UnsupportedLookAndFeelException e) {
            //e.printStackTrace();
            System.out.println(e.getMessage());
        }
    }

    private void setWindowProperties() {
        setLayout(gridBag);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(new Dimension(700, 600));
        setTitle("fAmos Quester");
        setResizable(false);
        setLocationRelativeTo(null);
    }

    private void setNimbusLookAndFeel() {
        try {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                }
            }
        } catch (Exception e) {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e2) {
            }
        }
    }

    public void setUpComponents() {
        tabs.addTab("Quest selection", selectionPanel);
        tabs.addTab("Quest info", infoPanel);
        tabs.addTab("Settings", settingsPanel);

        selectionPanel.setPreferredSize(new Dimension(650, 500));
        infoPanel.setPreferredSize(new Dimension(650, 500));
        settingsPanel.setPreferredSize(new Dimension(650, 500));
    }

    private void addComponents() {
        add(tabs);
    }

    public static void main(String[] args) {
        new GUI().setVisible(true);
    }
}
于 2013-08-25T01:55:37.580 に答える
0

このソリューションでは、「この」特定のウィンドウのルック アンド フィール設定を変更することを前提としています (ちょっとしたプライベート ヘルパー メソッド)。ユーザーからの入力を取得するためにダイアログ ウィンドウを使用しました (これを自分で再設計して、ユーザーから非表示にし、必要なときに変更を加えることができます)。もちろん、これはわかりやすくするために少し長くなっており、簡単に短くすることができます。

private void changeLookAndFeel() {
        final LookAndFeelInfo[] list = UIManager.getInstalledLookAndFeels();
        //Look And Feels available 


            final List<String> lookAndFeelsDisplay = new ArrayList<>();
            final List<String> lookAndFeelsRealNames = new ArrayList<>();

            for (LookAndFeelInfo each : list) {
                lookAndFeelsDisplay.add(each.getName()); //simplified name of each available look and feel
                lookAndFeelsRealNames.add(each.getClassName()); //class name
            }

            if (lookAndFeelsDisplay.size() != lookAndFeelsRealNames.size()) {
                throw new InternalError(); //should never happen, redundant
            }

            String changeSpeed = (String) JOptionPane.showInputDialog(this, "Choose Look and Feel Here\n(these are all available on your system):", "Choose Look And Feel", JOptionPane.QUESTION_MESSAGE, null, lookAndFeelsDisplay.toArray(), null);

            boolean update = false;
            if (changeSpeed != null && changeSpeed.length() > 0) {
                for (int a = 0; a < lookAndFeelsDisplay.size(); a++) {
                    if (changeSpeed.equals(lookAndFeelsDisplay.get(a))) {
                        try {
                            UIManager.setLookAndFeel(lookAndFeelsRealNames.get(a)); //reads the identical class name at the corresponding index position.
                            this.whichLookAndFeel = changeSpeed;
                            update = true;
                            break;
                        }
                        catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                            err.println(ex);
                            ex.printStackTrace();
                            Logger.getLogger(MyClass.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }

            if (update) {
                // make updates here...
            }
    }
于 2015-07-04T00:46:54.753 に答える