You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PreviewDialog.java 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. /*
  2. * $Id$
  3. * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
  4. * For details on use and redistribution please refer to the
  5. * LICENSE file included with these sources.
  6. */
  7. package org.apache.fop.viewer;
  8. /*
  9. * originally contributed by
  10. * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com,
  11. * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com,
  12. * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com
  13. * Doro Wiarda (wiarda@dwiarda.com:
  14. * added MessageListener support and made
  15. * the showing of the progress and error
  16. * messages Swing thread safe.
  17. * This is needed as xml parse errors do not
  18. * necessarily occur in the
  19. * EventDispatchThread.
  20. */
  21. import java.awt.*;
  22. import java.awt.print.*;
  23. import java.awt.event.*;
  24. import java.awt.image.BufferedImage;
  25. import java.util.StringTokenizer;
  26. import java.util.Vector;
  27. import javax.swing.*;
  28. import org.apache.fop.layout.*;
  29. import org.apache.fop.render.awt.*;
  30. import org.apache.fop.messaging.*;
  31. /**
  32. * Frame and User Interface for Preview
  33. */
  34. public class PreviewDialog extends JFrame implements ProgressListener,
  35. MessageListener {
  36. protected Translator res;
  37. protected int currentPage = 0;
  38. protected int pageCount = 0;
  39. protected AWTRenderer renderer;
  40. protected IconToolBar toolBar = new IconToolBar();
  41. protected Command printAction;
  42. protected Command firstPageAction;
  43. protected Command previousPageAction;
  44. protected Command nextPageAction;
  45. protected Command lastPageAction;
  46. protected JLabel zoomLabel =
  47. new JLabel(); // {public float getAlignmentY() { return 0.0f; }};
  48. protected JComboBox scale = new JComboBox() {
  49. public float getAlignmentY() {
  50. return 0.5f;
  51. }
  52. };
  53. protected JScrollPane previewArea = new JScrollPane();
  54. // protected JLabel statusBar = new JLabel();
  55. protected JPanel statusBar = new JPanel();
  56. protected GridBagLayout statusBarLayout = new GridBagLayout();
  57. protected JLabel statisticsStatus = new JLabel();
  58. protected JLabel processStatus = new JLabel();
  59. protected JLabel infoStatus = new JLabel();
  60. protected JLabel previewImageLabel = new JLabel();
  61. /**
  62. * Create a new PreviewDialog that uses the given renderer and translator.
  63. *
  64. * @param aRenderer the to use renderer
  65. * @param aRes the to use translator
  66. */
  67. public PreviewDialog(AWTRenderer aRenderer, Translator aRes) {
  68. res = aRes;
  69. renderer = aRenderer;
  70. printAction = new Command(res.getString("Print"), "Print") {
  71. public void doit() {
  72. print();
  73. }
  74. };
  75. firstPageAction = new Command(res.getString("First page"),
  76. "firstpg") {
  77. public void doit() {
  78. goToFirstPage(null);
  79. }
  80. };
  81. previousPageAction = new Command(res.getString("Previous page"),
  82. "prevpg") {
  83. public void doit() {
  84. goToPreviousPage(null);
  85. }
  86. };
  87. nextPageAction = new Command(res.getString("Next page"), "nextpg") {
  88. public void doit() {
  89. goToNextPage(null);
  90. }
  91. };
  92. lastPageAction = new Command(res.getString("Last page"), "lastpg") {
  93. public void doit() {
  94. goToLastPage(null);
  95. }
  96. };
  97. setDefaultCloseOperation(DISPOSE_ON_CLOSE);
  98. this.setSize(new Dimension(379, 476));
  99. previewArea.setMinimumSize(new Dimension(50, 50));
  100. this.setTitle("FOP: AWT-" + res.getString("Preview"));
  101. scale.addItem("25");
  102. scale.addItem("50");
  103. scale.addItem("75");
  104. scale.addItem("100");
  105. scale.addItem("150");
  106. scale.addItem("200");
  107. scale.setMaximumSize(new Dimension(80, 24));
  108. scale.setPreferredSize(new Dimension(80, 24));
  109. scale.addActionListener(new java.awt.event.ActionListener() {
  110. public void actionPerformed(ActionEvent e) {
  111. scale_actionPerformed(e);
  112. }
  113. });
  114. scale.setSelectedItem("100");
  115. renderer.setScaleFactor(100.0);
  116. zoomLabel.setText(res.getString("Zoom"));
  117. this.setJMenuBar(setupMenue());
  118. this.getContentPane().add(toolBar, BorderLayout.NORTH);
  119. toolBar.add(printAction);
  120. toolBar.addSeparator();
  121. toolBar.add(firstPageAction);
  122. toolBar.add(previousPageAction);
  123. toolBar.add(nextPageAction);
  124. toolBar.add(lastPageAction);
  125. toolBar.addSeparator();
  126. toolBar.add(zoomLabel, null);
  127. toolBar.addSeparator();
  128. toolBar.add(scale, null);
  129. this.getContentPane().add(previewArea, BorderLayout.CENTER);
  130. this.getContentPane().add(statusBar, BorderLayout.SOUTH);
  131. statisticsStatus.setBorder(BorderFactory.createEtchedBorder());
  132. processStatus.setBorder(BorderFactory.createEtchedBorder());
  133. infoStatus.setBorder(BorderFactory.createEtchedBorder());
  134. statusBar.setLayout(statusBarLayout);
  135. processStatus.setPreferredSize(new Dimension(200, 21));
  136. statisticsStatus.setPreferredSize(new Dimension(100, 21));
  137. infoStatus.setPreferredSize(new Dimension(100, 21));
  138. processStatus.setMinimumSize(new Dimension(200, 21));
  139. statisticsStatus.setMinimumSize(new Dimension(100, 21));
  140. infoStatus.setMinimumSize(new Dimension(100, 21));
  141. statusBar.add(processStatus,
  142. new GridBagConstraints(0, 0, 2, 1, 2.0, 0.0,
  143. GridBagConstraints.CENTER,
  144. GridBagConstraints.HORIZONTAL,
  145. new Insets(0, 0, 0, 5), 0, 0));
  146. statusBar.add(statisticsStatus,
  147. new GridBagConstraints(2, 0, 1, 2, 1.0, 0.0,
  148. GridBagConstraints.CENTER,
  149. GridBagConstraints.HORIZONTAL,
  150. new Insets(0, 0, 0, 5), 0, 0));
  151. statusBar.add(infoStatus,
  152. new GridBagConstraints(3, 0, 1, 1, 1.0, 0.0,
  153. GridBagConstraints.CENTER,
  154. GridBagConstraints.HORIZONTAL,
  155. new Insets(0, 0, 0, 0), 0, 0));
  156. previewArea.getViewport().add(previewImageLabel);
  157. showPage();
  158. }
  159. /**
  160. * Create a new menubar to be shown in this window.
  161. *
  162. * @return the newly created menubar
  163. */
  164. private JMenuBar setupMenue() {
  165. JMenuBar menuBar;
  166. JMenuItem menuItem;
  167. JMenu menu;
  168. JMenu subMenu;
  169. menuBar = new JMenuBar();
  170. menu = new JMenu(res.getString("File"));
  171. subMenu = new JMenu("OutputFormat");
  172. subMenu.add(new Command("mHTML"));
  173. subMenu.add(new Command("mPDF"));
  174. subMenu.add(new Command("mRTF"));
  175. subMenu.add(new Command("mTEXT"));
  176. // menu.add(subMenu);
  177. // menu.addSeparator();
  178. menu.add(new Command(res.getString("Print")) {
  179. public void doit() {
  180. print();
  181. }
  182. });
  183. menu.addSeparator();
  184. menu.add(new Command(res.getString("Exit")) {
  185. public void doit() {
  186. dispose();
  187. }
  188. });
  189. menuBar.add(menu);
  190. menu = new JMenu(res.getString("View"));
  191. menu.add(new Command(res.getString("First page")) {
  192. public void doit() {
  193. goToFirstPage(null);
  194. }
  195. });
  196. menu.add(new Command(res.getString("Previous page")) {
  197. public void doit() {
  198. goToPreviousPage(null);
  199. }
  200. });
  201. menu.add(new Command(res.getString("Next page")) {
  202. public void doit() {
  203. goToNextPage(null);
  204. }
  205. });
  206. menu.add(new Command(res.getString("Last page")) {
  207. public void doit() {
  208. goToLastPage(null);
  209. }
  210. });
  211. menu.add(new Command(res.getString("Go to Page") + " ...") {
  212. public void doit() {
  213. goToPage(null);
  214. }
  215. });
  216. menu.addSeparator();
  217. subMenu = new JMenu(res.getString("Zoom"));
  218. subMenu.add(new Command("25%") {
  219. public void doit() {
  220. setScale(25.0);
  221. }
  222. });
  223. subMenu.add(new Command("50%") {
  224. public void doit() {
  225. setScale(50.0);
  226. }
  227. });
  228. subMenu.add(new Command("75%") {
  229. public void doit() {
  230. setScale(75.0);
  231. }
  232. });
  233. subMenu.add(new Command("100%") {
  234. public void doit() {
  235. setScale(100.0);
  236. }
  237. });
  238. subMenu.add(new Command("150%") {
  239. public void doit() {
  240. setScale(150.0);
  241. }
  242. });
  243. subMenu.add(new Command("200%") {
  244. public void doit() {
  245. setScale(200.0);
  246. }
  247. });
  248. menu.add(subMenu);
  249. menu.addSeparator();
  250. menu.add(new Command(res.getString("Default zoom")) {
  251. public void doit() {
  252. setScale(100.0);
  253. }
  254. });
  255. menuBar.add(menu);
  256. menu = new JMenu(res.getString("Help"));
  257. menu.add(new Command(res.getString("Index")));
  258. menu.addSeparator();
  259. menu.add(new Command(res.getString("Introduction")));
  260. menu.addSeparator();
  261. menu.add(new Command(res.getString("About")) {
  262. public void doit() {
  263. startHelpAbout(null);
  264. }
  265. });
  266. menuBar.add(menu);
  267. return menuBar;
  268. }
  269. // Aktion Hilfe | Info durchgeführt
  270. /**
  271. * Show the About box
  272. *
  273. * @param e a value of type 'ActionEvent'
  274. */
  275. public void startHelpAbout(ActionEvent e) {
  276. PreviewDialogAboutBox dlg = new PreviewDialogAboutBox(this);
  277. Dimension dlgSize = dlg.getPreferredSize();
  278. Dimension frmSize = getSize();
  279. Point loc = getLocation();
  280. dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x,
  281. (frmSize.height - dlgSize.height) / 2 + loc.y);
  282. dlg.setModal(true);
  283. dlg.show();
  284. }
  285. /**
  286. * Change the current visible page
  287. *
  288. * @param number the page number to go to
  289. */
  290. private void goToPage(int number) {
  291. currentPage = number;
  292. renderer.setPageNumber(number);
  293. showPage();
  294. }
  295. /**
  296. * Shows the previous page.
  297. */
  298. private void goToPreviousPage(ActionEvent e) {
  299. if (currentPage <= 0)
  300. return;
  301. currentPage--;
  302. goToPage(currentPage);
  303. }
  304. /**
  305. * Shows the next page.
  306. */
  307. private void goToNextPage(ActionEvent e) {
  308. if (currentPage >= pageCount - 1)
  309. return;
  310. currentPage++;
  311. goToPage(currentPage);
  312. }
  313. /**
  314. * Shows the last page.
  315. */
  316. private void goToLastPage(ActionEvent e) {
  317. if (currentPage == pageCount - 1)
  318. return;
  319. currentPage = pageCount - 1;
  320. goToPage(currentPage);
  321. }
  322. /**
  323. * Shows a page by number.
  324. */
  325. private void goToPage(ActionEvent e) {
  326. GoToPageDialog d = new GoToPageDialog(this,
  327. res.getString("Go to Page"),
  328. true);
  329. d.setLocation((int)getLocation().getX() + 50,
  330. (int)getLocation().getY() + 50);
  331. d.show();
  332. currentPage = d.getPageNumber();
  333. if (currentPage < 1 || currentPage > pageCount)
  334. return;
  335. currentPage--;
  336. goToPage(currentPage);
  337. }
  338. /**
  339. * Shows the first page.
  340. */
  341. private void goToFirstPage(ActionEvent e) {
  342. if (currentPage == 0)
  343. return;
  344. currentPage = 0;
  345. goToPage(currentPage);
  346. }
  347. private void print() {
  348. PrinterJob pj = PrinterJob.getPrinterJob();
  349. // Nicht nötig, Pageable get a Printable.
  350. // pj.setPrintable(renderer);
  351. pj.setPageable(renderer);
  352. if (pj.printDialog()) {
  353. try {
  354. pj.print();
  355. } catch (PrinterException pe) {
  356. pe.printStackTrace();
  357. }
  358. }
  359. }
  360. public void setScale(double scaleFactor) {
  361. if (scaleFactor == 25.0)
  362. scale.setSelectedIndex(0);
  363. else if (scaleFactor == 50.0)
  364. scale.setSelectedIndex(1);
  365. else if (scaleFactor == 75.0)
  366. scale.setSelectedIndex(2);
  367. else if (scaleFactor == 100.0)
  368. scale.setSelectedIndex(3);
  369. else if (scaleFactor == 150.0)
  370. scale.setSelectedIndex(4);
  371. else if (scaleFactor == 200.0)
  372. scale.setSelectedIndex(5);
  373. renderer.setScaleFactor(scaleFactor);
  374. showPage();
  375. }
  376. void scale_actionPerformed(ActionEvent e) {
  377. setScale(new Double((String)scale.getSelectedItem()).doubleValue());
  378. }
  379. public void progress(int percentage) {
  380. progress(new String(percentage + "%"));
  381. }
  382. public void progress(int percentage, String message) {
  383. progress(new String(message + " " + percentage + "%"));
  384. }
  385. /**
  386. * Setting the text of a JLabel is not thread save, it
  387. * needs to be done in the EventThread. Here we make sure
  388. * it is done.
  389. */
  390. public void progress(String message) {
  391. SwingUtilities.invokeLater(new showProgress(message, false));
  392. }
  393. /**
  394. * This class is used to show status and error messages in
  395. * a thread safe way.
  396. */
  397. class showProgress implements Runnable {
  398. /**
  399. * The message to display
  400. */
  401. Object message;
  402. /**
  403. * Is this an errorMessage, i.e. should it be shown in
  404. * an JOptionPane or in the status bar.
  405. */
  406. boolean isErrorMessage = false;
  407. /**
  408. * Constructs showProgress thread
  409. * @param message message to display
  410. * @param isErrorMessage show in status bar or in JOptionPane
  411. */
  412. public showProgress(Object message, boolean isErrorMessage) {
  413. this.message = message;
  414. this.isErrorMessage = isErrorMessage;
  415. }
  416. public void run() {
  417. if (isErrorMessage) {
  418. JOptionPane.showMessageDialog(null, message, "Error",
  419. JOptionPane.ERROR_MESSAGE);
  420. } else
  421. processStatus.setText(message.toString());
  422. }
  423. }
  424. public void showPage() {
  425. showPageImage viewer = new showPageImage();
  426. if (SwingUtilities.isEventDispatchThread()) {
  427. viewer.run();
  428. } else
  429. SwingUtilities.invokeLater(viewer);
  430. }
  431. /**
  432. * This class is used to update the page image
  433. * in a thread safe way.
  434. */
  435. class showPageImage implements Runnable {
  436. /**
  437. * The run method that does the actuall updating
  438. */
  439. public void run() {
  440. BufferedImage pageImage = null;
  441. Graphics graphics = null;
  442. //renderer.render(currentPage);
  443. pageImage = renderer.getLastRenderedPage();
  444. if (pageImage == null)
  445. return;
  446. graphics = pageImage.getGraphics();
  447. graphics.setColor(Color.black);
  448. graphics.drawRect(0, 0, pageImage.getWidth() - 1,
  449. pageImage.getHeight() - 1);
  450. previewImageLabel.setIcon(new ImageIcon(pageImage));
  451. pageCount = renderer.getPageCount();
  452. statisticsStatus.setText(res.getString("Page") + " "
  453. + (currentPage + 1) + " "
  454. + res.getString("of") + " " + pageCount);
  455. }
  456. }
  457. /**
  458. * Called by MessageHandler if an error message or a
  459. * log message is received.
  460. */
  461. public void processMessage(MessageEvent event) {
  462. String error = event.getMessage();
  463. String text = processStatus.getText();
  464. FontMetrics fmt =
  465. processStatus.getFontMetrics(processStatus.getFont());
  466. int width = processStatus.getWidth() - fmt.stringWidth("...");
  467. showProgress showIt;
  468. if (event.getMessageType() == event.LOG) {
  469. if (!text.endsWith("\n")) {
  470. text = text + error;
  471. while (fmt.stringWidth(text) > width) {
  472. text = text.substring(1);
  473. width = processStatus.getWidth() - fmt.stringWidth("...");
  474. }
  475. } else
  476. text = error;
  477. progress(text);
  478. } else {
  479. error = error.trim();
  480. if (error.equals(">")) {
  481. text = text + error;
  482. while (fmt.stringWidth(text) > width) {
  483. text = text.substring(1);
  484. width = processStatus.getWidth() - fmt.stringWidth("...");
  485. }
  486. progress(processStatus.getText() + error);
  487. return;
  488. }
  489. if (error.equals(""))
  490. return;
  491. if (error.length() < 60) {
  492. showIt = new showProgress(error, true);
  493. } else {
  494. StringTokenizer tok = new StringTokenizer(error, " ");
  495. Vector labels = new Vector();
  496. StringBuffer buffer = new StringBuffer();
  497. String tmp, list[];
  498. while (tok.hasMoreTokens()) {
  499. tmp = tok.nextToken();
  500. if ((buffer.length() + tmp.length() + 1) < 60) {
  501. buffer.append(" ").append(tmp);
  502. } else {
  503. labels.add(buffer.toString());
  504. buffer = new StringBuffer();
  505. buffer.append(tmp);
  506. }
  507. }
  508. labels.add(buffer.toString());
  509. list = new String[labels.size()];
  510. for (int i = 0; i < labels.size(); i++) {
  511. list[i] = labels.elementAt(i).toString();
  512. }
  513. showIt = new showProgress(list, true);
  514. }
  515. if (SwingUtilities.isEventDispatchThread()) {
  516. showIt.run();
  517. } else {
  518. try {
  519. SwingUtilities.invokeAndWait(showIt);
  520. } catch (Exception e) {
  521. e.printStackTrace();
  522. progress(event.getMessage());
  523. }
  524. }
  525. }
  526. }
  527. public void dispose() {
  528. System.exit(0);
  529. }
  530. } // class PreviewDialog