Bundle: fix memory leak at init/reset
[fanfix.git] / 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
54 JPanel main = new JPanel();
55 main.setLayout(new BoxLayout(main, BoxLayout.PAGE_AXIS));
56 main.setBorder(new EmptyBorder(5, 5, 5, 5));
57
58 main.add(new JLabel(title));
59
60 items = new ArrayList<MetaInfo<E>>();
61 List<MetaInfo<E>> groupedItems = MetaInfo.getItems(type, bundle);
62 for (MetaInfo<E> item : groupedItems) {
63 // will init this.items
64 addItem(main, item, 0);
65 }
66
67 JPanel buttons = new JPanel();
68 buttons.setLayout(new BoxLayout(buttons, BoxLayout.PAGE_AXIS));
69 buttons.setBorder(new EmptyBorder(5, 5, 5, 5));
70
71 buttons.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 buttons.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 buttons.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 JScrollPane scroll = new JScrollPane(main);
109 scroll.getVerticalScrollBar().setUnitIncrement(16);
110
111 this.add(scroll, BorderLayout.CENTER);
112 this.add(buttons, BorderLayout.SOUTH);
113 }
114
115 private void addItem(JPanel main, MetaInfo<E> item, int nhgap) {
116 if (item.isGroup()) {
117 JPanel bpane = new JPanel(new BorderLayout());
118 bpane.setBorder(new TitledBorder(item.getName()));
119 JPanel pane = new JPanel();
120 pane.setBorder(new EmptyBorder(5, 5, 5, 5));
121 pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
122
123 String info = item.getDescription();
124 info = StringUtils.justifyTexts(info, 100);
125 if (!info.isEmpty()) {
126 info = info + "\n";
127 JTextArea text = new JTextArea(info);
128 text.setWrapStyleWord(true);
129 text.setOpaque(false);
130 text.setForeground(new Color(100, 100, 180));
131 text.setEditable(false);
132 pane.add(text);
133 }
134
135 for (MetaInfo<E> subitem : item) {
136 addItem(pane, subitem, nhgap + 11);
137 }
138 bpane.add(pane, BorderLayout.CENTER);
139 main.add(bpane);
140 } else {
141 items.add(item);
142 main.add(ConfigItem.createItem(item, nhgap));
143 }
144 }
145
146 /**
147 * Add an action button for this action.
148 *
149 * @param title
150 * the action title
151 * @param listener
152 * the action
153 */
154 private JComponent createButton(String title, ActionListener listener) {
155 JButton button = new JButton(title);
156 button.addActionListener(listener);
157
158 JPanel panel = new JPanel();
159 panel.setLayout(new BorderLayout());
160 panel.setBorder(new EmptyBorder(2, 10, 2, 10));
161 panel.add(button, BorderLayout.CENTER);
162
163 return panel;
164 }
165 }