# Druckerschacht wählen



## MScalli (2. Dez 2009)

Hi Leutz.
Ich habe vor ner langen Zeit schon mal an diesem Problem gesessen und es damals mehr oder weniger umgangen.
Nun komm ich da nicht mehr vorbei.
Es geht darum einen Druckauftrag(in meinem Beispiel zur vereinfachung irgend ein Bild) an einen bestimmten Schacht 
zu senden. Das Problem ist das ich Drucker mit ner masse Schächten habe und ich hier immer Wechseln muss.
Anbei mal ein kleines Beispiel das natürlich lauffähig ist.
Evtl. kann es mal einer bei sich ausprobieren und kommt auf eine Lösung..
Am besten wäre es wenn ich die 'Schachtnummern' verwenden könnte wie sie im Windows genommen werden.
Jede andere möglichkeit nehme ich aber auch 


```
import java.io.FileInputStream;

import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.MediaTray;

public class PrintTest1 {
  static public void main(String args[]) throws Exception {
    PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
    
    /**
     * Um diese Zeile geht es. -> pras.add((Attribute) MediaTray.BOTTOM);
     * Ich will/kann/darf nur aus den vorgegebenen Schächten auswählen
     * Aber es kann ja/wird ja mehr Schächte geben. 
     * Wie kann ich diese anzeigen/auswählen 
     * Zur auswahl stehen hier aber nur 
     * BOTTOM, ENVELOPE, LARGE_CAPACITY, MAUL, MANUAL, MIDDLE, SIDE UND TOP
     * Ich brauche dies in dem PrintRequestAttributeSet da ich mit JasperReports arbeite
     * und diese Klasse ohne Probleme verwendet werden kann.
     */
    pras.add((Attribute) MediaTray.);
    pras.add(new Copies(1));

    PrintService pss[] = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.GIF, pras);

    if (pss.length == 0){
      throw new RuntimeException("Kein Drucker-Service vorhanden.");
    }

    int selectedService = 0;
    for(int i = 0; i < pss.length; i++){
    	
    	//System.out.println("verfügbare Drucker :" + pss[i].getName());
    	
    	if(pss[i].getName().equals("HP LaserJet 5")){ // auswählen des Druckers 'HP LaserJet'
    		selectedService = i;
    	}
    }
    
    PrintService ps = pss[selectedService];
    System.out.println("ausgewählter Drucker(Service) :" + ps); 			// ausgabe -> 'Win32 Printer : HP LaserJet 5'
    System.out.println("ausgewählter Drucker(Drucker) :" + ps.getName()); 	// ausgabe -> 'HP LaserJet 5'

    DocPrintJob job = ps.createPrintJob();

    FileInputStream fin = new FileInputStream("C:\\Temp\\book.PNG");
    Doc doc = new SimpleDoc(fin, DocFlavor.INPUT_STREAM.GIF, null);

    //job.print(doc, pras);

    fin.close();
  }
}
```

Bitte helft mir den ich bin letztes mal schon verzweifelt und bin jetzt auch kurz davor


----------



## max40 (2. Dez 2009)

Warum darf/will/muss nur aus diesen vorgegebenen Schächten gewählt werden?
Für mal folgendes aus, dieser gibt dir zu jedem Drucker die MediaSize, MediaTray etc aus!
Da schau mal bei deinem Drucker welche Trays es gibt, und teste mit denen!


```
final HashPrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
		final PrintService[] printService = 
			PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.AUTOSENSE, pras);
		
		for (int i = 0, l = printService.length; i < l; i++){
			final PrintService service = printService[i];
			System.out.println(service.getName());
			final Media med[] = (Media[])service.getSupportedAttributeValues(Media.class, null, null);
			for (int k=0; k<med.length; k++) {
				System.out.println("Name : " + med[k].getClass()
						+ " - Value : " + med[k].getValue());
			}	
			System.out.println("===============================================");
		}
```


----------



## MScalli (2. Dez 2009)

also die ausgabe an dem Drucker den ich gerade teste wär die

===============================================
HP LaserJet 5
Name : class javax.print.attribute.standard.MediaSizeName - Value : 40
Name : class javax.print.attribute.standard.MediaSizeName - Value : 41
Name : class javax.print.attribute.standard.MediaSizeName - Value : 42
Name : class javax.print.attribute.standard.MediaSizeName - Value : 4
Name : class javax.print.attribute.standard.MediaSizeName - Value : 5
Name : class javax.print.attribute.standard.MediaSizeName - Value : 60
Name : class javax.print.attribute.standard.MediaSizeName - Value : 55
Name : class javax.print.attribute.standard.MediaSizeName - Value : 38
Name : class javax.print.attribute.standard.MediaSizeName - Value : 16
Name : class javax.print.attribute.standard.MediaSizeName - Value : 57
Name : class sun.print.Win32MediaTray - Value : 5
Name : class sun.print.Win32MediaTray - Value : 7
Name : class javax.print.attribute.standard.MediaTray - Value : 0
Name : class javax.print.attribute.standard.MediaTray - Value : 4
Name : class javax.print.attribute.standard.MediaTray - Value : 2
Name : class javax.print.attribute.standard.MediaTray - Value : 3
Name : class javax.print.attribute.standard.MediaTray - Value : 5


Leider haben wir kunden die Drucker mit ewig vielen Schächten haben und in jedem Schacht ist ein anderes Formular.
Je nach gewolltem Formular muss jetzt ein Schacht ausgewählt werden..
z.B. 
Schacht 1 -> Anschreiben
Schacht 2 -> Rechnung
Schacht 3 -> Lieferschein 
.... und und und..


Wie könnte ich z.B. an diesem Drucker, der jetzt paar mehr Schächte hat, einen bestimmten wählen
===============================================
HP CLJ 3800
Name : class javax.print.attribute.standard.MediaSizeName - Value : 40
Name : class javax.print.attribute.standard.MediaSizeName - Value : 41
Name : class javax.print.attribute.standard.MediaSizeName - Value : 45
Name : class javax.print.attribute.standard.MediaSizeName - Value : 42
Name : class javax.print.attribute.standard.MediaSizeName - Value : 3
Name : class javax.print.attribute.standard.MediaSizeName - Value : 4
Name : class javax.print.attribute.standard.MediaSizeName - Value : 5
Name : class javax.print.attribute.standard.MediaSizeName - Value : 26
Name : class javax.print.attribute.standard.MediaSizeName - Value : 27
Name : class javax.print.attribute.standard.MediaSizeName - Value : 51
Name : class javax.print.attribute.standard.MediaSizeName - Value : 60
Name : class javax.print.attribute.standard.MediaSizeName - Value : 55
Name : class javax.print.attribute.standard.MediaSizeName - Value : 38
Name : class javax.print.attribute.standard.MediaSizeName - Value : 16
Name : class javax.print.attribute.standard.MediaSizeName - Value : 57
Name : class javax.print.attribute.standard.MediaSizeName - Value : 49
Name : class javax.print.attribute.standard.MediaSizeName - Value : 46
Name : class sun.print.Win32MediaSize - Value : 130
Name : class sun.print.Win32MediaSize - Value : 131
Name : class sun.print.Win32MediaSize - Value : 132
Name : class sun.print.Win32MediaTray - Value : 5
Name : class sun.print.Win32MediaTray - Value : 9
Name : class sun.print.Win32MediaTray - Value : 10
Name : class sun.print.Win32MediaTray - Value : 11
Name : class sun.print.Win32MediaTray - Value : 12
Name : class sun.print.Win32MediaTray - Value : 13
Name : class sun.print.Win32MediaTray - Value : 14
Name : class sun.print.Win32MediaTray - Value : 15
Name : class sun.print.Win32MediaTray - Value : 16
Name : class sun.print.Win32MediaTray - Value : 17
Name : class sun.print.Win32MediaTray - Value : 18
Name : class sun.print.Win32MediaTray - Value : 19
Name : class sun.print.Win32MediaTray - Value : 20
Name : class sun.print.Win32MediaTray - Value : 21
Name : class sun.print.Win32MediaTray - Value : 22
Name : class sun.print.Win32MediaTray - Value : 23
Name : class sun.print.Win32MediaTray - Value : 24
Name : class sun.print.Win32MediaTray - Value : 25
Name : class sun.print.Win32MediaTray - Value : 26
Name : class sun.print.Win32MediaTray - Value : 27
Name : class sun.print.Win32MediaTray - Value : 28
Name : class sun.print.Win32MediaTray - Value : 29
Name : class sun.print.Win32MediaTray - Value : 30
Name : class sun.print.Win32MediaTray - Value : 31
Name : class sun.print.Win32MediaTray - Value : 32
Name : class sun.print.Win32MediaTray - Value : 33

ich habe jetzt hier zwar einige MediaTrays stehen... Aber wie verwende ich eben diese ?!?!?


----------



## max40 (2. Dez 2009)

Versuch es mal mit 

```
pras.add((Attribute) new MediaTray(1){});
```
und ersetzt 1 mit den Werten die du bislang noch nicht hattest und guck was dabei passiert!
Was anderes fällt mir dazu auch nicht gerade ein und ich kann es auch momentan nicht selber testen!


----------



## MScalli (3. Dez 2009)

Geht leider nicht so. 
Wär auch zu schön um so einfach zu sein 

bekomme diese Fehlermeldung

```
Exception in thread "main" java.lang.RuntimeException: Kein Drucker-Service vorhanden.
	at PrintTest1.main(PrintTest1.java:26)
```


----------



## FArt (3. Dez 2009)

Ich habe eine gute und eine schlechte Nachricht.
Die gute Nachricht: genau dieses Problem hatten wir auch und haben es gelöst.
Die schlechte Nachricht: es blieb uns nichts anderes übrig als die PrinterJob-Implementierung zu patchen und über den Endorsed-Mechanismus zur Laufzeit einzubinden.


----------



## MScalli (3. Dez 2009)

omg.. ich versteh ehrlich gesagt nur bahnhof!!!
Da weiss ich ehrlich gesagt nicht mal wo ich anfangen soll.
Printer-Job Patchen?!!??
Endorsed Mechanismus?!?!?

kannst mir bisschen mehr infos geben?


Ich hatte bis jetzt nur die Idee einfach den selben Drucker mehrmals zu installieren(für jeden Schacht 1 mal) und dann eben den 'anderen' Drucker anzusprechen.
Ich dachte nur es kann ja net sein das gerade Java das nicht kann!

gruss
MScalli


----------



## FArt (3. Dez 2009)

patchen: Klasse nach eigenen Bedürfnissen anpassen
endorsed Mechanismus: JDK 1.4.2 Java Endorsed Standards-related APIs & Developer Guides -- from Sun Microsystems

Den Drucker mehrfach zu installieren war in unserer Umgebung so nicht möglich, auf jeden Fall keine Option (wenn es klappt) ;-)


----------



## Onkel Hatti (6. Dez 2009)

Moinsen

Ich hab das Beispiel dieses Threads mal umgeändert und folgendes gemacht.

```
import java.io.FileInputStream;
 
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.MediaTray;
import javax.print.attribute.standard.Media;
import sun.print.Win32MediaTray;
 
public class PrintTest1 {
  static public void main(String args[]) throws Exception {
	  
	Win32MediaTray wmtray=null;
    PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();

    final HashPrintRequestAttributeSet pras1 = new HashPrintRequestAttributeSet();
    final PrintService[] printService = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.AUTOSENSE, pras1);
    
    for (int i = 0, l = printService.length; i < l; i++){
        final PrintService service = printService[i];
        System.out.println(service.getName());
        final Media med[] = (Media[])service.getSupportedAttributeValues(Media.class, null, null);
        for (int k=0; k<med.length; k++) {
            System.out.println("Name : " + med[k].getClass()
                    + " - Value : " + med[k].getValue());
            if(service.getName().equals("Canon iP4300"))
            {
            	if(med[k].getValue()==9)
            	{
            		wmtray=(Win32MediaTray)med[k];
            	}
            }
        }   
        System.out.println("===============================================");
    }
    /**
     * Um diese Zeile geht es. -> pras.add((Attribute) MediaTray.BOTTOM);
     * Ich will/kann/darf nur aus den vorgegebenen Schächten auswählen
     * Aber es kann ja/wird ja mehr Schächte geben. 
     * Wie kann ich diese anzeigen/auswählen 
     * Zur auswahl stehen hier aber nur 
     * BOTTOM, ENVELOPE, LARGE_CAPACITY, MAUL, MANUAL, MIDDLE, SIDE UND TOP
     * Ich brauche dies in dem PrintRequestAttributeSet da ich mit JasperReports arbeite
     * und diese Klasse ohne Probleme verwendet werden kann.
     */
    pras.add((Attribute)wmtray);
    pras.add(new Copies(1));
 
    PrintService pss[] = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.GIF, pras);
 
    if (pss.length == 0){
      throw new RuntimeException("Kein Drucker-Service vorhanden.");
    }
 
    int selectedService = 0;
    for(int i = 0; i < pss.length; i++){
        
        //System.out.println("verfügbare Drucker :" + pss[i].getName());
        
        if(pss[i].getName().equals("Canon iP4300")){ // auswählen des Druckers 'Canon IP4300'
            selectedService = i;
        }
    }
    
    PrintService ps = pss[selectedService];
    System.out.println("ausgewählter Drucker(Service) :" + ps);             // ausgabe -> 'Win32 Printer : HP LaserJet 5'
    System.out.println("ausgewählter Drucker(Drucker) :" + ps.getName());   // ausgabe -> 'HP LaserJet 5'
 
    DocPrintJob job = ps.createPrintJob();
 
    FileInputStream fin = new FileInputStream("d:\\Tmp\\book.PNG");
    Doc doc = new SimpleDoc(fin, DocFlavor.INPUT_STREAM.GIF, null);
 
    job.print(doc, pras);
 
    fin.close();
  }
}
```

Ich hab nur nen Canon IP4300 aber mit obigem Beispiel hat er mir das Bild in den Kassettenschacht gedruckt.
Vielleicht geht das ja so? Mein Canon hat nicht so viele Schächte...

Hatti


----------



## MScalli (7. Dez 2009)

Hab jetzt ewig rum probiert aber so geht es nicht.. leider..
bei diesen Werten..

HP LaserJet 5
Name : class javax.print.attribute.standard.MediaSizeName - Value : 40	-na-letter
Name : class javax.print.attribute.standard.MediaSizeName - Value : 41	-na-legal
Name : class javax.print.attribute.standard.MediaSizeName - Value : 42	-executive
Name : class javax.print.attribute.standard.MediaSizeName - Value : 4	-iso-a4
Name : class javax.print.attribute.standard.MediaSizeName - Value : 5	-iso-a5
Name : class javax.print.attribute.standard.MediaSizeName - Value : 60	-na-number-10-envelope
Name : class javax.print.attribute.standard.MediaSizeName - Value : 55	-iso-designated-long
Name : class javax.print.attribute.standard.MediaSizeName - Value : 38	-iso-c5
Name : class javax.print.attribute.standard.MediaSizeName - Value : 16	-iso-b5
Name : class javax.print.attribute.standard.MediaSizeName - Value : 57	-monarch-envelope
Name : class sun.print.Win32MediaTray - Value : 5	-Form-Source
Name : class sun.print.Win32MediaTray - Value : 8	-Automatische Auswahl
Name : class javax.print.attribute.standard.MediaTray - Value : 0	-top
Name : class javax.print.attribute.standard.MediaTray - Value : 4	-manual
Name : class javax.print.attribute.standard.MediaTray - Value : 2	-bottom
Name : class javax.print.attribute.standard.MediaTray - Value : 3	-envelope
Name : class javax.print.attribute.standard.MediaTray - Value : 5	-large-capacity

kann ich z.B. nur Value 8 ansprechen. bei den anderen bekomme ich immer die exception:

```
java.lang.ClassCastException: javax.print.attribute.standard.MediaSizeName cannot be cast to sun.print.Win32MediaTray
```

auch wenn ich hier 5 nehme... was eigentlich gehen müsste.
Irgendwie will das einfach nicht!!
Trotzdem schon mal vielen vielen dank für deine Bemühung Onkel Hatti..
vielleicht kommen wir zusammen ja noch auf ne lösung 
denn irgendwie hab ich im netzt NICHTS gefunden was dies einfach lösen würde.

gruss
MScalli


----------



## Onkel Hatti (7. Dez 2009)

Rein theoretisch schon, aber wenn du z.B. 5 nimmst und mal in deine schneidige Liste reinschaust, dann kommt noch mal nen MediaSizeName vor dem Win32MediaTray mit dem Value 5.
Und dann kommt natürlich obige Exception, weil das casten nicht geht.
Das war von mir jetzt grad nen schneller Hack, es sollte natürlich vor dem ungefragten casten noch ein Test stattfinden, ob es sich bei dem Attributeintrag auch wirklich um ein Attribut der Klasse Win32MediaTray handelt.

Hatti


----------

