How to print a JPanel into printer that has paintComponent override? - java

I created a graph in a JPanel with paintComponent function. Is there a way to print this graph?
When I try to call the JPanels paintAll from the print function its repeatedly calling the paintComponent. I want to physically print it, i.e., pass it to the printer job from my OS.
Here is the print:
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException {
double scaleX = pageFormat.getImageableWidth() / mainPanel.getWidth();
double scaleY = pageFormat.getImageableHeight() / mainPanel.getHeight();
double scale = Math.min(scaleX, scaleY);
Graphics2D g2d = (Graphics2D)graphics;
AffineTransform Tx = g2d.getTransform();
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
g2d.scale(scale, scale);
System.out.println(scale + " Came inside");
mainPanel.printAll(g2d);
g2d.setTransform(Tx);
return PAGE_EXISTS;
}
//mainPanel class has the method override as below
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
...
...
}

Related

Issue with BasicScrollBarUI and LAF

I'm creating a program which has a Nimbus laf, in there i'm using a JScrollPane with a BasicScrollBarUI.
sp = new JScrollPane(lista);
sp.getVerticalScrollBar().setUI(new CustomScrollBarUI());
The problem is that i need the Nimbus laf for some custom buttons, and the BasicScrollBarUI for the scroll bar which i can't make with Nimbus, if i use both my scrollbar gets out of the border.
Just like that
The class i'm using for ScrollBarUI is:
protected void paintTrack(Graphics g, JComponent c, Rectangle r) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Color color = ColorPri;
JScrollBar sb = (JScrollBar) c;
scrollBarWidth = 9;
if (!sb.isEnabled()) {
return;
} else if (isDragging) {
color = ColorSec;
}
g2.setColor(color);
g2.fillRect(r.x, r.y, r.width, r.height);
g2.setColor(color);
g2.fillRect(r.x, r.y, r.width, r.height);
}
#Override
protected void paintThumb(Graphics g, JComponent c, Rectangle r) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Color color = null;
JScrollBar sb = (JScrollBar) c;
if (!sb.isEnabled()) {
return;
} else if (isDragging) {
color = ColorPri;
} else if (isThumbRollover()) {
color = ColorSec;
} else {
color = ColorSec;
}
g2.setPaint(color);
g2.fillRoundRect(1, r.y, 7, r.height, 5, 5);
g2.dispose();
}
#Override
protected void setThumbBounds(int x, int y, int width, int height) {
super.setThumbBounds(x, y, width, height);
scrollbar.repaint();
}
}
The colors are received from the main class
Is there any way to fix it without having to delete the laf or the basicUI?
Thanks in advance

Java, not applicable for the arguments,affine transform?

public void paint(Graphics g) {
Rectangle rectangle = new Rectangle(100,100,100,100);
Graphics2D g2d = (Graphics2D) g;
AffineTransform transform = new AffineTransform();
transform.rotate(
Math.toRadians(45), rectangle.getX() + rectangle.width/2,
rectangle.getY() + rectangle.height/2
);
g2d.draw(transform);
}
I am trying to rotate a rectangle around a center, but its not working.
I am getting this error:
The method draw(Shape) in the type Graphics2D is not applicable for the arguments (AffineTransform)
The error indicates that you cannot call this method with transform.
You should try to call setTransform first and then draw the rectangle.
public void paint(Graphics g) {
Rectangle rectangle = new Rectangle(100,100,100,100);
Graphics2D g2d = (Graphics2D) g;
AffineTransform transform = new AffineTransform();
transform.rotate(
Math.toRadians(45), rectangle.getX() + rectangle.width/2,
rectangle.getY() + rectangle.height/2
);
g2d.setTransform(transform);
g2d.draw(rectangle);
}

how to set transparent text color of JTextField

I want to set the transparent text color of JTextField, means the color of the text on JTextField should be same as that of JFrame on which JTextField is added. Please tell how can I do this?
This is possibly a massive overkill, but as I understand the question, essentially, what this does is makes the text "transparent" or appear "cut out" of the text field...
public class CutoutTextField extends JTextField {
public CutoutTextField() {
init();
}
public CutoutTextField(String text) {
super(text);
init();
}
public CutoutTextField(int columns) {
super(columns);
init();
}
public CutoutTextField(String text, int columns) {
super(text, columns);
init();
}
public CutoutTextField(Document doc, String text, int columns) {
super(doc, text, columns);
init();
}
protected void init() {
setOpaque(false);
}
#Override
protected void paintComponent(Graphics g) {
TextUI ui = getUI();
// This is JUST the text
BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D ig = img.createGraphics();
applyQualityRenderingHints(ig);
ui.paint(ig, this);
ig.dispose();
// This is the background of the field...
BufferedImage bg = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
ig = bg.createGraphics();
applyQualityRenderingHints(ig);
ig.setColor(getBackground());
ig.fillRect(0, 0, getWidth(), getHeight());
ig.dispose();
BufferedImage masked = ImageUtilities.applyMask(img, bg, AlphaComposite.XOR);
int y = (getHeight() - masked.getHeight()) / 2;
g.drawImage(masked, 0, y, this);
}
public BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage, int method) {
BufferedImage maskedImage = null;
if (sourceImage != null) {
int width = maskImage.getWidth(null);
int height = maskImage.getHeight(null);
maskedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D mg = maskedImage.createGraphics();
applyQualityRenderingHints(mg);
int x = (width - sourceImage.getWidth(null)) / 2;
int y = (height - sourceImage.getHeight(null)) / 2;
mg.drawImage(sourceImage, x, y, null);
mg.setComposite(AlphaComposite.getInstance(method));
mg.drawImage(maskImage, 0, 0, null);
mg.dispose();
}
return maskedImage;
}
public void applyQualityRenderingHints(Graphics2D g2d) {
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
}
}
Understand, this is a massive hack!
What this basically does, is paints the text from field to a BufferedImage, it then generates a separate BufferedImage filled with the background color of the field and then XOR's the two images together, effectively cutting the text out of the background. It then simply paints the resulting BufferedImage.
Some will note that I've not called super.paintComponent, this is done deliberately as I don't want the field to paint the background AND text but want to take control over the process.
It's possible, because the field is transparent, that I could call super.paintComponent, but I'd be painting to one of the BufferedImages any way...

Java - Method that resizes, rotates and draws a image after arguments

im trying to make a method in java that will resize rotate and draw a image after given arguments.
It does not work tho. Idk how? Btw is it posible to do this with the normal Graphic class and not Graphic2D ? Thanks!
public void drawResizedAndRotatedImage(Image image, Graphics g, int x, int y, int sizeX, int sizeY, double degrees){
//Resize
BufferedImage im = new BufferedImage(sizeX, sizeY, BufferedImage.TYPE_4BYTE_ABGR);
#SuppressWarnings("unused")
Graphics g2 = (Graphics)im.getGraphics();
//Rotate
ImageIcon imageIcon = new ImageIcon(image);
BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = (Graphics2D)bufferedImage.getGraphics();
g2d.rotate(Math.toRadians(degrees), imageIcon.getIconWidth() / 2, imageIcon.getIconHeight() / 2);
//Draw
g.drawImage(image, x, y, sizeX, sizeY, null);
}
Okay, so you create a BufferedImage and grab it's Graphics context...
BufferedImage im = new BufferedImage(sizeX, sizeY, BufferedImage.TYPE_4BYTE_ABGR);
Graphics g2 = (Graphics)im.getGraphics();
And do nothing with it...
You then create a second BufferedImage, grab it's Graphics context, set it's rotational context and paint nothing to it...
BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = (Graphics2D)bufferedImage.getGraphics();
g2d.rotate(Math.toRadians(degrees), imageIcon.getIconWidth() / 2, imageIcon.getIconHeight() / 2);
You then paint the original image to the supplied Graphics context...
g.drawImage(image, x, y, sizeX, sizeY, null);
Having achieved nothing at all...
I think you need to start by taking a read through Transforming Shapes, Text, and Images to get some grounding on the basics...
Transformations are compounding, they also only effect whatever is painted to the Graphics context AFTER they have been applied.
The simplest approach would actually be to use a AffineTransform
double scaleWidth = (double)sizeX / (double)image.getWidth(this);
double scaleHeight = (double)sizeY / (double)image.getHeight(this);
BufferedImage img = new BufferedImage(sizeX, sizeY, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
AffineTransform at = new AffineTransform();
at.scale(scaleWidth, scaleHeight);
at.rotate(Math.toRadians(degrees), image.getWidth(this) / 2d, image.getHeight(this) / 2d);
g2d.setTransform(at);
g2d.drawImage(image, sizeX / 2, sizeY / 2, null);
g2d.dispose();
// And finally, the result...
g.drawImage(img, x, y, null);
For example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestImage {
public static void main(String[] args) {
new TestImage();
}
public TestImage() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage original;
public TestPane() {
try {
original = ImageIO.read(new File("Your image here"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public Image scaleAndRotate(Image image, int sizeX, int sizeY, double degrees) {
double scaleWidth = (double)sizeX / (double)image.getWidth(this);
double scaleHeight = (double)sizeY / (double)image.getHeight(this);
BufferedImage img = new BufferedImage(sizeX, sizeY, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
AffineTransform at = new AffineTransform();
at.scale(scaleWidth, scaleHeight);
at.rotate(Math.toRadians(degrees), image.getWidth(this) / 2d, image.getHeight(this) / 2d);
g2d.setTransform(at);
g2d.drawImage(image, sizeX / 2, sizeY / 2, null);
g2d.dispose();
return img;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int scaleWidth = getWidth() / 2;
int scaleHeight = getHeight() / 2;
Image img = scaleAndRotate(original, scaleWidth, scaleHeight, 45.0);
int x = (getWidth() - img.getWidth(this)) / 2;
int y = (getHeight()- img.getHeight(this)) / 2;
g2d.drawImage(img, x, y, this);
g2d.dispose();
}
}
}
You may also like to take a read through...
Java: maintaining aspect ratio of JPanel background image
Quality of Image after resize very low -- Java
For discussions about scaling algorithms and techniques
You should also know that the size of an image when it rotates also changes, have a look at (one of my favourite answers to refer to) Rotate an image in java for more details about how to calculate the resulting image size of a rotated image...

The print output to real printer is different than the one with virtual printer in java

In my app the following code prints front and back sides of card. On virtual printers (like Virtual PDF printer, ImagePrinter Pro and Microsoft XPS Document Writer) the output is correct. But when i tested it on real printer, it only printed half of the image in width, moreover the height is correct. I tested with A4 and Letter formates, but all in vane. Dont khow what's the problem.
public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
int w = 360, h = 240;
int padding = 2;
BufferedImage temp = new BufferedImage(w * 2, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D tempG = temp.createGraphics();
tempG.drawImage(card.getFrontImage(), 0, 0,
w, h, null);
tempG.drawImage(card.getBackImage(), w, 0,
w, h, null);
tempG.dispose();
g2d.drawImage(temp, (int) 0, 0 + padding,
(int) pageFormat.getImageableWidth(), (int) pageFormat.getImageableHeight()/5, null);
}
Any help?
This is pretty simple example...
The PageFormat can be established manually (as in the example) or from the printer selection dialog
public class TestPrint implements Printable {
private BufferedImage background;
public static final float DPI = 72;
public static void main(String[] args) {
new TestPrint();
}
public TestPrint() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
try {
background = ImageIO.read(new File("/Users/swhitehead/Dropbox/MegaTokyo/MgkGrl_Yuki_by_fredrin.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
float width = cmToPixel(21f, DPI);
float height = cmToPixel(29.7f, DPI);
Paper paper = new Paper();
float margin = cmToPixel(1, DPI);
paper.setImageableArea(margin, margin, width - (margin * 2), height - (margin * 2));
PageFormat pf = new PageFormat();
pf.setPaper(paper);
BufferedImage img = new BufferedImage(Math.round(width), Math.round(height), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fill(new Rectangle2D.Float(0, 0, width, height));
try {
g2d.setClip(new Rectangle2D.Double(pf.getImageableX(), pf.getImageableY(), pf.getImageableWidth(), pf.getImageableHeight()));
print(g2d, pf, 0);
} catch (PrinterException ex) {
ex.printStackTrace();
}
g2d.dispose();
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JLabel(new ImageIcon(img)));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public float cmToPixel(float cm, float dpi) {
return (dpi / 2.54f) * cm;
}
public int print(Graphics graphics, PageFormat pageFormat, int page) throws PrinterException {
if (page > 0) {
return NO_SUCH_PAGE;
}
Graphics2D g = (Graphics2D) graphics;
g.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
if (background != null) {
int x = (int)Math.round((pageFormat.getImageableWidth() - background.getWidth()) / 2f);
int y = (int)Math.round((pageFormat.getImageableHeight() - background.getHeight()) / 2f);
g.drawImage(background, x, y, null);
}
g.setColor(Color.BLACK);
g.draw(new Rectangle2D.Double(0, 0, pageFormat.getImageableWidth() - 1, pageFormat.getImageableHeight() - 1));
return PAGE_EXISTS;
}
}

Categories