写出来主要是希望遇到大神指点迷津,这自己边试边学得出来得经验来得太慢了,而且累。有没有更实用的资料或者书籍介绍java画图中,JFrame,JPanel,JComponent,Graphics,Graphices2D,Graphices3D,Shape,这些区别与联系的实用的资料书,本人将不胜感激!!!
其实主要是想用JComponent这个组件,里面有些画图方法比较方便。但是返回的对象又不知道怎么做处理导出,所以就尝试,实验出了这3种导出方法。
1.通过导出jfream窗口图片(这种方式是jfream窗口和图片保存都会做显示,jfream的黑框背景会显示,求大神指点)
package com.dasenlin.test;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import com.dasenlin.util.MyFrame;
public class TestJframePic {
public static final String DEST4 = "C:/Users/Toshiba/Desktop/testjframe.png";
/**
* @param args
*/
public static void main(String[] args) {
/*
* 在 AWT 的事件队列线程中创建窗口和组件, 确保线程安全,
* 即 组件创建、绘制、事件响应 需要处于同一线程。
*/
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
// 创建窗口对象
MyFrame frame = new MyFrame("折线",250,300);
// 显示窗口(必须显示,否则就是黑框,还有就是这个有点问题的就是,jfream的黑框背景会显示,求大神指点)
frame.setVisible(true);
savePic(frame);
}
});
}
public static void savePic(JFrame jf){
//得到窗口内容面板
Container content=jf.getContentPane();
//创建缓冲图片对象
BufferedImage img=new BufferedImage( jf.getWidth(),jf.getHeight(),BufferedImage.TYPE_INT_RGB);
//得到图形对象
Graphics2D g2d = img.createGraphics();
//将窗口内容面板输出到图形对象中
content.printAll(g2d);
//保存为图片
try{
ImageIO.write(img, "jpg", new File( DEST4));
}catch (IOException e){
e.printStackTrace();
}
//释放图形对象
g2d.dispose();
}
}
2.通过导出Jpanel图片(这种方式可以不用考虑jfream的黑框背景,甚至不显示jfream也能导出)
package com.dasenlin.util;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
/**
*
* @author Toshiba
*
*/
public class MyFrame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
public static final String DEST4 = "C:/Users/Toshiba/Desktop/testjframe.png";
public MyFrame(String title,Integer windowW,Integer windowH) {
super();
initFrame(title,windowW,windowH);
}
private void initFrame(String title,Integer windowW,Integer windowH) {
// 设置 窗口标题 和 窗口大小
setTitle(title);
setSize(windowW, windowH);
// 设置窗口关闭按钮的默认操作(点击关闭时退出进程)
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// 把窗口位置设置到屏幕的中心
setLocationRelativeTo(null);
// 设置窗口的内容面板
MyPanel panel = new MyPanel(this);
setContentPane(panel);
//自己的JPanel
// 必须要有大小
panel.setSize(windowW, windowH);
BufferedImage image = new BufferedImage(windowW, windowH, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
panel.paint(g2);
try {
ImageIO.write(image, "jpg", new File(DEST4));
} catch (IOException e) {
e.printStackTrace();
}
}
}
直接graphics2D中用graphics的画图方法导出
public static void savePic(JFrame jf){
BufferedImage images= DepParserSvgUtil.depParserSvg(dataList);
try{
ImageIO.write(images, "PNG", new File( DEST4));
}catch (IOException e){
e.printStackTrace();
}
}
public static BufferedImage depParserSvg(List<Map<String,Object>> yicunList){
BufferedImage bi = new BufferedImage(DEFAULT_W, DEFAULT_H, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
//设置画笔(设置背景)
g2d.setPaint(Color.WHITE);
g2d.fillRect(5, 5, DEFAULT_W, DEFAULT_H);
//draw string
g2d.setPaint(Color.BLACK);
Font f = new Font("宋体", Font.PLAIN, ZH_WORD_WIDTH);
g2d.setFont(f);
FontRenderContext context = g2d.getFontRenderContext();
for(int w=0; w<yicunList.size();w++){
String word = yicunList.get(w).get("word").toString();
String mark = yicunList.get(w).get("id").toString()+"|"+yicunList.get(w).get("post").toString();
String lable = yicunList.get(w).get("dep_type").toString();
float wordx = (float) WORDS_TRANSLATE.get(w).get("x");
float wordy = (float) WORDS_TRANSLATE.get(w).get("y");
g2d.drawString(word, wordx, wordy);
Rectangle2D bounds = f.getStringBounds(word, context);
g2d.draw(bounds);
double wordW=bounds.getWidth();//文本宽度
double wordH=bounds.getHeight();//文本高度
double ascent=-bounds.getY();//文本上坡度
LineMetrics metrics=f.getLineMetrics(word, context);
float descent=metrics.getDescent();//文本下坡度
float leading=metrics.getLeading();//文本行距
float markx = wordx;
float marky = (float) (wordy+descent+leading+wordH);
g2d.drawString(mark, markx, marky);
bounds = f.getStringBounds(mark, context);
g2d.draw(bounds);
double markW=bounds.getWidth();//文本宽度
//画边框矩形
double borderW = (double) Math.max(wordW, markW);
Rectangle2D msgRect=new Rectangle2D.Double(wordx,wordy-ascent,borderW,wordH*2+descent*2+leading*2);//包围文本的矩形
g2d.draw(msgRect);
//画关系线
int edge1x = EDGE_PATH.get(w).get(0).get("x");
int edge1y = EDGE_PATH.get(w).get(0).get("y");
int edge2x = EDGE_PATH.get(w).get(1).get("x");
int edge2y = EDGE_PATH.get(w).get(1).get("y");
int edge3x = EDGE_PATH.get(w).get(2).get("x");
int edge3y = EDGE_PATH.get(w).get(2).get("y");
int edge4x = EDGE_PATH.get(w).get(3).get("x");
int edge4y = EDGE_PATH.get(w).get(3).get("y");
g2d.drawLine(edge1x, edge1y, edge2x, edge2y);
g2d.drawLine(edge2x, edge2y, edge3x, edge3y);
g2d.drawLine(edge3x, edge3y, edge4x, edge4y);
//画箭头
int rectangle1x =edge4x-5;
int rectangle1y =edge4y;
int rectangle2x =edge4x+5;
int rectangle2y =edge4y;
int rectangle3x =edge4x;
int rectangle3y =edge4y+5;
g2d.drawLine(rectangle1x, rectangle1y, rectangle2x, rectangle2y);
g2d.drawLine(rectangle2x, rectangle2y, rectangle3x, rectangle3y);
g2d.drawLine(rectangle3x, rectangle3y, rectangle1x, rectangle1y);
//画lable
int lablex = EDGE_LABLE_INFO.get(w).get("x");
int labley = EDGE_LABLE_INFO.get(w).get("y");
int lableH = EDGE_LABLE_INFO.get(w).get("height");
int lableW = EDGE_LABLE_INFO.get(w).get("width");
f = new Font("SansSerif",Font.BOLD,ONE_LABLE_HEIGHT);
context = g2d.getFontRenderContext();
bounds = f.getStringBounds(lable,context);
g2d.setFont(f);
g2d.clearRect((int)(lablex*1.05 - bounds.getCenterX()), (int)(labley - (lableH/2) - bounds.getCenterY()), lableW, lableH);
g2d.drawString(lable, (float) (lablex*1.05 - bounds.getCenterX()), (float) (labley - (lableH/2) - bounds.getCenterY()));
}
/****************Graphics2DDrawEnd*****************/
g2d.dispose();//销毁资源
return bi;
}
综合上述,实用继承Jpanel并输出图片的方式比较好,可以兼顾jfream的前端输出,可以做后台输出。还可以实用组件的一些好用方法。代码结构比较清晰。
以下是Jpanel中画图的代码
package com.dasenlin.util;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import javax.swing.JPanel;
public class MyPanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private MyFrame frame;
public MyPanel(MyFrame frame) {
this.frame = frame;
}
/**
* 绘制面板的内容: 创建 JPanel 后会调用一次该方法绘制内容,
* 之后如果数据改变需要重新绘制, 可调用 updateUI() 方法触发
* 系统再次调用该方法绘制更新 JPanel 的内容。
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// 重新调用 Graphics 的绘制方法绘制时将自动擦除旧的内容
/* 自行打开下面注释查看各绘制效果 */
// 1. 线段 / 折线
drawLine(g);
// 2. 矩形 / 多边形
// drawRect(g);
// 3. 圆弧 / 扇形
// drawArc(g);
// 4. 椭圆
// drawOval(g);
// 5. 图片
// drawImage(g);
// 6. 文本
// drawString(g);
}
/**
* 1. 线段 / 折线
*/
private void drawLine(Graphics g) {
frame.setTitle("1. 线段 / 折线");
// 创建 Graphics 的副本, 需要改变 Graphics 的参数,
// 这里必须使用副本, 避免影响到 Graphics 原有的设置
Graphics2D g2d = (Graphics2D) g.create();
// 抗锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 设置画笔颜色
g2d.setColor(Color.RED);
}
写出来主要是希望遇到大神指点迷津,这自己边试边学得出来得经验来得太慢了,而且累。有没有更实用的资料或者书籍介绍java画图中,JFrame,JPanel,JComponent,Graphics,Graphices2d,Graphices3D,Shape,这些区别与联系的资料书,本人将不胜感激!!!