import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
private int actionEventId = ActionEvent.ACTION_FIRST;
- private SupportType supportType;
private BasicSearchable searchable;
- private int page;
private boolean searchByTags;
+ private int page;
+ private int maxPage;
- private String keywords;
private JTabbedPane searchTabs;
+
private JTextField keywordsField;
private JButton submitKeywords;
+ private SearchableTag currentTag;
private JPanel tagBars;
private List<JComboBox> combos;
- private JComboBox comboSupportTypes;
private List<ActionListener> actions = new ArrayList<ActionListener>();
private List<MetaData> stories = new ArrayList<MetaData>();
private int storyItem;
- // will throw illegalArgEx if bad support type
- public GuiReaderSearchByNamePanel(SupportType supportType) {
+ // will throw illegalArgEx if bad support type, NULL allowed
+ public GuiReaderSearchByNamePanel(final SupportType supportType,
+ final Runnable inUi) {
setLayout(new BorderLayout());
- setSupportType(supportType);
page = 1;
+ maxPage = -1;
+ currentTag = null;
searchByTags = false;
searchTabs = new JTabbedPane();
searchTabs.addTab("By tags", createByTagSearchPanel());
add(searchTabs, BorderLayout.CENTER);
+ updateSearchBy(searchByTags);
+
+ // TODO: check if null really is OK for supportType (must be)
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ setSupportType(supportType, inUi);
+ }
+ }).start();
}
private JPanel createByNameSearchPanel() {
// TODO: ENTER -> search
+ keywordsField.addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyReleased(KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_ENTER) {
+ search(keywordsField.getText(), 1, 0, null);
+ } else {
+ super.keyReleased(e);
+ }
+ }
+ });
+
submitKeywords.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- search(keywordsField.getText(), 0);
+ search(keywordsField.getText(), 1, 0, null);
}
});
return byTag;
}
- public SupportType getSupportType() {
- return supportType;
- }
-
- public void setSupportType(SupportType supportType) {
+ // slow
+ public void setSupportType(SupportType supportType, Runnable inUi) {
BasicSearchable searchable = BasicSearchable.getSearchable(supportType);
- if (searchable == null) {
+ if (searchable == null && supportType != null) {
throw new java.lang.IllegalArgumentException(
"Unupported support type: " + supportType);
}
- this.supportType = supportType;
this.searchable = searchable;
+
+ searchTag(null, 1, 0, inUi);
}
public int getPage() {
return page;
}
- public void setPage(int page) {
- // TODO: set against maxPage
- // TODO: update last search?
- this.page = page;
+ public int getMaxPage() {
+ return maxPage;
+ }
+
+ // throw outOfBounds if needed
+ public void setPage(int page, Runnable inUi) {
+ if (searchByTags) {
+ searchTag(currentTag, page, 0, inUi);
+ } else {
+ search(keywordsField.getText(), page, 0, inUi);
+ }
}
// actions will be fired in UIthread
return storyItem;
}
- private void fireAction() {
+ private void fireAction(final Runnable inUi) {
GuiReaderSearchFrame.inUi(new Runnable() {
@Override
public void run() {
GuiReaderSearchFrame.error(e);
}
}
+
+ if (inUi != null) {
+ inUi.run();
+ }
}
});
}
private void updateSearchBy(final boolean byTag) {
- if (byTag != this.searchByTags) {
- GuiReaderSearchFrame.inUi(new Runnable() {
- @Override
- public void run() {
- if (!byTag) {
- searchTabs.setSelectedIndex(0);
- } else {
- searchTabs.setSelectedIndex(1);
- }
+ GuiReaderSearchFrame.inUi(new Runnable() {
+ @Override
+ public void run() {
+ if (!byTag) {
+ searchTabs.setSelectedIndex(0);
+ } else {
+ searchTabs.setSelectedIndex(1);
}
- });
- }
+ }
+ });
}
// cannot be NULL
private void updateKeywords(final String keywords) {
- if (!keywords.equals(this.keywords)) {
+ if (!keywords.equals(keywordsField.getText())) {
GuiReaderSearchFrame.inUi(new Runnable() {
@Override
public void run() {
- GuiReaderSearchByNamePanel.this.keywords = keywords;
keywordsField.setText(keywords);
}
});
}
});
- combo.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- final SearchableTag tag = (SearchableTag) combo
- .getSelectedItem();
- if (tag != null) {
- while (comboIndex + 1 < combos.size()) {
- JComboBox combo = combos.remove(comboIndex + 1);
- tagBars.remove(combo);
- }
-
- addTagBar(tag, new Runnable() {
- @Override
- public void run() {
- // TODO: slow ui
- SearchableTag tag = ((SearchableTag) combo
- .getSelectedItem());
- if (tag != null && tag.isLeaf()) {
- BasicSearchable searchable = BasicSearchable
- .getSearchable(supportType);
- List<MetaData> metas = new ArrayList<MetaData>();
- try {
- metas = searchable.search(tag, 1);
- search(metas, 1,
- searchable.searchPages(tag), 0);
- } catch (IOException e) {
- error(e);
- }
- }
-
- setWaitingScreen(false);
- }
- });
- }
- }
- });
+ combo.addActionListener(createComboTagAction(comboIndex));
combos.add(combo);
tagBars.add(combo);
}
- // async, add children of tag, NULL = base tags
- private void addTagBar(final SearchableTag tag, final Runnable inUi) {
- new Thread(new Runnable() {
+ private ActionListener createComboTagAction(final int comboIndex) {
+ return new ActionListener() {
@Override
- public void run() {
- List<SearchableTag> children = new ArrayList<SearchableTag>();
- if (tag == null) {
- try {
- List<SearchableTag> baseTags = searchable.getTags();
- children = baseTags;
- } catch (IOException e) {
- error(e);
- }
- } else {
- try {
- searchable.fillTag(tag);
- } catch (IOException e) {
- error(e);
- }
+ public void actionPerformed(ActionEvent ae) {
+ List<JComboBox> combos = GuiReaderSearchByNamePanel.this.combos;
+ if (combos == null || comboIndex < 0
+ || comboIndex >= combos.size()) {
+ return;
+ }
- if (!tag.isLeaf()) {
- children = tag.getChildren();
- } else {
- children = null;
- }
+ // Tag can be NULL
+ final SearchableTag tag = (SearchableTag) combos
+ .get(comboIndex).getSelectedItem();
+
+ while (comboIndex + 1 < combos.size()) {
+ JComboBox combo = combos.remove(comboIndex + 1);
+ tagBars.remove(combo);
}
- final List<SearchableTag> fchildren = children;
- inUi(new Runnable() {
+ new Thread(new Runnable() {
@Override
public void run() {
- if (fchildren != null) {
- addTagBar(fchildren, tag);
+ final List<SearchableTag> children = getChildrenForTag(tag);
+ if (children != null) {
+ GuiReaderSearchFrame.inUi(new Runnable() {
+ @Override
+ public void run() {
+ addTagBar(children, tag);
+ }
+ });
}
- if (inUi != null) {
- inUi.run();
+ if (tag != null && tag.isLeaf()) {
+ try {
+ GuiReaderSearchByNamePanel.this.page = 1;
+ stories = searchable.search(tag, 1);
+ } catch (IOException e) {
+ GuiReaderSearchFrame.error(e);
+ GuiReaderSearchByNamePanel.this.page = 0;
+ stories = new ArrayList<MetaData>();
+ }
+
+ fireAction(null);
}
}
- });
+ }).start();
}
- }).start();
+ };
+ }
+
+ // sync, add children of tag, NULL = base tags
+ // return children of the tag or base tags or NULL
+ private List<SearchableTag> getChildrenForTag(final SearchableTag tag) {
+ List<SearchableTag> children = new ArrayList<SearchableTag>();
+ if (tag == null) {
+ try {
+ List<SearchableTag> baseTags = searchable.getTags();
+ children = baseTags;
+ } catch (IOException e) {
+ GuiReaderSearchFrame.error(e);
+ }
+ } else {
+ try {
+ searchable.fillTag(tag);
+ } catch (IOException e) {
+ GuiReaderSearchFrame.error(e);
+ }
+
+ if (!tag.isLeaf()) {
+ children = tag.getChildren();
+ } else {
+ children = null;
+ }
+ }
+
+ return children;
}
// item 0 = no selection, else = default selection
- // return: maxpage
- public int search(String keywords, int item) {
+ // throw if page > max
+ public void search(String keywords, int page, int item, Runnable inUi) {
List<MetaData> stories = new ArrayList<MetaData>();
int storyItem = 0;
}
if (page > 0) {
+ if (maxPage >= 0 && (page <= 0 || page > maxPage)) {
+ throw new IndexOutOfBoundsException("Page " + page + " out of "
+ + maxPage);
+ }
+
try {
stories = searchable.search(keywords, page);
} catch (IOException e) {
}
}
+ this.page = page;
this.stories = stories;
this.storyItem = storyItem;
- fireAction();
+ this.maxPage = maxPage;
- return maxPage;
+ fireAction(inUi);
}
+ // slow
// tag: null = base tags
- // return: max pages
- public int searchTag(SearchableTag tag, int item) {
+ // throw if page > max, but only if stories
+ public void searchTag(SearchableTag tag, int page, int item, Runnable inUi) {
List<MetaData> stories = new ArrayList<MetaData>();
int storyItem = 0;
+ currentTag = tag;
updateSearchBy(true);
updateTags(tag);
}
maxPage = searchable.searchPages(tag);
- if (page > 0) {
- if (tag.isLeaf()) {
- try {
- stories = searchable.search(tag, page);
- if (item > 0 && item <= stories.size()) {
- storyItem = item;
- } else if (item > 0) {
- GuiReaderSearchFrame
- .error(String
- .format("Story item does not exist: Tag [%s], item %d",
- tag.getFqName(), item));
- }
- } catch (IOException e) {
- GuiReaderSearchFrame.error(e);
+ if (page > 0 && tag.isLeaf()) {
+ if (maxPage >= 0 && (page <= 0 || page > maxPage)) {
+ throw new IndexOutOfBoundsException("Page " + page
+ + " out of " + maxPage);
+ }
+
+ try {
+ stories = searchable.search(tag, page);
+ if (item > 0 && item <= stories.size()) {
+ storyItem = item;
+ } else if (item > 0) {
+ GuiReaderSearchFrame
+ .error(String
+ .format("Story item does not exist: Tag [%s], item %d",
+ tag.getFqName(), item));
}
+ } catch (IOException e) {
+ GuiReaderSearchFrame.error(e);
}
}
} catch (IOException e) {
this.stories = stories;
this.storyItem = storyItem;
- fireAction();
+ this.page = page;
+ this.maxPage = maxPage;
- return maxPage;
+ fireAction(inUi);
}
/**
* this component is disabled
*/
@Override
- public void setEnabled(final boolean waiting) {
+ public void setEnabled(final boolean enabled) {
GuiReaderSearchFrame.inUi(new Runnable() {
@Override
public void run() {
- GuiReaderSearchByNamePanel.super.setEnabled(!waiting);
- keywordsField.setEnabled(!waiting);
- submitKeywords.setEnabled(!waiting);
- // TODO
+ GuiReaderSearchByNamePanel.super.setEnabled(enabled);
+ searchTabs.setEnabled(enabled);
+ keywordsField.setEnabled(enabled);
+ submitKeywords.setEnabled(enabled);
+ tagBars.setEnabled(enabled);
+ for (JComboBox combo : combos) {
+ combo.setEnabled(enabled);
+ }
}
});
}