当我在JPanel
内有所有绘图代码时,下面的代码正确地将图表绘制到paintComponent()
。但我想将结果保存到硬盘驱动器上的图像文件中以供其他地方使用。因此,我将绘图代码移到了updatePaint()
方法中,并采用下面显示的其他步骤首先绘制到bufferedimage
,然后让bufferedimage
可以打印到JPanel
和到保存的文件。问题是下面的代码只是打印黑色JPanel
而不是在重新排列代码之前绘制的图表。
如何更改下面的代码,以便bufferedimage显示预期的图表,并正确地绘制到JPanel,而不会干扰其保存到文件的能力?
package somepackage;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ChartPanel extends JPanel {
private BufferedImage paintImage = new BufferedImage(500, 400, BufferedImage.TYPE_3BYTE_BGR);
private double[] values;
private String[] names;
private String title;
private double fac_result;
public ChartPanel(double[] v, String[] n, String t, double fac_res) {
names = n;
values = v;
title = t;
fac_result = fac_res;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(paintImage, 0, 0, null);
}
// draw painting
public void updatePaint(){
Graphics g = paintImage.createGraphics();
// draw on paintImage using Graphics
if (values == null || values.length == 0)
return;
double minValue = 0;
double maxValue = 0;
for (int i = 0; i < values.length; i++) {
if (minValue > values[i])
minValue = values[i];
if (maxValue < values[i])
maxValue = values[i];
}
Dimension d = getSize();
int clientWidth = d.width;
int clientHeight = d.height;
int barWidth = clientWidth / values.length;
Font titleFont = new Font("SansSerif", Font.BOLD, 20);
FontMetrics titleFontMetrics = g.getFontMetrics(titleFont);
Font labelFont = new Font("SansSerif", Font.PLAIN, 10);
FontMetrics labelFontMetrics = g.getFontMetrics(labelFont);
int titleWidth = titleFontMetrics.stringWidth(title);
int y = titleFontMetrics.getAscent();
int x = (clientWidth - titleWidth) / 2;
g.setFont(titleFont);
g.drawString(title, x, y);
int top = titleFontMetrics.getHeight();
int bottom = labelFontMetrics.getHeight();
if (maxValue == minValue)
return;
double scale = (clientHeight - top - bottom) / (maxValue - minValue);
y = clientHeight - labelFontMetrics.getDescent();
g.setFont(labelFont);
System.out.println("fac_result in paintComponent() is: "+fac_result);
for (int i = 0; i < values.length; i++) {
int valueX = i * barWidth + 1;
int valueY = top;
int height = (int) (values[i] * scale);
if (values[i] >= 0)
valueY += (int) ((maxValue - values[i]) * scale);
else {
valueY += (int) (maxValue * scale);
height = -height;
}
System.out.println("names["+i+"] is: "+names[i]);
if((Double.parseDouble(names[i])<=(fac_result+0.5))&&(Double.parseDouble(names[i])>=(fac_result-0.5))){
g.setColor(Color.cyan);
g.fillRect(valueX, valueY, barWidth - 2, height);
System.out.println("condition met.");
}
else{
g.setColor(Color.red);
g.fillRect(valueX, valueY, barWidth - 2, height);
}
g.setColor(Color.black);
g.drawRect(valueX, valueY, barWidth - 2, height);
if(i%5==0){
int labelWidth = labelFontMetrics.stringWidth(names[i]);
x = i * barWidth + (barWidth - labelWidth) / 2;
g.drawString(names[i], x, y);
}
}
///////////
g.dispose();
// repaint panel with new modified paint
repaint();
}
public void save() throws IOException{
ImageIO.write(paintImage, "PNG", new File("C:\\Temp\\filename.png"));
}
public void load() throws IOException {
paintImage = ImageIO.read(new File("C:\\Temp\\filename.png"));
// update panel with new paint image
repaint();
}
}
注意:使用以下行从另一个类调用上面的代码:
new ChartPanel(values, names, label, fac_result));
答案 0 :(得分:2)
BufferedImage
的状态,您可以查看paintImage
是否为null
并在调用paintComponent
时创建并呈现它。Graphics
上下文。从内存中,将颜色设置为透明色,并在绘制之前使用clearRect
将内容清除回透明状态。