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]
# 1

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; }

}

74philipa at 2007-7-14 1:07:07 > top of Java-index,Security,Cryptography...
# 2
Ok, thank you very much!!!I will go and try that now.
jpsilvaa at 2007-7-14 1:07:07 > top of Java-index,Security,Cryptography...