на главную обучение сертификация статьи литература ссылки гостевая книга
  Список статей Оглавление Текст статьи  

Печать документов на принтере в Java

Автор:Качалов Михаил Викторович
Создан:07.05.2002


4. Печать документов с помощью Java 1.2 API

   В JDK версий 1.2 компания Sun существенно расширила набор классов для печати. Эти классы сосредоточенны в пакете java.awt.print.*. В этом же пакете находятся классы описывающие исключительные ситуации, возникающие при печати. Кроме того, для формирования изображения выводимого на печать, программист может использовать методы класса java.awt.Graphics2D более мощные и эффективные для формирования двумерной графики, чем методы класса Graphics.    При печати документа в Java 1.2 API используется подход сходный с Java 1.0 API. Для того, чтобы распечать документ нобходимо выполнить следующие шаги:
  1. Получить ссылку на системный принтер
  2. Сформировать изображение для печати
  3. Распечатать подготовленное изображение
   В качестве объекта использующегося для связи с системным принтером используется объект типа java.awt.print.PrinterJob. Ссылку на объект экземпляр класса PrinterJob можно получить с помощью статического метода этого же класса public static PrinterJob getPrinterJob(). Такое действие может выглядеть следующим образом:
	PrinterJob printerJob=PrinterJob.getPrinterJob();
   В случае, если в операционной системе компьютера на котором запускается программа принтер по умолчанию не установлен, метод getPrinterJob() вернет значение null. В отличие от ранее рассмотреного примера печати, при получении ссылки на объект связаный с принтером диалоговое окно не появляется. Для получения соответствующего диалога необходимо явно вызвать метод класса PrinterJob: public boolean printDialog().
Такое действие может выглядеть следующим образом:
	if(printerJob.printDialog()){
		печатаем документ
	}
   Этот метод возвращает булевское значение true в случае если пользователь нажал подтверждающую кнопку в окне диалога, а также в случае если работа ведется в неграфическом режиме и диалоговое окно не может быть выведено на экран. В Java 1.4 API существует аналогичный перегруженый метод, который позволяет выставлять начальные значения в настройках принтера. Необходимые настройки также можно передать позже при печати.

   Изображение для печати в API 1.2 формируется несколько иначе, чем в предыдущих версиях Java. Для формирования изображения необходимо создать класс реализующий интерфейс java.awt.print.Printable. От этого интерфейса создаваемый класс наследует единственный абстрактный метод public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException. Переопределяя этот метод программист собственно и определяет, что именно будет печататься принтером. Данный метод получает от вызывающей его программы ссылку на графический контекст принтера, рисуя на котором мы определяем изображение, выводимое на принтер. Объект типа Graphics передаваемый методу print() в качестве аргумента также реализует интерфейс java.awt.print.PrinterGraphics и соответвенно метод описаный в этом интерфейсе public PrinterJob getPrinterJob(), который позволяет внутри метода print() получить ссылку на объект типа PrinterJob.
   Помимо ссылки на графический контекст принтера метод print() также получает ссылку на объект типа java.awt.print.PageFormat, позволяющий получить информацию о размерах области печати (с учетом или без учета полей принтера) и ориентации бумаги, выбраной в настройках принтера.
   Третий аргумент получаемый методом print() - номер страницы для печати. Отсчет страниц ведется от 0. В случае если запрашиваемая страница может быть сформирована методом print() он должен вернуть целочисленную константу Printable.PAGE_EXISTS, в противном случае, если метод print() не может сформировать указанную страницу, он должен вернуть значение Printable.NO_SUCH_PAGE.
   Ниже приводится пример класса формирующего изображения страниц для печати. Этот класс позволит распечатать 2 страницы отобразив на них их номера (исходный текст класса PageImage.java):
class PageImage implements Printable{
	
	public int print(Graphics g, PageFormat pf, int pageNumber)
	  throws PrinterException{
		if(pageNumber>1){
			return(Printable.NO_SUCH_PAGE);
		}else{
			g.drawString("Page "+(pageNumber+1),150,150);
		}
		return(Printable.PAGE_EXISTS);
	}
	
}
   При формировании изображения большое значение имеют его размеры, если изображение не попадает в область печати, то принтер не выполняет задание! Причем поля изначально установленные для документа отличаются от размеров полей системного принтера.
Область печати документа

   Для определения области печати и орентации листа необходимо воспользоваться методами объекта типа PageFormat:

public double getHeight() возвращает полную высоту листа в пикселах из расчета 72 пиксела на дюйм
public double getWidth() возвращает полную ширину листа в пикселах из расчета 72 пиксела на дюйм
public double getImageableHeight() возвращает высоту области печати в пикселах из расчета 72px/in
public double getImageableWidth() возвращает ширину области печати в пикселах из расчета 72px/in
public double getImageableX() смещение по горизонтали левого верхнего угла обасти печати относительно левого верхнего угла листа
public double getImageableY() смещение по вертикали левого верхнего угла обасти печати относительно левого верхнего угла листа
public int getOrientation() возвращает ориентацию листа в виде целочисленной константы: PageFormat.PORTRAIT, PageFormat.LANDSCAPE, PageFormat.REVERSE_LANDSCAPE (начало координат находится в правом-верхнем углу листа, в книжной ориентации, положительное горизонтальное направление справа на лево, а положительное вертикальное направление сверху вниз)

   Также в классе PageFormat существуют методы для смены текущих настроек принтера, например смены ориентации листа и других настроек принтера при помощи вспомогательного класса java.awt.print.Paper.

   После описания класса формирующего изображение для печати, необходимо связать его с принтером и отпечатать создаваемый в нем документ. Для связывания принтера с объектом типа Printable, формирующим изображение для печати, в классе PrinterJob существует метод public void setPrintable(Printable painter), а для печати документа используется метод public void print() throws PrinterException того же класса. Таким образом для печати документа можно использовать следующий код:
	printerJob.setPrintable(new PageImage());
	try{
		printerJob.print();
		Thread.sleep(1000);
	}catch(Exception e){
		System.err.println(e.getMessage());
	}
   Временная задержка в 1 сек использована на случай, если операционная система в которой выполняется программа не сразу поставит задание в очередь на печать. При работе этого кода никаких окон появляться не будет и программа реализованная в примере J2SimplePrinting.java просто распечатает на принтере две страницы, сформированные в классе PageImage. Часто при написании подобных программ класс осуществляющий печать документа реализует в себе интерфейс Printable и переопределяет унаследованый метод print(), при этом программа получается более компактной.

   Для формирования изображения можно использовать не только методы класса Graphics, но и воспользоваться возможностями класса Graphics2D. Для этого при переопределении метода print(), унаследованного от интерфейса Printable, необходимо осуществить явное преобразование типов:
	Graphics2D graphics2d=(Graphics2D)graphics;
   При этом программист получает мощнейшие возможности по формированию графики для печати с помощью методов класса Graphics2D, например:
public int print(Graphics g, PageFormat pf, int pageNumber)
   throws PrinterException {
	if(pageNumber>0){
		return(Printable.NO_SUCH_PAGE);
	}else{
		Graphics2D g2=(Graphics2D)g;
		g2.setFont(new Font("Courier",Font.BOLD,35));
		g2.setPaint(new GradientPaint(50f,100f,Color.red,
			250f,100f,Color.blue));
		g2.drawString("Hello Java 2D",50f,100f);
		return(Printable.PAGE_EXISTS);   
	}
}
   В примере J2CoolPrinting.java были реализованы подобные действия. Результат работы этого примера представлен ниже:

Использование библиотек Java 2D


   Все вышеописанные примеры приложений иллюстрируют возможность Java 1.2 API осуществлять печать в неграфическом (консольном) режиме. При необходимости программист может вызвать стандартные диалоги операционной системы. Выше уже описывалось использования метода printDialog() класса PrinterJob, вызывающего диалоговое окно настроек принтера. Кроме этого метода, можно обратиться к методу public PageFormat pageDialog(PageFormat page) класса PrinterJob, открывающему диалог настроек свойств страницы.

Диалог свойств страницы (ОС Windows 98)

   Для того, вызвать это диалоговое окно и воспользоваться выбраными в нем настройками, в приложении необходимо выполнить следующий код:
	PrinterJob printerJob=PrinterJob.getPrinterJob();
	PageFormat pageFormat=printerJob.defaultPage();
	pageFormat=printerJob.pageDialog(pageFormat);
	printerJob.setPrintable(объект типа Printable,pageFormat);
   При вызове метода pageDialog() мы передаем ему начальные значения настроек свойств страницы, которые хранятся в виде обеъкта типа PageFormat. В данном случае с помощью метода defaultPage() класса PrinterJob создаются настройки страницы по умолчанию, соответствующие размеру бумаги, установленному по умолчанию для принтера. Чтобы сохранить настройки выбранные пользователем в диалоговом окне, объект типа PageFormat передается при вызове метода setPrintable() как дополнительный аргумент. Пример реализующий использование диалоговых окон операционной системы: J2DialogPrinting.java.


назад оглавление дальше