SWT Jface Eclipse Java

/*******************************************************************************
 * All Right Reserved. Copyright (c) 1998, 2004 Jackwind Li Guojie
 * 
 * Created on 2004-5-2 14:57:37 by JACK $Id$
 *  
 ******************************************************************************/
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.printing.PrintDialog;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.printing.PrinterData;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
public class SWTImageViewer {
  Display display = new Display();
  Shell shell = new Shell(display);
  Canvas canvas;
  Image image;
  String fileName;
  public SWTImageViewer() {
    shell.setText("Image viewer");
    shell.setLayout(new GridLayout(1, true));
    ToolBar toolBar = new ToolBar(shell, SWT.FLAT);
    ToolItem itemOpen = new ToolItem(toolBar, SWT.PUSH);
    itemOpen.setText("Open");
    itemOpen.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event event) {
        FileDialog dialog = new FileDialog(shell, SWT.OPEN);
        String file = dialog.open();
        if (file != null) {
          if (image != null)
            image.dispose();
          image = null;
          try {
            image = new Image(display, file);
          } catch (RuntimeException e) {
            // e.printStackTrace();
          }
          if (image != null) {
            fileName = file;
          } else {
            System.err.println(
              "Failed to load image from file: " + file);
          }
          canvas.redraw();
        }
      }
    });
    ToolItem itemPrintPreview = new ToolItem(toolBar, SWT.PUSH);
    itemPrintPreview.setText("Preview");
    itemPrintPreview.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event event) {
        ImagePrintPreviewDialog dialog =
          new ImagePrintPreviewDialog(ImageViewer.this);
        dialog.open();
      }
    });
    ToolItem itemPrint = new ToolItem(toolBar, SWT.PUSH);
    itemPrint.setText("Print");
    itemPrint.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event event) {
        print();
      }
    });
    canvas = new Canvas(shell, SWT.BORDER);
    canvas.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
    canvas.setLayoutData(new GridData(GridData.FILL_BOTH));
    canvas.addPaintListener(new PaintListener() {
      public void paintControl(PaintEvent e) {
        if (image == null) {
          e.gc.drawString("No image", 0, 0);
        } else {
          e.gc.drawImage(image, 0, 0);
        }
      }
    });
    image = new Image(display, "rntsoft.gif");
    fileName = "scene.jpg";
    shell.setSize(500, 400);
    shell.open();
    //textUser.forceFocus();
    // Set up the event loop.
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch()) {
        // If no more entries in event queue
        display.sleep();
      }
    }
    display.dispose();
  }
  /**
   * Lets the user to select a printer and prints the image on it.
   *  
   */
  void print() {
    PrintDialog dialog = new PrintDialog(shell);
    // Prompts the printer dialog to let the user select a printer.
    PrinterData printerData = dialog.open();
    if (printerData == null) // the user cancels the dialog
      return;
    // Loads the printer.
    Printer printer = new Printer(printerData);
    print(printer, null);
  }
  /**
   * Prints the image current displayed to the specified printer.
   * 
   * @param printer
   */
  void print(final Printer printer, PrintMargin printMargin) {
    if (image == null) // If no image is loaded, do not print.
      return;
    final Point printerDPI = printer.getDPI();
    final Point displayDPI = display.getDPI();
    System.out.println(displayDPI + " " + printerDPI);
    
    final PrintMargin margin = (printMargin == null ?  PrintMargin.getPrintMargin(printer, 1.0) : printMargin);
    Thread printThread = new Thread() {
      public void run() {
        if (!printer.startJob(fileName)) {
          System.err.println("Failed to start print job!");
          printer.dispose();
          return;
        }
        GC gc = new GC(printer);
        if (!printer.startPage()) {
          System.err.println("Failed to start a new page!");
          gc.dispose();
          return;
        } else {
          int imageWidth = image.getBounds().width;
          int imageHeight = image.getBounds().height;
          // Handles DPI conversion.
          double dpiScaleFactorX = printerDPI.x * 1.0 / displayDPI.x;
          double dpiScaleFactorY = printerDPI.y * 1.0 / displayDPI.y;
          // If the image is too large to draw on a page, reduces its
          // width and height proportionally.
          double imageSizeFactor =
            Math.min(
              1,
              (margin.right - margin.left)
                * 1.0
                / (dpiScaleFactorX * imageWidth));
          imageSizeFactor =
            Math.min(
              imageSizeFactor,
              (margin.bottom - margin.top)
                * 1.0
                / (dpiScaleFactorY * imageHeight));
          // Draws the image to the printer.
          gc.drawImage(
            image,
            0,
            0,
            imageWidth,
            imageHeight,
            margin.left,
            margin.top,
            (int) (dpiScaleFactorX * imageSizeFactor * imageWidth),
            (int) (dpiScaleFactorY
              * imageSizeFactor
              * imageHeight));
          gc.dispose();
        }
        printer.endPage();
        printer.endJob();
        printer.dispose();
        System.out.println("Printing job done!");
      }
    };
    printThread.start();
  }
  public static void main(String[] args) {
    new SWTImageViewer();
  }
}
class ImagePrintPreviewDialog extends Dialog {
  ImageViewer viewer;
  Shell shell;
  Canvas canvas;
  Printer printer;
  PrintMargin margin;
  Combo combo;
  public ImagePrintPreviewDialog(ImageViewer viewer) {
    super(viewer.shell);
    this.viewer = viewer;
  }
  public void open() {
    shell =
      new Shell(
        viewer.shell,
        SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE);
    shell.setText("Print preview");
    shell.setLayout(new GridLayout(4, false));
    final Button buttonSelectPrinter = new Button(shell, SWT.PUSH);
    buttonSelectPrinter.setText("Select a printer");
    buttonSelectPrinter.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event event) {
        PrintDialog dialog = new PrintDialog(shell);
        // Prompts the printer dialog to let the user select a printer.
        PrinterData printerData = dialog.open();
        if (printerData == null) // the user cancels the dialog
          return;
        // Loads the printer.
        final Printer printer = new Printer(printerData);
        setPrinter(
          printer,
          Double.parseDouble(
            combo.getItem(combo.getSelectionIndex())));
      }
    });
    new Label(shell, SWT.NULL).setText("Margin in inches: ");
    combo = new Combo(shell, SWT.READ_ONLY);
    combo.add("0.5");
    combo.add("1.0");
    combo.add("1.5");
    combo.add("2.0");
    combo.add("2.5");
    combo.add("3.0");
    combo.select(1);
    combo.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event event) {
        double value =
          Double.parseDouble(
            combo.getItem(combo.getSelectionIndex()));
        setPrinter(printer, value);
      }
    });
    final Button buttonPrint = new Button(shell, SWT.PUSH);
    buttonPrint.setText("Print");
    buttonPrint.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event event) {
        if (printer == null)
          viewer.print();
        else
          viewer.print(printer, margin);
        shell.dispose();
      }
    });
    canvas = new Canvas(shell, SWT.BORDER);
    GridData gridData = new GridData(GridData.FILL_BOTH);
    gridData.horizontalSpan = 4;
    canvas.setLayoutData(gridData);
    canvas.addPaintListener(new PaintListener() {
      public void paintControl(PaintEvent e) {
        int canvasBorder = 20;
        if (printer == null || printer.isDisposed())
          return;
        Rectangle rectangle = printer.getBounds();
        Point canvasSize = canvas.getSize();
        double viewScaleFactor =
          (canvasSize.x - canvasBorder * 2) * 1.0 / rectangle.width;
        viewScaleFactor =
          Math.min(
            viewScaleFactor,
            (canvasSize.y - canvasBorder * 2)
              * 1.0
              / rectangle.height);
        int offsetX =
          (canvasSize.x - (int) (viewScaleFactor * rectangle.width))
            / 2;
        int offsetY =
          (canvasSize.y - (int) (viewScaleFactor * rectangle.height))
            / 2;
        e.gc.setBackground(
          shell.getDisplay().getSystemColor(SWT.COLOR_WHITE));
        // draws the page layout
        e.gc.fillRectangle(
          offsetX,
          offsetY,
          (int) (viewScaleFactor * rectangle.width),
          (int) (viewScaleFactor * rectangle.height));
        // draws the margin.
        e.gc.setLineStyle(SWT.LINE_DASH);
        e.gc.setForeground(
          shell.getDisplay().getSystemColor(SWT.COLOR_BLACK));
        int marginOffsetX =
          offsetX + (int) (viewScaleFactor * margin.left);
        int marginOffsetY =
          offsetY + (int) (viewScaleFactor * margin.top);
        e.gc.drawRectangle(
          marginOffsetX,
          marginOffsetY,
          (int) (viewScaleFactor * (margin.right - margin.left)),
          (int) (viewScaleFactor * (margin.bottom - margin.top)));
        if (viewer.image != null) {
          int imageWidth = viewer.image.getBounds().width;
          int imageHeight = viewer.image.getBounds().height;
          double dpiScaleFactorX =
            printer.getDPI().x
              * 1.0
              / shell.getDisplay().getDPI().x;
          double dpiScaleFactorY =
            printer.getDPI().y
              * 1.0
              / shell.getDisplay().getDPI().y;
          double imageSizeFactor =
            Math.min(
              1,
              (margin.right - margin.left)
                * 1.0
                / (dpiScaleFactorX * imageWidth));
          imageSizeFactor =
            Math.min(
              imageSizeFactor,
              (margin.bottom - margin.top)
                * 1.0
                / (dpiScaleFactorY * imageHeight));
          e.gc.drawImage(
            viewer.image,
            0,
            0,
            imageWidth,
            imageHeight,
            marginOffsetX,
            marginOffsetY,
            (int) (dpiScaleFactorX
              * imageSizeFactor
              * imageWidth
              * viewScaleFactor),
            (int) (dpiScaleFactorY
              * imageSizeFactor
              * imageHeight
              * viewScaleFactor));
        }
      }
    });
    shell.setSize(400, 400);
    shell.open();
    setPrinter(null, 1.0);
    // Set up the event loop.
    while (!shell.isDisposed()) {
      if (!shell.getDisplay().readAndDispatch()) {
        // If no more entries in event queue
        shell.getDisplay().sleep();
      }
    }
  }
  /**
   * Sets target printer.
   * 
   * @param printer
   */
  void setPrinter(Printer printer, double marginSize) {
    if (printer == null) {
      printer = new Printer(Printer.getDefaultPrinterData());
    }
    this.printer = printer;
    margin = PrintMargin.getPrintMargin(printer, marginSize);
    canvas.redraw();
  }
}
/**
 * Contains margin information (in pixels) for a print job.
 *  
 */
class PrintMargin {
  // Margin to the left side, in pixels
  public int left;
  //  Margins to the right side, in pixels
  public int right;
  //  Margins to the top side, in pixels
  public int top;
  //  Margins to the bottom side, in pixels
  public int bottom;
  private PrintMargin(int left, int right, int top, int bottom) {
    this.left = left;
    this.right = right;
    this.top = top;
    this.bottom = bottom;
  }
  /**
   * Returns a PrintMargin object containing the true border margins for the
   * specified printer with the given margin in inches.
   * Note: all four sides share the same margin width. 
   * @param printer
   * @param margin
   * @return
   */
  static PrintMargin getPrintMargin(Printer printer, double margin) {
    return getPrintMargin(printer, margin, margin, margin, margin);
  }
  /**
   * Returns a PrintMargin object containing the true border margins for the
   * specified printer with the given margin width (in inches) for each side.
   */
  static PrintMargin getPrintMargin(
    Printer printer,
    double marginLeft,
    double marginRight,
    double marginTop,
    double marginBottom) {
    Rectangle clientArea = printer.getClientArea();
    Rectangle trim = printer.computeTrim(0, 0, 0, 0);
    //System.out.println(printer.getBounds() + " - " + clientArea + "" +
    // trim);
    Point dpi = printer.getDPI();
    int leftMargin = (int) (marginLeft * dpi.x) - trim.x;
    int rightMargin =
      clientArea.width
        + trim.width
        - (int) (marginRight * dpi.x)
        - trim.x;
    int topMargin = (int) (marginTop * dpi.y) - trim.y;
    int bottomMargin =
      clientArea.height
        + trim.height
        - (int) (marginBottom * dpi.y)
        - trim.y;
    return new PrintMargin(
      leftMargin,
      rightMargin,
      topMargin,
      bottomMargin);
  }
  public String toString() {
    return "Margin { "
      + left
      + ", "
      + right
      + "; "
      + top
      + ", "
      + bottom
      + " }";
  }
}