From 908bbb351f8db585068e364394a543dc10f736ae Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Sun, 24 Mar 2019 17:41:59 +0100 Subject: [PATCH] gui: fix viewers, now ~OK --- .../fanfix/reader/ui/GuiReaderViewer.java | 1 - .../reader/ui/GuiReaderViewerPanel.java | 165 +++++++++++++++--- .../reader/ui/GuiReaderViewerTextOutput.java | 7 +- 3 files changed, 140 insertions(+), 33 deletions(-) diff --git a/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewer.java b/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewer.java index 48dfa49..398ac5c 100644 --- a/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewer.java +++ b/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewer.java @@ -182,7 +182,6 @@ public class GuiReaderViewer extends JFrame { chapterLabel.setText("  Chapter " + chap.getNumber() + ": " + chap.getName() + ""); - System.out.println(chap); mainPanel.setChapter(chap); } } diff --git a/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewerPanel.java b/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewerPanel.java index 1ff4fcc..18f6aca 100644 --- a/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewerPanel.java +++ b/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewerPanel.java @@ -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("    <    "); 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("    >    "); 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. + *

+ * Do NOT 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' enabled 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. + *

+ * Do NOT 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."); + } + }); } } } diff --git a/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewerTextOutput.java b/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewerTextOutput.java index c5f7943..e9a44b5 100644 --- a/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewerTextOutput.java +++ b/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewerTextOutput.java @@ -41,10 +41,7 @@ public class GuiReaderViewerTextOutput { builder.append(chap.getName()); builder.append(""); - builder.append(""); - for (Paragraph para : chap) { - writeParagraph(para); - } + builder.append("

"); } @Override @@ -54,7 +51,7 @@ public class GuiReaderViewerTextOutput { } paraInQuote = false; - builder.append(""); + builder.append("
"); builder.append(""); } -- 2.27.0