X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Ffanfix%2Freader%2Fui%2FGuiReaderViewerPanel.java;h=08a9c9c34e10901fcb5bce3644c9057b0eb991b4;hb=3530eefe42ed0154d576afe44e1247757231c354;hp=1ff4fcc45c69de3e2c4ebb7c48cf9b7bc2df536e;hpb=32ba91e9d2443ac9d17d3db66eef4c570d02cdf1;p=fanfix.git diff --git a/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewerPanel.java b/src/be/nikiroo/fanfix/reader/ui/GuiReaderViewerPanel.java index 1ff4fcc..08a9c9c 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,12 +10,15 @@ 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.bundles.StringIdGui; import be.nikiroo.fanfix.data.Chapter; import be.nikiroo.fanfix.data.Story; import be.nikiroo.utils.Image; @@ -29,9 +34,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 +57,20 @@ 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.setEditable(false); + 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 +78,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 +89,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 +99,7 @@ public class GuiReaderViewerPanel extends JPanel { main.add(right, BorderLayout.EAST); add(main, BorderLayout.CENTER); + main.invalidate(); } setChapter(story.getMeta().getResume()); @@ -106,7 +120,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 +130,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. @@ -139,26 +196,86 @@ public class GuiReaderViewerPanel extends JPanel { } imageProgress.setValue(i); - imageProgress.setString(String.format("Image %d / %d", i + 1, chap - .getParagraphs().size())); + imageProgress.setString(GuiReader.trans(StringIdGui.IMAGE_PROGRESSION, + i + 1, chap.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(); + + // prepare the viewport to get the right sizes later on + image.setIcon(null); + scroll.setViewportView(image); + + 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."); + } + }); } } }