Search |
|||||||
How to draw simple diagrams the easy way (with Java2D)Posted by cayhorstmann on October 8, 2009 at 9:12 PM PDT
When you need to produce lots of fairly straightforward graphs, Java2D is your friend. In this blog, I show you how you can render simple images as crisp-looking PDF or EPS files, provided you can draw them on a Graphics2D object. Recently, I had to draw a bunch of simple images, such as this one
or this PDF
Of course, you can do these drawings in Illustrator or Inkscape. But if you are a coder like me, a graphics program may not be your cup of tea. It takes me about 15 seconds to code
for (int i = 0; i < 6; i++)
for (int j = 0; j < 6; j++) {
g2.setColor(2 <= i && i <= 3 && 2 <= j && j <= 3 ? Color.GREEN : Color.RED);
g2.fillRect(i * 30, j * 30, 29, 29);
}
(Or at least it feels like 15 seconds :-)) To do the same in Inkscape would take me a seriously long time, and I would be bored to tears. What about that maze? I had to set it up anyway for a CS1 lab, using Alice, and it wasn't much extra trouble to add a Once you can draw your image on a
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.print.*;
import java.io.*;
import javax.imageio.*;
import javax.print.*;
import javax.print.attribute.*;
import javax.swing.*;
public class Image {
// Set your image dimensions here
private static int IMAGE_WIDTH = ...;
private static int IMAGE_HEIGHT = ...;
public static void draw(Graphics2D g2) {
// Your drawing instructions go here
...
}
// No need to touch anything below this line
public static void main(String[] args)
{
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JComponent component = new JComponent() {
public void paintComponent(Graphics g) {
draw((Graphics2D) g);
}
public Dimension getPreferredSize() {
return new Dimension(IMAGE_WIDTH, IMAGE_HEIGHT);
}
};
frame.add(component);
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu menu = new JMenu("File");
menu.setMnemonic('F');
menuBar.add(menu);
JMenuItem item = new JMenuItem("Save", 'S');
menu.add(item);
item.setAccelerator(KeyStroke.getKeyStroke("ctrl S"));
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
JFileChooser chooser = new JFileChooser();
if (chooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION)
try {
saveImage(component, chooser.getSelectedFile().getPath());
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
frame.pack();
frame.setVisible(true);
}
private static void saveImage(final JComponent comp, String fileName) throws IOException, PrintException {
if (fileName.endsWith(".ps")) {
DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
String mimeType = "application/postscript";
StreamPrintServiceFactory[] factories = StreamPrintServiceFactory.lookupStreamPrintServiceFactories(flavor, mimeType);
FileOutputStream out = new FileOutputStream(fileName);
if (factories.length > 0) {
PrintService service = factories[0].getPrintService(out);
SimpleDoc doc = new SimpleDoc(new Printable() {
public int print(Graphics g, PageFormat pf, int page) {
if (page >= 1) return Printable.NO_SUCH_PAGE;
else {
double sf1 = pf.getImageableWidth() / (comp.getWidth() + 1);
double sf2 = pf.getImageableHeight() / (comp.getHeight() + 1);
double s = Math.min(sf1, sf2);
Graphics2D g2 = (Graphics2D) g;
g2.translate((pf.getWidth() - pf.getImageableWidth()) / 2, (pf.getHeight() - pf.getImageableHeight()) / 2);
g2.scale(s, s);
comp.paint(g);
return Printable.PAGE_EXISTS;
}
}
}, flavor, null);
DocPrintJob job = service.createPrintJob();
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
job.print(doc, attributes);
}
} else {
Rectangle rect = comp.getBounds();
BufferedImage image = new BufferedImage(rect.width, rect.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D) image.getGraphics();
g.setColor(Color.WHITE);
g.fill(rect);
g.setColor(Color.BLACK);
comp.paint(g);
String extension = fileName.substring(fileName.lastIndexOf('.') + 1);
ImageIO.write(image, extension, new File(fileName));
g.dispose();
}
}
}
»
Related Topics >>
J2SE Java Tools Comments
Comments are listed in date ascending order (oldest first)
|
|||||||
|
|
JavaFX Can Save to Image File
JavaFX has an unpublished method to save scenes to an image file:
Scene.renderToImage(Object)import javafx.stage.Stage;
import javafx.scene.Scene;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
def stage = Stage { scene: Scene { } }
try {
//Add to scene.
def bufferedImage = new BufferedImage( 640, 480, BufferedImage.TYPE_INT_RGB );
stage.scene.renderToImage( bufferedImage );
def bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("yourFileName.png"));
javax.imageio.ImageIO.write( bufferedImage, "PNG", bufferedOutputStream );
bufferedOutputStream.close();
}
catch ( ioException: IOException ) {
println( ioException.getMessage( ) );
}