default search/filter to realtime
[nikiroo-utils.git] / src / be / nikiroo / fanfix_swing / gui / BrowserPanel.java
1 package be.nikiroo.fanfix_swing.gui;
2
3 import java.awt.BorderLayout;
4 import java.awt.Component;
5 import java.awt.Dimension;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.util.List;
9
10 import javax.swing.JButton;
11 import javax.swing.JPanel;
12 import javax.swing.JTabbedPane;
13 import javax.swing.event.ChangeEvent;
14 import javax.swing.event.ChangeListener;
15
16 import be.nikiroo.fanfix.Instance;
17 import be.nikiroo.fanfix.library.BasicLibrary;
18 import be.nikiroo.fanfix_swing.gui.book.BookInfo;
19 import be.nikiroo.fanfix_swing.gui.browser.AuthorTab;
20 import be.nikiroo.fanfix_swing.gui.browser.BasicTab;
21 import be.nikiroo.fanfix_swing.gui.browser.SourceTab;
22 import be.nikiroo.fanfix_swing.gui.browser.TagsTab;
23 import be.nikiroo.fanfix_swing.gui.utils.ListenerPanel;
24 import be.nikiroo.fanfix_swing.gui.utils.UiHelper;
25
26 /**
27 * Panel dedicated to browse the stories through different means: by authors, by
28 * tags or by sources.
29 *
30 * @author niki
31 */
32 public class BrowserPanel extends ListenerPanel {
33 private static final long serialVersionUID = 1L;
34
35 /**
36 * The {@link ActionEvent} you receive from
37 * {@link BrowserPanel#addActionListener(ActionListener)} can return this as
38 * a command (see {@link ActionEvent#getActionCommand()}) if they were
39 * created in the scope of a source.
40 */
41 static public final String SOURCE_SELECTION = "source_selection";
42 /**
43 * The {@link ActionEvent} you receive from
44 * {@link BrowserPanel#addActionListener(ActionListener)} can return this as
45 * a command (see {@link ActionEvent#getActionCommand()}) if they were
46 * created in the scope of an author.
47 */
48 static public final String AUTHOR_SELECTION = "author_selection";
49 /**
50 * The {@link ActionEvent} you receive from
51 * {@link BrowserPanel#addActionListener(ActionListener)} can return this as
52 * a command (see {@link ActionEvent#getActionCommand()}) if they were
53 * created in the scope of a tag.
54 */
55 static public final String TAGS_SELECTION = "tags_selection";
56 /**
57 * The {@link ActionEvent} you receive from
58 * {@link BrowserPanel#addActionListener(ActionListener)} can return this as
59 * a command (see {@link ActionEvent#getActionCommand()}) if they were
60 * created in the scope of a tab change.
61 */
62 static public final String TAB_CHANGE = "tab_change";
63
64 private JTabbedPane tabs;
65 private SourceTab sourceTab;
66 private AuthorTab authorTab;
67 private TagsTab tagsTab;
68
69 private boolean keepSelection;
70
71 /**
72 * Create a nesw {@link BrowserPanel}.
73 */
74 public BrowserPanel() {
75 this.setPreferredSize(new Dimension(200, 800));
76
77 this.setLayout(new BorderLayout());
78 tabs = new JTabbedPane();
79
80 int index = 0;
81 tabs.add(sourceTab = new SourceTab(index++, SOURCE_SELECTION));
82 tabs.add(authorTab = new AuthorTab(index++, AUTHOR_SELECTION));
83 tabs.add(tagsTab = new TagsTab(index++, TAGS_SELECTION));
84
85 configureTab(tabs, sourceTab, "Sources", "Tooltip for Sources");
86 configureTab(tabs, authorTab, "Authors", "Tooltip for Authors");
87 configureTab(tabs, tagsTab, "Tags", "Tooltip for Tags");
88
89 JPanel options = new JPanel();
90 options.setLayout(new BorderLayout());
91
92 final JButton keep = new JButton("Keep selection");
93 UiHelper.setButtonPressed(keep, keepSelection);
94 keep.addActionListener(new ActionListener() {
95 @Override
96 public void actionPerformed(ActionEvent e) {
97 keepSelection = !keepSelection;
98 UiHelper.setButtonPressed(keep, keepSelection);
99 keep.setSelected(keepSelection);
100 if (!keepSelection) {
101 unselect();
102 }
103 }
104 });
105
106 options.add(keep, BorderLayout.CENTER);
107
108 add(tabs, BorderLayout.CENTER);
109 add(options, BorderLayout.SOUTH);
110
111 tabs.addChangeListener(new ChangeListener() {
112 @Override
113 public void stateChanged(ChangeEvent e) {
114 if (!keepSelection) {
115 unselect();
116 }
117
118 fireActionPerformed(TAB_CHANGE);
119 }
120 });
121 }
122
123 @SuppressWarnings("rawtypes")
124 private void unselect() {
125 for (int i = 0; i < tabs.getTabCount(); i++) {
126 if (i == tabs.getSelectedIndex())
127 continue;
128
129 BasicTab tab = (BasicTab) tabs.getComponent(i);
130 tab.unselect();
131 }
132 }
133
134 private void configureTab(JTabbedPane tabs,
135 @SuppressWarnings("rawtypes") BasicTab tab, String name,
136 String tooltip) {
137 tab.setBaseTitle(name);
138 tabs.setTitleAt(tab.getIndex(), tab.getTitle());
139 tabs.setToolTipTextAt(tab.getIndex(), tooltip);
140 listenTabs(tabs, tab);
141 }
142
143 private void listenTabs(final JTabbedPane tabs,
144 @SuppressWarnings("rawtypes") final BasicTab tab) {
145 tab.addActionListener(new ActionListener() {
146 @Override
147 public void actionPerformed(ActionEvent e) {
148 tabs.setTitleAt(tab.getIndex(), tab.getTitle());
149 fireActionPerformed(e.getActionCommand());
150 }
151 });
152 }
153
154 /**
155 * Get the {@link BookInfo} to highlight, even if none or more than one are
156 * selected.
157 * <p>
158 * Return a special "all" {@link BookInfo} of the correct type when nothing
159 * is selected.
160 *
161 * @return the {@link BookInfo} to highlight, can be NULL
162 */
163 public BookInfo getHighlight() {
164 String selected1 = null;
165 Component selectedTab = tabs.getSelectedComponent();
166 if (selectedTab instanceof BasicTab) {
167 @SuppressWarnings({ "unchecked", "rawtypes" })
168 List<String> selectedAll = ((BasicTab) selectedTab)
169 .getSelectedElements();
170 if (!selectedAll.isEmpty()) {
171 selected1 = selectedAll.get(0);
172 }
173 }
174
175 BasicLibrary lib = Instance.getInstance().getLibrary();
176 if (tabs.getSelectedComponent() == sourceTab) {
177 return BookInfo.fromSource(lib, selected1);
178 } else if (tabs.getSelectedComponent() == authorTab) {
179 return BookInfo.fromAuthor(lib, selected1);
180 } else if (tabs.getSelectedComponent() == tagsTab) {
181 return BookInfo.fromTag(lib, selected1);
182 }
183
184 // ...what?
185 return null;
186 }
187
188 /**
189 * The currently selected sources, or an empty list.
190 *
191 * @return the sources (cannot be NULL)
192 */
193 public List<String> getSelectedSources() {
194 return sourceTab.getSelectedElements();
195 }
196
197 /**
198 * The currently selected authors, or an empty list.
199 *
200 * @return the sources (cannot be NULL)
201 */
202 public List<String> getSelectedAuthors() {
203 return authorTab.getSelectedElements();
204 }
205
206 /**
207 * The currently selected tags, or an empty list.
208 *
209 * @return the sources (cannot be NULL)
210 */
211 public List<String> getSelectedTags() {
212 return tagsTab.getSelectedElements();
213 }
214
215 /**
216 * Reload all the data from the 3 tabs.
217 */
218 public void reloadData() {
219 sourceTab.reloadData();
220 authorTab.reloadData();
221 tagsTab.reloadData();
222 }
223 }