Problems writing Image to a file.
Hi, I am kind of new in graphical programming in java (I am not new, but I almost never program GUIs and that sort of stuff). I am coding some classes to show a couple of charts in a window (JFrame), and then write them into two separate files.
All GUI part is fine, the charts are printed fine in the screen. However, when I send the Images to the file, I get the first one ok, but the second is in a black background (so I can only see the body of the chart, which I specifically state to be drawn on a white rectangle, but I can't see the axis and values).
I've tried debugging the code, and I figure I must be leaving something turned into black color for the second pass (when I write the second chart into the file), but I'm forcing everything into light gray color, and I get the same.
I really hope you can help me on this. Here is my code:
<font size=2><pre>
public class GraphicsToFile {
private ArrayList <Object [] > biv = new ArrayList();
private ImageWriter writer;
public GraphicsToFile(BufferedImage bi, String outPutFile)
{
Object [] obj = new Object[] {bi,outPutFile};
this.biv.add(obj);
Iterator writers = ImageIO.getImageWritersByFormatName("jpg");
this.writer = (ImageWriter) writers.next();
}
public void writeImagesToFile()
{
try{
for(Object[] obj : biv)
{
BufferedImage buffIm = (BufferedImage) obj[0];
String str = (String) obj[1];
File f = new File(str);
ImageOutputStream ios = ImageIO.createImageOutputStream(f);
writer.setOutput(ios);
writer.write(buffIm);
}
} catch(Exception e)
{
System.err.println("Can抰 write image to the specified file!");
}
}
public void addImage(BufferedImage obi, String outPutFile)
{
Object [] obj = new Object[] {obi,outPutFile};
this.biv.add(obj);
}
}
</pre></font>
That is the code for writing the images into the files.
Next, the code to make the chart:
<font size=2><pre>
public class Graficas extends JComponent {
public int top;
public int bottom;
public int left;
public int right;
int titleHeight;
int labelWidth;
FontMetrics fm;
int padding;
String title;
int min;
int max;
Vector<GraphItem> items;
int position;
int increment;
private Stroke normalStroke;
private Stroke dashedStroke = new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, new float[] {15}, 0);
private static final long serialVersionUID = 1L;
public Graficas(int min, int max, String title) {
this.title = title;
this.min = min;
this.max = max;
this.items = new Vector();
}
public void paint(Graphics g) {
Graphics2D g2D = (Graphics2D)g; // Get a 2D device context
g.setColor(LIGHT_GRAY);
populateValues();
g2D.setBackground(LIGHT_GRAY);
g2D.setColor(LIGHT_GRAY);
g2D.setPaint(LIGHT_GRAY);
g2D.fill(getBounds());
// Create and draw the background rectangle
g2D.setPaint(WHITE);
g2D.fill(new Rectangle(left, top, (right-left), (bottom - top)));
// draw the title
fm = getFontMetrics(getFont());
g2D.setPaint(BLACK);
g2D.drawString(title, (getWidth() - fm.stringWidth(title))/2, top);
// draw the max and min values
g2D.drawString(new Integer(min).toString(), padding, bottom);
g2D.drawString(new Integer(max).toString(), padding, top + titleHeight);
// draw the vertical and horizontal lines
g2D.drawLine(left, top, left, bottom);
g2D.drawLine(left, bottom, right, bottom);
if(items.size()!= 0)
increment = (right - left)/(items.size());
else
System.exit(2);
position = left;
Color temp = g2D.getColor();
int ancho;
for (GraphItem item : items)
{
float ped = (item.getValue()- min)*(bottom - top);
ped = ped / (max - min);
ped = bottom - ped;
int adjustedValue = new Float(ped).intValue();
//Punto medio = (position+(increment/2));
//Menos medio ancho del nombre a cada lado = - (fm.stringWidth(item.getTitle())/2))
g2D.setPaint(BLACK);
g2D.drawString(item.getTitle(), ((position+(increment/2)) - (fm.stringWidth(item.getTitle())/2)), adjustedValue - 2);
g2D.setColor(item.getColor());
if(increment< 120)
ancho = increment;
else
ancho = 120;
g2D.fill(new Rectangle((position+(increment/2)-(ancho/2)), adjustedValue, ancho, (bottom - adjustedValue)));
//Draw the dashed line
normalStroke = g2D.getStroke();
g2D.setPaint(BLACK);
g2D.drawLine((position+(increment/2)-(ancho/2)), adjustedValue,(position+(increment/2)+(ancho/2)), adjustedValue);
g2D.setStroke(dashedStroke);
g2D.drawLine((position+(increment/2)-(ancho/2)), adjustedValue, left, adjustedValue);
g2D.drawString(new Float(item.getValue()).toString(), (left - fm.stringWidth(new Float(item.getValue()).toString())), adjustedValue);
g2D.setStroke(normalStroke);
position+=increment;
g2D.setColor(temp);
}
}
private void populateValues() {
fm = getFontMetrics(getFont());
titleHeight = fm.getHeight();
labelWidth = Math.max(fm.stringWidth(new Integer(min).toString()),
fm.stringWidth(new Integer(max).toString())) + 2;
padding = (2*getWidth())/100;
top = padding + titleHeight;
bottom = getHeight() - padding;
left = padding + labelWidth;
right =getWidth() - padding;
// System.out.println("Top = " + new Integer(top).toString() + " Bottom = " + new Integer(bottom).toString() + " Right = " + new Integer(right).toString() + " Left = " +new Integer(left).toString());
// System.out.println("Padding = " + new Integer(padding).toString() + " titleHeight = " + new Integer(titleHeight).toString() + " labelWidth = " + new Integer(labelWidth).toString());
}
}
</pre></font>
And finally, the code from where I launch this:
<font size=2><pre>
public static void main ( String[] aArguments ) throws IOException
{
final ResultsManager theApp= new ResultsManager();
SwingUtilities.invokeLater(
new Runnable() { // Anonymous Runnable class object
public void run() {// Run method executed in thread
//theApp.exportResults(2.3f, 4.2f, "Pepito");// Call static GUI creator
theApp.exportComparedResults(1, 2, "pepito", 3, 4, "Maria");
}
});
}
public void exportComparedResults(float CEI_res, float GSI_res, String projectName, float CEI_res2, float GSI_res2, String projectName2){
System.out.println("Project "+projectName+":");
System.out.println(CEI_res);
System.out.println(GSI_res);
System.out.println("Project "+projectName2+":");
System.out.println(CEI_res2);
System.out.println(GSI_res2);
//Get Results File Contents
String results = formatResults( CEI_res, GSI_res, projectName, CEI_res2, GSI_res2, projectName2);
FileOutputStream outputFile = prepareOutputFile(prepareTxtOutputName(projectName+"_"+projectName2));
writeOutPutFile(outputFile, results);
getWindow();
aWindow.setBackground(LIGHT_GRAY);
float max = java.lang.StrictMath.max(CEI_res, CEI_res2) * 1.4f;
Graficas sv = new Graficas(0, new Float(max).intValue(), "CIE Results");
sv.setBackground(LIGHT_GRAY);
sv.addItem(projectName, CEI_res, BLUE);
sv.addItem(projectName2, CEI_res2, YELLOW);
max = java.lang.StrictMath.max(GSI_res2, GSI_res) * 1.4f;
Graficas sv2 = new Graficas(0, new Float(max).intValue(), "GSI Results");
sv2.setBackground(LIGHT_GRAY);
sv2.addItem(projectName, GSI_res, BLUE);
sv2.addItem(projectName2, GSI_res2, YELLOW);
GridLayout grid = new GridLayout(2,1,20,20);
aWindow.setLayout(grid);
aWindow.getContentPane().add(sv);
aWindow.getContentPane().add(sv2);
aWindow.getContentPane().setBackground(LIGHT_GRAY);
// Set the position to screen center & size to half screen size
aWindow.setBounds(wndSize.width/4, wndSize.height/7,// Position
wndSize.width/2, new Float(wndSize.height*0.8).intValue());// Size
showGraphics("METRICS COMPUTATION RESULTS");
GraphicsToFile gtf = new GraphicsToFile(getImage(sv), dirname+"\\"+prepareImageOutputName(projectName+"_"+projectName2+"_"+"CIE Results"));
gtf.addImage(getImage(sv2), dirname+"\\"+prepareImageOutputName(projectName+"_"+projectName2+"_"+ "GSI Results"));
gtf.writeImagesToFile();
}
private BufferedImage getImage(Component component){
if(component==null){return null;}
int width = component.getWidth();
int height = component.getHeight();
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
component.paintAll(g);
g.dispose();
return image;
}
private String prepareImageOutputName(String project_name)
{
// Prepare Result File and Streams.
return "metricsResults_" + project_name + ".jpg";
}
}
</pre></font>
I am avoinding getters and setters, together with some other not-affecting methods.
I really hope you can help me out with this. Thank you.
Message was edited by:
jpsilva
jpsilva
[9693 byte] By [
jpsilvaa] at [2007-10-2 21:51:16]

Works okay now. "getBounds" in Graficas "paint" was the problem.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.imageio.stream.*;
import javax.swing.*;
import static java.awt.Color.*;
public class RM {
public static void main ( String[] aArguments ) throws IOException {
final RM theApp = new RM();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// theApp.exportResults(2.3f, 4.2f, "Pepito");
theApp.exportComparedResults(1, 2, "pepito", 3, 4, "Maria");
}
});
}
public void exportComparedResults(float CEI_res, float GSI_res,
String projectName,
float CEI_res2, float GSI_res2,
String projectName2) {
System.out.println("Project "+projectName+":");
System.out.println(CEI_res);
System.out.println(GSI_res);
System.out.println("Project "+projectName2+":");
System.out.println(CEI_res2);
System.out.println(GSI_res2);
//Get Results File Contents
String results = formatResults( CEI_res, GSI_res, projectName,
CEI_res2, GSI_res2, projectName2);
FileOutputStream outputFile =
prepareOutputFile(prepareTxtOutputName(projectName+"_"+projectName2));
writeOutPutFile(outputFile, results);
//getWindow();
JFrame aWindow = new JFrame();
aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
aWindow.setBackground(LIGHT_GRAY);
float max = java.lang.StrictMath.max(CEI_res, CEI_res2) * 1.4f;
Graficas sv = new Graficas(0, new Float(max).intValue(), "CIE Results");
sv.setBackground(LIGHT_GRAY);
sv.addItem(projectName, CEI_res, BLUE);
sv.addItem(projectName2, CEI_res2, YELLOW);
max = java.lang.StrictMath.max(GSI_res2, GSI_res) * 1.4f;
Graficas sv2 = new Graficas(0, new Float(max).intValue(), "GSI Results");
sv2.setBackground(LIGHT_GRAY);
sv2.addItem(projectName, GSI_res, BLUE);
sv2.addItem(projectName2, GSI_res2, YELLOW);
GridLayout grid = new GridLayout(2,1,20,20);
aWindow.setLayout(grid);
aWindow.getContentPane().add(sv);
aWindow.getContentPane().add(sv2);
// use this trick to see the background of your components
// it reveals the cause of the black background - see Graficas.paint
aWindow.getContentPane().setBackground(RED);
// Set the position to screen center & size to half screen size
Dimension wndSize = Toolkit.getDefaultToolkit().getScreenSize();
aWindow.setBounds(wndSize.width/4, wndSize.height/7,
wndSize.width/2, new Float(wndSize.height*0.8).intValue());
aWindow.setVisible(true);
showGraphics("METRICS COMPUTATION RESULTS");
String dirname = ".";
GraphicsToFile gtf = new GraphicsToFile(getImage(sv),
dirname+"\\"+
prepareImageOutputName(projectName+
"_"+projectName2+"_"+"CIE Results"));
gtf.addImage(getImage(sv2), dirname+"\\"+
prepareImageOutputName(projectName+"_"+projectName2+
"_"+ "GSI Results"));
gtf.writeImagesToFile();
}
private BufferedImage getImage(Component component) {
if(component==null) { return null; }
int width = component.getWidth();
int height = component.getHeight();
Dimension d = component.getPreferredSize();
System.out.printf("\twidth %dheight %d%s\n",
width, height, d);
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
component.paint(g);
g.dispose();
return image;
}
private String prepareImageOutputName(String project_name) {
// Prepare Result File and Streams.
return "metricsResults_" + project_name + ".jpg";
}
String formatResults( float CEI_res, float GSI_res, String projectName,
float CEI_res2, float GSI_res2, String projectName2) {
return String.valueOf(CEI_res) + " " + String.valueOf(GSI_res) +
" " + projectName + " " + String.valueOf(CEI_res2) +
" " + String.valueOf(GSI_res2) + " " + projectName2;
}
String prepareTxtOutputName(String s) {
return "s" + ".txt";
}
void writeOutPutFile(FileOutputStream fos, String s) {
}
FileOutputStream prepareOutputFile(String s) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(s);
} catch(FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
return fos;
}
void showGraphics(String s) { System.out.println(s); }
}
class GraphicsToFile {
// avoid the compiler warnings
private ArrayList<Object[]> biv = new ArrayList<Object[]>();
private ImageWriter writer;
public GraphicsToFile(BufferedImage bi, String outPutFile) {
Object[] obj = new Object[] {bi, outPutFile};
this.biv.add(obj);
Iterator writers = ImageIO.getImageWritersByFormatName("jpg");
this.writer = (ImageWriter) writers.next();
}
public void writeImagesToFile() {
try {
for(Object[] obj : biv) {
BufferedImage buffIm = (BufferedImage) obj[0];
String str = (String) obj[1];
File f = new File(str);
ImageOutputStream ios = ImageIO.createImageOutputStream(f);
writer.setOutput(ios);
writer.write(buffIm);
}
} catch(Exception e) {
System.err.println("Can抰 write image to the specified file!");
}
}
public void addImage(BufferedImage obi, String outPutFile) {
Object[] obj = new Object[] {obi, outPutFile};
this.biv.add(obj);
}
}
class Graficas extends JComponent {
public int top;
public int bottom;
public int left;
public int right;
int titleHeight;
int labelWidth;
FontMetrics fm;
int padding;
String title;
int min;
int max;
Vector<GraphItem> items;
int position;
int increment;
private Stroke normalStroke;
private Stroke dashedStroke = new BasicStroke(2, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND,
0, new float[] {15}, 0);
private static final long serialVersionUID = 1;
public Graficas(int min, int max, String title) {
this.title = title;
this.min = min;
this.max = max;
// avoid the compiler warnings
this.items = new Vector<GraphItem>();
}
public void paint(Graphics g) {
Graphics2D g2D = (Graphics2D)g; // Get a 2D device context
g.setColor(LIGHT_GRAY);
populateValues();
// you can fill the background with these two lines
g2D.setBackground(LIGHT_GRAY);
g2D.clearRect(0, 0, getWidth(), getHeight());
//g2D.setColor(LIGHT_GRAY); redundant, not needed
// or these next two lines
//g2D.setPaint(LIGHT_GRAY);
//g2D.fillRect(0, 0, getWidth(), getHeight());
// this was the problem with the background:
// the local component bounds are (0, 0, width, height)
// getBounds is a Rectangle in the parent containers
// space, ie, not located at (0, 0)
// so you're filling something else besides the background
// of this component
//g2D.fill(getBounds());
System.out.printf("bounds for %s = %s\n\n", title, getBounds());
// Create and draw the background rectangle
g2D.setPaint(WHITE);
g2D.fill(new Rectangle(left, top, (right-left), (bottom - top)));
// draw the title
fm = getFontMetrics(getFont());
g2D.setPaint(BLACK);
g2D.drawString(title, (getWidth() - fm.stringWidth(title))/2, top);
// draw the max and min values
g2D.drawString(new Integer(min).toString(), padding, bottom);
g2D.drawString(new Integer(max).toString(), padding, top + titleHeight);
// draw the vertical and horizontal lines
g2D.drawLine(left, top, left, bottom);
g2D.drawLine(left, bottom, right, bottom);
if(items.size()!= 0)
increment = (right - left)/(items.size());
else
System.exit(2);
position = left;
Color temp = g2D.getColor();
int ancho;
for (GraphItem item : items) {
float ped = (item.getValue()- min)*(bottom - top);
ped = ped / (max - min);
ped = bottom - ped;
int adjustedValue = new Float(ped).intValue();
//Punto medio = (position+(increment/2));
//Menos medio ancho del nombre a cada lado =
// - (fm.stringWidth(item.getTitle())/2))
g2D.setPaint(BLACK);
g2D.drawString(item.getTitle(),
((position+(increment/2)) - (fm.stringWidth(item.getTitle())/2)),
adjustedValue - 2);
g2D.setColor(item.getColor());
if(increment< 120)
ancho = increment;
else
ancho = 120;
g2D.fill(new Rectangle((position+(increment/2)-(ancho/2)), adjustedValue,
ancho, (bottom - adjustedValue)));
//Draw the dashed line
normalStroke = g2D.getStroke();
g2D.setPaint(BLACK);
g2D.drawLine((position+(increment/2)-(ancho/2)), adjustedValue,
(position+(increment/2)+(ancho/2)), adjustedValue);
g2D.setStroke(dashedStroke);
g2D.drawLine((position+(increment/2)-(ancho/2)), adjustedValue,
left, adjustedValue);
g2D.drawString(new Float(item.getValue()).toString(),
(left - fm.stringWidth(new Float(item.getValue()).toString())),
adjustedValue);
g2D.setStroke(normalStroke);
position+=increment;
g2D.setColor(temp);
}
}
void addItem(String s, float f, Color c) {
items.add(new GraphItem(s, f, c));
repaint();
}
private void populateValues() {
fm = getFontMetrics(getFont());
titleHeight = fm.getHeight();
labelWidth = Math.max(fm.stringWidth(new Integer(min).toString()),
fm.stringWidth(new Integer(max).toString())) + 2;
padding = (2*getWidth())/100;
top = padding + titleHeight;
bottom = getHeight() - padding;
left = padding + labelWidth;
right =getWidth() - padding;
System.out.println("Top = " + top + " Bottom = " + bottom +
" Right = " + right + " Left = " + left);
System.out.println("Padding = " + padding +
" titleHeight = " + titleHeight +
" labelWidth = " + labelWidth);
}
}
class GraphItem {
String title;
float value;
Color color;
GraphItem(String title, float value, Color color) {
this.title = title;
this.value = value;
this.color = color;
}
public String getTitle() { return title; }
public float getValue() { return value; }
public Color getColor() { return color; }
}