Commit | Line | Data |
---|---|---|
3cdf3fd8 NR |
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 | } |