1 33 34 package edu.rice.cs.drjava.ui; 35 36 import javax.swing.*; 37 import javax.swing.event.*; 38 import javax.swing.border.MatteBorder ; 39 import javax.swing.border.EmptyBorder ; 40 import java.awt.event.*; 41 import java.awt.*; 42 import java.awt.print.*; 43 import java.awt.image.*; 44 import java.net.*; 45 import java.lang.reflect.Method ; 46 import edu.rice.cs.drjava.model.*; 47 48 51 public abstract class PreviewFrame extends JFrame { 52 53 protected final SingleDisplayModel _model; 54 protected final MainFrame _mainFrame; 55 protected final Pageable _print; 56 protected volatile int _pageNumber; 57 58 64 private final PageChangerUpdater _pageChanger; 65 66 private static abstract class PageChangerUpdater { 67 abstract void update(int pageNumber) throws Exception ; 68 abstract JComponent getComponent(); 69 } 70 71 private class JTextFieldChanger extends PageChangerUpdater { 72 private final JTextField textfield; 73 private JTextFieldChanger(JTextField tf) { textfield = tf; } 74 void update(int pageNumber) throws Exception { textfield.setText(String.valueOf(pageNumber)); } 75 JComponent getComponent() { return textfield; } 76 } 77 78 private class JSpinnerChanger extends PageChangerUpdater { 79 private volatile JComponent spinner; 80 private volatile Method setValueMethod; 81 private final Object [] args = new Object [1]; 82 private JSpinnerChanger(Class <?> spinnerClass, JComponent spinnerObj) throws Exception { 83 spinner = spinnerObj; 84 setValueMethod = spinnerClass.getMethod("setValue", Object .class); 85 } 86 void update(int pageNumber) throws Exception { 87 args[0] = new Integer (pageNumber); 88 setValueMethod.invoke(spinner, args); 89 } 90 JComponent getComponent() { return spinner; } 91 } 92 93 private final int PREVIEW_WIDTH; 95 private final int PREVIEW_HEIGHT; 96 private final int PREVIEW_PAGE_WIDTH; 97 private final int PREVIEW_PAGE_HEIGHT; 98 99 private final double PAGE_ZOOM = 0.7; 100 private final static int PAGE_BORDER = 20; 101 private final int TOOLBAR_HEIGHT = 35; 102 private static final String ICON_PATH = "/edu/rice/cs/drjava/ui/icons/"; 103 104 private JToolBar _toolBar; 106 private PagePreview _pagePreview; 107 108 110 private final ActionListener _printListener = new ActionListener() { 111 public void actionPerformed(ActionEvent ae) { 112 _print(); 113 _close(); 114 } 115 }; 116 117 118 private final Action _closeAction = new AbstractAction("Close") { 119 public void actionPerformed(ActionEvent ae) { _close(); } 120 }; 121 122 123 private final Action _nextPageAction = new AbstractAction("Next Page") { 124 public void actionPerformed(ActionEvent ae) { _nextPage(); } 125 }; 126 127 128 private final Action _prevPageAction = new AbstractAction("Previous Page") { 129 public void actionPerformed(ActionEvent ae) { _previousPage(); } 130 }; 131 132 133 private final WindowListener _windowCloseListener = new WindowAdapter() { 134 public void windowClosing(WindowEvent ev) { _close(); } 135 }; 136 137 140 public PreviewFrame(SingleDisplayModel model, MainFrame mainFrame, boolean interactions) 141 throws IllegalStateException { 142 super("Print Preview"); 143 mainFrame.hourglassOn(); 144 _model = model; 145 _mainFrame = mainFrame; 146 _toolBar = new JToolBar(); 147 _print = setUpDocument(model, interactions); 148 _pageChanger = createPageChanger(); 149 150 151 PageFormat first = _print.getPageFormat(0); 152 153 PREVIEW_PAGE_WIDTH = (int) (PAGE_ZOOM * first.getWidth()); 154 PREVIEW_PAGE_HEIGHT = (int) (PAGE_ZOOM * first.getHeight()); 155 156 PREVIEW_WIDTH = PREVIEW_PAGE_WIDTH + (2 * PAGE_BORDER); 157 PREVIEW_HEIGHT = PREVIEW_PAGE_HEIGHT + (2 * PAGE_BORDER) + TOOLBAR_HEIGHT; 158 159 _setUpActions(); 160 _setUpToolBar(); 161 162 _pagePreview = new PagePreview(PREVIEW_PAGE_WIDTH, PREVIEW_PAGE_HEIGHT); 163 _pageNumber = 0; 164 165 166 PagePreviewContainer ppc = new PagePreviewContainer(); 167 ppc.add(_pagePreview); 168 JPanel tbCont = new JPanel(new BorderLayout()); 169 JPanel cp = new JPanel(new BorderLayout()); 170 tbCont.add(_toolBar,BorderLayout.NORTH); 171 tbCont.add(Box.createVerticalStrut(10),BorderLayout.SOUTH); 172 tbCont.setBorder(new EmptyBorder (0,0,5,0)); 173 setContentPane(cp); 174 cp.setBorder(new EmptyBorder (5,5,5,5)); 175 cp.add(tbCont, BorderLayout.NORTH); 176 cp.add(ppc, BorderLayout.SOUTH); 177 178 addWindowListener(_windowCloseListener); 179 180 showPage(); 181 _updateActions(); 182 183 setSize(PREVIEW_WIDTH, PREVIEW_HEIGHT); 184 setDefaultCloseOperation(DISPOSE_ON_CLOSE); 185 setVisible(true); 186 } 187 188 189 abstract protected void _print(); 190 191 196 abstract protected Pageable setUpDocument(SingleDisplayModel model, boolean interactions); 197 198 private void _close() { 199 dispose(); 200 _mainFrame.hourglassOff(); 201 } 202 203 private void _nextPage() { 204 _pageNumber++; 205 _goToPage(_pageNumber); 206 } 207 208 private void _previousPage() { 209 _pageNumber--; 210 _goToPage(_pageNumber); 211 } 212 213 private void _goToPage(int pi) { 214 _pageNumber = pi; 215 showPage(); 216 _updateActions(); 217 } 218 219 protected void _showError(Exception e, String title, String message) { 220 JOptionPane.showMessageDialog(this, message + "\n" + e, title, JOptionPane.ERROR_MESSAGE); 221 } 222 223 226 private void _updateActions() { 227 _nextPageAction.setEnabled(_print.getNumberOfPages() > (_pageNumber + 1)); 228 _prevPageAction.setEnabled(_pageNumber > 0); 229 try { _pageChanger.update(_pageNumber + 1); } 230 catch(Exception e) { } 231 } 232 233 234 private void _setUpActions() { 235 _closeAction.putValue(Action.SHORT_DESCRIPTION, "Close"); 237 _nextPageAction.putValue(Action.SMALL_ICON, _getIcon("Forward16.gif")); 239 _nextPageAction.putValue(Action.SHORT_DESCRIPTION, "Next Page"); 240 _prevPageAction.putValue(Action.SMALL_ICON, _getIcon("Back16.gif")); 241 _prevPageAction.putValue(Action.SHORT_DESCRIPTION, "Previous Page"); 242 } 243 244 private PageChangerUpdater createPageChanger() { 245 try { 248 Class <?> spinnerClass = Class.forName("javax.swing.JSpinner"); 249 final JComponent spinner = (JComponent) spinnerClass.newInstance(); 250 final Method getter = spinnerClass.getMethod("getValue",new Class [0]); 251 Object model = callMethod(spinner, spinnerClass, "getModel",null,null); 252 Class <?> modelClass = model.getClass(); 253 Class <?>[] ca = new Class <?>[] {Comparable .class}; 254 Object [] aa = new Object [] {new Integer (1)}; 255 callMethod(model,modelClass,"setMinimum",ca,aa); 256 aa[0] = new Integer (_print.getNumberOfPages()); 257 callMethod(model,modelClass,"setMaximum",ca,aa); 258 ca[0] = ChangeListener.class; 259 aa[0] = new ChangeListener() { 260 public void stateChanged(ChangeEvent ev) { 261 int num = _pageNumber; 262 try { 263 num = ((Number ) getter.invoke(spinner,new Object [0])).intValue()-1; 264 if ((num >= 0) && (num < _print.getNumberOfPages())) _goToPage(num); 265 else _updateActions(); 266 } 267 catch(Exception ex) { _updateActions(); } 268 } 269 }; 270 callMethod(spinner, spinnerClass,"addChangeListener",ca,aa); 271 return new JSpinnerChanger(spinnerClass, spinner); 272 } catch(Exception e) { 273 274 final JTextField tf = new JTextField(); 275 tf.addActionListener(new ActionListener() { 276 public void actionPerformed(ActionEvent ae) { 277 try { 278 int pageToGoTo = Integer.parseInt(tf.getText()) - 1; 279 if ((pageToGoTo < 0) || (pageToGoTo >= _print.getNumberOfPages())) { _updateActions(); } 280 else _goToPage(pageToGoTo); 281 } 282 catch (NumberFormatException e) { _updateActions(); } 283 } 284 }); 285 return new JTextFieldChanger(tf); 286 } 287 } 288 289 private static Object callMethod(Object rec, Class <?> c, String name, Class <?>[] ca, Object [] args) throws Exception { 290 Method m = c.getMethod(name,ca); 291 return m.invoke(rec,args); 292 } 293 294 295 private ImageIcon _getIcon(String name) { 296 URL url = PreviewFrame.class.getResource(ICON_PATH + name); 297 if (url != null) return new ImageIcon(url); 298 return null; 299 } 300 301 302 private void _setUpToolBar() { 303 _toolBar.setFloatable(false); 304 305 JButton printButton = new JButton("Print...",_getIcon("Print16.gif")); 307 printButton.setToolTipText("Print this document"); 308 printButton.addActionListener(_printListener); 309 _toolBar.add(printButton); 310 _toolBar.addSeparator(); 311 _toolBar.add(_closeAction); 312 313 _toolBar.add(Box.createHorizontalGlue()); 315 316 _toolBar.add(_prevPageAction); 318 _toolBar.add(_nextPageAction); 319 _toolBar.addSeparator(); 320 321 JLabel gotop = new JLabel("Page"); 322 323 JLabel of = new JLabel(" of " + _print.getNumberOfPages()); 324 325 _toolBar.add(gotop); 326 _toolBar.addSeparator(); 327 JComponent c = _pageChanger.getComponent(); 328 Dimension d = c.getPreferredSize(); 329 d = new Dimension(100,d.height); 330 c.setMaximumSize(d); 331 c.setPreferredSize(d); 332 c.setMinimumSize(d); 333 c.setToolTipText("Goto Page"); 334 _toolBar.add(c); 335 _toolBar.add(of); 336 } 337 338 339 private void showPage() { 340 BufferedImage img = new BufferedImage((int) _model.getPageFormat().getWidth(), 341 (int) _model.getPageFormat().getHeight(), 342 BufferedImage.TYPE_INT_RGB); 343 Graphics g = img.getGraphics(); 344 g.setColor(Color.white); 345 g.fillRect(0, 0, (int) _model.getPageFormat().getWidth(), (int) _model.getPageFormat().getHeight()); 346 347 try { 348 _print.getPrintable(_pageNumber).print(g, _model.getPageFormat(), _pageNumber); 349 _pagePreview.setImage(img); 350 } 351 catch (PrinterException e) { } 352 } 353 354 355 class PagePreviewContainer extends JPanel { 356 public Dimension getPreferredSize() { return getParent().getSize(); } 357 358 359 public void doLayout() { 360 Component cp = getComponent(0); 361 362 Dimension dm = cp.getPreferredSize(); 363 int Hindent = (int) (getPreferredSize().getWidth() - dm.getWidth()) / 2; 364 int Vindent = TOOLBAR_HEIGHT + (int) ((getPreferredSize().getHeight() - dm.getHeight() - TOOLBAR_HEIGHT) / 2); 365 _pagePreview.setBounds(Hindent, Vindent, (int) dm.getWidth(), (int) dm.getHeight()); 366 } 367 } 368 369 370 static class PagePreview extends JPanel { 371 protected final int _width; 372 protected final int _height; 373 protected volatile Image _source; 374 protected volatile Image _image; 375 376 377 public PagePreview(int width, int height) { 378 super(); 379 _width = width; 380 _height = height; 381 setBorder(new MatteBorder (1, 1, 2, 2, Color.black)); 382 setBackground(Color.white); 383 } 384 385 386 protected void updateScaled() { 387 _image = _source.getScaledInstance(_width, _height, Image.SCALE_SMOOTH); 388 _image.flush(); 389 } 390 391 394 public void setImage(Image i) { 395 _source = i; 396 updateScaled(); 397 repaint(); 398 } 399 400 public Dimension getPreferredSize() { return new Dimension(_width, _height); } 401 402 public Dimension getMaximumSize() { return getPreferredSize(); } 403 404 public Dimension getMinimumSize() { return getPreferredSize(); } 405 406 public void paint(Graphics g) { 407 g.setColor(getBackground()); 408 g.fillRect(0, 0, _width, _height); 409 g.drawImage(_image, 0, 0, this); 410 paintBorder(g); 411 } 412 } 413 } | Popular Tags |