题目
编写应用程序,可以绘制图形、保存绘制结果和打开已绘图形。可以选择要绘制图形的形状和颜色,选择是否填充,绘制相应的图形,并且可保存到文件中。示例输出如图所示。
分析
要实现的功能主要有.
- 形状绘制
- 颜色选择
- 形状填充
- 打开图片文件
- 保存Graphics 2D成文件
- 图形化界面设计(按钮、面板、菜单、框架)
代码
import java.awt.*;
import java.awt.event.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.io.*;
public class paintPen {
public static void main(String[] args) {
DrawFrame frame=new DrawFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class DrawFrame extends JFrame
{
private JFileChooser chooser=new JFileChooser();//文件选择
private JButton colorButton=new JButton("颜色");//选择颜色按钮
private JPanel leftPanel=new JPanel();//左部各种按钮的面板
private paintingPanel painting=new paintingPanel();//画出的图形的面板
private ButtonGroup group=new ButtonGroup();//是否填充单选按钮组
public DrawFrame()
{
setSize(600,310);
setTitle("画笔");
/**
* 创建菜单,菜单条包括一个菜单File,File包含三个菜单项Open,Save和Exit
*/
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu menu=new JMenu("文件");
menuBar.add(menu);
JMenuItem openItem=new JMenuItem("打开");
menu.add(openItem);
openItem.addActionListener(new FileOpenListener());
JMenuItem saveItem=new JMenuItem("保存");
menu.add(saveItem);
saveItem.addActionListener(new FileSaveListener());
JMenuItem exitItem = new JMenuItem("退出");
menu.add(exitItem);
//为菜单项注册事件监听器,点击时程序退出
exitItem.addActionListener(new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
System.exit(0);
}
});
/**
左部各种按钮的添加
**/
//在面板中添加左部形状、颜色及填充按钮,并添加事件监听器
addShapeButton("直线");
addShapeButton("圆");
addShapeButton("椭圆");
addShapeButton("矩形");
//添加颜色按钮的事件监听器
colorButton.setPreferredSize(new Dimension(60,30));//设置按钮为统一大小
colorButton.addActionListener(new colorListener());
leftPanel.add(colorButton);//向左部面板中添加按钮
//向面板中添加单选按钮
addRadioButton("不填充",0);
addRadioButton("填充",1);
//设置panel大小
leftPanel.setPreferredSize(new Dimension(100,400));
/**
* 加入框架中
*/
add(leftPanel,"West");
add(painting,"Center");
}
//打开图片事件监听器
private class FileOpenListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
//设置当前工作目录
chooser.setCurrentDirectory(new File("."));
//文件过滤
imgFileFilter filter=new imgFileFilter();
chooser.setFileFilter(filter);
//显示选择对话框
chooser.showOpenDialog(null);
//获取选择文件名
String filename=chooser.getSelectedFile().getPath();
//打开图片
try {
Image image=ImageIO.read(new File(filename));
painting.setImage(image);
repaint();
}
catch(IOException e){
e.printStackTrace();
}
}
}
//保存图片事件监听器
class FileSaveListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
//设置当前工作目录
chooser.setCurrentDirectory(new File("."));
//文件过滤
imgFileFilter filter=new imgFileFilter();
chooser.setFileFilter(filter);
//显示对话框
chooser.showSaveDialog(null);
//图片保存到文件
File file=chooser.getSelectedFile();
int imgWidth=painting.getWidth();
int imgHeight=painting.getHeight();
BufferedImage image = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2=image.createGraphics();
painting.paintComponent(g2);//panel上的内容写到image
try{
ImageIO.write(image,"JPEG",file);
}
catch(Exception e){
e.printStackTrace();
}
}
}
//向选择图形面板中添加按钮
public void addShapeButton(String name)
{
//添加按钮
JButton button=new JButton(name);
button.setPreferredSize(new Dimension(60,30));//设置按钮为统一大小
leftPanel.add(button);//向左部面板中添加按钮
//添加事件监听器,点击按钮,画出图形
shapeAction listener=new shapeAction(name);
button.addActionListener(listener);
}
//形状按钮的事件监听器,负责根据形状名画出图形
private class shapeAction implements ActionListener
{
private String name;
public shapeAction(String name)
{
this.name=name;
}
public void actionPerformed(ActionEvent event)
{
painting.setType(name);
repaint();
}
}
//颜色按钮的事件监听器,负责选择颜色,重绘图形
private class colorListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
Color defaultColor=Color.RED;//默认颜色设为红色
Color selected=JColorChooser.showDialog(null,"颜色设置",defaultColor);
//重绘图形颜色
if(selected!=null)
{
painting.setColor(selected);
repaint();
}
}
}
//向按钮组中添加单选按钮,确定是否填充
public void addRadioButton(String name,int fill)
{
//添加单选按钮
JRadioButton button=new JRadioButton(name);
group.add(button);
leftPanel.add(button);
//添加事件监听器,填充图形
ActionListener listener=new ActionListener() {
public void actionPerformed(ActionEvent evt)
{
painting.setFill(fill);
repaint();
}
};
button.addActionListener(listener);
}
}
//图片文件过滤类
class imgFileFilter extends FileFilter
{
//返回该类型的说明信息
public String getDescription()
{
return "jpg/jpeg/png文件";
}
//是否接受
public boolean accept(File f)
{
if(f.isDirectory())
return true;
String name=f.getName().toLowerCase();
if(name.endsWith(".jpeg")||name.endsWith(".jpg")||name.endsWith("png"))
return true;
else return false;
}
}
//画板类,负责显示图形
class paintingPanel extends JPanel
{
private String type="";//形状类型
private int fill=0;//是否填充
private Color color=Color.RED;//颜色
private Image image=null;//显示图片
//四个形状的参数
private double c1;
private double c2;
private double c3;
private double c4;
//默认构造
public paintingPanel()
{
setBackground(Color.WHITE);//背景色设为白色
//生成四个随机数作为形状的参数
c1=Math.random()*150;
c2=Math.random()*150;
c3=Math.random()*150;
c4=Math.random()*150;
}
//含参构造
public paintingPanel(String name,int fill,Color cl,Image image)
{
this.type=name;
this.fill=fill;
this.color=cl;
this.image=image;
setBackground(Color.WHITE);//背景色设为白色
//生成四个随机数作为形状的参数
c1=Math.random()*150;
c2=Math.random()*150;
c3=Math.random()*150;
c4=Math.random()*150;
}
//设置和返回成员变量
public void setImage(Image image)
{
this.image=image;
this.type="";
}
public String getType() {
return type;
}
//换形状的时候坐标位置也相应改变
public void setType(String type) {
this.type = type;
this.image=null;
c1=Math.random()*150;
c2=Math.random()*150;
c3=Math.random()*150;
c4=Math.random()*150;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getFill() {
return fill;
}
public void setFill(int fill)
{
this.fill=fill;
}
//重写paintComponent()
public void paintComponent(Graphics g)
{
super.paintComponent(g);
//画出图形
if(image==null)
{
MyShape s=new MyShape(c1,c2,c3,c4,type,fill,color);
s.draw(g);
}
//显示图片
else
{
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
}
}
}
MyShape类
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;
//图形类
class MyShape
{
//图形的类型
private String type;
//是否填充
private int fill;
//颜色
private Color color;
//四个坐标
private double coordinate1;
private double coordinate2;
private double coordinate3;
private double coordinate4;
//无参构造
public MyShape()
{
fill=0;
coordinate1=0;
coordinate2=0;
coordinate3=0;
coordinate4=0;
}
//含参构造
public MyShape(double a,double b,double c,double d,String t,int f,Color cl)
{
type=t;
fill=f;
color=cl;
coordinate1=a;
coordinate2=b;
coordinate3=c;
coordinate4=d;
}
//画图形
public void draw(Graphics g)
{
Graphics2D g2=(Graphics2D)g;
switch(type)
{
case "直线":
Line2D line=new Line2D.Double(coordinate1,coordinate2,coordinate3,coordinate4);
g2.setColor(color);
g2.draw(line);
break;
case "圆":
Ellipse2D e=new Ellipse2D.Double(coordinate1,coordinate2,coordinate3,coordinate3);
//如果需要填充
if(fill==1)
{
g2.setPaint(color);
g2.fill(e);
}
//不需要填充,直接画图形
else
{
g2.setColor(color);
g2.draw(e);
}
break;
case "椭圆":
//四个坐标为:startx,starty,width,height
Ellipse2D c=new Ellipse2D.Double(coordinate1,coordinate2,coordinate3,coordinate4);
//如果需要填充
if(fill==1)
{
g2.setPaint(color);
g2.fill(c);
}
//不需要填充,直接画图形
else
{
g2.setColor(color);
g2.draw(c);
}
break;
case "矩形":
Rectangle2D rect=new Rectangle2D.Double(coordinate1,coordinate2,coordinate3,coordinate4);
//如果需要填充
if(fill==1)
{
g2.setPaint(color);
g2.fill(rect);
}
//不需要填充,直接画图形
else
{
g2.setColor(color);
g2.draw(rect);
}
}
}
//设置和获取四个坐标
public double getCoordinate1() {
return coordinate1;
}
public void setCoordinate1(double coordinate1) {
this.coordinate1 = coordinate1;
}
public double getCoordinate2() {
return coordinate2;
}
public void setCoordinate2(double coordinate2) {
this.coordinate2 = coordinate2;
}
public double getCoordinate3() {
return coordinate3;
}
public void setCoordinate3(double coordinate3) {
this.coordinate3 = coordinate3;
}
public double getCoordinate4() {
return coordinate4;
}
public void setCoordinate4(double coordinate4) {
this.coordinate4 = coordinate4;
}
}
运行结果