import be.nikiroo.fanfix_swing.gui.utils.CoverImager;
import be.nikiroo.fanfix_swing.gui.utils.UiHelper;
import be.nikiroo.fanfix_swing.gui.viewer.ViewerImages;
-import be.nikiroo.fanfix_swing.gui.viewer.Viewer;
+import be.nikiroo.fanfix_swing.gui.viewer.ViewerNonImages;
import be.nikiroo.utils.Progress;
import be.nikiroo.utils.StringUtils;
ViewerImages viewer = new ViewerImages(story);
viewer.setVisible(true);
} else {
- Viewer viewer = new Viewer(Instance.getInstance().getLibrary(),
- story);
+ ViewerNonImages viewer = new ViewerNonImages(
+ Instance.getInstance().getLibrary(), story);
viewer.setVisible(true);
}
import be.nikiroo.fanfix_swing.gui.PropertiesPanel;
import be.nikiroo.fanfix_swing.gui.book.BookInfo;
import be.nikiroo.fanfix_swing.gui.utils.UiHelper;
-import be.nikiroo.fanfix_swing.gui.viewer.ViewerPanel;
+import be.nikiroo.fanfix_swing.gui.viewer.TODEL_ViewerPanel;
import be.nikiroo.utils.Progress;
import be.nikiroo.utils.ui.ProgressBar;
JPanel props = new PropertiesPanel(lib, info.getMeta(), false);
main.add(props, BorderLayout.NORTH);
- main.add(new ViewerPanel(info.getMeta(), info.getMeta()
+ main.add(new TODEL_ViewerPanel(info.getMeta(), info.getMeta()
.isImageDocument()), BorderLayout.CENTER);
main.add(createImportButton(lib), BorderLayout.SOUTH);
*
* @author niki
*/
-public class ViewerPanel extends JPanel {
+public class TODEL_ViewerPanel extends JPanel {
private static final long serialVersionUID = 1L;
private boolean imageDocument;
* @param story
* the {@link Story} to work on
*/
- public ViewerPanel(Story story) {
+ public TODEL_ViewerPanel(Story story) {
this(story.getMeta(), story.getMeta().isImageDocument());
}
* @param isImageDocument
* TRUE if it is an image document, FALSE if not
*/
- public ViewerPanel(MetaData meta, boolean isImageDocument) {
+ public TODEL_ViewerPanel(MetaData meta, boolean isImageDocument) {
super(new BorderLayout());
this.imageDocument = isImageDocument;
new Thread(new Runnable() {
@Override
public void run() {
- final String content = htmlOutput.convert(chap);
+ final String content = htmlOutput.convert(chap, true);
// Wait until size computations are correct
while (!scroll.isValid()) {
try {
+++ /dev/null
-package be.nikiroo.fanfix_swing.gui.viewer;
-
-import java.awt.BorderLayout;
-import java.awt.Font;
-import java.awt.LayoutManager;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import javax.swing.BorderFactory;
-import javax.swing.BoxLayout;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.SwingConstants;
-
-import be.nikiroo.fanfix.Instance;
-import be.nikiroo.fanfix.bundles.StringIdGui;
-import be.nikiroo.fanfix.data.Chapter;
-import be.nikiroo.fanfix.data.MetaData;
-import be.nikiroo.fanfix.data.Story;
-import be.nikiroo.fanfix.library.BasicLibrary;
-import be.nikiroo.fanfix_swing.gui.PropertiesPanel;
-import be.nikiroo.fanfix_swing.gui.utils.UiHelper;
-
-/**
- * An internal, Swing-based {@link Story} viewer.
- * <p>
- * Works on both text and image document (see {@link MetaData#isImageDocument()}
- * ).
- *
- * @author niki
- */
-public class Viewer extends JFrame {
- private static final long serialVersionUID = 1L;
-
- private Story story;
- private MetaData meta;
- private JLabel title;
- private PropertiesPanel descPane;
- private ViewerPanel mainPanel;
- private NavBar navbar;
-
- /**
- * Create a new {@link Story} viewer.
- *
- * @param lib
- * the {@link BasicLibrary} to load the cover from
- * @param story
- * the {@link Story} to display
- */
- public Viewer(BasicLibrary lib, Story story) {
- setTitle(Instance
- .getInstance()
- .getTransGui()
- .getString(StringIdGui.TITLE_STORY, story.getMeta().getLuid(),
- story.getMeta().getTitle()));
-
- setSize(800, 600);
-
- this.story = story;
- this.meta = story.getMeta();
-
- initGuiBase(lib);
- initGuiNavButtons();
-
- setChapter(-1);
-
- UiHelper.setFrameIcon(this);
- }
-
- /**
- * Initialise the base panel with everything but the navigation buttons.
- *
- * @param lib
- * the {@link BasicLibrary} to use to retrieve the cover image in
- * the description panel
- */
- private void initGuiBase(BasicLibrary lib) {
- setLayout(new BorderLayout());
-
- title = new JLabel();
- title.setFont(new Font(Font.SERIF, Font.BOLD,
- title.getFont().getSize() * 3));
- title.setText(meta.getTitle());
- title.setHorizontalAlignment(SwingConstants.CENTER);
- title.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
- add(title, BorderLayout.NORTH);
-
- JPanel contentPane = new JPanel(new BorderLayout());
- add(contentPane, BorderLayout.CENTER);
-
- descPane = new PropertiesPanel(lib, meta, false);
- contentPane.add(descPane, BorderLayout.NORTH);
-
- mainPanel = new ViewerPanel(story);
- contentPane.add(mainPanel, BorderLayout.CENTER);
- }
-
- /**
- * Create the 4 navigation buttons in {@link Viewer#navButtons} and
- * initialise them.
- */
- private void initGuiNavButtons() {
- navbar = new NavBar(-1, story.getChapters().size() - 1) {
- private static final long serialVersionUID = 1L;
-
- @Override
- public String getExtraLabel() {
- int chapter = getIndex();
- Chapter chap;
- if (chapter < 0) {
- chap = meta.getResume();
- descPane.setVisible(true);
- } else {
- chap = story.getChapters().get(chapter);
- descPane.setVisible(false);
- }
-
- String chapterDisplay = Instance
- .getInstance()
- .getTransGui()
- .getString(StringIdGui.CHAPTER_HTML_UNNAMED,
- chap.getNumber(), story.getChapters().size());
- if (chap.getName() != null && !chap.getName().trim().isEmpty()) {
- chapterDisplay = Instance
- .getInstance()
- .getTransGui()
- .getString(StringIdGui.CHAPTER_HTML_NAMED,
- chap.getNumber(),
- story.getChapters().size(), chap.getName());
- }
-
- return "<HTML>" + chapterDisplay + "</HTML>";
- }
- };
-
- navbar.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- setChapter(navbar.getIndex());
- }
- });
-
- JPanel navButtonsPane = new JPanel();
- LayoutManager layout = new BoxLayout(navButtonsPane, BoxLayout.X_AXIS);
- navButtonsPane.setLayout(layout);
-
- add(navbar, BorderLayout.SOUTH);
- }
-
- /**
- * Set the current chapter, 0-based.
- * <p>
- * Chapter -1 is reserved for the description page.
- *
- * @param chapter
- * the chapter number to set
- */
- private void setChapter(int chapter) {
- Chapter chap;
- if (chapter < 0) {
- chap = meta.getResume();
- descPane.setVisible(true);
- } else {
- chap = story.getChapters().get(chapter);
- descPane.setVisible(false);
- }
-
- mainPanel.setChapter(chap);
- }
-}
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
-import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.SwingWorker;
private NavBar navbar;
private JLabel area;
private JScrollPane scroll;
- private JTextField page;
private DefaultComboBoxModel<ZoomLevel> zoomBoxModel;
private DelayWorker worker;
--- /dev/null
+package be.nikiroo.fanfix_swing.gui.viewer;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.concurrent.ExecutionException;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JEditorPane;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import javax.swing.JToolBar;
+import javax.swing.SwingWorker;
+
+import be.nikiroo.fanfix.Instance;
+import be.nikiroo.fanfix.bundles.StringIdGui;
+import be.nikiroo.fanfix.data.MetaData;
+import be.nikiroo.fanfix.data.Story;
+import be.nikiroo.fanfix.library.BasicLibrary;
+import be.nikiroo.fanfix_swing.gui.PropertiesPanel;
+import be.nikiroo.fanfix_swing.gui.utils.UiHelper;
+import be.nikiroo.utils.ui.DelayWorker;
+import be.nikiroo.utils.ui.UIUtils;
+
+/**
+ * An internal, Swing-based {@link Story} viewer.
+ * <p>
+ * Works on both text and image document (see {@link MetaData#isImageDocument()}
+ * ).
+ *
+ * @author niki
+ */
+public class ViewerNonImages extends JFrame {
+ private static final long serialVersionUID = 1L;
+
+ private Story story;
+ private ViewerTextOutput html;
+
+ private NavBar navbar;
+ private JLabel title;
+ private JScrollPane scroll;
+ private JPanel mainPane;
+ private JEditorPane area;
+ private JPanel descPane;
+
+ private DelayWorker worker;
+
+ /**
+ * Create a new {@link Story} viewer.
+ *
+ * @param lib
+ * the {@link BasicLibrary} to use to retrieve the cover image in
+ * the description panel
+ * @param story
+ * the {@link Story} to display
+ *
+ */
+ public ViewerNonImages(BasicLibrary lib, Story story) {
+ this.story = story;
+ this.setTitle(Instance.getInstance().getTransGui().getString(
+ StringIdGui.TITLE_STORY, story.getMeta().getLuid(),
+ story.getMeta().getTitle()));
+
+ this.setSize(800, 600);
+
+ html = new ViewerTextOutput();
+ worker = new DelayWorker(100);
+ worker.start();
+
+ initGui(lib);
+ setChapter(0);
+
+ UiHelper.setFrameIcon(this);
+ }
+
+ /**
+ * Initialise the base panel.
+ *
+ * @param lib
+ * the {@link BasicLibrary} to use to retrieve the cover image in
+ * the description panel
+ */
+ private void initGui(BasicLibrary lib) {
+ this.setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
+
+ title = new JLabel();
+ title.setFont(
+ new Font(Font.SERIF, Font.BOLD, title.getFont().getSize() * 2));
+ title.setText(story.getMeta().getTitle());
+ title.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ title.setToolTipText(story.getMeta().getTitle());
+
+ JToolBar toolbarTitle = createToolBar();
+ toolbarTitle.add(title);
+
+ area = new JEditorPane("text/html", "");
+ area.setEditable(false);
+ area.setAlignmentY(TOP_ALIGNMENT);
+ area.setOpaque(true);
+ area.setFocusable(true);
+ area.setBackground(new JTextField().getBackground());
+ area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+
+ scroll = UIUtils.scroll(area, false);
+
+ JLabel descLabel = new JLabel("Description");
+ descLabel.setFont(new Font(Font.SERIF, Font.BOLD,
+ (int) Math.round(descLabel.getFont().getSize() * 1.5)));
+ descLabel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ descLabel.setHorizontalAlignment(JLabel.CENTER);
+ descLabel.setOpaque(true);
+ Color bg = descLabel.getBackground();
+ descLabel.setBackground(descLabel.getForeground());
+ descLabel.setForeground(bg);
+
+ descPane = new JPanel(new BorderLayout());
+ PropertiesPanel desc = new PropertiesPanel(lib, story.getMeta(), false);
+ desc.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+ descPane.add(desc, BorderLayout.CENTER);
+ descPane.add(descLabel, BorderLayout.SOUTH);
+
+ area.setSize(scroll.getViewport().getSize());
+ area.requestFocus();
+
+ this.add(toolbarTitle);
+ this.add(descPane);
+ this.add(scroll);
+
+ listen();
+ }
+
+ private void listen() {
+ navbar.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ setChapter(navbar.getIndex());
+ }
+ });
+ }
+
+ private JToolBar createToolBar() {
+ JToolBar toolbar = new JToolBar();
+ navbar = new NavBar(0, story.getChapters().size());
+ toolbar.add(navbar);
+ return toolbar;
+ }
+
+ /**
+ * Set the current chapter, 0-based.
+ * <p>
+ * Chapter 0 will also toggle the description page on top.
+ *
+ * @param chapter
+ * the chapter number to set
+ */
+ private void setChapter(final int chapter) {
+ worker.delay("update chapter", new SwingWorker<String, Void>() {
+ @Override
+ protected String doInBackground() throws Exception {
+ if (chapter <= 0) {
+ return html.convert(story.getMeta().getResume(), false);
+ }
+
+ return html.convert(story.getChapters().get(chapter - 1), true);
+ }
+
+ @Override
+ protected void done() {
+ try {
+ String text = get();
+ if (chapter <= 0) {
+ descPane.setVisible(true);
+ } else {
+ descPane.setVisible(false);
+ }
+
+ area.setText(text);
+ area.setSize(scroll.getViewport().getSize());
+ area.setCaretPosition(0);
+ area.scrollRectToVisible(new Rectangle());
+
+ // So we can use the keyboard navigation even after a
+ // toolbar click
+ area.requestFocus();
+ } catch (InterruptedException e) {
+ } catch (ExecutionException e) {
+ }
+ }
+ });
+ }
+}
*
* @author niki
*/
-public class ViewerTextOutput {
+class ViewerTextOutput {
private StringBuilder builder;
private BasicOutput output;
private Story fakeStory;
+ private boolean chapterName;
/**
- * Create a new {@link ViewerTextOutput} that will convert a
- * {@link Chapter} into HTML3 suited for Java Swing.
+ * Create a new {@link ViewerTextOutput} that will convert a {@link Chapter}
+ * into HTML3 suited for Java Swing.
*/
public ViewerTextOutput() {
builder = new StringBuilder();
@Override
protected void writeChapterHeader(Chapter chap) throws IOException {
- builder.append("<HTML>");
-
- builder.append("<H1>");
- builder.append("Chapter ");
- builder.append(chap.getNumber());
- builder.append(": ");
- builder.append(chap.getName());
- builder.append("</H1>");
+ builder.append("<HTML style='line-height: normal;'>");
+
+ if (chapterName) {
+ builder.append("<H1>");
+ builder.append("Chapter ");
+ builder.append(chap.getNumber());
+ if (chap.getName() != null
+ && !chap.getName().trim().isEmpty()) {
+ builder.append(": ");
+ builder.append(chap.getName());
+ }
+ builder.append("</H1>");
+ }
builder.append("<DIV align='justify'>");
}
* Convert the chapter into HTML3 code.
*
* @param chap
- * the {@link Chapter} to convert.
+ * the {@link Chapter} to convert
+ * @param chapterName
+ * display the chapter name
*
* @return HTML3 code tested with Java Swing
*/
- public String convert(Chapter chap) {
+ public String convert(Chapter chap, boolean chapterName) {
+ this.chapterName = chapterName;
builder.setLength(0);
try {
fakeStory.setChapters(Arrays.asList(chap));