some update/refresh fixes
[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.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 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 * The {@link ActionEvent} you receive from
58 * {@link BrowserPanel#addActionListener(ActionListener)} can return this as a
59 * command (see {@link ActionEvent#getActionCommand()}) if they were created in
60 * 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, @SuppressWarnings("rawtypes") BasicTab tab, String name,
135 String tooltip) {
136 tab.setBaseTitle(name);
137 tabs.setTitleAt(tab.getIndex(), tab.getTitle());
138 tabs.setToolTipTextAt(tab.getIndex(), tooltip);
139 listenTabs(tabs, tab);
140 }
141
142 private void listenTabs(final JTabbedPane tabs, @SuppressWarnings("rawtypes") final BasicTab tab) {
143 tab.addActionListener(new ActionListener() {
144 @Override
145 public void actionPerformed(ActionEvent e) {
146 tabs.setTitleAt(tab.getIndex(), tab.getTitle());
147 fireActionPerformed(e.getActionCommand());
148 }
149 });
150 }
151
152 /**
153 * Get the {@link BookInfo} to highlight, even if none or more than one are
154 * selected.
155 * <p>
156 * Return a special "all" {@link BookInfo} of the correct type when nothing is
157 * selected.
158 *
159 * @return the {@link BookInfo} to highlight, can be NULL
160 */
161 public BookInfo getHighlight() {
162 String selected1 = null;
163 Component selectedTab = tabs.getSelectedComponent();
164 if (selectedTab instanceof BasicTab) {
165 @SuppressWarnings({ "unchecked", "rawtypes" })
166 List<String> selectedAll = ((BasicTab) selectedTab).getSelectedElements();
167 if (!selectedAll.isEmpty()) {
168 selected1 = selectedAll.get(0);
169 }
170 }
171
172 BasicLibrary lib = Instance.getInstance().getLibrary();
173 if (tabs.getSelectedComponent() == sourceTab) {
174 return BookInfo.fromSource(lib, selected1);
175 } else if (tabs.getSelectedComponent() == authorTab) {
176 return BookInfo.fromAuthor(lib, selected1);
177 } else if (tabs.getSelectedComponent() == tagsTab) {
178 return BookInfo.fromTag(lib, selected1);
179 }
180
181 // ...what?
182 return null;
183 }
184
185 /**
186 * The currently selected sources, or an empty list.
187 *
188 * @return the sources (cannot be NULL)
189 */
190 public List<String> getSelectedSources() {
191 return sourceTab.getSelectedElements();
192 }
193
194 /**
195 * The currently selected authors, or an empty list.
196 *
197 * @return the sources (cannot be NULL)
198 */
199 public List<String> getSelectedAuthors() {
200 return authorTab.getSelectedElements();
201 }
202
203 /**
204 * The currently selected tags, or an empty list.
205 *
206 * @return the sources (cannot be NULL)
207 */
208 public List<String> getSelectedTags() {
209 return tagsTab.getSelectedElements();
210 }
211
212 /**
213 * Reload all the data from the 3 tabs.
214 */
215 public void reloadData() {
216 sourceTab.reloadData();
217 authorTab.reloadData();
218 tagsTab.reloadData();
219 }
220 }