X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Ffanfix%2Freader%2Fui%2FGuiReaderMainPanel.java;h=a5eb6916f5972b281d7b7237a3464e2f50ee7c55;hb=58701825851d5533ec28b0ecd6c0c5ed645655c5;hp=ea564ab2370df877345dca234b0c0bd2c30816f7;hpb=8590da196b2eca1f6d69e157cf7b122f6d5c6ef7;p=fanfix.git diff --git a/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java b/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java index ea564ab..a5eb691 100644 --- a/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java +++ b/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java @@ -2,17 +2,22 @@ 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; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -29,6 +34,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; @@ -37,6 +43,7 @@ import be.nikiroo.fanfix.library.BasicLibrary.Status; import be.nikiroo.fanfix.library.LocalLibrary; import be.nikiroo.fanfix.reader.BasicReader; import be.nikiroo.fanfix.reader.ui.GuiReaderBook.BookActionListener; +import be.nikiroo.fanfix.reader.ui.GuiReaderBookInfo.Type; import be.nikiroo.utils.Progress; import be.nikiroo.utils.ui.ProgressBar; @@ -77,13 +84,13 @@ class GuiReaderMainPanel extends JPanel { /** * Create the main menu bar. + *
+ * Will invalidate the layout.
*
- * @param libOk
- * the library can be queried
- *
- * @return the bar
+ * @param status
+ * the library status, must not be NULL
*/
- public void createMenu(boolean b);
+ public void createMenu(Status status);
/**
* Create a popup menu for a {@link GuiReaderBook} that represents a
@@ -103,26 +110,26 @@ class GuiReaderMainPanel extends JPanel {
}
/**
- * A {@link Runnable} with a {@link Story} parameter.
+ * A {@link Runnable} with a {@link MetaData} parameter.
*
* @author niki
*/
- public interface StoryRunnable {
+ public interface MetaDataRunnable {
/**
* Run the action.
*
- * @param story
- * the story
+ * @param meta
+ * the meta of the story
*/
- public void run(Story story);
+ public void run(MetaData meta);
}
/**
* 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
*/
@@ -133,16 +140,16 @@ class GuiReaderMainPanel extends JPanel {
pane = new JPanel();
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
+ JScrollPane scroll = new JScrollPane(pane);
- Integer icolor = Instance.getUiConfig().getColor(
- UiConfig.BACKGROUND_COLOR);
+ Integer icolor = Instance.getInstance().getUiConfig().getColor(UiConfig.BACKGROUND_COLOR);
if (icolor != null) {
color = new Color(icolor);
setBackground(color);
pane.setBackground(color);
+ scroll.setBackground(color);
}
- JScrollPane scroll = new JScrollPane(pane);
scroll.getVerticalScrollBar().setUnitIncrement(16);
add(scroll, BorderLayout.CENTER);
@@ -158,17 +165,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 +183,60 @@ 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 +313,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 +323,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 +334,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();
@@ -340,11 +361,17 @@ class GuiReaderMainPanel extends JPanel {
List
+ * 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.getInstance().getTraceHandler().error(e);
+ } catch (InvocationTargetException e) {
+ Instance.getInstance().getTraceHandler().error(e);
+ }
+ }
+ }
+
/**
* Import a {@link Story} into the main {@link LocalLibrary}.
*
@@ -454,12 +581,14 @@ class GuiReaderMainPanel extends JPanel {
// No data will be handled
}
- if (clipboard == null || !clipboard.startsWith("http")) {
+ if (clipboard == null || !(clipboard.startsWith("http://") || //
+ clipboard.startsWith("https://"))) {
clipboard = "";
}
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,8 +610,10 @@ 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,
+ public void imprt(final String url, final MetaDataRunnable onSuccess,
String onSuccessPgName) {
final Progress pg = new Progress();
final Progress pgImprt = new Progress();
@@ -490,13 +621,13 @@ 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;
- Story story = null;
+ MetaData meta = null;
try {
- story = helper.getReader().getLibrary()
+ meta = helper.getReader().getLibrary()
.imprt(BasicReader.getUrl(url), pgImprt);
} catch (IOException e) {
ex = e;
@@ -509,15 +640,18 @@ 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) {
- onSuccess.run(story);
+ onSuccess.run(meta);
}
}
pgOnSuccess.done();
@@ -593,9 +727,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 +740,27 @@ class GuiReaderMainPanel extends JPanel {
refreshBooks();
}
});
+
+ focus();
+ }
+
+ /**
+ * Focus the first {@link GuiReaderGroup} we find.
+ */
+ private void focus() {
+ GuiReaderGroup group = null;
+ Map