Bundle: fix memory leak at init/reset
[fanfix.git] / ui / ConfigEditor.java
CommitLineData
d350b96b
NR
1package be.nikiroo.utils.ui;
2
3import java.awt.BorderLayout;
d18e136e 4import java.awt.Color;
d350b96b
NR
5import java.awt.event.ActionEvent;
6import java.awt.event.ActionListener;
7import java.io.IOException;
9cc3f77b 8import java.util.ArrayList;
d350b96b
NR
9import java.util.List;
10
11import javax.swing.BoxLayout;
12import javax.swing.JButton;
49f79f31
NR
13import javax.swing.JComponent;
14import javax.swing.JLabel;
d350b96b 15import javax.swing.JPanel;
49f79f31 16import javax.swing.JScrollPane;
d18e136e 17import javax.swing.JTextArea;
d350b96b 18import javax.swing.border.EmptyBorder;
d18e136e 19import javax.swing.border.TitledBorder;
d350b96b 20
d18e136e 21import be.nikiroo.utils.StringUtils;
d350b96b 22import be.nikiroo.utils.resources.Bundle;
9e834013 23import be.nikiroo.utils.resources.MetaInfo;
d350b96b
NR
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
db31c358 33 *
d350b96b
NR
34 * @param <E>
35 * the type of {@link Bundle} to edit
36 */
37public class ConfigEditor<E extends Enum<E>> extends JPanel {
38 private static final long serialVersionUID = 1L;
9e834013 39 private List<MetaInfo<E>> items;
d350b96b
NR
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
49f79f31
NR
48 * @param title
49 * the title to display before the options
d350b96b 50 */
49f79f31
NR
51 public ConfigEditor(Class<E> type, final Bundle<E> bundle, String title) {
52 this.setLayout(new BorderLayout());
49f79f31 53
a721319a 54 JPanel main = new JPanel();
49f79f31 55 main.setLayout(new BoxLayout(main, BoxLayout.PAGE_AXIS));
d18e136e 56 main.setBorder(new EmptyBorder(5, 5, 5, 5));
9cc3f77b 57
49f79f31 58 main.add(new JLabel(title));
d350b96b 59
9cc3f77b
NR
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
d18e136e 64 addItem(main, item, 0);
d350b96b
NR
65 }
66
a721319a
NR
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() {
cd0c27d2 72 @Override
d350b96b 73 public void actionPerformed(ActionEvent e) {
9e834013 74 for (MetaInfo<E> item : items) {
d350b96b
NR
75 item.reload();
76 }
77 }
49f79f31 78 }));
d350b96b 79
a721319a 80 buttons.add(createButton("Default", new ActionListener() {
cd0c27d2 81 @Override
d350b96b
NR
82 public void actionPerformed(ActionEvent e) {
83 Object snap = bundle.takeSnapshot();
84 bundle.reload(true);
9e834013 85 for (MetaInfo<E> item : items) {
d350b96b
NR
86 item.reload();
87 }
88 bundle.reload(false);
89 bundle.restoreSnapshot(snap);
90 }
49f79f31 91 }));
d350b96b 92
a721319a 93 buttons.add(createButton("Save", new ActionListener() {
cd0c27d2 94 @Override
d350b96b 95 public void actionPerformed(ActionEvent e) {
9e834013 96 for (MetaInfo<E> item : items) {
d5026c09 97 item.save(true);
d350b96b
NR
98 }
99
100 try {
101 bundle.updateFile();
102 } catch (IOException e1) {
103 e1.printStackTrace();
104 }
105 }
49f79f31 106 }));
a721319a
NR
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);
d350b96b
NR
113 }
114
d18e136e 115 private void addItem(JPanel main, MetaInfo<E> item, int nhgap) {
76b51de9 116 if (item.isGroup()) {
d18e136e
NR
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()) {
fde375c1 126 info = info + "\n";
d18e136e
NR
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
76b51de9 135 for (MetaInfo<E> subitem : item) {
d18e136e 136 addItem(pane, subitem, nhgap + 11);
76b51de9 137 }
d18e136e
NR
138 bpane.add(pane, BorderLayout.CENTER);
139 main.add(bpane);
76b51de9 140 } else {
9cc3f77b 141 items.add(item);
a0376372 142 main.add(ConfigItem.createItem(item, nhgap));
76b51de9
NR
143 }
144 }
145
d350b96b
NR
146 /**
147 * Add an action button for this action.
148 *
149 * @param title
150 * the action title
151 * @param listener
152 * the action
153 */
49f79f31 154 private JComponent createButton(String title, ActionListener listener) {
d350b96b
NR
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
49f79f31 163 return panel;
d350b96b
NR
164 }
165}