在java中设计热敏打印机的收据

时间:2013-12-07 00:13:46

标签: java swing printing graphics2d

我在Android中有一个项目,我在其中制作了一个类似购物清单的应用程序,可以打印到收据热敏打印机。 我设计收据的方式很简单:我创建了一个.xml布局,其中我为标题添加了1个线性布局,为列添加了3个垂直linearlayouts,为页脚添加了另一个。之后我只是以编程方式将文本添加到布局中然后将.xml发送到打印。 这很棒,我可以轻松设置字体,轻松移动内容,添加图像,徽标等等。

现在,我知道我可以使用graphics2d和打印GUI组件,我用textarea测试它并且效果很好。当你有100行时它甚至滚动,不像jframes它只打印它看到的。

我的问题是我需要3-4列文字。这样的东西:

1. Bananas         4     11.20$
2. Toilet paper    12    3.99$
3. Donuts          1     0.49$

我可以将它添加到文本区域并打印它,但问题是文本的长度会有所不同,文本会变得混乱和不均匀。

那么,我怎么能在android中做一些事情:添加3-4列我可以添加文本,即使它们有100行,打印机也会成功打印所有这些而不是你可以看到的那些而不向下滚动?

提前致谢,祝你有愉快的一天!

1 个答案:

答案 0 :(得分:0)

将近6年后,我终于重新开始了该项目,并考虑发布最终使用的解决方案,所以这里是:

@Log4j2
@Service
public class PrintService implements Printable {

@Autowired
private PreviewManager previewManager;

public boolean printCopies() {

    final JPanel printPanel = new JPanel();
    DefaultListModel listModel = new DefaultListModel();

    printPanel.setLayout(new BoxLayout(printPanel, BoxLayout.PAGE_AXIS));
    printPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    JLabel label = new JLabel("Select the number of copies");
    listModel.addElement("0");
    listModel.addElement("1");
    listModel.addElement("2");
    listModel.addElement("3");
    listModel.addElement("4");
    listModel.addElement("5");

    final JList list = new JList(listModel);
    list.setVisibleRowCount(1);
    list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    list.setLayoutOrientation(JList.HORIZONTAL_WRAP);

    final int[] nrOfCopies = {1};
    list.addListSelectionListener(lse -> nrOfCopies[0] = Integer.parseInt((String) list.getSelectedValue()));
    printPanel.add(label);

    printPanel.add(list);
    label.setAlignmentX(JComponent.CENTER_ALIGNMENT);
    list.setAlignmentX(JComponent.CENTER_ALIGNMENT);
    list.setSelectedIndex(1);
    JOptionPane jop = new JOptionPane(printPanel,
            JOptionPane.PLAIN_MESSAGE,
            JOptionPane.OK_CANCEL_OPTION);
    JDialog dialog = jop.createDialog(EMPTY_STRING);
    dialog.setAlwaysOnTop(true);
    dialog.addComponentListener(new ComponentAdapter() {
        @Override
        public void componentShown(ComponentEvent e) {
            SwingUtilities.invokeLater(list::requestFocusInWindow);
        }
    });
    dialog.setVisible(true);
    int result = (Integer) jop.getValue();
    dialog.dispose();

    if (result == JOptionPane.OK_OPTION) {
        log.info("Printing {} copies of the list", nrOfCopies[0]);
        for (int c = 0; c < nrOfCopies[0]; c++) {
            print();
        }
        return true;
    }
    // todo: bring back
    return false;
}

public void print() {
    PrinterJob pjob = PrinterJob.getPrinterJob();
    javax.print.PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
    for (javax.print.PrintService printer : printServices) {
        // in my case I use a Star TSP143 thermal printer
        if (printer.getName().contains("tsp143")) {
            try {
                pjob.setPrintService(printer);
            } catch (PrinterException e) {
                log.error(e);
            }
        }
    }
    PageFormat preformat = pjob.defaultPage();
    preformat.setOrientation(PageFormat.PORTRAIT);
    PageFormat postformat = pjob.defaultPage(preformat);
    Paper p = preformat.getPaper();
    p.setImageableArea(0, 0, postformat.getWidth(), postformat.getHeight());
    postformat.setPaper(p);

    //If user does not hit cancel then print.
    if (preformat != postformat) {
        //Set print component
        pjob.setPrintable(PrintService.this, postformat);
        try {
            pjob.print();
        } catch (PrinterException ex) {
            log.error(ex);
        }
    }
}


@Override
public int print(Graphics g, PageFormat format, int page_index) {
    // depends on your use case, printableJpanel is going to be the panel you are going to print
    JPanel printableJpanel = previewManager.getPrintablePanel();
    if (page_index > 0) {
        return Printable.NO_SUCH_PAGE;
    }

    // get the bounds of the component
    Dimension dim = printableJpanel.getSize();
    double cHeight = dim.getHeight();
    double cWidth = dim.getWidth();

    // get the bounds of the printable area
    double pHeight = format.getImageableHeight();
    double pWidth = format.getImageableWidth();

    double pXStart = format.getImageableX();
    double pYStart = format.getImageableY();

    double xRatio = pWidth / cWidth;
    double yRatio = pHeight / cHeight;

    Graphics2D g2 = (Graphics2D) g;
    g2.translate(pXStart, pYStart);
    g2.scale(xRatio, 0.80);
    printableJpanel.paint(g2);

    return Printable.PAGE_EXISTS;

    }
}

祝你好运!