X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Ffanfix%2Freader%2Fui%2FGuiReaderMainPanel.java;h=5192278992ee03e5cfae845dc4891ff5621fd3ad;hb=484a31aadf54746222f9f35fb607a2ebee4e5e58;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..5192278 100644 --- a/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java +++ b/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java @@ -2,14 +2,16 @@ 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.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 +31,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 +80,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 +123,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 +161,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(); } @@ -179,50 +182,46 @@ class GuiReaderMainPanel extends JPanel { pane.setVisible(false); final Progress pg = new Progress(); final String typeF = type; - outOfUi(pg, new Runnable() { + outOfUi(pg, true, new Runnable() { @Override public void run() { - BasicLibrary lib = helper.getReader().getLibrary(); - Status status = lib.getStatus(); + final BasicLibrary lib = helper.getReader().getLibrary(); + final Status status = lib.getStatus(); if (status == Status.READY) { lib.refresh(pg); - invalidate(); - helper.createMenu(true); - if (typeF == null) { - addBookPane(true, false); - } else { - addBookPane(typeF, true); - } - refreshBooks(); - validate(); - pane.setVisible(true); - } else { - invalidate(); - helper.createMenu(false); - validate(); - - String err = lib.getLibraryName() + "\n"; - switch (status) { - case INVALID: - err += "Library not valid"; - break; - - case UNAUTORIZED: - err += "You are not allowed to access this library"; - break; - - case UNAVAILABLE: - err += "Library currently unavailable"; - break; - - default: - err += "An error occured when contacting the library"; - break; - } - - error(err, "Library error", null); } + + inUi(new Runnable() { + @Override + public void run() { + if (status == Status.READY) { + helper.createMenu(true); + if (typeF == null) { + addBookPane(true, false); + } else { + addBookPane(typeF, true); + } + pane.setVisible(true); + } else { + helper.createMenu(false); + validate(); + + String desc = Instance.getTransGui().getStringX( + StringIdGui.ERROR_LIB_STATUS, + status.toString()); + if (desc == null) { + desc = GuiReader + .trans(StringIdGui.ERROR_LIB_STATUS); + } + + String err = lib.getLibraryName() + "\n" + desc; + error(err, GuiReader + .trans(StringIdGui.TITLE_ERROR_LIBRARY), + null); + } + } + }); } }); } @@ -253,7 +252,8 @@ class GuiReaderMainPanel extends JPanel { BasicLibrary lib = helper.getReader().getLibrary(); if (type) { if (!listMode) { - addListPane("Sources", lib.getSources(), type); + addListPane(GuiReader.trans(StringIdGui.MENU_SOURCES), + lib.getSources(), type); } else { for (String tt : lib.getSources()) { if (tt != null) { @@ -263,7 +263,8 @@ class GuiReaderMainPanel extends JPanel { } } else { if (!listMode) { - addListPane("Authors", lib.getAuthors(), type); + addListPane(GuiReader.trans(StringIdGui.MENU_AUTHORS), + lib.getAuthors(), type); } else { for (String tt : lib.getAuthors()) { if (tt != null) { @@ -277,7 +278,8 @@ class GuiReaderMainPanel extends JPanel { /** * Add a new {@link GuiReaderGroup} on the frame to display the books of the * selected type or author. - * + *

+ * Will invalidate the layout. * * @param value * the author or the type, or NULL to get all the @@ -293,11 +295,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 +305,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 @@ -321,18 +321,19 @@ class GuiReaderMainPanel extends JPanel { /** * 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 +357,7 @@ class GuiReaderMainPanel extends JPanel { bookPane.refreshBooks(words); } - pane.repaint(); - this.repaint(); + this.validate(); } /** @@ -368,7 +368,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 +382,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 +398,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 +430,9 @@ class GuiReaderMainPanel extends JPanel { public void run() { try { run.run(); - refreshBooks(); + if (refreshBooks) { + refreshBooks(); + } } finally { reload.done(); if (!pg.isDone()) { @@ -432,6 +444,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 +496,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 +519,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 +530,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 +549,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 +636,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