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