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