GUI search: regorg done
[fanfix.git] / src / be / nikiroo / fanfix / reader / ui / GuiReaderSearchByNamePanel.java
CommitLineData
741e8467
NR
1package be.nikiroo.fanfix.reader.ui;
2
3import java.awt.BorderLayout;
741e8467
NR
4import java.awt.event.ActionEvent;
5import java.awt.event.ActionListener;
7cc1e743
NR
6import java.awt.event.KeyAdapter;
7import java.awt.event.KeyEvent;
741e8467
NR
8import java.io.IOException;
9import java.util.ArrayList;
10import java.util.List;
11
741e8467 12import javax.swing.JButton;
741e8467 13import javax.swing.JPanel;
741e8467 14import javax.swing.JTextField;
741e8467
NR
15
16import be.nikiroo.fanfix.data.MetaData;
17import be.nikiroo.fanfix.searchable.BasicSearchable;
741e8467
NR
18
19/**
20 * This panel represents a search panel that works for keywords and tags based
21 * searches.
22 *
23 * @author niki
24 */
741e8467
NR
25public class GuiReaderSearchByNamePanel extends JPanel {
26 private static final long serialVersionUID = 1L;
27
741e8467 28 private BasicSearchable searchable;
7cc1e743 29
741e8467
NR
30 private JTextField keywordsField;
31 private JButton submitKeywords;
32
9c598207
NR
33 private int page;
34 private int maxPage;
741e8467
NR
35 private List<MetaData> stories = new ArrayList<MetaData>();
36 private int storyItem;
37
9c598207
NR
38 public GuiReaderSearchByNamePanel(final Runnable fireEvent) {
39 super(new BorderLayout());
741e8467
NR
40
41 keywordsField = new JTextField();
9c598207 42 add(keywordsField, BorderLayout.CENTER);
741e8467
NR
43
44 submitKeywords = new JButton("Search");
9c598207 45 add(submitKeywords, BorderLayout.EAST);
741e8467 46
7cc1e743
NR
47 keywordsField.addKeyListener(new KeyAdapter() {
48 @Override
49 public void keyReleased(KeyEvent e) {
50 if (e.getKeyCode() == KeyEvent.VK_ENTER) {
9c598207 51 search(keywordsField.getText(), 1, 0);
7cc1e743
NR
52 } else {
53 super.keyReleased(e);
54 }
55 }
56 });
57
741e8467
NR
58 submitKeywords.addActionListener(new ActionListener() {
59 @Override
60 public void actionPerformed(ActionEvent e) {
9c598207
NR
61 new Thread(new Runnable() {
62 @Override
63 public void run() {
64 search(keywordsField.getText(), 1, 0);
65 fireEvent.run();
66 }
67 }).start();
741e8467
NR
68 }
69 });
70
9c598207 71 setSearchable(null);
741e8467
NR
72 }
73
9c598207
NR
74 /**
75 * The {@link BasicSearchable} object use for the searches themselves.
76 * <p>
77 * Can be NULL, but no searches will work.
78 *
79 * @param searchable
80 * the new searchable
81 */
82 public void setSearchable(BasicSearchable searchable) {
741e8467 83 this.searchable = searchable;
9c598207
NR
84 page = 1;
85 maxPage = -1;
86 storyItem = 0;
87 stories = new ArrayList<MetaData>();
88 updateKeywords("");
741e8467
NR
89 }
90
91 public int getPage() {
92 return page;
93 }
94
7cc1e743
NR
95 public int getMaxPage() {
96 return maxPage;
97 }
98
9c598207
NR
99 public String getCurrentKeywords() {
100 return keywordsField.getText();
741e8467
NR
101 }
102
103 public List<MetaData> getStories() {
104 return stories;
105 }
106
107 // selected item or 0 if none ! one-based !
108 public int getStoryItem() {
109 return storyItem;
110 }
111
741e8467
NR
112 // cannot be NULL
113 private void updateKeywords(final String keywords) {
7cc1e743 114 if (!keywords.equals(keywordsField.getText())) {
741e8467
NR
115 GuiReaderSearchFrame.inUi(new Runnable() {
116 @Override
117 public void run() {
741e8467
NR
118 keywordsField.setText(keywords);
119 }
120 });
121 }
122 }
123
741e8467 124 // item 0 = no selection, else = default selection
7cc1e743 125 // throw if page > max
9c598207 126 public void search(String keywords, int page, int item) {
741e8467
NR
127 List<MetaData> stories = new ArrayList<MetaData>();
128 int storyItem = 0;
129
741e8467
NR
130 updateKeywords(keywords);
131
132 int maxPage = -1;
133 try {
134 maxPage = searchable.searchPages(keywords);
135 } catch (IOException e) {
136 GuiReaderSearchFrame.error(e);
137 }
138
139 if (page > 0) {
7cc1e743
NR
140 if (maxPage >= 0 && (page <= 0 || page > maxPage)) {
141 throw new IndexOutOfBoundsException("Page " + page + " out of "
142 + maxPage);
143 }
144
741e8467
NR
145 try {
146 stories = searchable.search(keywords, page);
147 } catch (IOException e) {
148 GuiReaderSearchFrame.error(e);
149 stories = new ArrayList<MetaData>();
150 }
151
152 if (item > 0 && item <= stories.size()) {
153 storyItem = item;
154 } else if (item > 0) {
155 GuiReaderSearchFrame.error(String.format(
156 "Story item does not exist: Search [%s], item %d",
157 keywords, item));
158 }
159 }
160
7cc1e743 161 this.page = page;
7cc1e743 162 this.maxPage = maxPage;
741e8467
NR
163 this.stories = stories;
164 this.storyItem = storyItem;
741e8467
NR
165 }
166
167 /**
168 * Enables or disables this component, depending on the value of the
169 * parameter <code>b</code>. An enabled component can respond to user input
170 * and generate events. Components are enabled initially by default.
171 * <p>
172 * Disabling this component will also affect its children.
173 *
174 * @param b
175 * If <code>true</code>, this component is enabled; otherwise
176 * this component is disabled
177 */
178 @Override
9c598207
NR
179 public void setEnabled(boolean b) {
180 super.setEnabled(b);
181 keywordsField.setEnabled(b);
182 submitKeywords.setEnabled(b);
741e8467
NR
183 }
184}