Java:将程序输出打印到物理打印机
我是一个相对较新的程序员,所以这可能是一个非常简单的问题,但它让我有点困惑 我正在尝试将Java GUI的最终输出打印到打印机上。现在,在我的GUI中,我有了它,所以当你点击打印时,会弹出一个可用打印机的列表,根据你选择的打印机,它会打印到那台打印机上 但事实并非如此。我通过在互联网上搜索这个问题的解决方案获得了大部分代码,并找到了一些有前途的代码。但是,它是从一个文件中打印出来的。因此,我在方法中所做的只是首先将输出写入一个文件,以便使用相同的方法 在使用该方法之前,有两件事:Java:将程序输出打印到物理打印机,java,netbeans,printing,Java,Netbeans,Printing,我是一个相对较新的程序员,所以这可能是一个非常简单的问题,但它让我有点困惑 我正在尝试将Java GUI的最终输出打印到打印机上。现在,在我的GUI中,我有了它,所以当你点击打印时,会弹出一个可用打印机的列表,根据你选择的打印机,它会打印到那台打印机上 但事实并非如此。我通过在互联网上搜索这个问题的解决方案获得了大部分代码,并找到了一些有前途的代码。但是,它是从一个文件中打印出来的。因此,我在方法中所做的只是首先将输出写入一个文件,以便使用相同的方法 在使用该方法之前,有两件事: 没有引发错误或
private void printToPrinter()
{
File output = new File("PrintFile.txt");
output.setWritable(true);
//Will become the user-selected printer.
Object selection = null;
try
{
BufferedWriter out = new BufferedWriter(new FileWriter(output));
out.write(calculationTextArea.getText() + "\n" + specificTextArea.getText());
out.close();
}
catch (java.io.IOException e)
{
System.out.println("Unable to write Output to disk, error occured in saveToFile() Method.");
}
FileInputStream textStream = null;
try
{
textStream = new FileInputStream("PrintFile.txt");
}
catch (java.io.FileNotFoundException e)
{
System.out.println("Error trying to find the print file created in the printToPrinter() method");
}
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
Doc mydoc = new SimpleDoc(textStream, flavor, null);
//Look up available printers.
PrintService[] printers = PrintServiceLookup.lookupPrintServices(flavor, null);
if (printers.length == 0)
{
// No printers found. Inform user.
jOptionPane2.showMessageDialog(this, "No printers could be found on your system!", "Error!", JOptionPane.ERROR_MESSAGE);
}
else
{
selection = jOptionPane2.showInputDialog(this, "Please select the desired printer:", "Print",
JOptionPane.INFORMATION_MESSAGE, null, printers,
PrintServiceLookup.lookupDefaultPrintService());
if (selection instanceof PrintService)
{
PrintService chosenPrinter = (PrintService) selection;
DocPrintJob printJob = chosenPrinter.createPrintJob();
try
{
printJob.print(mydoc, null);
}
catch (javax.print.PrintException e)
{
jOptionPane2.showMessageDialog(this, "Unknown error occured while attempting to print.", "Error!", JOptionPane.ERROR_MESSAGE);
}
}
}
}
您可以直接打印JFrame/JPanel的图形,而不是生成文档。此代码应适用于:
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setJobName("name");
PageFormat format = pj.getPageFormat(null);
pj.setPrintable (new Printable() {
@Override
public int print(Graphics pg, PageFormat pf, int pageNum) throws PrinterException {
if (pageNum > 0){
return Printable.NO_SUCH_PAGE;
}
Graphics2D g2 = (Graphics2D) pg;
this.paint(g2);
return Printable.PAGE_EXISTS;
}
}, format);
if (pj.printDialog() == false)
return;
pj.print();
} catch (PrinterException ex) {
// handle exception
}
}
所以我找到了一种适合我的情况的方法,我想我会把它贴出来,以防它对任何人都有用 该解决方案的基本原理是Java有自己的完整(至少与我的相比)printDialog弹出窗口,它有比我所需要的更多的内容(页面布局编辑、预览等),使用它所要做的就是将一个实现可打印的对象交给它,并在该对象中创建图形和绘制文档 我只需要画出我的输出字符串,这很容易做到,我甚至找到了一个StringReader,这样我就可以不再天真地写文件,而只是在BufferedReader中获得我的输出 这是密码。我绘制图像的方法和类分为两部分: 方法:
private void printToPrinter()
{
String printData = CalculationTextArea.getText() + "\n" + SpecificTextArea.getText();
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(new OutputPrinter(printData));
boolean doPrint = job.printDialog();
if (doPrint)
{
try
{
job.print();
}
catch (PrinterException e)
{
// Print job did not complete.
}
}
}
下面是打印文档的类:
public class OutputPrinter implements Printable
{
private String printData;
public OutputPrinter(String printDataIn)
{
this.printData = printDataIn;
}
@Override
public int print(Graphics g, PageFormat pf, int page) throws PrinterException
{
// Should only have one page, and page # is zero-based.
if (page > 0)
{
return NO_SUCH_PAGE;
}
// Adding the "Imageable" to the x and y puts the margins on the page.
// To make it safe for printing.
Graphics2D g2d = (Graphics2D)g;
int x = (int) pf.getImageableX();
int y = (int) pf.getImageableY();
g2d.translate(x, y);
// Calculate the line height
Font font = new Font("Serif", Font.PLAIN, 10);
FontMetrics metrics = g.getFontMetrics(font);
int lineHeight = metrics.getHeight();
BufferedReader br = new BufferedReader(new StringReader(printData));
// Draw the page:
try
{
String line;
// Just a safety net in case no margin was added.
x += 50;
y += 50;
while ((line = br.readLine()) != null)
{
y += lineHeight;
g2d.drawString(line, x, y);
}
}
catch (IOException e)
{
//
}
return PAGE_EXISTS;
}
}
不管怎样,这就是我解决这个问题的方法!希望它能对某人有所帮助 创建一个
JTextComponent
(我建议使用JTextArea
,这样您就可以使用append()
),并将所需内容追加到字段中。不要在视图上显示它,它只是一个隐藏字段,用于打印
所有JTextComponent
s都有print()
方法。只需调用hiddenTextArea.print()
,其余的就可以处理了
JTextArea hiddenTextArea = new JTextArea();
for (String s : dataToPrintCollection) {
hiddenTextArea.append(s + "\n");
}
try {
hiddenTextArea.print();
} catch (PrinterException e) {}
您确定打印机没有收到空文件吗?打印机是否打印出任何内容?甚至是空白页?是否可以打印到虚拟打印机并捕获输出?例如(Microsoft XPS Document Writer)打印机没有打印任何内容,没有空白页。当我检查“java打印”作业的作业信息时,它收到了一条作业消息:“此文档不符合Adobe文档结构约定,可能无法正确打印!”我目前正在尝试一种方法,以便在文档转到打印机前捕获该文档,以再次检查其有效性。感谢您的回答!这可能行得通,但我从两个不同选项卡上的两个单独的JTextArea中提取。问题是,我知道它们总是能够放在一个页面上,所以我宁愿从它们两个页面上提取文本并打印在一个页面上,以方便用户。我试图找到解决方案,但不知何故,无法在另一个页面上绘制图形。您的代码中可能存在缺陷。开始时,将坐标系原点转换为可成像区域的起点(
g2d.translate(x,y)
)。之后,您可以使用与此原点相关的坐标绘制任何对象。但是,您可以保留可成像区域的x/y坐标以供以后使用(这是毫无意义的,因为您已经将原点转换为这些坐标)。可能的解决方案可能是取消调用g2d.translate(x,y)代码>或更改x+=50;y+=50代码>至x=50;y=50代码>