1 package be
.nikiroo
.fanfix
.reader
.ui
;
3 import java
.awt
.BorderLayout
;
4 import java
.awt
.Component
;
5 import java
.awt
.EventQueue
;
6 import java
.awt
.event
.ActionEvent
;
7 import java
.awt
.event
.ActionListener
;
8 import java
.io
.IOException
;
9 import java
.lang
.reflect
.InvocationTargetException
;
10 import java
.util
.ArrayList
;
11 import java
.util
.List
;
13 import javax
.swing
.JButton
;
14 import javax
.swing
.JComboBox
;
15 import javax
.swing
.JFrame
;
16 import javax
.swing
.JLabel
;
17 import javax
.swing
.JPanel
;
18 import javax
.swing
.JScrollPane
;
19 import javax
.swing
.JTabbedPane
;
20 import javax
.swing
.JTextField
;
22 import be
.nikiroo
.fanfix
.Instance
;
23 import be
.nikiroo
.fanfix
.data
.MetaData
;
24 import be
.nikiroo
.fanfix
.reader
.ui
.GuiReaderBook
.BookActionListener
;
25 import be
.nikiroo
.fanfix
.searchable
.BasicSearchable
;
26 import be
.nikiroo
.fanfix
.searchable
.SearchableTag
;
27 import be
.nikiroo
.fanfix
.supported
.SupportType
;
30 * This frame will allow you to search through the supported websites for new
35 public class GuiReaderSearch
extends JFrame
{
36 private static final long serialVersionUID
= 1L;
38 private List
<SupportType
> supportTypes
;
39 private SupportType supportType
;
40 private boolean searchByTags
;
41 private List
<SearchableTag
> tags
;
42 private String keywords
;
46 private JComboBox
<SupportType
> comboSupportTypes
;
47 private JTabbedPane searchTabs
;
48 private JTextField keywordsField
;
49 private JButton submitKeywords
;
51 private boolean seeWordcount
;
52 private GuiReaderGroup books
;
54 public GuiReaderSearch(final GuiReader reader
) {
55 super("Browse stories");
56 setLayout(new BorderLayout());
59 tags
= new ArrayList
<SearchableTag
>();
64 supportTypes
= new ArrayList
<SupportType
>();
65 for (SupportType type
: SupportType
.values()) {
66 if (BasicSearchable
.getSearchable(type
) != null) {
67 supportTypes
.add(type
);
70 supportType
= supportTypes
.isEmpty() ?
null : supportTypes
.get(0);
72 comboSupportTypes
= new JComboBox
<SupportType
>(
73 supportTypes
.toArray(new SupportType
[] {}));
74 comboSupportTypes
.addActionListener(new ActionListener() {
76 public void actionPerformed(ActionEvent e
) {
77 updateSupportType((SupportType
) comboSupportTypes
81 JPanel searchSites
= new JPanel(new BorderLayout());
82 searchSites
.add(comboSupportTypes
, BorderLayout
.CENTER
);
83 searchSites
.add(new JLabel(" " + "Website : "), BorderLayout
.WEST
);
85 searchTabs
= new JTabbedPane();
86 searchTabs
.addTab("By name", createByNameSearchPanel());
87 searchTabs
.addTab("By tags", createByTagSearchPanel());
89 JPanel top
= new JPanel(new BorderLayout());
90 top
.add(searchSites
, BorderLayout
.NORTH
);
91 top
.add(searchTabs
, BorderLayout
.CENTER
);
93 add(top
, BorderLayout
.NORTH
);
95 books
= new GuiReaderGroup(reader
, null, null);
96 books
.setActionListener(new BookActionListener() {
98 public void select(GuiReaderBook book
) {
102 public void popupRequested(GuiReaderBook book
, Component target
,
107 public void action(GuiReaderBook book
) {
108 new GuiReaderSearchAction(reader
.getLibrary(), book
.getInfo())
112 JScrollPane scroll
= new JScrollPane(books
);
113 scroll
.getVerticalScrollBar().setUnitIncrement(16);
114 add(scroll
, BorderLayout
.CENTER
);
117 private JPanel
createByNameSearchPanel() {
118 JPanel byName
= new JPanel(new BorderLayout());
120 keywordsField
= new JTextField();
121 byName
.add(keywordsField
, BorderLayout
.CENTER
);
123 submitKeywords
= new JButton("Search");
124 byName
.add(submitKeywords
, BorderLayout
.EAST
);
126 // TODO: ENTER -> search
128 submitKeywords
.addActionListener(new ActionListener() {
130 public void actionPerformed(ActionEvent e
) {
131 search(supportType
, keywordsField
.getText(), page
, 0);
138 private JPanel
createByTagSearchPanel() {
139 JPanel byTag
= new JPanel();
140 JPanel searchBars
= new JPanel();
141 add(searchBars
, BorderLayout
.NORTH
);
146 private void updateSupportType(SupportType supportType
) {
147 if (supportType
!= this.supportType
) {
148 this.supportType
= supportType
;
149 comboSupportTypes
.setSelectedItem(supportType
);
151 // TODO: reset all tags
155 private void updateSearchBy(final boolean byTag
) {
156 if (byTag
!= this.searchByTags
) {
157 inUi(new Runnable() {
161 searchTabs
.setSelectedIndex(0);
163 searchTabs
.setSelectedIndex(1);
170 private void updatePages(final int page
, final Integer maxPage
) {
171 inUi(new Runnable() {
174 GuiReaderSearch
.this.page
= page
;
175 GuiReaderSearch
.this.maxPage
= maxPage
;
177 System
.out
.println("page: " + page
);
178 System
.out
.println("max page: " + maxPage
);
184 private void updateKeywords(final String keywords
) {
185 if (!keywords
.equals(this.keywords
)) {
186 inUi(new Runnable() {
189 GuiReaderSearch
.this.keywords
= keywords
;
190 keywordsField
.setText(keywords
);
197 private void updateTags(final SearchableTag tag
) {
198 inUi(new Runnable() {
206 private void updateBooks(final List
<GuiReaderBookInfo
> infos
) {
207 setWaitingScreen(true);
208 inUi(new Runnable() {
211 books
.refreshBooks(infos
, seeWordcount
);
212 setWaitingScreen(false);
217 // item 0 = no selection, else = default selection
218 public void search(final SupportType searchOn
, final String keywords
,
219 final int page
, final int item
) {
221 setWaitingScreen(true);
223 updateSupportType(searchOn
);
224 updateSearchBy(false);
225 updateKeywords(keywords
);
226 updatePages(page
, maxPage
);
228 new Thread(new Runnable() {
231 BasicSearchable search
= BasicSearchable
232 .getSearchable(searchOn
);
237 maxPage
= search
.searchPages(keywords
);
238 } catch (IOException e
) {
239 Instance
.getTraceHandler().error(e
);
241 updateBooks(new ArrayList
<GuiReaderBookInfo
>());
242 updatePages(0, maxPage
);
244 List
<GuiReaderBookInfo
> infos
= new ArrayList
<GuiReaderBookInfo
>();
246 for (MetaData meta
: search
.search(keywords
, page
)) {
247 infos
.add(GuiReaderBookInfo
.fromMeta(meta
));
249 } catch (IOException e
) {
250 Instance
.getTraceHandler().error(e
);
254 updatePages(page
, maxPage
);
257 if (item
> 0 && item
<= books
.getBooksCount()) {
258 // TODO: "click" on item ITEM
262 setWaitingScreen(false);
267 public void searchTag(final SupportType searchOn
, final int page
,
268 final int item
, final SearchableTag tag
) {
270 setWaitingScreen(true);
272 updateSupportType(searchOn
);
273 updateSearchBy(true);
275 updatePages(page
, maxPage
);
277 new Thread(new Runnable() {
280 BasicSearchable search
= BasicSearchable
281 .getSearchable(searchOn
);
286 maxPage
= search
.searchPages(tag
);
287 } catch (IOException e
) {
288 Instance
.getTraceHandler().error(e
);
291 updatePages(page
, maxPage
);
294 List
<MetaData
> metas
= null;
295 List
<SearchableTag
> subtags
= null;
300 metas
= search
.search(tag
, page
);
301 } catch (IOException e
) {
302 metas
= new ArrayList
<MetaData
>();
303 Instance
.getTraceHandler().error(e
);
305 count
= metas
.size();
307 subtags
= tag
.getChildren();
308 count
= subtags
.size();
314 MetaData meta
= metas
.get(item
- 1);
315 // TODO: select story
317 SearchableTag subtag
= subtags
319 // TODO: search on tag
325 setWaitingScreen(false);
331 * Process the given action in the main Swing UI thread.
333 * The code will make sure the current thread is the main UI thread and, if
334 * not, will switch to it before executing the runnable.
336 * Synchronous operation.
341 private void inUi(final Runnable run
) {
342 if (EventQueue
.isDispatchThread()) {
346 EventQueue
.invokeAndWait(run
);
347 } catch (InterruptedException e
) {
348 Instance
.getTraceHandler().error(e
);
349 } catch (InvocationTargetException e
) {
350 Instance
.getTraceHandler().error(e
);
355 private void setWaitingScreen(final boolean waiting
) {
356 inUi(new Runnable() {
359 GuiReaderSearch
.this.setEnabled(!waiting
);
360 books
.setEnabled(!waiting
);
361 submitKeywords
.setEnabled(!waiting
);