目标:使用Java中的GUI工具包Swing实现画图软件的创建
UI界面
首先要创建出这样的样子的界面,这就要用到JFrame类,创建一个窗体对象,然后将所有的组件(按钮、画布等)放入窗体对象中。
publicclass UI {publicJFrame jf;publicJPanel drawJP, toolJP;publicvoidshowUI(){// new一个JFrame窗体
jf =newJFrame("画图工具");// 设置窗体大小
jf.setSize(600,600);// 设置窗体的布局为边界布局,分为东南西北中五个方位,可以将组件添加到指定的地方
jf.setLayout(newBorderLayout());// 设置窗体居中显示
jf.setLocationRelativeTo(null);// 给窗体设置退出按钮 关掉即退出程序
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 定制绘画模块// new一个绘画区域的JPanel
drawJP =newJPanel();// 设置背景颜色为灰色,如果不设置背景颜色分别不出来不同Jpanel
drawJP.setBackground(Color.GRAY);//将绘画模块加到窗体中,边界布局选择中间,如果选择CENTER的话就不要设置大小,默认自动填满
jf.add(drawJP,BorderLayout.CENTER);// 定制工具模块
toolJP =newJPanel();// 设置背景颜色为白色
toolJP.setBackground(Color.WHITE);// 除了窗体使用setSize(),其他组件的大小设置都需要使用setPreferredSize()方法
toolJP.setPreferredSize(newDimension(100,0));//将工具栏模块加到窗体中,边界布局选择东边
jf.add(toolJP,BorderLayout.EAST);// 定制功能按钮// 定义一个tools字符串数组存放你需要的工具String[] tools ={"直线","椭圆","三角形","多边形","铅笔"};// 遍历字符串数组,每遍历一次就在工具栏模块中添加一个对应名字的按钮,并设置大小for(int i =0; i < tools.length; i++){JButton jbt =newJButton(tools[i]);
jbt.setPreferredSize(newDimension(80,30));
toolJP.add(jbt);}// 定义颜色按钮Color[] colors ={Color.GREEN,Color.BLUE,Color.RED,Color.PINK};// 遍历字符串数组,每遍历一次就在颜色模块中添加一个对应颜色的按钮,// 并设置大小和按钮的背景颜色for(int i =0; i < colors.length; i++){JButton jbt =newJButton();
jbt.setBackground(colors[i]);
jbt.setPreferredSize(newDimension(30,30));
toolJP.add(jbt);}// 设置窗体为可见,不然看不见窗体以及窗体中的内容
jf.setVisible(true);}publicstaticvoidmain(String[] args){UI ui =newUI();
ui.showUI();}}
功能的实现
需要实现按钮的功能,需要在按钮上安装监听器,监听按钮的变化,从而做出对应的反应,只需要在上述代码中加入一小部分。
按钮点击功能的实现
在形状选择按钮部分添加监听器
// 定制功能按钮String[] tools ={"直线","椭圆","三角形","多边形","铅笔"};for(int i =0; i < tools.length; i++){JButton jbt =newJButton(tools[i]);
jbt.setPreferredSize(newDimension(80,30));// 给添加的每个按钮添加监听器
jbt.addActionListener(drawMouse);
toolJP.add(jbt);}
在颜色选择按钮部分添加监听器
// 定义颜色按钮Color[] colors ={Color.GREEN,Color.BLUE,Color.RED,Color.PINK};for(int i =0; i < colors.length; i++){JButton jbt =newJButton();
jbt.setBackground(colors[i]);
jbt.setPreferredSize(newDimension(30,30));// 给添加的每个按钮添加监听器
jbt.addActionListener(drawMouse);
toolJP.add(jbt);}
这里的drawMouse是自己定义的一个类,用来实现ActionListener这个接口,要实现接口就需要实现接口中的所有方法。
importjavax.swing.*;importjava.awt.*;importjava.awt.event.*;publicclassDrawMouseimplementsActionListener{privateString tool;privateColor color;// 按钮点击@OverridepublicvoidactionPerformed(ActionEvent e){// 使用getActionCommand命令获得当前点击按钮的命令// 因为工具和颜色都是属于JButton,不同的是工具按钮的命令中有文字,// 而颜色按钮只有背景颜色,命令内容是一个空字符串所有进行判断。if(e.getActionCommand().equals("")){JButton jButton =(JButton) e.getSource();
color = jButton.getBackground();
g.setColor(color);System.out.println(color);}else{
tool = e.getActionCommand();System.out.println(tool);}}}
具体功能的实现
需要在UI类中添加鼠标监听器以及画笔
注意: 画笔的获取需要在setVisible(true)之后
jf.setVisible(true);DrawMouse drawMouse =newDrawMouse();Graphics g = drawJP.getGraphics();
drawMouse.setG(g);
drawJP.addMouseListener(drawMouse);
drawJP.addMouseMotionListener(drawMouse);
同时需要在DrawMouse类中实现对应的接口功能,将所有方法进行重写
因此DrawMouse类更改为:
importjavax.swing.*;importjava.awt.*;importjava.awt.event.*;/**
* @Description:
* @Author: cy
* @date: 2022/8/13 17:57
**/publicclassDrawMouseimplementsActionListener,MouseListener{privateString tool;privateColor color;privateint x1, y1, x2, y2, x3, y3;// 设置标志位 帮助确定是否为第一次画线,在画三角形和多边形中有用privateint flag =1;privateGraphics g;publicvoidsetG(Graphics g){this.g = g;
tool ="直线";}// 按钮点击@OverridepublicvoidactionPerformed(ActionEvent e){if(e.getActionCommand().equals("")){JButton jButton =(JButton) e.getSource();
color = jButton.getBackground();
g.setColor(color);System.out.println(color);}else{
tool = e.getActionCommand();System.out.println(tool);}}// 鼠标点击@OverridepublicvoidmouseClicked(MouseEvent e){
x3 = e.getX();
y3 = e.getY();// 因为标志位在第一次时被置为2,所有x1,x2坐标并不会更新,直接画剩余的两条线就行if(tool.equals("三角形")){
g.drawLine(x3,y3,x2,y2);
g.drawLine(x3,y3,x1,y1);
flag =1;}// 与三角形不同的就是需要将一开始的x3作为下一次的起点 ,然后在使用当前的x3和上一次的x3进行连接if(tool.equals("多边形")&& flag ==2){
g.drawLine(x3,y3,x2,y2);
x2 = x3;
y2 = y3;// 使用getClickCount判断双击,如果双击,就和最初的x1相连接,完成绘制if(e.getClickCount()==2){
g.drawLine(x3,y3,x1,y1);
flag =1;}}}// 鼠标按压@OverridepublicvoidmousePressed(MouseEvent e){if(flag ==1){
x1 = e.getX();
y1 = e.getY();}}// 鼠标释放@OverridepublicvoidmouseReleased(MouseEvent e){if(flag ==1){
x2 = e.getX();
y2 = e.getY();}if(tool.equals("直线")){
g.drawLine(x1,y1,x2,y2);System.out.println("直线");}if(tool.equals("椭圆")){
g.drawOval(Math.min(x1,x2),Math.min(y1, y2),Math.abs(x2 - x1),Math.abs(y2 - y1));}if(tool.equals("三角形")){
g.drawLine(x1,y1,x2,y2);
flag++;}if(tool.equals("多边形")&& flag ==1){
g.drawLine(x1,y1,x2,y2);
flag++;}}@OverridepublicvoidmouseEntered(MouseEvent e){}@OverridepublicvoidmouseExited(MouseEvent e){}@OverridepublicvoidmouseDragged(MouseEvent e){
x2 = e.getX();
y2 = e.getY();// 绘制连续线段需要时刻更新前一次的终点坐标作为下一次的起点坐标,相当于一直在画很小的线段if(tool.equals("铅笔")){
g.drawLine(x1,y1,x2,y2);
x1 = x2;
y1 = y2;}}@OverridepublicvoidmouseMoved(MouseEvent e){}}
下面还需要实现画线预览功能以及窗体重绘的问题后续更新
版权归原作者 非洲大主教 所有, 如有侵权,请联系我们删除。