我是一名初级Java开发人员,我想构建一个类,它接受JTable并在屏幕上预览它将如何在默认打印机上打印。这就是我们用来称为"打印预览",就像MS Word,Excel等一样。
我们已经知道Java不支持这种开箱即用的功能。
基于一些例子,我发现谷歌搜索我建了两个班级。第一个TestPreview.java显示JTable,第二个PrintPreview.java预览如何在打印机上打印JTable。
我有两个按钮来浏览页面," PREV"和" NEXT"和"打印'按钮打印JTable。 我的问题是,当我的JTable在多个页面中有太多行和跨度时,PrintPreview不起作用。它一次又一次地显示相同的页面。此外,它不显示整个JTable数据,但只显示其中的一部分,我无法弄清楚原因。
请帮忙。
以下是我的两个班级
的 TestPreview.java 的
package printpreviewdemo;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.*;
import java.awt.print.*;
import java.text.MessageFormat;
import javax.print.attribute.*;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.Sides;
import javax.swing.JTable.PrintMode;
class TestPreview extends JFrame implements ActionListener {
PrinterJob printerJob = PrinterJob.getPrinterJob();
HashPrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
JTable table = null;
public TestPreview() {
super("Test of Print Preview");
getContentPane().add(createTable());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setExtendedState(Frame.MAXIMIZED_BOTH);
setVisible(true);
}
private JPanel createTable() {
String val[][] = {
{"A", "Test 01", "A", "Test 01"},
{"B", "Test 02", "B", "Test 02"},
{"C", "Test 03", "C", "Test 03"},
{"D", "Test 04", "D", "Test 04"},
{"E", "Test 05", "E", "Test 05"},
{"F", "Test 06", "F", "Test 06"},
{"G", "Test 01", "G", "Test 01"},
{"H", "Test 02", "H", "Test 02"},
{"I", "Test 03", "I", "Test 03"},
{"J", "Test 03", "J", "Test 03"},
{"K", "Test 04", "K", "Test 04"},
{"L", "Test 05", "L", "Test 05"},
{"M", "Test 06", "M", "Test 06"},
{"N", "Test 01", "N", "Test 01"},
{"O", "Test 02", "O", "Test 02"},
{"P", "Test 03", "P", "Test 03"},
{"Q", "Test 04", "Q", "Test 04"},
{"R", "Test 05", "R", "Test 05"},
{"S", "Test 06", "S", "Test 06"},
{"T", "Test 01", "T", "Test 01"},
{"U", "Test 02", "U", "Test 02"},
{"V", "Test 03", "V", "Test 03"},
{"W", "Test 04", "W", "Test 04"},
{"X", "Test 05", "X", "Test 05"},
{"Y", "Test 06", "Y", "Test 06"},
{"Z", "Test 01", "Z", "Test 01"},
{"1", "Test 02", "1", "Test 02"},
{"2", "Test 03", "2", "Test 03"},
{"3", "Test 04", "3", "Test 04"},
{"4", "Test 05", "4", "Test 05"},
{"5", "Test 06", "5", "Test 06"},
{"6", "Test 01", "6", "Test 01"},
{"7", "Test 02", "7", "Test 02"},
{"8", "Test 03", "8", "Test 03"},
{"9", "Test 04", "9", "Test 04"},
{"10", "Test 05","10", "Test 05"},
{"11", "Test 02","11", "Test 02"},
{"12", "Test 03","12", "Test 03"},
{"13", "Test 04","13", "Test 04"},
{"14", "Test 05","14", "Test 05"},
{"15", "Test 06","15", "Test 06"},
{"16", "Test 01","16", "Test 01"},
{"17", "Test 02","17", "Test 02"},
{"18", "Test 03","18", "Test 03"},
{"19", "Test 04","19", "Test 04"},
{"20", "Test 05","20", "Test 05"},
{"30", "Test 05","30", "Test 05"},
{"31", "Test 02","31", "Test 02"},
{"32", "Test 03","32", "Test 03"},
{"33", "Test 04","33", "Test 04"},
{"34", "Test 05","34", "Test 05"},
{"35", "Test 06","35", "Test 06"},
{"36", "Test 01","36", "Test 01"},
{"37", "Test 02","37", "Test 02"},
{"38", "Test 03","38", "Test 03"},
{"39", "Test 04","39", "Test 04"},
{"40", "Test 05","40", "Test 05"},
{"40", "Test 05","40", "Test 05"},
{"41", "Test 02","41", "Test 02"},
{"42", "Test 03","42", "Test 03"},
{"43", "Test 04","43", "Test 04"},
{"44", "Test 05","44", "Test 05"},
{"45", "Test 06","45", "Test 06"},
{"46", "Test 01","46", "Test 01"},
{"47", "Test 02","47", "Test 02"},
{"48", "Test 03","48", "Test 03"},
{"49", "Test 04","49", "Test 04"},
{"50", "Test 05","50", "Test 05"},
{"50", "Test 05","50", "Test 05"},
{"51", "Test 02","51", "Test 02"},
{"52", "Test 03","52", "Test 03"},
{"53", "Test 04","53", "Test 04"},
{"54", "Test 05","54", "Test 05"},
{"55", "Test 06","55", "Test 06"},
{"56", "Test 01","56", "Test 01"},
{"57", "Test 02","57", "Test 02"},
{"58", "Test 03","58", "Test 03"},
{"59", "Test 04","59", "Test 04"},
{"60", "Test 05","60", "Test 05"}
};
String headers[] = {"A", "B", "C", "D"};
table = new JTable(val, headers);
JButton previewButton = new JButton("Preview Table");
previewButton.addActionListener(this);
JPanel panel = new JPanel(new BorderLayout()), top = new JPanel(new FlowLayout());
top.add(previewButton);
panel.add(top, "North");
panel.add(new JScrollPane(table), "Center");
return panel;
}
@Override
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand().equals("Preview Table"))
attributes.add(new MediaPrintableArea(6, 6, 198, 278, MediaPrintableArea.MM)); // A4: 210x297mm
attributes.add(Sides.DUPLEX);
attributes.add(OrientationRequested.LANDSCAPE);
new PrintPreview(
table.getPrintable(PrintMode.FIT_WIDTH, null, new MessageFormat("Page {0}") ),
printerJob.getPageFormat(attributes)
);
}
public static void main(String arg[]) {
new TestPreview();
}
}
的 PrintPreview.java 的
package printpreviewdemo;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.awt.print.*;
class PrintPreview extends JFrame implements ActionListener, ItemListener {
JButton printButton = new JButton("Print");
Pageable pageable = null;
double scale = 1.0;
Page page[] = null;
JComboBox combobox = new JComboBox();
CardLayout cardlayout = new CardLayout();
JPanel previewPanel = new JPanel(cardlayout);
JButton backButton = new JButton("PREV"), forwardButton = new JButton("NEXT");
public PrintPreview(final Printable printable, final PageFormat pageFormat) {
super("Print Preview");
pageable = new Pageable() {
@Override
public int getNumberOfPages() {
Graphics graphics = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB).getGraphics();
int numPages = 0;
try {
while (printable.print(graphics, pageFormat, numPages) == Printable.PAGE_EXISTS) {
numPages++;
}
} catch (Exception ex) {
}
return numPages;
}
@Override
public PageFormat getPageFormat(int x) {
return pageFormat;
}
@Override
public Printable getPrintable(int x) {
return printable;
}
};
createPreview();
}
private void createPreview() {
page = new Page[pageable.getNumberOfPages()];
PageFormat pageFormat = pageable.getPageFormat(0);
Dimension size = new Dimension((int) pageFormat.getPaper().getWidth(), (int) pageFormat.getPaper().getHeight());
if (pageFormat.getOrientation() != PageFormat.PORTRAIT) {
size = new Dimension(size.height, size.width);
}
for (int i = 0; i < page.length; i++) {
combobox.addItem("" + (i + 1));
page[i] = new Page(i, size);
previewPanel.add("" + (i + 1), new JScrollPane(page[i]));
}
setTopPanel();
getContentPane().add(previewPanel, "Center");
pack();
setExtendedState(Frame.MAXIMIZED_BOTH);
setVisible(true);
}
private void setTopPanel() {
FlowLayout fl = new FlowLayout();
GridBagLayout gbl = new GridBagLayout();
JPanel topPanel = new JPanel(gbl), temp = new JPanel(fl);
backButton.addActionListener(this);
forwardButton.addActionListener(this);
backButton.setEnabled(false);
forwardButton.setEnabled(page.length > 1);
temp.add(combobox);
temp.add(backButton);
temp.add(forwardButton);
temp.add(printButton);
topPanel.add(temp);
printButton.addActionListener(this);
combobox.addItemListener(this);
getContentPane().add(topPanel, "North");
}
@Override
public void itemStateChanged(ItemEvent ie) {
cardlayout.show(previewPanel, (String) combobox.getSelectedItem());
backButton.setEnabled(combobox.getSelectedIndex() == 0 ? false : true);
forwardButton.setEnabled(combobox.getSelectedIndex() == combobox.getItemCount() - 1 ? false : true);
validate();
}
@Override
public void actionPerformed(ActionEvent ae) {
Object o = ae.getSource();
if (o == printButton) {
try {
PrinterJob pj = PrinterJob.getPrinterJob();
pj.defaultPage(pageable.getPageFormat(0));
pj.setPageable(pageable);
if (pj.printDialog()) {
pj.print();
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex.toString(), "Error in Printing", 1);
}
} else if (o == backButton) {
combobox.setSelectedIndex(combobox.getSelectedIndex() == 0 ? 0 : combobox.getSelectedIndex() - 1);
if (combobox.getSelectedIndex() == 0) {
backButton.setEnabled(false);
}
} else if (o == forwardButton) {
combobox.setSelectedIndex(combobox.getSelectedIndex() == combobox.getItemCount() - 1 ? 0 : combobox.getSelectedIndex() + 1);
if (combobox.getSelectedIndex() == combobox.getItemCount() - 1) {
forwardButton.setEnabled(false);
}
}
}
class Page extends JLabel {
final int n;
final PageFormat pageformat;
BufferedImage bufferimage = null;
Dimension size = null;
public Page(int currentpage, Dimension size) {
this.size = size;
bufferimage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
n = currentpage;
pageformat = pageable.getPageFormat(n);
Graphics g = bufferimage.getGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, (int) pageformat.getWidth(), (int) pageformat.getHeight());
try {
pageable.getPrintable(n).print(g, pageformat, n);
} catch (Exception ex) {
}
setIcon(new ImageIcon(bufferimage));
}
}
}
答案 0 :(得分:0)
怀疑它是否仍有意义,但问题是TablePrintable是单用的。没有办法重置第二遍。
第二次调用jTable.getPrintable()会获得一个新的TablePrintable,因此您需要使用第一个用于计算页面,第二次用于实际打印。
实际上,您实际上并不需要计算页数。 getNumberofPages()可以返回零;只需在页面耗尽时结束打印循环。
另一种解决方法是复制TablePrintable的源代码并为变量&#39; last&#39;添加重置方法。和Rectangle值。