ConfigItem upgrade
[fanfix.git] / src / be / nikiroo / utils / ui / ConfigEditor.java
1 package be.nikiroo.utils.ui;
2
3 import java.awt.BorderLayout;
4 import java.awt.Color;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
7 import java.io.IOException;
8 import java.util.List;
9
10 import javax.swing.BoxLayout;
11 import javax.swing.JButton;
12 import javax.swing.JComponent;
13 import javax.swing.JLabel;
14 import javax.swing.JPanel;
15 import javax.swing.JScrollPane;
16 import javax.swing.JTextArea;
17 import javax.swing.border.EmptyBorder;
18 import javax.swing.border.TitledBorder;
19
20 import be.nikiroo.utils.StringUtils;
21 import be.nikiroo.utils.resources.Bundle;
22 import be.nikiroo.utils.resources.MetaInfo;
23
24 /**
25 * A configuration panel for a {@link Bundle}.
26 * <p>
27 * All the items in the given {@link Bundle} will be displayed in editable
28 * controls, with options to Save, Reset and/or Reset to the application default
29 * values.
30 *
31 * @author niki
32 *
33 * @param <E>
34 * the type of {@link Bundle} to edit
35 */
36 public class ConfigEditor<E extends Enum<E>> extends JPanel {
37 private static final long serialVersionUID = 1L;
38 private List<MetaInfo<E>> items;
39
40 /**
41 * Create a new {@link ConfigEditor} for this {@link Bundle}.
42 *
43 * @param type
44 * a class instance of the item type to work on
45 * @param bundle
46 * the {@link Bundle} to sort through
47 * @param title
48 * the title to display before the options
49 */
50 public ConfigEditor(Class<E> type, final Bundle<E> bundle, String title) {
51 this.setLayout(new BorderLayout());
52 JPanel main = new JPanel();
53
54 JScrollPane scroll = new JScrollPane(main);
55 scroll.getVerticalScrollBar().setUnitIncrement(16);
56 this.add(scroll, BorderLayout.CENTER);
57
58 main.setLayout(new BoxLayout(main, BoxLayout.PAGE_AXIS));
59 main.setBorder(new EmptyBorder(5, 5, 5, 5));
60
61 main.add(new JLabel(title));
62
63 items = MetaInfo.getItems(type, bundle);
64 for (MetaInfo<E> item : items) {
65 addItem(main, item, 0);
66 }
67
68 main.add(createButton("Reset", new ActionListener() {
69 @Override
70 public void actionPerformed(ActionEvent e) {
71 for (MetaInfo<E> item : items) {
72 item.reload();
73 }
74 }
75 }));
76
77 main.add(createButton("Default", new ActionListener() {
78 @Override
79 public void actionPerformed(ActionEvent e) {
80 Object snap = bundle.takeSnapshot();
81 bundle.reload(true);
82 for (MetaInfo<E> item : items) {
83 item.reload();
84 }
85 bundle.reload(false);
86 bundle.restoreSnapshot(snap);
87 }
88 }));
89
90 main.add(createButton("Save", new ActionListener() {
91 @Override
92 public void actionPerformed(ActionEvent e) {
93 for (MetaInfo<E> item : items) {
94 item.save();
95 }
96
97 try {
98 bundle.updateFile();
99 } catch (IOException e1) {
100 e1.printStackTrace();
101 }
102 }
103 }));
104 }
105
106 private void addItem(JPanel main, MetaInfo<E> item, int nhgap) {
107 if (item.isGroup()) {
108 JPanel bpane = new JPanel(new BorderLayout());
109 bpane.setBorder(new TitledBorder(item.getName()));
110 JPanel pane = new JPanel();
111 pane.setBorder(new EmptyBorder(5, 5, 5, 5));
112 pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
113
114 String info = item.getDescription();
115 info = StringUtils.justifyTexts(info, 100);
116 if (!info.isEmpty()) {
117 JTextArea text = new JTextArea(info);
118 text.setWrapStyleWord(true);
119 text.setOpaque(false);
120 text.setForeground(new Color(100, 100, 180));
121 text.setEditable(false);
122 pane.add(text);
123 }
124
125 for (MetaInfo<E> subitem : item) {
126 addItem(pane, subitem, nhgap + 11);
127 }
128 bpane.add(pane, BorderLayout.CENTER);
129 main.add(bpane);
130 } else {
131 main.add(new ConfigItem<E>(item, nhgap));
132 }
133 }
134
135 /**
136 * Add an action button for this action.
137 *
138 * @param title
139 * the action title
140 * @param listener
141 * the action
142 */
143 private JComponent createButton(String title, ActionListener listener) {
144 JButton button = new JButton(title);
145 button.addActionListener(listener);
146
147 JPanel panel = new JPanel();
148 panel.setLayout(new BorderLayout());
149 panel.setBorder(new EmptyBorder(2, 10, 2, 10));
150 panel.add(button, BorderLayout.CENTER);
151
152 return panel;
153 }
154 }