/*
* BasicPrintPreviewPaneUI.java
* :tabSize=4:indentSize=4:noTabs=false:
* :folding=explicit:collapseFolds=1:
*
* Copyright (C) 2016 Dale Anson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.gjt.sp.jedit.print;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.LayoutManager;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.*;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ComponentUI;
import org.gjt.sp.jedit.gui.DropShadowBorder;
/**
* Concrete implementation of a PrintPreviewPaneUI.
*/
public class BasicPrintPreviewPaneUI extends PrintPreviewPaneUI implements ChangeListener
{
private PrintPreviewPane printPreviewPane = null;
private JScrollPane scrollPane = null;
private PrintPreviewRenderer printPreviewRenderer = null;
/**
* Required by super class.
* @param c not used
* @return one of these
*/
public static ComponentUI createUI( JComponent c )
{
return new BasicPrintPreviewPaneUI();
}
/**
* Configures the specified component appropriate for the look and feel.
* This method is invoked when the <code>ComponentUI</code> instance is being installed
* as the UI delegate on the specified component. This method should
* completely configure the component for the look and feel,
* including the following:
* <ol>
* <li>Install any default property values for color, fonts, borders,
* icons, opacity, etc. on the component. Whenever possible,
* property values initialized by the client program should <i>not</i>
* be overridden.
* </li><li>Install a <code>LayoutManager</code> on the component if necessary.
* </li><li>Create/add any required sub-components to the component.
* </li><li>Create/install event listeners on the component.
* </li><li>Create/install a <code>PropertyChangeListener</code> on the component in order
* to detect and respond to component property changes appropriately.
* </li><li>Install keyboard UI (mnemonics, traversal, etc.) on the component.
* </li><li>Initialize any appropriate instance data.
* </li></ol>
* @param c The actual component.
*/
public void installUI( JComponent c )
{
printPreviewPane = ( PrintPreviewPane )c;
installDefaults();
installComponents();
installListeners();
}
/**
* Install default values for colors, fonts, borders, etc.
*/
public void installDefaults()
{
printPreviewPane.setLayout( createLayoutManager() );
}
/**
* Create and install any sub-components.
*/
public void installComponents()
{
printPreviewRenderer = new PrintPreviewRenderer();
scrollPane = new JScrollPane( printPreviewRenderer );
scrollPane.getVerticalScrollBar().setUnitIncrement(20);
printPreviewPane.add( scrollPane, BorderLayout.CENTER );
}
/**
* Install any action listeners, mouse listeners, etc.
*/
public void installListeners()
{
printPreviewPane.addChangeListener( this );
}
/**
* Tear down and clean up.
*/
public void uninstallUI( JComponent c )
{
c.setLayout( null );
uninstallListeners();
uninstallComponents();
uninstallDefaults();
printPreviewPane = null;
}
public void uninstallDefaults()
{
}
/**
* Tear down and clean up.
*/
public void uninstallComponents()
{
printPreviewRenderer = null;
}
public void uninstallListeners()
{
printPreviewPane.removeChangeListener( this );
}
public void stateChanged( ChangeEvent event )
{
if ( printPreviewRenderer != null )
{
printPreviewRenderer.setSize( printPreviewRenderer.getPreferredSize() );
printPreviewRenderer.repaint();
}
}
/**
* @return a BorderLayout
*/
protected LayoutManager createLayoutManager()
{
return new BorderLayout();
}
/**
* Panel to display the print preview.
*/
public class PrintPreviewRenderer extends JPanel
{
public PrintPreviewRenderer()
{
//setBorder( new DropShadowBorder() );
}
/**
* @return current paper size
*/
public Dimension getPaperSize()
{
// get the paper size set by the user
PrintPreviewModel model = printPreviewPane.getModel();
if ( model != null )
{
PrintRequestAttributeSet attributes = model.getAttributes();
float zoomLevel = model.getZoomLevel();
Media media = ( Media )attributes.get( Media.class );
MediaSize mediaSize = null;
if ( media instanceof MediaSizeName )
{
MediaSizeName name = ( MediaSizeName )media;
mediaSize = MediaSize.getMediaSizeForName( name );
int units = MediaPrintableArea.INCH;
float dpi = 72 * zoomLevel;
float paperWidth = mediaSize.getX( units ) * dpi;
float paperHeight = mediaSize.getY( units ) * dpi;
Dimension newSize = new Dimension();
newSize.setSize( paperWidth, paperHeight );
OrientationRequested orientationRequested = ( OrientationRequested )attributes.get( OrientationRequested.class );
if ( OrientationRequested.LANDSCAPE.equals( orientationRequested ) || OrientationRequested.REVERSE_LANDSCAPE.equals( orientationRequested ) )
{
if ( paperWidth < paperHeight )
{
newSize.setSize( newSize.getHeight(), newSize.getWidth() );
}
}
return newSize;
}
// otherwise, use the default paper size
Paper paper = model.getPaper();
Dimension defaultSize = new Dimension( new Double( paper.getWidth() * zoomLevel ).intValue(), new Double( paper.getHeight() * zoomLevel ).intValue() );
return defaultSize;
}
return getSize();
}
// make the print preview be no larger than the view size
@Override
public Dimension getPreferredSize()
{
return getPaperSize();
}
@Override
public Dimension getMinimumSize()
{
return getPreferredSize();
}
public void paintComponent( Graphics gfx )
{
PrintPreviewModel model = printPreviewPane.getModel();
if ( model == null )
{
return;
}
super.paintComponent( gfx );
Dimension currentSize = getPaperSize();
double width = currentSize.getWidth();
double height = currentSize.getHeight();
// paint background white
gfx.setColor( Color.WHITE );
gfx.fillRect( 0, 0, new Double( width ).intValue(), new Double( height ).intValue() );
// print the page into this panel
updateModel();
model.setGraphics( gfx );
BufferPrinter1_7.printPage( model );
scrollPane.revalidate();
printPreviewPane.revalidate();
}
private void updateModel()
{
PrintPreviewModel pageFormat = printPreviewPane.getModel();
if ( pageFormat == null )
{
return;
}
// get the printable area from the attributes
PrintRequestAttributeSet attributes = pageFormat.getAttributes();
float zoomLevel = pageFormat.getZoomLevel();
MediaPrintableArea mpa = ( MediaPrintableArea )attributes.get( MediaPrintableArea.class );
int units = MediaPrintableArea.INCH;
double dpi = 72.0 * zoomLevel; // Paper uses 72 dpi
double x = ( double )mpa.getX( units ) * dpi;
double y = ( double )mpa.getY( units ) * dpi;
double w = ( double )mpa.getWidth( units ) * dpi;
double h = ( double )mpa.getHeight( units ) * dpi;
// apply the mpa dimensions to the paper and page format
Paper paper = new Paper();
Dimension paperSize = getPaperSize();
paper.setSize( paperSize.getWidth(), paperSize.getHeight() );
int orientation = PageFormat.PORTRAIT;
OrientationRequested or = ( OrientationRequested )attributes.get( OrientationRequested.class );
if ( OrientationRequested.LANDSCAPE.equals( or ) )
{
paper.setSize( paperSize.getHeight(), paperSize.getWidth() );
orientation = PageFormat.LANDSCAPE;
}
else
if ( OrientationRequested.REVERSE_LANDSCAPE.equals( or ) )
{
paper.setSize( paperSize.getHeight(), paperSize.getWidth() );
orientation = PageFormat.REVERSE_LANDSCAPE;
}
paper.setImageableArea( x, y, w, h );
pageFormat.setPaper( paper );
pageFormat.setOrientation( orientation );
}
}
}