java - 如何在类(class)中单独更新外观和感觉干净?

标签 java swing look-and-feel jmenuitem

我想通过 JRadioButtonMenuItem 更新我的外观。我在 Stackoverflow 中搜索,但发现的是 1 个类中的一大堆代码。对于我这样的初学者来说,将功能分离到一个特殊的类中更容易。 这是我的框架类。

public class CalenderFrame extends JFrame {

public CalenderFrame() throws HeadlessException {
    createFrame();
}
public void createFrame() {
    setJMenuBar(CalenderMenuBar.getInstance().createMenu());

    setTitle("Calender");
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setPreferredSize(new Dimension(400, 300));
    pack();
    setLocationRelativeTo(null);
    setVisible(true);
}
}

这就是我的 MenueBar 类。我只是给出了针对这个问题的一小段代码。这个类是一个单例类。

public JMenuBar createMenu() {
JMenu lookAndFeelMenu = new JMenu("Look & Feel");
        JRadioButtonMenuItem lAndFWindowsItem = new JRadioButtonMenuItem("Windows",true);
        lAndFWindowsItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == lAndFWindowsItem) {
                    lAndFAction(1);
                }
            }
        });
        JRadioButtonMenuItem lAndFMetalItem = new JRadioButtonMenuItem("Metal",false);
        lAndFMetalItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == lAndFMetalItem) {
                    lAndFAction(2);
                }
            }
        });
        JRadioButtonMenuItem lAndFMotifItem = new JRadioButtonMenuItem("Motif", false);
        lAndFMotifItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == lAndFMotifItem) {
                    lAndFAction(3);
                }
            }
        });
        ButtonGroup group = new ButtonGroup();
        group.add(lAndFWindowsItem);
        group.add(lAndFMetalItem);
        group.add(lAndFMotifItem);

        lookAndFeelMenu.add(lAndFWindowsItem);
        lookAndFeelMenu.add(lAndFMetalItem);
        lookAndFeelMenu.add(lAndFMotifItem);
   }

public void lAndFAction(int counter) {
       try {
        String plaf = "";
        if (counter == 1) {
            plaf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
        } else if (counter == 2) {
            plaf = "javax.swing.plaf.metal.MetalLookAndFeel";
        } else if (counter == 3) {
            plaf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
        }

        UIManager.setLookAndFeel(plaf);
        //SwingUtilities.updateComponentTreeUI(this);


    } catch (UnsupportedLookAndFeelException ue) {
        System.err.println(ue.toString());
    } catch (ClassNotFoundException ce) {
        System.err.println(ce.toString());
    } catch (InstantiationException ie) {
        System.err.println(ie.toString());
    } catch (IllegalAccessException iae) {
        System.err.println(iae.toString());
    }
    }
}

希望大家能够帮助我。

最佳答案

我不确定您的问题到底是什么。但是,更改 LaF 后必须更新组件。根据Look and Feel Documentation :

Changing the Look and Feel After Startup

You can change the L&F with setLookAndFeel even after the program's GUI is visible. To make existing components reflect the new L&F, invoke the SwingUtilities updateComponentTreeUI method once per top-level container. Then you might wish to resize each top-level container to reflect the new sizes of its contained components. For example:

UIManager.setLookAndFeel(lnfName);
SwingUtilities.updateComponentTreeUI(frame); 
frame.pack();

因此,您需要对 UI 中包含组件的框架进行引用。一个想法是做类似的事情:

public class CalendarMenuBar {
    // Add this field to tour factory
    private static JFrame frameThatWillBeUpdated;

    // ... (Your code goes here)

    // update this method to receive the reference of the frame which will
    // need to be refreshed (update the GUI)
    public JMenuBar createMenu(JFrame frame) {
        // sets the reference for the frame
        frameThatWillBeUpdated = frame;

        // ... (the rest of your code for this method)
    }

    // ...

    // Update this method to refresh the frame
    public void lAndFAction(int counter) {
        try{
            // ... (your code)

            // Set the LaF
            UIManager.setLookAndFeel(plaf);
            // Update the component tree (frame and its children)
            SwingUtilities.updateComponentTreeUI(frameThatWillBeUpdated);
            // repack to resize 
            frame.pack();

        } catch(Exception ex){ 
            // Your catches
        }
    }
}

以下是创建框架时如何使用它(在 CalenderFrame 类中):

public void createFrame() {
    // use this frame as reference
    setJMenuBar(CalenderMenuBar.getInstance().createMenu(this));

    // ... (your code goes here)
}

关于java - 如何在类(class)中单独更新外观和感觉干净?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44504689/

相关文章:

java - 更改 JSlider 的外观

jsf - PrimeFaces CSS 皮肤未显示在登录页面中,还有 JavaScript 未定义错误

java - 使用字符串名称创建变量

java - 将给定时间转换为 GMT

JavaFX FXML - 使用 fx :id 获取 MenuItem

java在查询后设置id

java - 新类(class),无法通过它们验证数学问题

java - JTable 未从 SwingWorker 线程更新

java - GUI - actionListener 方法

java - 自定义JButton样式