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
.JPanel
;
17 import javax
.swing
.JScrollPane
;
18 import javax
.swing
.JTabbedPane
;
19 import javax
.swing
.JTextField
;
21 import be
.nikiroo
.fanfix
.Instance
;
22 import be
.nikiroo
.fanfix
.data
.MetaData
;
23 import be
.nikiroo
.fanfix
.reader
.ui
.GuiReaderBook
.BookActionListener
;
24 import be
.nikiroo
.fanfix
.searchable
.BasicSearchable
;
25 import be
.nikiroo
.fanfix
.searchable
.SearchableTag
;
26 import be
.nikiroo
.fanfix
.supported
.SupportType
;
29 * This frame will allow you to search through the supported websites for new
34 public class GuiReaderSearch
extends JFrame
{
35 private static final long serialVersionUID
= 1L;
37 private List
<SupportType
> supportTypes
;
38 private SupportType supportType
;
39 private List
<SearchableTag
> tags
;
40 private String keywords
;
44 private JComboBox
<SupportType
> comboSupportTypes
;
45 private JTabbedPane searchTabs
;
47 private boolean seeWordcount
;
48 private GuiReaderGroup books
;
50 public GuiReaderSearch(final GuiReader reader
) {
52 super("Browse stories");
53 setLayout(new BorderLayout());
56 tags
= new ArrayList
<SearchableTag
>();
60 supportTypes
= new ArrayList
<SupportType
>();
61 for (SupportType type
: SupportType
.values()) {
62 if (BasicSearchable
.getSearchable(type
) != null) {
63 supportTypes
.add(type
);
66 supportType
= supportTypes
.isEmpty() ?
null : supportTypes
.get(0);
68 JPanel top
= new JPanel(new BorderLayout());
69 comboSupportTypes
= new JComboBox
<SupportType
>(
70 supportTypes
.toArray(new SupportType
[] {}));
71 comboSupportTypes
.addActionListener(new ActionListener() {
73 public void actionPerformed(ActionEvent e
) {
74 setSupportType((SupportType
) comboSupportTypes
78 top
.add(comboSupportTypes
, BorderLayout
.NORTH
);
81 searchTabs
= new JTabbedPane();
82 searchTabs
.addTab("By name", createByNameSearchPanel());
83 searchTabs
.addTab("By tags", createByTagSearchPanel());
85 top
.add(searchTabs
, BorderLayout
.CENTER
);
87 add(top
, BorderLayout
.NORTH
);
89 books
= new GuiReaderGroup(reader
, null, null);
90 books
.setActionListener(new BookActionListener() {
92 public void select(GuiReaderBook book
) {
96 public void popupRequested(GuiReaderBook book
, Component target
,
101 public void action(GuiReaderBook book
) {
102 new GuiReaderSearchAction(reader
.getLibrary(), book
.getInfo())
106 JScrollPane scroll
= new JScrollPane(books
);
107 scroll
.getVerticalScrollBar().setUnitIncrement(16);
108 add(scroll
, BorderLayout
.CENTER
);
111 public void setSupportType(SupportType supportType
) {
112 this.supportType
= supportType
;
113 comboSupportTypes
.setSelectedItem(supportType
);
117 private JPanel
createByNameSearchPanel() {
118 JPanel byName
= new JPanel(new BorderLayout());
120 final JTextField keywordsField
= new JTextField();
121 byName
.add(keywordsField
, BorderLayout
.CENTER
);
124 JButton submit
= new JButton("Search");
125 byName
.add(submit
, BorderLayout
.EAST
);
127 // TODO: ENTER -> search
129 submit
.addActionListener(new ActionListener() {
131 public void actionPerformed(ActionEvent e
) {
132 search(supportType
, keywordsField
.getText(), page
, 0);
139 private JPanel
createByTagSearchPanel() {
140 JPanel byTag
= new JPanel();
141 JPanel searchBars
= new JPanel();
142 add(searchBars
, BorderLayout
.NORTH
);
147 // item 0 = no selction, else = default selection
148 public void search(final SupportType searchOn
, final String keywords
,
149 final int page
, final int item
) {
150 setSupportType(searchOn
);
151 this.keywords
= keywords
;
154 new Thread(new Runnable() {
157 BasicSearchable search
= BasicSearchable
158 .getSearchable(searchOn
);
163 maxPage
= search
.searchPages(keywords
);
164 } catch (IOException e
) {
165 Instance
.getTraceHandler().error(e
);
167 updateBooks(new ArrayList
<GuiReaderBookInfo
>());
168 updatePages(0, maxPage
);
170 List
<GuiReaderBookInfo
> infos
= new ArrayList
<GuiReaderBookInfo
>();
172 for (MetaData meta
: search
.search(keywords
, page
)) {
173 infos
.add(GuiReaderBookInfo
.fromMeta(meta
));
175 } catch (IOException e
) {
176 Instance
.getTraceHandler().error(e
);
180 updatePages(page
, maxPage
);
183 if (item
> 0 && item
<= books
.getBooksCount()) {
184 // TODO: "click" on item ITEM
191 private void updatePages(final int page
, final Integer maxPage
) {
192 inUi(new Runnable() {
195 GuiReaderSearch
.this.page
= page
;
196 GuiReaderSearch
.this.maxPage
= maxPage
;
198 System
.out
.println("page: " + page
);
199 System
.out
.println("max page: " + maxPage
);
204 private void updateBooks(final List
<GuiReaderBookInfo
> infos
) {
205 inUi(new Runnable() {
208 books
.refreshBooks(infos
, seeWordcount
);
213 private void searchTag(SupportType searchOn
, int page
, int item
,
214 boolean sync
, Integer
... tags
) throws IOException
{
216 BasicSearchable search
= BasicSearchable
.getSearchable(searchOn
);
217 SearchableTag stag
= search
.getTag(tags
);
221 System
.out
.println("Known tags: ");
223 for (SearchableTag s
: search
.getTags()) {
224 System
.out
.println(String
.format("%d: %s", i
, s
.getName()));
230 search
.search(stag
, 1);
231 System
.out
.println(stag
.getPages());
233 System
.out
.println(stag
.getCount());
236 List
<MetaData
> metas
= null;
237 List
<SearchableTag
> subtags
= null;
241 metas
= search
.search(stag
, page
);
242 count
= metas
.size();
244 subtags
= stag
.getChildren();
245 count
= subtags
.size();
251 MetaData meta
= metas
.get(item
- 1);
252 // displayStory(meta);
254 SearchableTag subtag
= subtags
.get(item
- 1);
255 // displayTag(subtag);
258 System
.out
.println("Invalid item: only " + count
264 System
.out
.println(String
.format("Content of %s: ",
266 // displayStories(metas);
269 System
.out
.println(String
.format("Subtags of %s: ",
271 // displayTags(subtags);
279 * Process the given action in the main Swing UI thread.
281 * The code will make sure the current thread is the main UI thread and, if
282 * not, will switch to it before executing the runnable.
284 * Synchronous operation.
289 public void inUi(final Runnable run
) {
290 if (EventQueue
.isDispatchThread()) {
294 EventQueue
.invokeAndWait(run
);
295 } catch (InterruptedException e
) {
296 Instance
.getTraceHandler().error(e
);
297 } catch (InvocationTargetException e
) {
298 Instance
.getTraceHandler().error(e
);