博主是一枚正在学习Java语言的小白,这篇博客也是博主的第一篇博客,想在这里分享给大家。这个绘图程序的关键是怎样使用Java的鼠标事件处理,我做的这个程序就是利用鼠标按下“public void mousePressed(MouseEvent e)”事件和鼠标释放“public void mouseReleased(MouseEvent e)”事件来完成绘制简单图形的。
除了绘制图案以外,我还做了两个菜单按钮,一个是“新建”,另一个是“保存”。“保存”菜单我做的不详细,不会用选择目录的方式保存,保存是利用 Java的一个类Robot提供了抓屏功能实现的,这里感谢一位大牛博主“小白的学习笔记”的一篇文章,链接Java在JPanel中自由绘图,并将绘图保存为jpg文件小白的学习笔记
下面是我做的程序的效果图:
所有代码都有详细的注释,下面给出步骤和全部的代码。
1、设计程序的容器分布和具有的组件。(我的程序的是大致是这样的)
2、编写的程序具体组件和容器代码,并设置好布局。
(我这里是用一个DrawForm.java类,“画图功能区”按钮用到了三个图片,在文章最后给出)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
public class DrawForm extends JFrame{
private static final long serialVersionUID = 1L;
static int DrawFormCount=1; //此静态变量用做“新建”菜单创建的绘图窗口数
private int width=1280; //定义窗体的宽度
private int height=720; //定义窗体的高度
private String Title; //定义窗体名字Title,用作保存时使用
JMenuBar JMenubar; //定义菜单条
JMenu JMenuNew; //定义菜单“新建”
JMenu JMenuSave; //定义菜单“保存”
JPanel JPanelTop; //定义JPanelTop面板,放ID,Name相关JButton和JTextField
JButton BtnID; //定义BtnID按钮
JTextField TfdID; //定义TfdID文本框
JButton BtnName; //定义BtnName按钮
JTextField TfdName; //定义TfdName文本框
JPanel JPanelWorkPlace; //定义JPanelWorkPlace,用来放JPanelWorkOfLeft和JPanelWorkOfDraw
JPanel JPanelWorkOfLeft; //定义JPanelWorkOfLeft用来放 选择绘图的哪个图案的按钮
JButton BtnDrawLine; //定义画直线的BtnDrawLine按钮
JButton BtnDrawRectangle; //定义画矩形的BtnDrawRectangle按钮
JButton BtnDrawOval; //定义画椭圆的BtnDrawOval按钮
JPanel JPanelWorkOfDraw; //定义JPanelWorkOfDraw,用做画图面板
JLabel JLabelShowID; //定义JLabelShowI用做ID显示
JLabel JLabelShowName; //定义JLabelShowName用做姓名显示
public DrawForm(String title){ //构造函数初始化
Title=title;
setTitle(title); //设置标题
InitComponent(); //初始化窗体组件
AddComponent(); //添加组件到窗口
AddListenerToComponent(); //给组件添加监听器
setLayout(null); //设置窗体的布局为空(null)布局
setBounds((Toolkit.getDefaultToolkit().getScreenSize().width-width)/2, (Toolkit.getDefaultToolkit().getScreenSize().height-height)/2, width, height); //设置窗体的大小和位置
//Toolkit.getDefaultToolkit().getScreenSize().width/height 获取屏幕的的宽度和高度
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
private void InitComponent(){ //初始化窗体组件函数
JMenubar=new JMenuBar();
JMenuNew=new JMenu("新建");
JMenuSave=new JMenu("保存");
JPanelTop=new JPanel();
JPanelTop.setLayout(new FlowLayout(FlowLayout.CENTER)); //设置JPanelTop的布局为FlowLayout.CENTER
JPanelTop.setBorder(new LineBorder(new Color(0,0,0))); //设置JPanelTop的边框
JPanelTop.setBounds(0, 0, 1280, 40); //设置JPanelTop的位置,上层容器布局需要设置为null布局
BtnID=new JButton("ID"); //实例化BtnID按钮,文字显示“ID”
BtnID.setBackground(new Color(225,225,225)); //设置BtnID按钮的背景颜色
BtnID.setPreferredSize(new Dimension(67,28)); //设置BtnID按钮的大小,在FlowLayout布局的组件需要使用setPreferredSize(new Dimension())方法
BtnName=new JButton("Name"); //实例化BtnName按钮,文字显示“Name”
BtnName.setBackground(new Color(225,225,225)); //设置BtnName的背景颜色
BtnName.setPreferredSize(new Dimension(67,28)); //设置BtnName按钮的大小,在FlowLayout布局的组件需要使用setPreferredSize(new Dimension())方法
TfdID=new JTextField(); //实例化TfdID文本框
TfdID.setPreferredSize(new Dimension(100, 28));
TfdID.setHorizontalAlignment(JTextField.CENTER);
TfdName=new JTextField(); //实例化TfdName文本框
TfdName.setPreferredSize(new Dimension(100, 28));
TfdName.setHorizontalAlignment(JTextField.CENTER);
JPanelWorkPlace=new JPanel();
JPanelWorkPlace.setLayout(null); //设置JPanelWorkPlace的布局为空(null)布局
JPanelWorkPlace.setBorder(new LineBorder(new Color(0,0,0))); //设置JPanelWorkPlace的边框
JPanelWorkPlace.setBounds(0, 40, 1280, 617); //设置JPanelWorkPlace的位置和大小
JPanelWorkOfLeft=new JPanel();
JPanelWorkOfLeft.setBorder(new LineBorder(new Color(0,0,0))); //设置JPanelWorkOfLeft的边框
JPanelWorkOfLeft.setBounds(10, 10, 150, 597); //设置JPanelWorkOfLeft的位置
JPanelWorkOfLeft.setBackground(Color.white); //设置JPanelWorkOfLeft的背景颜色为白色
BtnDrawLine=new JButton("直线",new ImageIcon("Images/LineTool.jpg")); //实例化一个带图片和文本的按钮
BtnDrawLine.setPreferredSize(new Dimension(130,65)); //设置BtnDrawLine的大小
BtnDrawLine.setHorizontalAlignment(JButton.LEFT ); //设置BtnDrawLine的文本对齐为水平对齐
BtnDrawLine.setBackground(Color.white); //设置BtnDrawLine的背景颜色为白色
BtnDrawRectangle=new JButton("矩形",new ImageIcon("Images/RectTool.jpg"));
BtnDrawRectangle.setPreferredSize(new Dimension(130,65));
BtnDrawRectangle.setHorizontalAlignment(JButton.LEFT );
BtnDrawRectangle.setBackground(Color.white);
BtnDrawOval=new JButton("椭圆",new ImageIcon("Images/OvalTool.jpg"));
BtnDrawOval.setPreferredSize(new Dimension(130,65));
BtnDrawOval.setHorizontalAlignment(JButton.LEFT );
BtnDrawOval.setBackground(Color.white);
JPanelWorkOfDraw=new JPanel();
JPanelWorkOfDraw.setLayout(null); //设置JPanelWorkOfDraw为空(null)布局
JPanelWorkOfDraw.setBorder(new LineBorder(new Color(0,0,0))); //设置JPanelWorkOfDraw的边框
JPanelWorkOfDraw.setBounds(180,10,1075,597); //设置JPanelWorkOfDraw的位置
JPanelWorkOfDraw.setBackground(Color.white); //设置JPanelWorkOfDraw的背景颜色
JLabelShowID=new JLabel();
JLabelShowName=new JLabel();
JLabelShowID.setBounds(925, 497, 150, 50); //设置JLabelShowID的位置为右下角
JLabelShowID.setFont(new Font("黑体",Font.BOLD,20)); //设置JLabelShowID的字体
JLabelShowID.setHorizontalAlignment(JLabel.CENTER); //设置文本水平居中对齐
//JLabelShowID.setBorder(new LineBorder(new Color(0,0,0)));
JLabelShowID.setBackground(new Color(255,255,255)); //设置JLabelShowID的背景颜色为白色
JLabelShowName.setBounds(925, 547, 150, 50); //设置JLabelShowName的位置为右下角
JLabelShowName.setFont(new Font("黑体",Font.BOLD,20)); //设置JLabelShowName的字体
JLabelShowName.setHorizontalAlignment(JLabel.CENTER);
//JLabelShowName.setBorder(new LineBorder(new Color(0,0,0)));
JLabelShowName.setBackground(new Color(255,255,255)); //设置JLabelShowName的背景颜色为白色
}
private void AddComponent(){ //添加组件方法
JMenubar.add(JMenuNew); //把菜单“新建”加到菜单条
JMenubar.add(JMenuSave); //把菜单“保存”加到菜单条
setJMenuBar(JMenubar); //设置窗体菜单条
JPanelTop.add(BtnID); //给JPanelTop添加关于ID、Name的组件
JPanelTop.add(TfdID); //
JPanelTop.add(BtnName); //
JPanelTop.add(TfdName); //
JPanelWorkOfLeft.add(BtnDrawLine); //给左侧工具栏添加三个分别画直线、矩形、椭圆的功能按钮
JPanelWorkOfLeft.add(BtnDrawRectangle);
JPanelWorkOfLeft.add(BtnDrawOval);
JPanelWorkOfDraw.add(JLabelShowID); //给画图区域右下角添加显示ID和Name的文本框
JPanelWorkOfDraw.add(JLabelShowName);
JPanelWorkPlace.add(JPanelWorkOfLeft); //把左侧功能选择和画图区域组合起来加到JPanelWorkPlace容器中
JPanelWorkPlace.add(JPanelWorkOfDraw);
add(JPanelTop); //window容器添加JPanelTop和JPanelWorkPlace两个容器构成整个窗体
add(JPanelWorkPlace);
}
private void AddListenerToComponent(){ //定义给组件添加监听器的方法
TopBtnListen IDListener=new TopBtnListen(); //创建顶部ID按钮的事件处理对象
IDListener.setLabelTextField(JLabelShowID, TfdID); //设置事件处理对象的数据
BtnID.addActionListener(IDListener); //为BtnID添加监听器
TopBtnListen NameListener=new TopBtnListen(); //创建顶部Name按钮的事件处理对象
NameListener.setLabelTextField(JLabelShowName, TfdName); //设置事件处理对象的数据
BtnName.addActionListener(NameListener); //为BtnName添加监听器
DrawListen DrawListener=new DrawListen(JPanelWorkOfDraw); //引用JPanelWorkOfDraw对象创建监听对象,此DrawListener对象注册到功能按钮上面,实现对JPanelWorkOfDraw引用的绘图
BtnDrawLine.addActionListener(DrawListener); //将监听对象DrawListener添加到BtnDrawLine按钮
BtnDrawRectangle.addActionListener(DrawListener); //将监听对象DrawListener添加到BtnDrawRectangle按钮
BtnDrawOval.addActionListener(DrawListener); //将监听对象DrawListener添加到BtnDrawOval按钮
JMenuNew.addMouseListener(new MouseAdapter(){ //给JMenuNew添加一个事件监听器
public void mouseClicked(MouseEvent e) { //鼠标单击时创建一个Title为“新建绘图+DrawFormCount”的窗口
JFrame newJFrame=new DrawForm("新建绘图"+DrawFormCount);
newJFrame.setVisible(true); //设置窗体可见
DrawFormCount++; //静态变量自增
}
});
MenuSaveListen MenuSaveListener=new MenuSaveListen(Title,this,JPanelWorkOfDraw); //引用Title,this这个窗体Frame和JPanelWorkOfDraw对象创建监听对象,此监听对象实现了对JPanelWorkOfDraw的区域截屏保存
JMenuSave.addMouseListener(MenuSaveListener); //将监听对象MenuSaveListener添加到JMenuSave按钮
}
}
3、编写组件的事件处理类(我这里有三个类,菜单“新建”的时间处理类使用了匿名类实现,具体看DrawForm.java类下的AddListenerToComponent()方法为JMenuNew添加监听器的代码。)
第一个是顶部ID,Name按钮的事件处理类TopBtnListen.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class TopBtnListen implements ActionListener{ //定义顶部ID,Name按钮的事件处理类
private JLabel ShowLabel; //此变量用来显示窗口的JTextField文本
private JTextField Tfd; //此变量用来存储窗口的JTextFiled的文本
public void setLabelTextField(JLabel label,JTextField textfield){ //定义初始化私有变量的方法
ShowLabel=label;
Tfd=textfield;
}
public void actionPerformed(ActionEvent arg0) { //鼠标事件执行JLabel显示JTextField的文本
ShowLabel.setText(Tfd.getText());
}
}
第二个是“画图功能区”按钮的事件处理类DrawListen.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
public class DrawListen implements ActionListener{ //“画图功能区”按钮的事件处理类,选中按钮给”画图区“添加画图监听匿名事件处理类MouseAdapter
private int startX; //记录鼠标按下时的位置
private int startY;
private int endX; //记录鼠标释放时的位置
private int endY;
private JPanel JPanelWorkOfDraw; //用做传入变量,画图
public DrawListen(JPanel JPanelWorkOfDraw){
this.JPanelWorkOfDraw=JPanelWorkOfDraw;
}
String ButtonType=""; //记录按钮的类型
public void actionPerformed(ActionEvent e) {
ButtonType=e.getActionCommand(); //取出按钮的事件命令文本
JPanelWorkOfDraw.addMouseListener(new MouseAdapter(){ //为JPanelWorkOfDraw添加鼠标监听事件
public void mousePressed(MouseEvent e) { //鼠标按下时执行的操作
startX=e.getX(); //记录鼠标按下时的位置
startY=e.getY();
}
public void mouseReleased(MouseEvent e) {
endX=e.getX(); //记录鼠标释放时的位置
endY=e.getY();
if("直线".equals(ButtonType)) { //如果按钮的事件命令文本是“直线”,绘制直线
JPanelWorkOfDraw.getGraphics().drawLine(startX, startY, endX, endY);
}
else if(ButtonType.equals("矩形")) { //如果按钮的事件命令文本是“矩形”,绘制矩形
JPanelWorkOfDraw.getGraphics().drawRect(startX, startY, endX-startX, endY-startY);
}
else if(ButtonType.equals("椭圆")){ //如果按钮的事件命令文本是“椭圆”,绘制椭圆
JPanelWorkOfDraw.getGraphics().drawOval(startX, startY, endX-startX, endY-startY);
}
}
});
}
}
第三个是菜单“保存”处理类MenuSaveListen.java
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
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 MenuSaveListen implements MouseListener{ //定义文件保存处理类
private String Title; //定义窗体名字变量
private JFrame DrawForm; //定义窗体变量
private JPanel JPanelWorkOfDraw; //定义JPanelWorkOfDraw变量,JPanelWorkOfDraw是绘图区域
public MenuSaveListen(String Title, JFrame DrawForm,JPanel JPanelWorkOfDraw){ //构造函数初始化类的变量
this.Title=Title;
this.DrawForm=DrawForm;
this.JPanelWorkOfDraw=JPanelWorkOfDraw;
}
@Override
public void mouseClicked(MouseEvent e) { //事件源单击时执行
String path=System.getProperty("user.dir"); //获取当前的工作目录
BufferedImage myImage = null; //初始化截屏图片,它是BufferedImage类型的变量
try {
//对JPanelWorkOfDraw的区域进行截屏操作,具体的Rectangle截屏参数由DrawForm窗体设置JPanelWorkOfDraw的位置和大小有关
myImage = new Robot().createScreenCapture(new Rectangle(DrawForm.getX()+189, DrawForm.getY()+107, JPanelWorkOfDraw.getWidth()-2, JPanelWorkOfDraw.getHeight()-2));
ImageIO.write(myImage, "jpg", new File(path+"/"+Title+".jpg")); //执行保存,扩展名为.jpg
System.out.println("Save File \'"+Title+".jpg\'"+" to Workfold Succeed!"); //在Console输出提示信息
}
catch (AWTException e1) {
e1.printStackTrace();
}
catch (IOException e1) {
e1.printStackTrace();
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
}
4、编写带主函数的DrawMain.java类
public class DrawMain {
public static void main(String[] args) {
DrawForm Draw=new DrawForm("绘图");
Draw.setVisible(true);
}
}
附:按钮的三张图片(LineTool.jpg、RectTool.jpg、OvalTool.jpg)