Reputation: 4592
I have a JPanel that draws shapes and allows those shapes to be selected. I'm starting to add the capability to transform this view using the AffineTransform object, in conjunction with the Graphics2D object.
In my paint() method, of course a Graphics object is passed in. I set a new transform on that object (in this case, just scaling things by 2), and everything in the paint() method draws correctly according to the AffineTransform I just set. At this point the drawing shapes part works great! Now on to the shape selection...
Shape selection starts in the mousePressed() event (My JPanel implements the MouseListener interface). When I have a mousePressed() event, I call this.getGraphics() to get the JPanel's Graphics object. I then case it to a Graphics2D object and call getTransform() on it to get my current transform so I can map the clicked point to the transformed point. When I call getTransform(), however, the AffineTransform is back to the default AffineTransform of [1, 0, 0], [0, 1, 0].
I'm thinking that maybe the Graphics object passed to the JPanel's paint() is different than the one I have in my JPanel, but I'm not sure on that. Does anyone have any idea what's going on here?
Upvotes: 2
Views: 1212
Reputation: 387
Simple Class Print An Object OR JPanel.
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.DialogTypeSelection;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class TemplateDemo extends JFrame implements Printable, ActionListener {
JButton btn;
JTextField name_txt;
JPanel panel;
public TemplateDemo() {
panel = new JPanel(null);
panel.setBounds(0, 0, 300, 300);
add(panel);
name_txt = new JTextField();
name_txt.setBounds(0, 10, 200, 20);
panel.add(name_txt);
btn = new JButton("Click");
btn.setBounds(0, 240, 200, 30);
btn.addActionListener(this);
panel.add(btn);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(0, 0, 400, 400);
setLayout(null);
setVisible(true);
}
@Override
public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
Graphics2D graphics = (Graphics2D) g;
if (pageIndex == 0) {
g.translate((int) pageFormat.getImageableX(), (int) pageFormat.getImageableY());
panel.print(g);
return PAGE_EXISTS;
}
return NO_SUCH_PAGE;
}
@Override
public void actionPerformed(ActionEvent e) {
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(this);
PrintRequestAttributeSet set = new HashPrintRequestAttributeSet();
set.add(Chromaticity.COLOR);
set.add(DialogTypeSelection.COMMON);
if (pj.printDialog(set)) {
try {
pj.print(set);
} catch (PrinterException ex) {
}
}
}
public static void main(String[] args) {
new TemplateDemo();
}
}
Upvotes: 0
Reputation: 1792
Yes, you can't be sure that you will get the same Graphics object back. In fact, you shouldn't work with a Graphics object outside of the paintComponent()
method, as this breaks the Swing UI model. You will probably get artifacts and/or incomplete drawing if you do this. The right approach is to have some instance variables that store the state of your UI/widget. When mousePressed()
is called, you just update those variables and call repaint()
. Then in your paintComponent()
method, apply the appropriate transforms and draw your UI.
Upvotes: 4