gui: fix viewers, now ~OK
authorNiki Roo <niki@nikiroo.be>
Sun, 24 Mar 2019 16:41:59 +0000 (17:41 +0100)
committerNiki Roo <niki@nikiroo.be>
Sun, 24 Mar 2019 16:41:59 +0000 (17:41 +0100)
src/be/nikiroo/fanfix/reader/ui/GuiReaderViewer.java
src/be/nikiroo/fanfix/reader/ui/GuiReaderViewerPanel.java
src/be/nikiroo/fanfix/reader/ui/GuiReaderViewerTextOutput.java

index 48dfa498472421904516009260c34e371cf1526a..398ac5c77c70ba9ec66fd70df5bea083bd66f49c 100644 (file)
@@ -182,7 +182,6 @@ public class GuiReaderViewer extends JFrame {
                        chapterLabel.setText("<HTML>&nbsp;&nbsp;<B>Chapter "
                                        + chap.getNumber() + "</B>: " + chap.getName() + "</HTML>");
 
-                       System.out.println(chap);
                        mainPanel.setChapter(chap);
                }
        }
index 1ff4fcc45c69de3e2c4ebb7c48cf9b7bc2df536e..18f6aca577f760fddf4e163b1f4d120658f6bc2a 100644 (file)
@@ -1,6 +1,8 @@
 package be.nikiroo.fanfix.reader.ui;
 
 import java.awt.BorderLayout;
+import java.awt.EventQueue;
+import java.awt.Graphics2D;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.image.BufferedImage;
@@ -8,10 +10,12 @@ import java.awt.image.BufferedImage;
 import javax.swing.Icon;
 import javax.swing.ImageIcon;
 import javax.swing.JButton;
+import javax.swing.JEditorPane;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JProgressBar;
 import javax.swing.JScrollPane;
+import javax.swing.SwingConstants;
 
 import be.nikiroo.fanfix.Instance;
 import be.nikiroo.fanfix.data.Chapter;
@@ -29,9 +33,14 @@ public class GuiReaderViewerPanel extends JPanel {
 
        private boolean imageDocument;
        private Chapter chap;
-
-       private JLabel label;
+       private JScrollPane scroll;
        private GuiReaderViewerTextOutput htmlOutput;
+
+       // text only:
+       private JEditorPane text;
+
+       // image only:
+       private JLabel image;
        private JProgressBar imageProgress;
        private int currentImage;
        private JButton left;
@@ -47,17 +56,19 @@ public class GuiReaderViewerPanel extends JPanel {
                super(new BorderLayout());
 
                this.imageDocument = story.getMeta().isImageDocument();
-               this.label = new JLabel();
-               label.setAlignmentY(TOP_ALIGNMENT);
+
+               this.text = new JEditorPane("text/html", "");
+               text.setAlignmentY(TOP_ALIGNMENT);
                htmlOutput = new GuiReaderViewerTextOutput();
 
-               if (!imageDocument) {
-                       // TODO: why is it broken?
-                       // text.setPreferredSize(new Dimension(500, 500));
+               image = new JLabel();
+               image.setHorizontalAlignment(SwingConstants.CENTER);
 
-                       JScrollPane scroll = new JScrollPane(label);
-                       scroll.getVerticalScrollBar().setUnitIncrement(16);
+               scroll = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+                               JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+               scroll.getVerticalScrollBar().setUnitIncrement(16);
 
+               if (!imageDocument) {
                        add(scroll, BorderLayout.CENTER);
                } else {
                        imageProgress = new JProgressBar();
@@ -65,9 +76,9 @@ public class GuiReaderViewerPanel extends JPanel {
                        add(imageProgress, BorderLayout.SOUTH);
 
                        JPanel main = new JPanel(new BorderLayout());
-                       main.add(label, BorderLayout.CENTER);
+                       main.add(scroll, BorderLayout.CENTER);
 
-                       left = new JButton(" < ");
+                       left = new JButton("<HTML>&nbsp; &nbsp; &lt; &nbsp; &nbsp;</HTML>");
                        left.addActionListener(new ActionListener() {
                                @Override
                                public void actionPerformed(ActionEvent e) {
@@ -76,7 +87,7 @@ public class GuiReaderViewerPanel extends JPanel {
                        });
                        main.add(left, BorderLayout.WEST);
 
-                       right = new JButton(" > ");
+                       right = new JButton("<HTML>&nbsp; &nbsp; &gt; &nbsp; &nbsp;</HTML>");
                        right.addActionListener(new ActionListener() {
                                @Override
                                public void actionPerformed(ActionEvent e) {
@@ -86,6 +97,7 @@ public class GuiReaderViewerPanel extends JPanel {
                        main.add(right, BorderLayout.EAST);
 
                        add(main, BorderLayout.CENTER);
+                       main.invalidate();
                }
 
                setChapter(story.getMeta().getResume());
@@ -106,7 +118,7 @@ public class GuiReaderViewerPanel extends JPanel {
                this.chap = chap;
 
                if (!imageDocument) {
-                       label.setText(htmlOutput.convert(chap));
+                       setText(chap);
                } else {
                        left.setVisible(chap.getNumber() > 0);
                        right.setVisible(chap.getNumber() > 0);
@@ -116,13 +128,56 @@ public class GuiReaderViewerPanel extends JPanel {
                        imageProgress.setMaximum(chap.getParagraphs().size() - 1);
 
                        if (chap.getNumber() == 0) {
-                               label.setText(htmlOutput.convert(chap));
+                               setText(chap);
                        } else {
                                setImage(0);
                        }
                }
        }
 
+       /**
+        * Will set and display the current chapter text.
+        * 
+        * @param chap
+        *            the chapter to display
+        */
+       private void setText(final Chapter chap) {
+               new Thread(new Runnable() {
+                       @Override
+                       public void run() {
+                               final String content = htmlOutput.convert(chap);
+                               // Wait until size computations are correct
+                               while (!scroll.isValid()) {
+                                       try {
+                                               Thread.sleep(1);
+                                       } catch (InterruptedException e) {
+                                       }
+                               }
+
+                               setText(content);
+                       }
+               }).start();
+       }
+
+       /**
+        * Actually set the text in the UI.
+        * <p>
+        * Do <b>NOT</b> use this method from the UI thread.
+        * 
+        * @param content
+        *            the text
+        */
+       private void setText(final String content) {
+               EventQueue.invokeLater(new Runnable() {
+                       @Override
+                       public void run() {
+                               text.setText(content);
+                               text.setCaretPosition(0);
+                               scroll.setViewportView(text);
+                       }
+               });
+       }
+
        /**
         * Will set and display the current image, take care about the progression
         * and update the left and right cursors' <tt>enabled</tt> property.
@@ -143,22 +198,78 @@ public class GuiReaderViewerPanel extends JPanel {
                                .getParagraphs().size()));
 
                currentImage = i;
-               label.setText("");
-               label.setIcon(null);
 
-               Image img = chap.getParagraphs().get(i).getContentImage();
-               if (img == null) {
-                       label.setText("Error: cannot render image.");
-               } else {
+               final Image img = chap.getParagraphs().get(i).getContentImage();
+
+               new Thread(new Runnable() {
+                       @Override
+                       public void run() {
+                               // Wait until size computations are correct
+                               while (!scroll.isValid()) {
+                                       try {
+                                               Thread.sleep(1);
+                                       } catch (InterruptedException e) {
+                                       }
+                               }
+
+                               if (img == null) {
+                                       setText("Error: cannot render image.");
+                               } else {
+                                       setImage(img);
+                               }
+                       }
+               }).start();
+       }
+
+       /**
+        * Actually set the image in the UI.
+        * <p>
+        * Do <b>NOT</b> use this method from the UI thread.
+        * 
+        * @param img
+        *            the image to set
+        */
+       private void setImage(Image img) {
+               try {
+                       int scrollWidth = scroll.getWidth()
+                                       - scroll.getVerticalScrollBar().getWidth();
+
+                       BufferedImage buffImg = ImageUtilsAwt.fromImage(img);
+
+                       int iw = buffImg.getWidth();
+                       int ih = buffImg.getHeight();
+                       double ratio = ((double) ih) / iw;
+
+                       int w = scrollWidth;
+                       int h = (int) (ratio * scrollWidth);
+
+                       BufferedImage resizedImage = new BufferedImage(w, h,
+                                       BufferedImage.TYPE_4BYTE_ABGR);
+
+                       Graphics2D g = resizedImage.createGraphics();
                        try {
-                               BufferedImage buffImg = ImageUtilsAwt.fromImage(img);
-                               Icon icon = new ImageIcon(buffImg);
-                               label.setIcon(icon);
-                       } catch (Exception e) {
-                               Instance.getTraceHandler().error(
-                                               new Exception("Failed to load image into label", e));
-                               label.setText("Error: cannot load image.");
+                               g.drawImage(buffImg, 0, 0, w, h, null);
+                       } finally {
+                               g.dispose();
                        }
+
+                       final Icon icon = new ImageIcon(resizedImage);
+                       EventQueue.invokeLater(new Runnable() {
+                               @Override
+                               public void run() {
+                                       image.setIcon(icon);
+                                       scroll.setViewportView(image);
+                               }
+                       });
+               } catch (Exception e) {
+                       Instance.getTraceHandler().error(
+                                       new Exception("Failed to load image into label", e));
+                       EventQueue.invokeLater(new Runnable() {
+                               @Override
+                               public void run() {
+                                       text.setText("Error: cannot load image.");
+                               }
+                       });
                }
        }
 }
index c5f7943c17ed9eab4a03eb0d0a22f4c3b3eeb26e..e9a44b5ef8e0b1c94e293eec6187de58dc6346f6 100644 (file)
@@ -41,10 +41,7 @@ public class GuiReaderViewerTextOutput {
                                builder.append(chap.getName());
                                builder.append("</H1>");
 
-                               builder.append("<JUSTIFY>");
-                               for (Paragraph para : chap) {
-                                       writeParagraph(para);
-                               }
+                               builder.append("<DIV align='justify'>");
                        }
 
                        @Override
@@ -54,7 +51,7 @@ public class GuiReaderViewerTextOutput {
                                }
                                paraInQuote = false;
 
-                               builder.append("</JUSTIFY>");
+                               builder.append("</DIV>");
                                builder.append("</HTML>");
                        }