X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;ds=sidebyside;f=src%2Fbe%2Fnikiroo%2Ffanfix%2Freader%2Fui%2FGuiReaderMainPanel.java;h=cfd1e947013cbff6916b96f54a096e426e957422;hb=96f0625f2aa6f012083c87fa14df854ccdb576be;hp=ea564ab2370df877345dca234b0c0bd2c30816f7;hpb=8590da196b2eca1f6d69e157cf7b122f6d5c6ef7;p=nikiroo-utils.git diff --git a/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java b/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java index ea564ab..cfd1e94 100644 --- a/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java +++ b/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java @@ -2,14 +2,18 @@ package be.nikiroo.fanfix.reader.ui; import java.awt.BorderLayout; import java.awt.Color; +import java.awt.Component; +import java.awt.EventQueue; import java.awt.Frame; import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; import java.io.File; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.net.UnknownHostException; import java.util.ArrayList; @@ -29,6 +33,7 @@ import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import be.nikiroo.fanfix.Instance; +import be.nikiroo.fanfix.bundles.StringIdGui; import be.nikiroo.fanfix.bundles.UiConfig; import be.nikiroo.fanfix.data.MetaData; import be.nikiroo.fanfix.data.Story; @@ -77,13 +82,13 @@ class GuiReaderMainPanel extends JPanel { /** * Create the main menu bar. + *
+ * Will invalidate the layout.
*
* @param libOk
* the library can be queried
- *
- * @return the bar
*/
- public void createMenu(boolean b);
+ public void createMenu(boolean libOk);
/**
* Create a popup menu for a {@link GuiReaderBook} that represents a
@@ -120,9 +125,9 @@ class GuiReaderMainPanel extends JPanel {
/**
* Create a new {@link GuiReaderMainPanel}.
*
- * @param reader
- * the associated {@link GuiReader} to forward some commands and
- * access its {@link LocalLibrary}
+ * @param parent
+ * the associated {@link FrameHelper} to forward some commands
+ * and access its {@link LocalLibrary}
* @param type
* the type of {@link Story} to load, or NULL for all types
*/
@@ -158,17 +163,17 @@ class GuiReaderMainPanel extends JPanel {
pgBar.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- invalidate();
+ pgBar.invalidate();
pgBar.setProgress(null);
- validate();
setEnabled(true);
+ validate();
}
});
pgBar.addUpdateListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- invalidate();
+ pgBar.invalidate();
validate();
repaint();
}
@@ -176,53 +181,56 @@ class GuiReaderMainPanel extends JPanel {
books = new TreeMap
+ * Will invalidate the layout.
*
* @param value
* the author or the type, or NULL to get all the
@@ -293,11 +304,8 @@ class GuiReaderMainPanel extends JPanel {
books.put(value, bookPane);
- this.invalidate();
pane.invalidate();
pane.add(bookPane);
- pane.validate();
- this.validate();
bookPane.setActionListener(new BookActionListener() {
@Override
@@ -306,9 +314,10 @@ class GuiReaderMainPanel extends JPanel {
}
@Override
- public void popupRequested(GuiReaderBook book, MouseEvent e) {
+ public void popupRequested(GuiReaderBook book, Component target,
+ int x, int y) {
JPopupMenu popup = helper.createBookPopup();
- popup.show(e.getComponent(), e.getX(), e.getY());
+ popup.show(target, x, y);
}
@Override
@@ -316,23 +325,26 @@ class GuiReaderMainPanel extends JPanel {
openBook(book);
}
});
+
+ focus();
}
/**
* Clear the pane from any book that may be present, usually prior to adding
* new ones.
+ *
+ * Will invalidate the layout.
*/
public void removeBookPanes() {
books.clear();
pane.invalidate();
- this.invalidate();
pane.removeAll();
- pane.validate();
- this.validate();
}
/**
* Refresh the list of {@link GuiReaderBook}s from disk.
+ *
+ * Will validate the layout, as it is a "refresh" operation.
*/
public void refreshBooks() {
BasicLibrary lib = helper.getReader().getLibrary();
@@ -356,8 +368,7 @@ class GuiReaderMainPanel extends JPanel {
bookPane.refreshBooks(words);
}
- pane.repaint();
- this.repaint();
+ this.validate();
}
/**
@@ -368,7 +379,7 @@ class GuiReaderMainPanel extends JPanel {
*/
public void openBook(final GuiReaderBook book) {
final Progress pg = new Progress();
- outOfUi(pg, new Runnable() {
+ outOfUi(pg, false, new Runnable() {
@Override
public void run() {
try {
@@ -382,7 +393,8 @@ class GuiReaderMainPanel extends JPanel {
});
} catch (IOException e) {
Instance.getTraceHandler().error(e);
- error("Cannot open the selected book", "Error", e);
+ error(GuiReader.trans(StringIdGui.ERROR_CANNOT_OPEN),
+ GuiReader.trans(StringIdGui.TITLE_ERROR), e);
}
}
});
@@ -397,18 +409,27 @@ class GuiReaderMainPanel extends JPanel {
*
* @param progress
* the {@link ProgressBar} or NULL
+ * @param refreshBooks
+ * TRUE to refresh the books after
* @param run
* the action to run
*/
- public void outOfUi(Progress progress, final Runnable run) {
+ public void outOfUi(Progress progress, final boolean refreshBooks,
+ final Runnable run) {
final Progress pg = new Progress();
- final Progress reload = new Progress("Reload books");
+ final Progress reload = new Progress(
+ GuiReader.trans(StringIdGui.PROGRESS_OUT_OF_UI_RELOAD_BOOKS));
+
if (progress == null) {
progress = new Progress();
}
- pg.addProgress(progress, 90);
- pg.addProgress(reload, 10);
+ if (refreshBooks) {
+ pg.addProgress(progress, 100);
+ } else {
+ pg.addProgress(progress, 90);
+ pg.addProgress(reload, 10);
+ }
invalidate();
pgBar.setProgress(pg);
@@ -420,7 +441,9 @@ class GuiReaderMainPanel extends JPanel {
public void run() {
try {
run.run();
- refreshBooks();
+ if (refreshBooks) {
+ refreshBooks();
+ }
} finally {
reload.done();
if (!pg.isDone()) {
@@ -432,6 +455,31 @@ class GuiReaderMainPanel extends JPanel {
}, "outOfUi thread").start();
}
+ /**
+ * Process the given action in the main Swing UI thread.
+ *
+ * The code will make sure the current thread is the main UI thread and, if
+ * not, will switch to it before executing the runnable.
+ *
+ * Synchronous operation.
+ *
+ * @param run
+ * the action to run
+ */
+ public void inUi(final Runnable run) {
+ if (EventQueue.isDispatchThread()) {
+ run.run();
+ } else {
+ try {
+ EventQueue.invokeAndWait(run);
+ } catch (InterruptedException e) {
+ Instance.getTraceHandler().error(e);
+ } catch (InvocationTargetException e) {
+ Instance.getTraceHandler().error(e);
+ }
+ }
+ }
+
/**
* Import a {@link Story} into the main {@link LocalLibrary}.
*
@@ -459,7 +507,8 @@ class GuiReaderMainPanel extends JPanel {
}
url = JOptionPane.showInputDialog(GuiReaderMainPanel.this,
- "url of the story to import?", "Importing from URL",
+ GuiReader.trans(StringIdGui.SUBTITLE_IMPORT_URL),
+ GuiReader.trans(StringIdGui.TITLE_IMPORT_URL),
JOptionPane.QUESTION_MESSAGE, null, null, clipboard);
} else if (fc.showOpenDialog(this) != JFileChooser.CANCEL_OPTION) {
url = fc.getSelectedFile().getAbsolutePath();
@@ -481,6 +530,8 @@ class GuiReaderMainPanel extends JPanel {
* the {@link Story} to import by {@link URL}
* @param onSuccess
* Action to execute on success
+ * @param onSuccessPgName
+ * the name to use for the onSuccess progress bar
*/
public void imprt(final String url, final StoryRunnable onSuccess,
String onSuccessPgName) {
@@ -490,7 +541,7 @@ class GuiReaderMainPanel extends JPanel {
pg.addProgress(pgImprt, 95);
pg.addProgress(pgOnSuccess, 5);
- outOfUi(pg, new Runnable() {
+ outOfUi(pg, true, new Runnable() {
@Override
public void run() {
Exception ex = null;
@@ -509,11 +560,14 @@ class GuiReaderMainPanel extends JPanel {
pgOnSuccess.setProgress(0);
if (!ok) {
if (e instanceof UnknownHostException) {
- error("URL not supported: " + url, "Cannot import URL",
- null);
+ error(GuiReader.trans(
+ StringIdGui.ERROR_URL_NOT_SUPPORTED, url),
+ GuiReader.trans(StringIdGui.TITLE_ERROR), null);
} else {
- error("Failed to import " + url + ": \n"
- + e.getMessage(), "Cannot import URL", e);
+ error(GuiReader.trans(
+ StringIdGui.ERROR_URL_IMPORT_FAILED, url,
+ e.getMessage()), GuiReader
+ .trans(StringIdGui.TITLE_ERROR), e);
}
} else {
if (onSuccess != null) {
@@ -593,9 +647,10 @@ class GuiReaderMainPanel extends JPanel {
}
@Override
- public void popupRequested(GuiReaderBook book, MouseEvent e) {
+ public void popupRequested(GuiReaderBook book, Component target,
+ int x, int y) {
JPopupMenu popup = helper.createSourceAuthorPopup();
- popup.show(e.getComponent(), e.getX(), e.getY());
+ popup.show(target, x, y);
}
@Override
@@ -605,6 +660,27 @@ class GuiReaderMainPanel extends JPanel {
refreshBooks();
}
});
+
+ focus();
+ }
+
+ /**
+ * Focus the first {@link GuiReaderGroup} we find.
+ */
+ private void focus() {
+ GuiReaderGroup group = null;
+ Map