I know I have seen this on the forum, but I cannot find it. Is there a way to add patterns to bars to make them more easy to distinguish. I'm not looking for something as flexible as seriesPaint, only one pattern would do.
/vs
counterpart to setSeriesStroke for barcharts
Re: counterpart to setSeriesStroke for barcharts
I've not yet found a good method for drawing background patterns to fill arbitrary shapes in Java2D...suggestions are welcome.
Regards,
Dave Gilbert
Regards,
Dave Gilbert
Re: counterpart to setSeriesStroke for barcharts
I've gotten this working ok using java.awt.TexturePaint with the JFreeChart.setSeriesPaint() method.....
See http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html for explanation on how TexturePaint() works/etc.
See below for code on how to integrate with JFreeChart.
In addion to this code, you'll have to create pattern files for each series.... let me know if you'd like me to send you the ones I'm using (they aren't anything special at the moment).
/** Take an Image associated with a file, and wait until it is
* done loading. Just a simple application of MediaTracker.
* If you are loading multiple images, don't use this
* consecutive times; instead use the version that takes
* an array of images.
* see http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html
*/
private static boolean waitForImage(Image image, Component c) {
MediaTracker tracker = new MediaTracker(c);
tracker.addImage(image, 0);
try {
tracker.waitForAll();
} catch(InterruptedException ie) {}
return(!tracker.isErrorAny());
}
/** Create Image from a file, then turn that into a BufferedImage.
* see http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html
*/
private static BufferedImage getBufferedImage(String imageFile, Component c) {
Image image = c.getToolkit().getImage(imageFile);
waitForImage(image, c);
BufferedImage bufferedImage =new BufferedImage(image.getWidth(c), image.getHeight(c), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.drawImage(image, 0, 0, c);
return(bufferedImage);
}
/* Returns the TexturedPaint Object assoiciatd with Series Index nIndex
* see http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html
*/
private static TexturePaint getTexturePaint(int nIndex) {
//@todo XXXX imageDirectory should be pulled from a configuration file
String imageDirectory = "/myImageDirectory/";
String imageFileName =imageDirectory + "pattern" + nIndex + ".png";
javax.swing.JPanel jPanelDummy = new javax.swing.JPanel();
BufferedImage image = getBufferedImage(imageFileName, jPanelDummy);
Rectangle imageRect = new Rectangle(0, 0,image.getWidth(),image.getHeight()); //needs to be very small!!!
TexturePaint imagePaint =new TexturePaint(image, imageRect);
return imagePaint;
}
.....
//... within your code, you'll need something like this...
//... note: I do this only when I know I need to render a black and white
//image (ie when printing to a black and white printer). when rendering to
//a screen or a color printer, I just use straight colors/etc.
// set the hatch pattern for each series...
// should be bigger than highest # of series
TexturePaint[] hatchPatterns = new TexturePaint[MAX_SERIES+1];
for (int i=0; i<hatchPatterns.length; i++) {
hatchPatterns = getTexturePaint(i);
}
plot.setSeriesPaint(hatchPatterns);
//Color of the outline - needed because some of our bars may be white in color - don't want a snowman in a snowstorm problem when printing to a black and white printer
plot.setSeriesOutlinePaint(new Paint[] { Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black });
See http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html for explanation on how TexturePaint() works/etc.
See below for code on how to integrate with JFreeChart.
In addion to this code, you'll have to create pattern files for each series.... let me know if you'd like me to send you the ones I'm using (they aren't anything special at the moment).
/** Take an Image associated with a file, and wait until it is
* done loading. Just a simple application of MediaTracker.
* If you are loading multiple images, don't use this
* consecutive times; instead use the version that takes
* an array of images.
* see http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html
*/
private static boolean waitForImage(Image image, Component c) {
MediaTracker tracker = new MediaTracker(c);
tracker.addImage(image, 0);
try {
tracker.waitForAll();
} catch(InterruptedException ie) {}
return(!tracker.isErrorAny());
}
/** Create Image from a file, then turn that into a BufferedImage.
* see http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html
*/
private static BufferedImage getBufferedImage(String imageFile, Component c) {
Image image = c.getToolkit().getImage(imageFile);
waitForImage(image, c);
BufferedImage bufferedImage =new BufferedImage(image.getWidth(c), image.getHeight(c), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.drawImage(image, 0, 0, c);
return(bufferedImage);
}
/* Returns the TexturedPaint Object assoiciatd with Series Index nIndex
* see http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html
*/
private static TexturePaint getTexturePaint(int nIndex) {
//@todo XXXX imageDirectory should be pulled from a configuration file
String imageDirectory = "/myImageDirectory/";
String imageFileName =imageDirectory + "pattern" + nIndex + ".png";
javax.swing.JPanel jPanelDummy = new javax.swing.JPanel();
BufferedImage image = getBufferedImage(imageFileName, jPanelDummy);
Rectangle imageRect = new Rectangle(0, 0,image.getWidth(),image.getHeight()); //needs to be very small!!!
TexturePaint imagePaint =new TexturePaint(image, imageRect);
return imagePaint;
}
.....
//... within your code, you'll need something like this...
//... note: I do this only when I know I need to render a black and white
//image (ie when printing to a black and white printer). when rendering to
//a screen or a color printer, I just use straight colors/etc.
// set the hatch pattern for each series...
// should be bigger than highest # of series
TexturePaint[] hatchPatterns = new TexturePaint[MAX_SERIES+1];
for (int i=0; i<hatchPatterns.length; i++) {
hatchPatterns = getTexturePaint(i);
}
plot.setSeriesPaint(hatchPatterns);
//Color of the outline - needed because some of our bars may be white in color - don't want a snowman in a snowstorm problem when printing to a black and white printer
plot.setSeriesOutlinePaint(new Paint[] { Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black, Color.black });
Re: counterpart to setSeriesStroke for barcharts
Thanks. I'm not sure I get it tho. How is this texturepaint combined with the usual setSeriesPaint that controls color?
Re: counterpart to setSeriesStroke for barcharts
texturepaint class works just like the paint class...
The setSeriesPaint takes an array of texturepaint objects just as happily as a an array of Paint objects.... see the following code snippets:
// set the hatch pattern for each series...
TexturePaint[] hatchPatterns = new TexturePaint[MAX_SERIES+1];
for (int i=0; i<hatchPatterns.length; i++) {
hatchPatterns = getTexturePaint(i);
}
plot.setSeriesPaint(hatchPatterns);
//this replaces the normal way to work with setSeriesPaint, ie:
plot.setSeriesPaint(new Paint[] { Color.blue, Color.green, Color.red, Color.cyan, Color.pink });
----
If you want blue dots and red diagonals and green vertical stripes, etc., you just need to make the images in your pattern image files colored appropriately.
Our needs here is that we only use the patterns when printing to a B&W printer, so we made all the hatch patterns in black and white.
hope this helps.
The setSeriesPaint takes an array of texturepaint objects just as happily as a an array of Paint objects.... see the following code snippets:
// set the hatch pattern for each series...
TexturePaint[] hatchPatterns = new TexturePaint[MAX_SERIES+1];
for (int i=0; i<hatchPatterns.length; i++) {
hatchPatterns = getTexturePaint(i);
}
plot.setSeriesPaint(hatchPatterns);
//this replaces the normal way to work with setSeriesPaint, ie:
plot.setSeriesPaint(new Paint[] { Color.blue, Color.green, Color.red, Color.cyan, Color.pink });
----
If you want blue dots and red diagonals and green vertical stripes, etc., you just need to make the images in your pattern image files colored appropriately.
Our needs here is that we only use the patterns when printing to a B&W printer, so we made all the hatch patterns in black and white.
hope this helps.
Re: counterpart to setSeriesStroke for barcharts
For my purpouse it would be good if the color paint wasn't connected to the texture, just as setSeriesStroke isn't. I want to use texture on top of color, to add an extra attribute to the series. Thanks for the help anyways.