我有一个带有Icon的jLabel我应该打印。但是,我无法将jLabel的图标变为全尺寸。
以下是我认为影响打印尺寸的一些代码。
public static void printComponentToFile(Component comp, boolean fill) throws PrinterException {
Paper paper = new Paper();
paper.setSize(8.3 * 72, 11.7 * 72); //here
paper.setImageableArea(18, 18, 100, 300); //and here
PageFormat pf = new PageFormat();
pf.setPaper(paper);
pf.setOrientation(PageFormat.LANDSCAPE);
BufferedImage img = new BufferedImage(
(int) Math.round(pf.getWidth()),
(int) Math.round(pf.getHeight()),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight()));
ComponentPrinter cp = new ComponentPrinter(comp, fill);
try {
cp.print(g2d, pf, 0);
} finally {
g2d.dispose();
}
try {
ImageIO.write(img, "png", new File("Page-" + (fill ? "Filled" : "") + ".png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static class ComponentPrinter implements Printable {
private Component comp;
private boolean fill;
public ComponentPrinter(Component comp, boolean fill) {
this.comp = comp;
this.fill = fill;
}
@Override
public int print(Graphics g, PageFormat format, int page_index) throws PrinterException {
if (page_index > 0) {
return Printable.NO_SUCH_PAGE;
}
Graphics2D g2 = (Graphics2D) g;
g2.translate(format.getImageableX(), format.getImageableY());
double width = (int) Math.floor(format.getImageableWidth()); // here too
double height = (int) Math.floor(format.getImageableHeight()); // and here
if (!fill) {
width = Math.min(width, comp.getPreferredSize().width); // here
height = Math.min(height, comp.getPreferredSize().height); // here
}
comp.setBounds(0, 0, (int) Math.floor(width), (int) Math.floor(height));
if (comp.getParent() == null) {
comp.addNotify();
}
comp.validate();
comp.doLayout();
comp.printAll(g2);
if (comp.getParent() != null) {
comp.removeNotify();
}
return Printable.PAGE_EXISTS;
}
}
那么我应该改变什么呢?另外,如何在打印过程中放置单选按钮?这是因为我想用标签打印出无线电按钮。
这是我使用按钮打印标签的方式:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try {
printComponent(jLabel2, false);
} catch (PrinterException ex) {
Logger.getLogger(MappingScreen.class.getName()).log(Level.SEVERE, null, ex);
}
}
我可以这样做吗?:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try {
printComponent(jLabel2, false);
printComponent(jRadioBtn1, false); //change
} catch (PrinterException ex) {
Logger.getLogger(M.class.getName()).log(Level.SEVERE, null, ex);
}
}
更新:
我想我必须在这里添加一些内容来打印另一个组件:
public static void main(String args[]) {
try {
JLabel label = new JLabel(
"This is a test",
new ImageIcon("/adv/mapp.jpg"),
JLabel.CENTER);
printComponentToFile(label, true);
printComponentToFile(label, false);
} catch (PrinterException exp) {
exp.printStackTrace();
}
请帮忙。谢谢
答案 0 :(得分:4)
所以,基于Printing a JFrame and its components中提出的概念,我已经能够产生这两个例子......
使用以下JPanel
作为基本组件......
public static class PrintForm extends JPanel {
public PrintForm() {
setLayout(new GridBagLayout());
JLabel label = new JLabel("This is a label");
label.setVerticalTextPosition(JLabel.BOTTOM);
label.setHorizontalTextPosition(JLabel.CENTER);
try {
label.setIcon(new ImageIcon(ImageIO.read(new File("C:\\hold\\thumbnails\\_cg_1009___Afraid___by_Serena_Clearwater.png"))));
} catch (IOException ex) {
ex.printStackTrace();
}
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.weighty = 1;
add(label, gbc);
JRadioButton rb = new JRadioButton("Open to suggestions");
rb.setSelected(true);
gbc.gridy++;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.NONE;
add(rb, gbc);
}
}
根据Fit/Scale JComponent to page being printed中提出的概念,我能够拍摄7680x4800的图像并将其缩小以在842x598的范围内打印。
现在请注意。 JLabel
不支持扩展。如果您的图像不适合可用空间,您将不得不自己进行缩放。以下解决方案对整个组件进行了扩展,尽管如此,通过一些巧妙的重新安排,可以使TestPane
缩放它的图像而不是使用上面的示例......
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ScalablePrintingTest {
public static void main(String[] args) {
new ScalablePrintingTest();
}
public ScalablePrintingTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final TestPane imagePane = new TestPane();
JButton print = new JButton("Print");
print.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
//printComponent(imagePane);
printComponentToFile(imagePane);
} catch (PrinterException ex) {
ex.printStackTrace();
}
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(imagePane);
frame.add(print, BorderLayout.SOUTH);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage bg;
public TestPane() {
try {
bg = ImageIO.read(new File("/path/to/a/image"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return bg == null ? new Dimension(200, 200) : new Dimension(bg.getWidth(), bg.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (bg != null) {
int x = (getWidth() - bg.getWidth()) / 2;
int y = (getHeight() - bg.getHeight()) / 2;
g2d.drawImage(bg, x, y, this);
}
g2d.dispose();
}
}
public void printComponent(Component comp) {
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setJobName(" Print Component ");
pj.setPrintable(new ComponentPrintable(comp));
if (!pj.printDialog()) {
return;
}
try {
pj.print();
} catch (PrinterException ex) {
System.out.println(ex);
}
}
public static void printComponentToFile(Component comp) throws PrinterException {
Paper paper = new Paper();
paper.setSize(8.3 * 72, 11.7 * 72);
paper.setImageableArea(18, 18, 559, 783);
PageFormat pf = new PageFormat();
pf.setPaper(paper);
pf.setOrientation(PageFormat.LANDSCAPE);
BufferedImage img = new BufferedImage(
(int) Math.round(pf.getWidth()),
(int) Math.round(pf.getHeight()),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight()));
ComponentPrintable cp = new ComponentPrintable(comp);
try {
cp.print(g2d, pf, 0);
} finally {
g2d.dispose();
}
try {
ImageIO.write(img, "png", new File("Page-Scaled.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static class ComponentPrintable implements Printable {
private Component comp;
private ComponentPrintable(Component comp) {
this.comp = comp;
}
@Override
public int print(Graphics g, PageFormat pf, int pageNumber)
throws PrinterException {
// TODO Auto-generated method stub
if (pageNumber > 0) {
return Printable.NO_SUCH_PAGE;
}
// Get the preferred size ofthe component...
Dimension compSize = comp.getPreferredSize();
// Make sure we size to the preferred size
comp.setSize(compSize);
// Get the the print size
Dimension printSize = new Dimension();
printSize.setSize(pf.getImageableWidth(), pf.getImageableHeight());
// Calculate the scale factor
double scaleFactor = getScaleFactorToFit(compSize, printSize);
// Don't want to scale up, only want to scale down
if (scaleFactor > 1d) {
scaleFactor = 1d;
}
// Calcaulte the scaled size...
double scaleWidth = compSize.width * scaleFactor;
double scaleHeight = compSize.height * scaleFactor;
// Create a clone of the graphics context. This allows us to manipulate
// the graphics context without begin worried about what effects
// it might have once we're finished
Graphics2D g2 = (Graphics2D) g.create();
// Calculate the x/y position of the component, this will center
// the result on the page if it can
double x = ((pf.getImageableWidth() - scaleWidth) / 2d) + pf.getImageableX();
double y = ((pf.getImageableHeight() - scaleHeight) / 2d) + pf.getImageableY();
// Create a new AffineTransformation
AffineTransform at = new AffineTransform();
// Translate the offset to out "center" of page
at.translate(x, y);
// Set the scaling
at.scale(scaleFactor, scaleFactor);
// Apply the transformation
g2.transform(at);
// Print the component
comp.printAll(g2);
// Dispose of the graphics context, freeing up memory and discarding
// our changes
g2.dispose();
comp.revalidate();
return Printable.PAGE_EXISTS;
}
}
public static double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
public static double getScaleFactor(int iMasterSize, int iTargetSize) {
double dScale = 1;
if (iMasterSize > iTargetSize) {
dScale = (double) iTargetSize / (double) iMasterSize;
} else {
dScale = (double) iTargetSize / (double) iMasterSize;
}
return dScale;
}
}
答案 1 :(得分:2)
我打算更新我以前的答案,但已被接受......
此示例基本上结合了Fit/Scale JComponent to page being printed和Printing a JFrame and its components中提供的解决方案,并演示了在打印组件时将组件缩放以使组件能够自行缩放的区别...
它会创建interface
Printable
的{{1}}链,我希望这有助于消除任何混淆......好吧,那就少了......
首先......
左侧的面板是静态的,也就是说,组件不会缩放图像。右侧的面板是动态的,也就是说,当组件的大小发生变化时,组件将缩放图像。
使用缩放方法打印时的静态面板。您会注意到标签和单选按钮也已缩放
与使用填充方法时的动态面板相比。您会注意到标签和单选按钮没有缩放,但保持正常大小,但背景图像会缩放...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class PrintComponentTest {
public static void main(String[] args) {
new PrintComponentTest();
}
public PrintComponentTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private StaticImagePane staticImagePane;
private DynamicImagePane dynamicImagePane;
public TestPane() {
JPanel content = new JPanel(new GridLayout());
content.add(new JScrollPane(preparePane(staticImagePane = new StaticImagePane())));
content.add(preparePane(dynamicImagePane = new DynamicImagePane()));
setLayout(new BorderLayout());
add(content);
JPanel options = new JPanel();
JButton normal = new JButton("Print");
normal.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
printComponentToFile(new FillableCompentPrintable(staticImagePane, false), new File("Static-Normal.png"));
printComponentToFile(new FillableCompentPrintable(staticImagePane, true), new File("Static-Filled.png"));
printComponentToFile(new ScalableCompentPrintable(staticImagePane), new File("Static-Scaled.png"));
printComponentToFile(new FillableCompentPrintable(dynamicImagePane, false), new File("Dynamic-Normal.png"));
printComponentToFile(new FillableCompentPrintable(dynamicImagePane, true), new File("Dynamic-Filled.png"));
printComponentToFile(new ScalableCompentPrintable(dynamicImagePane), new File("Dynamic-Scaled.png"));
staticImagePane.invalidate();
dynamicImagePane.invalidate();
staticImagePane.revalidate();
dynamicImagePane.revalidate();
invalidate();
revalidate();
} catch (PrinterException ex) {
ex.printStackTrace();
}
}
});
options.add(normal);
add(options, BorderLayout.SOUTH);
}
protected JPanel preparePane(JPanel panel) {
panel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JLabel label = new JLabel("This is some text on a label");
label.setForeground(Color.WHITE);
panel.add(label, gbc);
JRadioButton btn = new JRadioButton("Do you agree", true);
btn.setOpaque(false);
btn.setForeground(Color.WHITE);
panel.add(btn, gbc);
return panel;
}
}
public void printComponent(ComponentPrintable printable) {
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setJobName(" Print Component ");
pj.setPrintable(printable);
if (!pj.printDialog()) {
return;
}
try {
pj.print();
} catch (PrinterException ex) {
System.out.println(ex);
}
}
public static void printComponentToFile(ComponentPrintable printable, File file) throws PrinterException {
Paper paper = new Paper();
paper.setSize(8.3 * 72, 11.7 * 72);
paper.setImageableArea(18, 18, 559, 783);
PageFormat pf = new PageFormat();
pf.setPaper(paper);
pf.setOrientation(PageFormat.LANDSCAPE);
BufferedImage img = new BufferedImage(
(int) Math.round(pf.getWidth()),
(int) Math.round(pf.getHeight()),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight()));
try {
printable.print(g2d, pf, 0);
} finally {
g2d.dispose();
}
try {
ImageIO.write(img, "png", file);
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static interface ComponentPrintable extends Printable {
public Component getComponent();
}
public abstract static class AbstractComponentPrintable implements ComponentPrintable {
private final Component component;
public AbstractComponentPrintable(Component component) {
this.component = component;
}
@Override
public Component getComponent() {
return component;
}
protected void beforePrinting(Component comp) {
if (comp.getParent() == null) {
comp.addNotify();
}
comp.invalidate();
comp.revalidate();
comp.doLayout();
}
protected void afterPrinting(Component comp) {
if (comp.getParent() != null) {
comp.removeNotify();
} else {
comp.invalidate();
comp.revalidate();
}
}
@Override
public int print(Graphics g, PageFormat format, int page_index) throws PrinterException {
if (page_index > 0) {
return Printable.NO_SUCH_PAGE;
}
Graphics2D g2 = (Graphics2D) g;
printComponent(g2, format, getComponent());
return Printable.PAGE_EXISTS;
}
protected abstract void printComponent(Graphics2D g, PageFormat pf, Component comp);
}
public static class FillableCompentPrintable extends AbstractComponentPrintable {
private boolean fill;
public FillableCompentPrintable(Component component, boolean fill) {
super(component);
this.fill = fill;
}
public boolean isFill() {
return fill;
}
@Override
protected void printComponent(Graphics2D g2, PageFormat pf, Component comp) {
g2.translate(pf.getImageableX(), pf.getImageableY());
double width = (int) Math.floor(pf.getImageableWidth());
double height = (int) Math.floor(pf.getImageableHeight());
if (!isFill()) {
width = Math.min(width, comp.getPreferredSize().width);
height = Math.min(height, comp.getPreferredSize().height);
}
comp.setBounds(0, 0, (int) Math.floor(width), (int) Math.floor(height));
beforePrinting(comp);
comp.printAll(g2);
afterPrinting(comp);
// Debug purposes only...
g2.translate(-pf.getImageableX(), -pf.getImageableY());
g2.setColor(Color.RED);
g2.drawRect(0, 0, (int) pf.getWidth() - 1, (int) pf.getHeight() - 1);
}
}
public static class ScalableCompentPrintable extends AbstractComponentPrintable {
public ScalableCompentPrintable(Component component) {
super(component);
}
@Override
protected void printComponent(Graphics2D g2d, PageFormat pf, Component comp) {
// Get the preferred size ofthe component...
Dimension compSize = comp.getPreferredSize();
// Make sure we size to the preferred size
comp.setSize(compSize);
// Get the the print size
Dimension printSize = new Dimension();
printSize.setSize(pf.getImageableWidth(), pf.getImageableHeight());
// Calculate the scale factor
double scaleFactor = getScaleFactorToFit(compSize, printSize);
// Don't want to scale up, only want to scale down
if (scaleFactor > 1d) {
scaleFactor = 1d;
}
// Calcaulte the scaled size...
double scaleWidth = compSize.width * scaleFactor;
double scaleHeight = compSize.height * scaleFactor;
// Create a clone of the graphics context. This allows us to manipulate
// the graphics context without begin worried about what effects
// it might have once we're finished
Graphics2D g2 = (Graphics2D) g2d.create();
// Calculate the x/y position of the component, this will center
// the result on the page if it can
double x = ((pf.getImageableWidth() - scaleWidth) / 2d) + pf.getImageableX();
double y = ((pf.getImageableHeight() - scaleHeight) / 2d) + pf.getImageableY();
// Create a new AffineTransformation
AffineTransform at = new AffineTransform();
// Translate the offset to out "center" of page
at.translate(x, y);
// Set the scaling
at.scale(scaleFactor, scaleFactor);
// Apply the transformation
g2.transform(at);
// Print the component
beforePrinting(comp);
comp.printAll(g2);
afterPrinting(comp);
// Dispose of the graphics context, freeing up memory and discarding
// our changes
g2.dispose();
// Debug purposes only...
g2d.setColor(Color.RED);
g2d.drawRect(0, 0, (int) pf.getWidth() - 1, (int) pf.getHeight() - 1);
}
public static double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
public static double getScaleFactor(int iMasterSize, int iTargetSize) {
double dScale = 1;
if (iMasterSize > iTargetSize) {
dScale = (double) iTargetSize / (double) iMasterSize;
} else {
dScale = (double) iTargetSize / (double) iMasterSize;
}
return dScale;
}
}
public class StaticImagePane extends JPanel {
private BufferedImage image;
public StaticImagePane() {
try {
setImage(ImageIO.read(new File("path\to\a\image")));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
repaint();
}
@Override
public Dimension getPreferredSize() {
BufferedImage bg = getImage();
return bg == null ? new Dimension(200, 200) : new Dimension(bg.getWidth(), bg.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
paintBackground(g2d);
g2d.dispose();
}
protected void paintBackground(Graphics2D g2d) {
paintBackground(g2d, getImage());
}
protected void paintBackground(Graphics2D g2d, Image bg) {
if (bg != null) {
int x = (getWidth() - bg.getWidth(this)) / 2;
int y = (getHeight() - bg.getHeight(this)) / 2;
g2d.drawImage(bg, x, y, this);
}
}
}
public class DynamicImagePane extends StaticImagePane {
private Image scaled;
public DynamicImagePane() {
try {
setImage(ImageIO.read(new File("path\to\a\image")));
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public void invalidate() {
super.invalidate();
if (getImage() != null) {
int width = getWidth();
int height = getHeight();
if (width > 0 && height > 0) {
// Keep the aspect ratio
if (width > height) {
width = -1;
} else if (height > width) {
height = -1;
}
scaled = getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH);
}
}
}
public Image getScaledImage() {
return scaled;
}
@Override
protected void paintBackground(Graphics2D g2d) {
paintBackground(g2d, getScaledImage());
}
}
}
请注意,这只是一个例子,需要做很多工作。
一个问题是缩放,有关详细信息,请参阅The Perils of Image.getScaledInstance();有关更好的方法,请参见Quality of Image after resize very low -- Java ...
答案 2 :(得分:1)
为了使其有效,我将其更改为:
//OLD:
public void printComponent(Component comp) {
//NEW:
public void printComponent(JComponent comp, boolean fill) throws PrinterException {
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setJobName(" Print Component ");
pj.setPrintable(new ComponentPrintable(comp));
if (!pj.printDialog()) {
return;
}
try {
pj.print();
} catch (PrinterException ex) {
System.out.println(ex);
}
}