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
);
154 private void updateSearchBy(final boolean byTag
) {
155 if (byTag
!= this.searchByTags
) {
156 inUi(new Runnable() {
160 searchTabs
.setSelectedIndex(0);
162 searchTabs
.setSelectedIndex(1);
169 private void updatePages(final int page
, final Integer maxPage
) {
170 inUi(new Runnable() {
173 GuiReaderSearch
.this.page
= page
;
174 GuiReaderSearch
.this.maxPage
= maxPage
;
176 System
.out
.println("page: " + page
);
177 System
.out
.println("max page: " + maxPage
);
183 private void updateKeywords(final String keywords
) {
184 if (!keywords
.equals(this.keywords
)) {
185 inUi(new Runnable() {
188 GuiReaderSearch
.this.keywords
= keywords
;
189 keywordsField
.setText(keywords
);
196 private void updateTags(final SearchableTag tag
) {
197 inUi(new Runnable() {
205 private void updateBooks(final List
<GuiReaderBookInfo
> infos
) {
206 setWaitingScreen(true);
207 inUi(new Runnable() {
210 books
.refreshBooks(infos
, seeWordcount
);
211 setWaitingScreen(false);
216 // item 0 = no selection, else = default selection
217 public void search(final SupportType searchOn
, final String keywords
,
218 final int page
, final int item
) {
220 setWaitingScreen(true);
222 updateSupportType(searchOn
);
223 updateSearchBy(false);
224 updateKeywords(keywords
);
225 updatePages(page
, maxPage
);
227 new Thread(new Runnable() {
230 BasicSearchable search
= BasicSearchable
231 .getSearchable(searchOn
);
236 maxPage
= search
.searchPages(keywords
);
237 } catch (IOException e
) {
238 Instance
.getTraceHandler().error(e
);
240 updateBooks(new ArrayList
<GuiReaderBookInfo
>());
241 updatePages(0, maxPage
);
243 List
<GuiReaderBookInfo
> infos
= new ArrayList
<GuiReaderBookInfo
>();
245 for (MetaData meta
: search
.search(keywords
, page
)) {
246 infos
.add(GuiReaderBookInfo
.fromMeta(meta
));
248 } catch (IOException e
) {
249 Instance
.getTraceHandler().error(e
);
253 updatePages(page
, maxPage
);
256 if (item
> 0 && item
<= books
.getBooksCount()) {
257 // TODO: "click" on item ITEM
261 setWaitingScreen(false);
266 public void searchTag(final SupportType searchOn
, final int page
,
267 final int item
, final SearchableTag tag
) {
269 setWaitingScreen(true);
271 updateSupportType(searchOn
);
272 updateSearchBy(true);
274 updatePages(page
, maxPage
);
276 new Thread(new Runnable() {
279 BasicSearchable search
= BasicSearchable
280 .getSearchable(searchOn
);
285 maxPage
= search
.searchPages(tag
);
286 } catch (IOException e
) {
287 Instance
.getTraceHandler().error(e
);
290 updatePages(page
, maxPage
);
293 List
<MetaData
> metas
= null;
294 List
<SearchableTag
> subtags
= null;
299 metas
= search
.search(tag
, page
);
300 } catch (IOException e
) {
301 metas
= new ArrayList
<MetaData
>();
302 Instance
.getTraceHandler().error(e
);
304 count
= metas
.size();
306 subtags
= tag
.getChildren();
307 count
= subtags
.size();
313 MetaData meta
= metas
.get(item
- 1);
314 // TODO: select story
316 SearchableTag subtag
= subtags
318 // TODO: search on tag
324 setWaitingScreen(false);
330 * Process the given action in the main Swing UI thread.
332 * The code will make sure the current thread is the main UI thread and, if
333 * not, will switch to it before executing the runnable.
335 * Synchronous operation.
340 private void inUi(final Runnable run
) {
341 if (EventQueue
.isDispatchThread()) {
345 EventQueue
.invokeAndWait(run
);
346 } catch (InterruptedException e
) {
347 Instance
.getTraceHandler().error(e
);
348 } catch (InvocationTargetException e
) {
349 Instance
.getTraceHandler().error(e
);
354 private void setWaitingScreen(final boolean waiting
) {
355 inUi(new Runnable() {
358 GuiReaderSearch
.this.setEnabled(!waiting
);
359 books
.setEnabled(!waiting
);
360 submitKeywords
.setEnabled(!waiting
);