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