diff --git a/src/main/java/com/jFxKasse/controller/MainWindowController.java b/src/main/java/com/jFxKasse/controller/MainWindowController.java index 07f9fdd..ac7da53 100644 --- a/src/main/java/com/jFxKasse/controller/MainWindowController.java +++ b/src/main/java/com/jFxKasse/controller/MainWindowController.java @@ -41,6 +41,7 @@ import com.jFxKasse.datatypes.Job; import com.jFxKasse.datatypes.tableDataCurrentOrder; import com.jFxKasse.datatypes.tableDataJob; import com.jFxKasse.datatypes.tableDataPositionen; +import com.jFxKasse.datatypes.PrintDataSimple; public class MainWindowController { @@ -565,6 +566,28 @@ public class MainWindowController currentJob.createPosCatDBString(), "verbucht", String.valueOf(currentJob.getJobValue())); + System.out.println(currentJob.getJobnumber()); + + PrinterController pc = new PrinterController(); + + pc.searchPrinters(); + + pc.selectPrinter("CUPS-PDF"); + + PrintDataSimple pds = new PrintDataSimple(28, 1, 2, + getSystemTime() + " " + getSystemDate(), "Firma GmbH", + "Vielen Dank für den Einkauf"); + + pds.setData(Integer.toString(currentJob.getJobnumber()), + dbc.getTime_Job(currentJob.getJobnumber()), + dbc.getQuantity_Job(currentJob.getJobnumber()), + dbc.getName_Job(currentJob.getJobnumber()), + dbc.getValue_Job(currentJob.getJobnumber()), + dbc.getCategory_Job(currentJob.getJobnumber()), + dbc.getJobValue_Job(currentJob.getJobnumber())); + + pc.printString(pds.getPrintString()); + fillTableJobs(); currentJob = null; diff --git a/src/main/java/com/jFxKasse/controller/PrinterController.java b/src/main/java/com/jFxKasse/controller/PrinterController.java new file mode 100644 index 0000000..e416870 --- /dev/null +++ b/src/main/java/com/jFxKasse/controller/PrinterController.java @@ -0,0 +1,141 @@ +/** + * some parts are from http://www.mets-blog.com/java-pos-thermal-printer-example/ + */ + +package com.jFxKasse.controller; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.nio.charset.StandardCharsets; + +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.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; + +public class PrinterController implements Printable +{ + // All available Printers on this system + private PrintService[] printService; + + // selected printer + private PrintService selectedPrinter; + + private DocFlavor flavor; + + public PrinterController() + { + flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE; + } + + /** + * @return A String array with all available printers + */ + public String[] getAvailablePrinters() + { + int printerSize = PrinterJob.lookupPrintServices().length; + String printers[] = new String[printerSize]; + + for (int i = 0; i < printers.length; i++) { + printers[i] = this.printService[i].getName(); + } + return printers; + } + + /** + * searchs connected printers on the system + */ + public void searchPrinters() + { + PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet(); + this.printService = PrintServiceLookup.lookupPrintServices(flavor, pras); + String printers[] = getAvailablePrinters(); + System.out.println("Printers found:"); + System.out.println("++++++++++++++++++++"); + for (int i = 0; i < printers.length; i++) { + System.out.println(printers[i]); + } + System.out.println("++++++++++++++++++++"); + } + + /** + * Selects the printer via its name + * @param printerName + */ + public void selectPrinter(String printerName) + { + String printers[] = getAvailablePrinters(); + + for (int i = 0; i < printers.length; i++) { + if (printerName.equals(printers[i])) { + selectedPrinter = printService[i]; + System.out.println("Printer: " + printers[i] + " selected"); + return; + } + } + } + + /** + * + * @param input data as String + */ + public void printString(String text) + { + + PrintService service = selectedPrinter; + DocPrintJob job = service.createPrintJob(); + + try { + byte[] bytes; + bytes = text.getBytes(StandardCharsets.UTF_8); + Doc doc = new SimpleDoc(bytes, flavor, null); + job.print(doc, null); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public int print(Graphics g, PageFormat pf, int page) throws PrinterException + { + if (page > 0) { /* We have only one page, and 'page' is zero-based */ + return NO_SUCH_PAGE; + } + + /* + * User (0,0) is typically outside the imageable area, so we must + * translate by the X and Y values in the PageFormat to avoid clipping + */ + Graphics2D g2d = (Graphics2D) g; + g2d.translate(pf.getImageableX(), pf.getImageableY()); + /* Now we perform our rendering */ + return PAGE_EXISTS; + } + + public void printBytes(byte[] bytes) + { + PrintService service = selectedPrinter; + DocPrintJob job = service.createPrintJob(); + + try { + Doc doc = new SimpleDoc(bytes, flavor, null); + job.print(doc, null); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void cutPaper() + { + byte[] cutP = new byte[] { 0x1d, 'V', 1 }; + printBytes(cutP); + } +} diff --git a/src/main/java/com/jFxKasse/datatypes/PrintData.java b/src/main/java/com/jFxKasse/datatypes/PrintData.java new file mode 100644 index 0000000..350e4e2 --- /dev/null +++ b/src/main/java/com/jFxKasse/datatypes/PrintData.java @@ -0,0 +1,182 @@ +package com.jFxKasse.datatypes; + +public abstract class PrintData +{ + + protected int headerSpace; + + protected int footerSpace; + + protected int lineBreak; + + protected String header; + + protected String footer; + + protected String positionenQuantity; + + protected String positionenName; + + protected String positionenValue; + + protected String positionenCategory; + + protected String jobID; + + protected String timeAndDateOrder; + + protected String timeAndDatePrint; + + protected String jobValue; + + /** + * Constructor with all data that is not in the DB + * @param lineBreak + * @param headerSpace + * @param footerSpace + * @param timeAndDatePrint + * @param header + * @param footer + */ + public PrintData(int lineBreak, int headerSpace, int footerSpace, + String timeAndDatePrint, String header, String footer) + { + this.lineBreak = lineBreak; + this.headerSpace = headerSpace; + this.footerSpace = footerSpace; + this.timeAndDatePrint = timeAndDatePrint; + this.header = header; + this.footer = footer; + } + + /** + * set all Data that is in the DB + * @param jobID + * @param timeAndDateOrder + * @param positionenQuantity + * @param positionenName + * @param positionenValue + * @param positionenCategory + * @param jobValue + */ + public void setData(String jobID, String timeAndDateOrder, + String positionenQuantity, String positionenName, + String positionenValue, String positionenCategory, String jobValue) + { + this.jobID = jobID; + this.timeAndDateOrder = timeAndDateOrder; + this.positionenQuantity = positionenQuantity; + this.positionenName = positionenName; + this.positionenValue = positionenValue; + this.positionenCategory = positionenCategory; + this.jobValue = jobValue; + + } + + /** + * + * @param data String + * @return same String splitted with \n after the max. line lenght + */ + protected String breakLines(String data) + { + boolean next = false; + + int count = lineBreak; + + if (data.length() > lineBreak) { + // Needs to be splitted + next = true; + } else { + // No need to be splitted + return data; + } + + // first part + String tmp = data.substring(0, lineBreak); + + while (next) { + + try { + tmp = tmp + "\n" + data.substring(count, lineBreak + count); + count = count + lineBreak; + } catch (Exception e) { + // data string not long enough + next = false; + } + + } + // add the last part + return tmp + "\n" + data.substring(count); + } + + /** + * prints a line of '--------' + * @return + */ + protected String getSeparator() + { + String tmp = "-"; + + for (int i = 1; i < lineBreak; i++) { + tmp = tmp + "-"; + } + return tmp; + } + + /** + * sets a String into the center + * @param data + * @return the centered String + */ + protected String setCenter(String data) + { + int dataLenght = data.length(); + int prefix = ((lineBreak - dataLenght) / 2); + String tmp = " "; + + for (int i = 1; i < prefix; i++) { + tmp = tmp + " "; + } + tmp = tmp + data; + + return breakLines(tmp); + } + + /** + * sets a String right-justified after an prefix + * @param prefix + * @param data + * @return the right-justified String + */ + protected String setRight(String prefix, String data) + { + + int prefixLenght = prefix.length(); + + int dataLenght = data.length(); + + String tmp = prefix; + + int fill = lineBreak - (prefixLenght + dataLenght); + + if (fill < 0) { + tmp = tmp + "\n"; + fill = lineBreak - dataLenght; + } + + for (int i = 0; i < fill; i++) { + tmp = tmp + " "; + } + + tmp = tmp + data; + + return tmp; + } + + /** + * How the print String or Strings are made + */ + abstract protected void generatePrintString(); + +} diff --git a/src/main/java/com/jFxKasse/datatypes/PrintDataSimple.java b/src/main/java/com/jFxKasse/datatypes/PrintDataSimple.java new file mode 100644 index 0000000..b1301d8 --- /dev/null +++ b/src/main/java/com/jFxKasse/datatypes/PrintDataSimple.java @@ -0,0 +1,93 @@ +package com.jFxKasse.datatypes; + +public class PrintDataSimple extends PrintData +{ + + private String printString; + + /** + * Constructor with all data that is not in the DB + * @param lineBreak + * @param headerSpace + * @param footerSpace + * @param timeAndDatePrint + * @param header + * @param footer + */ + public PrintDataSimple(int lineBreak, int headerSpace, int footerSpace, + String timeAndDatePrint, String header, String footer) + { + super(lineBreak, headerSpace, footerSpace, timeAndDatePrint, header, + footer); + } + + /** + * Generates the String + * @return the final Print String + */ + public String getPrintString() + { + generatePrintString(); + return this.printString; + } + + @Override + protected void generatePrintString() + { + /* Header */ + String header = "\n"; + for (int i = 1; i < headerSpace; i++) { + header = header + "\n"; + } + + // This is the final header + header = header + setCenter(this.header); + + /* Info */ + + String info = setRight("Bestellung: ", timeAndDateOrder) + "\n" + + setRight("Druck: ", timeAndDatePrint) + "\n" + + setRight("Bestellnummer: ", jobID); + + /* Positionen */ + + String positionen = "\n"; + + int posCount = positionenQuantity.length() + - positionenQuantity.replace(";", "").length() + 1; + + String[] positionQuantity = positionenQuantity.split(";"); + + String[] positionName = positionenName.split(";"); + + String[] positionValue = positionenValue.split(";"); + + for (int i = 0; i < posCount; i++) { //All different posNames + int quantity = Integer.parseInt(positionQuantity[i]); + for (int j = 0; j < quantity; j++) { //quantities + positionen = positionen + setRight(breakLines(positionName[i]), + positionValue[i] + " €") + "\n"; + } + } + + /* Price */ + + String price = setRight("Gesamt: ", (jobValue + " €")); + + /* Footer */ + + String footer = setCenter(this.footer); + + for (int i = 1; i < footerSpace; i++) { + footer = footer + "\n"; + } + footer = footer + "_"; + + /* Build final Print String */ + + printString = header + "\n" + getSeparator() + "\n" + info + "\n" + + getSeparator() + "\n" + positionen + "\n" + getSeparator() + "\n" + + price + "\n" + getSeparator() + "\n" + footer; + } + +}