如何将 Java 首选项 Class 与 JRadioButton 一起使用

How to use the Java Preferences Class with JRadioButton

我正在构建一个小程序,它有一个设置屏幕,用户可以在其中选择颜色主题。我为每种颜色都使用了 JRadioButton,但我无法让程序保存它以供下次 运行 程序使用。这是我的代码:

private Preferences userPreferences = Preferences.userRoot();
MainWindow() {
    super("Timer");
    setLayout(new GridLayout(4,3,5,5));
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setSize(650,290);
    setResizable(false);
    userPreferences.get("COLOR_CODE", "#ededed");

    //MORE CODE HERE

@Override
public void menuSelected(MenuEvent e) {
    //Open settings window
    if(e.getSource().equals(settings)) {
        about.setEnabled(false);
        exit.setEnabled(false);
        settingsFrame = new SettingsWindow();
        settingsFrame.setAlwaysOnTop(true);
        settingsFrame.setLocationRelativeTo(null);
        settingsFrame.setVisible(true);

        //WindowListener for closing the settings window
        settingsFrame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent we) {
                settings.setEnabled(true);
                about.setEnabled(true);
                exit.setEnabled(true);
            }
        });

        //Adding action listeners to the radio buttons
        settingsFrame.defaultColorRB.addActionListener(ee -> {
            settingsFrame.setColor("#ededed");
            getContentPane().setBackground(Color.decode(settingsFrame.getColorCode()));
            userPreferences.put("COLOR_CODE", settingsFrame.getColorCode());
        });

        settingsFrame.whiteColorRB.addActionListener(ee -> {
            settingsFrame.setColor("#FFFFFF");
            getContentPane().setBackground(Color.decode(settingsFrame.getColorCode()));
            userPreferences.put("COLOR_CODE", settingsFrame.getColorCode());
        });

        settingsFrame.lightGrayColorRB.addActionListener(ee -> {
            settingsFrame.setColor("#D2D8DF");
            getContentPane().setBackground(Color.decode(settingsFrame.getColorCode()));
            userPreferences.put("COLOR_CODE", settingsFrame.getColorCode());
        });

        settingsFrame.darkGrayColorRB.addActionListener(ee -> {
            settingsFrame.setColor("#A2A4A6");
            getContentPane().setBackground(Color.decode(settingsFrame.getColorCode()));
            userPreferences.put("COLOR_CODE", settingsFrame.getColorCode());
        });

        settingsFrame.yellowColorRB.addActionListener(ee -> {
            settingsFrame.setColor("#FBFF00");
            getContentPane().setBackground(Color.decode(settingsFrame.getColorCode()));
            userPreferences.put("COLOR_CODE", settingsFrame.getColorCode());
        });

        settingsFrame.pinkColorRB.addActionListener(ee -> {
            settingsFrame.setColor("#F58EB3");
            getContentPane().setBackground(Color.decode(settingsFrame.getColorCode()));
            userPreferences.put("COLOR_CODE", settingsFrame.getColorCode());
        });

        settingsFrame.cyanColorRB.addActionListener(ee -> {
            settingsFrame.setColor("#32D0F7");
            getContentPane().setBackground(Color.decode(settingsFrame.getColorCode()));
            userPreferences.put("COLOR_CODE", settingsFrame.getColorCode());
        });

    }
}

谁能告诉我为什么上面的代码不保存用户选择的颜色?

一个好的用法首先是创建一个节点,而不是直接在用户根节点中保存首选项。 试试这个:

// This will define a node in which the preferences can be stored
prefs = Preferences.userRoot().node(this.getClass().getName());

看看这是否改变了什么。

如果保存颜色代码,如问题中所述,您将需要测试保存的颜色代码和 select 相应的按钮。示例,非常基础,仅供演示:

// assuming userPreferences is java.util.prefs.Preferences
String colorCode = userPreferences.get("COLOR_CODE", "#ededed");
switch (colorCode.toLowerCase()) {
    case "#ededed": defaultColorRB.setSelected(true); break;
    case "#ffffff": whiteColorRB.setSelected(true); break;
    ...
    default: /* none selected - not sure what you want to do in that case */ break;
}

提示 1:使用常量作为首选项键 "COLOR_CODE" 和颜色(例如 "ededed")

提示 2:由于您使用的是单选按钮,即一些不同的颜色,因此保存 selected 单选按钮索引(或某个常量)而不是颜色代码本身(例如#ededed)。如果允许用户 select 任何颜色,不仅是单选按钮的颜色,您一定要保存颜色代码。

这是第二个提示的示例:

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.Preferences;

import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;

public class Radio {

    private static final String PREF_BUTTON_INDEX = "color button";
    private final Preferences prefs = Preferences.userNodeForPackage(getClass());


    private static final String[] COLORS = { "#ededed", "#ffffff", "#a00000" };
    private List<JRadioButton> buttons;
    private JLabel output;  // so we can see something, simulating usage of color

    private Radio() {
        buttons = new ArrayList<>();
        SwingUtilities.invokeLater(this::initGUI);
    }

    private void initGUI() {
        JPanel panel = new JPanel();
        ButtonGroup group = new ButtonGroup();
        for (int i = 0; i < COLORS.length; i++) {
            JRadioButton button = new JRadioButton(COLORS[i]);
            button.addActionListener(this::buttonSelected);
            group.add(button);
            panel.add(button);
            buttons.add(button);
        }

        output = new JLabel("undefined");
        output.setBorder(new TitledBorder("Color:"));
        panel.add(output);

        int colorIndex = prefs.getInt(PREF_BUTTON_INDEX, -1);
        if (colorIndex != -1) {
            buttons.get(colorIndex).setSelected(true);
            output.setText(COLORS[colorIndex]);
        }

        JOptionPane.showMessageDialog(null, panel);
    }

    private void buttonSelected(ActionEvent ev) {
        int index = buttons.indexOf(ev.getSource());
        if (index != -1) {
            output.setText(COLORS[index]);
            prefs.putInt(PREF_BUTTON_INDEX, index);
        }
    }

    public static void main(String[] args) {
        new Radio();
    }
}