org.jclarion.clarion.ClarionPrinter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of clarion-runtime Show documentation
Show all versions of clarion-runtime Show documentation
JClarion runtime environment
The newest version!
/**
* Copyright 2010, by Andrew Barnham
*
* The contents of this file are subject to
* GNU Lesser General Public License (LGPL), v.3
* http://www.gnu.org/licenses/lgpl.txt
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
*/
package org.jclarion.clarion;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import sun.print.ServiceDialog;
import sun.print.SunAlternateMedia;
import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.Fidelity;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.OrientationRequested;
import javax.swing.JButton;
import org.jclarion.clarion.constants.Icon;
import org.jclarion.clarion.constants.Prop;
import org.jclarion.clarion.constants.Propprint;
import org.jclarion.clarion.print.AWTPrintContext;
import org.jclarion.clarion.print.Page;
import org.jclarion.clarion.print.PageBook;
import org.jclarion.clarion.runtime.CRun;
import org.jclarion.clarion.runtime.CWin;
import org.jclarion.clarion.runtime.CWinImpl;
import org.jclarion.clarion.swing.ClarionEventQueue;
import org.jclarion.clarion.swing.gui.CommandList;
import org.jclarion.clarion.swing.gui.RemoteWidget;
import org.jclarion.clarion.swing.gui.RemoteTypes;
/**
* Model clarion printer
*
* @author barney
*
*/
public class ClarionPrinter extends PropertyObject implements RemoteWidget
{
private static ClarionPrinter instance;
private static Logger log = Logger.getLogger(ClarionPrinter.class.getName());
private static final long JOB_INACTIVE = 2l*60*60*1000; // if a job is inactive for two hours - then silently reset it
public static void main(String args[])
{
getInstance().getJob();
getInstance().printerDialog(Clarion.newString("test"),1);
for (Attribute a : getInstance().attr.toArray()) {
System.out.println(a);
}
}
/**
* Get instance of printer object
* @return
*/
public static ClarionPrinter getInstance()
{
if (instance==null) {
synchronized(ClarionPrinter.class) {
if (instance==null) {
instance=new ClarionPrinter();
CRun.addShutdownHook(new Runnable() {
public void run()
{
instance=null;
}
} );
}
}
}
return instance;
}
private PrintService[] services;
private PrintService service;
private PrintService defaultService;
private PrinterJob job;
private String lastJobError;
private long jobLastAccessed;
private PrintRequestAttributeSet attr;
public ClarionPrinter()
{
CWin.getInstance();
services=PrinterJob.lookupPrintServices();
defaultService=PrintServiceLookup.lookupDefaultPrintService();
if (getJob()!=null) {
setProperty(Propprint.DEVICE,getJob().getPrintService().getName());
}
}
@Override
public PropertyObject getParentPropertyObject() {
return null;
}
public static final int PRINTER_DIALOG=1;
public static final int START_PRINT_JOB=2;
public static final int SPOOL_PAGE=3;
@Override
public CommandList getCommandList() {
return CommandList.create()
.add("PRINTER_DIALOG",1)
.add("START_PRINT_JOB",2)
.add("SPOOL_PAGE",3)
;
}
@Override
public boolean isGuiCommand(int command)
{
switch(command) {
case START_PRINT_JOB:
case SPOOL_PAGE:
return false;
}
return true;
}
public int lastJob=0;
private Map jobs=new HashMap();
public void remove(int id)
{
synchronized(jobs) {
jobs.remove(id);
}
}
public Object command(int command,Object... params)
{
if (command==PRINTER_DIALOG) {
return doPrinterDialog((ClarionString)params[0],(Integer)params[1]);
}
if (command==START_PRINT_JOB) {
int id ;
synchronized(this) {
lastJob++;
id = lastJob;
}
PrinterJob pj = getJob();
if (pj==null) {
if (lastJobError==null) {
CWin.message(
Clarion.newString("Print Job Failed. Could not start print. Maybe Printer is offline?"),
Clarion.newString("Printer Error"),
Icon.EXCLAMATION);
} else {
CWin.message(
Clarion.newString("Print Job Failed. Could not start print. "+lastJobError),
Clarion.newString("Printer Error"),
Icon.EXCLAMATION);
}
return -1;
}
CurrentJob cj =new CurrentJob(id,pj,getAttribute(),(String)params[0],(Integer)params[1]);
this.job=null;
synchronized(jobs) {
jobs.put(id,cj);
}
cj.start();
return id;
}
if (command==SPOOL_PAGE) {
CurrentJob cj=null;
synchronized(jobs) {
cj=jobs.get((Integer)params[0]);
}
if (cj!=null) {
cj.spoolPage((Integer)params[1],(Page)params[2]);
}
return null;
}
return null;
}
public static class CurrentJob extends Thread implements Printable,Pageable
{
private PrintRequestAttributeSet att;
private PrinterJob job;
private Page pages[];
private ClarionApplication app;
private int status=0;
private int id;
public CurrentJob(int id,PrinterJob job,PrintRequestAttributeSet a,String name,int count)
{
this.id=id;
att=new HashPrintRequestAttributeSet();
att.addAll(a);
this.job=job;
this.job.setJobName(name);
pages=new Page[count];
}
public void spoolPage(int index,Page page) {
synchronized(pages) {
pages[index]=page;
pages.notifyAll();
}
}
@Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
if (app!=null) {
int percent = pageIndex*100/pages.length;
app.setProperty(Prop.STATUSTEXT,status,"Spooling "+percent+"%");
app.getStatusPane().notifyStatusChange();
}
if (pageIndex>=pages.length) return Printable.NO_SUCH_PAGE;
Page p = getPage(pageIndex);
p.print(new AWTPrintContext((Graphics2D)graphics));
return Printable.PAGE_EXISTS;
}
@Override
public int getNumberOfPages() {
return pages.length;
}
public Page getPage(int ofs)
{
synchronized(pages) {
while (pages[ofs]==null) {
try {
pages.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return pages[ofs];
}
}
@Override
public PageFormat getPageFormat(int pageIndex) throws IndexOutOfBoundsException {
Page p = getPage(pageIndex);
HashPrintRequestAttributeSet tattr=new HashPrintRequestAttributeSet();
tattr.addAll(att);
if (p.getLandscape()>0) {
tattr.add(OrientationRequested.LANDSCAPE);
} else {
tattr.add(OrientationRequested.PORTRAIT);
}
switch(p.getPaper()) {
case org.jclarion.clarion.constants.Paper.A4:
tattr.add(MediaSizeName.ISO_A4);
break;
case org.jclarion.clarion.constants.Paper.LEGAL:
tattr.add(MediaSizeName.NA_LEGAL);
break;
case org.jclarion.clarion.constants.Paper.LETTER:
tattr.add(MediaSizeName.NA_LETTER);
break;
case org.jclarion.clarion.constants.Paper.USER:
{
try {
tattr.add(new MediaSize(
(float)(p.getPaperWidth()*p.getXScale()),
(float)(p.getPaperHeight()*p.getYScale()),
MediaSize.INCH));
} catch (Exception ex) { }
break;
}
case 0:
break;
default:
}
PageFormat pf =job.getPageFormat(tattr);
if (pf.getImageableWidth()<=0) {
log.warning("PageFormat is invalid - using default attributes");
pf=job.getPageFormat(att);
if (pf.getImageableWidth()<=0) {
log.warning("PageFormat is invalid - using default page");
pf=job.getPageFormat(null);
}
}
return pf;
}
@Override
public Printable getPrintable(int pageIndex) throws IndexOutOfBoundsException {
return this;
}
@Override
public void run() {
try {
app = CWin.getInstance().getGuiApp();
if (app!=null) {
if (app.getStatusPane()==null) {
app=null;
}
}
if (app!=null) {
while ( true ) {
status++;
int w = app.getProperty(Prop.STATUS,status).intValue();
if (w==0) break;
}
app.setProperty(Prop.STATUS,status,150);
app.setProperty(Prop.STATUSTEXT,status,"Spooling...");
app.getStatusPane().notifyStatusChange();
}
PageFormat pf =job.getPageFormat(att);
if (pf.getImageableWidth()<=0) {
pf=job.getPageFormat(null);
}
if (pf.getImageableWidth()<=0) {
log.warning("PageFormat is invalid - printing without pageable setting");
PrintServiceAttributeSet pas = job.getPrintService().getAttributes();
if (pas!=null) {
for (Attribute a : pas.toArray()) {
log.info(a.getName()+" "+a.getCategory()+" "+a);
}
}
job.setPrintable(this);
} else {
job.setPageable(this);
}
try {
job.print(att);
} catch (PrinterException e) {
e.printStackTrace();
CWin.message(
Clarion.newString("Print Job Failed:"+e.getMessage()),
Clarion.newString("Printer Error"),
Icon.EXCLAMATION);
try {
job.print();
} catch (PrinterException e1) {
e1.printStackTrace();
CWin.message(
Clarion.newString("Print Job Failed On Retry:"+e.getMessage()),
Clarion.newString("Printer Error"),
Icon.EXCLAMATION);
}
}
if (app!=null) {
app.setProperty(Prop.STATUS,status,0);
}
} finally {
ClarionPrinter.getInstance().remove(id);
}
}
}
public void print(ClarionReport cr,PageBook book)
{
String name = "Clarion Print Job";
if (cr!=null) {
String newName = cr.getProperty(Prop.TEXT).toString().trim();
if (newName.length()>0) name=newName;
}
int count=0;
for (int scan=0;scan0) {
service=services[0];
}
if (service!=null) {
try {
job=PrinterJob.getPrinterJob();
job.setPrintService(service);
lastJobError=null;
} catch (PrinterException e) {
lastJobError=e.getMessage();
e.printStackTrace();
job=null;
}
}
if (attr==null) {
attr=new HashPrintRequestAttributeSet();
}
}
jobLastAccessed=System.currentTimeMillis();
return job;
}
public PrintService getService()
{
getJob();
return service;
}
public PrintRequestAttributeSet getAttribute()
{
getJob();
return attr;
}
public void __setAttribute_dead_code(PrintRequestAttributeSet printAttribute,PropertyObject report,float xscale,float yscale)
{
printAttribute = ClarionPrinter.getInstance().getAttribute();
if (report.isProperty(Prop.LANDSCAPE)) {
printAttribute.add(OrientationRequested.LANDSCAPE);
} else {
printAttribute.add(OrientationRequested.PORTRAIT);
}
int type = report.getProperty(Propprint.PAPER).intValue();
switch(type) {
case org.jclarion.clarion.constants.Paper.A4:
printAttribute.add(MediaSizeName.ISO_A4);
break;
case org.jclarion.clarion.constants.Paper.LEGAL:
printAttribute.add(MediaSizeName.NA_LEGAL);
break;
case org.jclarion.clarion.constants.Paper.LETTER:
printAttribute.add(MediaSizeName.NA_LETTER);
break;
case org.jclarion.clarion.constants.Paper.USER:
{
int pw=report.getProperty(Propprint.PAPERWIDTH).intValue();
int ph=report.getProperty(Propprint.PAPERHEIGHT).intValue();
try {
printAttribute.add(new MediaSize(
(float)(pw*72.0*xscale),
(float)(ph*72.0*yscale),
MediaSize.INCH));
} catch (Exception ex) { }
break;
}
case 0:
break;
default:
throw new IllegalStateException("Paper Type not supported");
}
}
@Override
protected void notifyLocalChange(int indx, ClarionObject value) {
if (indx==Propprint.DEVICE && job!=null && !value.toString().trim().equals(job.getPrintService().getName())) {
job=null;
}
super.notifyLocalChange(indx, value);
}
public void notePrintFailure(PrinterJob job)
{
if (job==this.job) {
this.job.cancel();
this.job=null;
}
}
@Override
public boolean isModalCommand(int command)
{
return true;
}
private String doPrinterDialog(final ClarionString title,final Integer mode)
{
Object lock=new Object();
ClarionEventQueue.getInstance().setRecordState(false,"Entering printDialog",lock);
PrintService ps = printDialog(title!=null?title.toString():null,
mode,null,50,50,services,
getJob()==null? null : getJob().getPrintService(),
null,getAttribute());
ClarionEventQueue.getInstance().setRecordState(true,"Exiting printDialog",lock);
if (ps==null) return null;
String name = ps.getName();
ClarionString cs = new ClarionString(name);
setProperty(Propprint.DEVICE,cs);
return name;
}
public boolean printerDialog(final ClarionString title,final Integer mode)
{
AbstractWindowTarget target = CWin.getWindowTarget();
if (target!=null) {
target.setActiveState(false);
}
String name = (String)CWinImpl.runNow(this,PRINTER_DIALOG,title,mode);
if (target!=null) {
target.setActiveState(true);
}
if (name!=null) {
setProperty(Propprint.DEVICE,name);
return true;
}
return false;
}
@SuppressWarnings({ "rawtypes" })
private PrintService printDialog(
String title,Integer mode,
GraphicsConfiguration gc, int x,
int y, PrintService[] services, PrintService defaultService,
DocFlavor flavor, PrintRequestAttributeSet attributes)
throws HeadlessException
{
int defaultIndex = -1;
if (defaultService != null) {
for (int i = 0; i < services.length; i++) {
if (services[i].equals(defaultService)) {
defaultIndex = i;
break;
}
}
if (defaultIndex < 0) {
defaultIndex=0;
}
} else {
defaultIndex = 0;
}
Window owner = null;
Rectangle gcBounds = (gc == null) ? GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice()
.getDefaultConfiguration().getBounds() : gc.getBounds();
ServiceDialog dialog;
if (owner instanceof Frame) {
dialog = new ServiceDialog(gc, x + gcBounds.x, y + gcBounds.y,
services, defaultIndex, flavor, attributes, (Frame) owner);
} else {
dialog = new ServiceDialog(gc, x + gcBounds.x, y + gcBounds.y,
services, defaultIndex, flavor, attributes, (Dialog) owner);
}
if (title!=null) dialog.setTitle(title);
if (mode!=null && mode==1) {
replace(dialog);
}
dialog.setVisible(true);
if (dialog.getStatus() == ServiceDialog.APPROVE) {
PrintRequestAttributeSet newas = dialog.getAttributes();
Class dstCategory = Destination.class;
Class amCategory = SunAlternateMedia.class;
Class fdCategory = Fidelity.class;
if (attributes.containsKey(dstCategory) && !newas.containsKey(dstCategory)) {
attributes.remove(dstCategory);
}
if (attributes.containsKey(amCategory) && !newas.containsKey(amCategory)) {
attributes.remove(amCategory);
}
attributes.addAll(newas);
Fidelity fd = (Fidelity) attributes.get(fdCategory);
if (fd != null) {
if (fd == Fidelity.FIDELITY_TRUE) {
removeUnsupportedAttributes(dialog.getPrintService(),flavor, attributes);
}
}
}
return dialog.getPrintService();
}
private void replace(Component dialog) {
if (dialog instanceof JButton) {
JButton b = (JButton)dialog;
if (b.getText().equals("Print")) b.setText("OK");
}
if (dialog instanceof Container) {
for ( Component child : ((Container)dialog).getComponents() ) {
replace(child);
}
}
}
/**
* Removes any attributes from the given AttributeSet that are
* unsupported by the given PrintService/DocFlavor combination.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private void removeUnsupportedAttributes(PrintService ps,
DocFlavor flavor,
AttributeSet aset)
{
AttributeSet asUnsupported = ps.getUnsupportedAttributes(flavor,
aset);
if (asUnsupported != null) {
Attribute[] usAttrs = asUnsupported.toArray();
for (int i=0; i getChildWidgets() {
return null;
}
private int id;
@Override
public int getID() {
return id;
}
@Override
public void setID(int id) {
this.id=id;
}
@Override
public void disposeWidget() {
}
@Override
public RemoteWidget getParentWidget()
{
return null;
}
@Override
public int getWidgetType() {
return RemoteTypes.PRINTER;
}
@Override
public void addWidget(RemoteWidget child) {
}
@Override
public Map getChangedMetaData() {
return null;
}
@Override
public void setMetaData(Map data) {
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy