欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

简单的画图工具

程序员文章站 2022-03-04 18:59:34
...
[img]http://dl2.iteye.com/upload/attachment/0103/7262/4e6b36c9-7d3c-3eb7-8e04-e6a3574d5584.jpg[/img]

简易画板主要使用JFrame,JPanel,JLabel等,还要添加相应的监听器。
首先新建主类。
JFrame是一个容器,允许程序员把其他组件添加到它里面,把它们组织起来,并把它们呈现给用户。

public static void main(String[] args) {
DrawUI ui = new DrawUI();
ui.initDrawUI();
}

public void initDrawUI()
{
this.setTitle("画板");
this.setSize(600,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(ture);
}
}

将整个窗口分为西边,南边和中间三面,西边放工具,南边放颜色挑选,中间放置画板。所以整个窗口需要BorderLayout来分割窗口。

BorderLayout一个布置容器的边框布局,它可以对容器组件进行安排,并调整其大小,使其符合下列五个区域:北、南、东、西、中。每个区域最多只能包含一个组件,并通过相应的常量进行标识:NORTH、SOUTH、EAST、WEST、CENTER。当使用边框布局将一个组件添加到容器中时,要使用这五个常量之一。


//添加BorderLayout方法分割窗口:
BorderLayout layout = new BorderLayout();
this.setLayout(layout);

//分别在三面添加JPanel类,划分大小,并分别设置西边南边和中间的背景颜色。
JPanel left = new JPanel();
left.setPreferredSize(new Dimension(80,1));
left.setBackground(new Color(235,235,235));

JPanel center = new JPanel();
center.setBackground(Color.GRAY);

JPanel foot = new JPanel();
foot.setPreferredSize(new Dimension(1,80));
foot.setBackground(new Color(235,235,235));

//添加到窗口上
this.add(left,BorderLayout.WEST);
this.add(center,BorderLayout.CENTER);
this.add(foot,BorderLayout.SOUTH);

//在left添加工具按钮,并添加触碰,按下等的动作变化(这里需要用到for函数)。
//由于是单选按钮,则需要填加到group中。
ButtonGroup group = new ButtonGroup();
String[] commands = {"0","1","eraser","3","4","5","pencil","7","喷枪","9","line","11",
"rect","13","oval","15"
};
for(int i=0;i<16;i++)
{
JRadioButton radio = new JRadioButton();
ImageIcon lineIcon = new ImageIcon("imgs/draw"+i+".jpg");
radio.setIcon(lineIcon);

ImageIcon lineIcon1 = new ImageIcon("imgs/draw"+i+"-1.jpg");
radio.setRolloverIcon(lineIcon1);

ImageIcon lineIcon2 = new ImageIcon("imgs/draw"+i+"-2.jpg");
radio.setPressedIcon(lineIcon2);

ImageIcon lineIcon3 = new ImageIcon("imgs/draw"+i+"-3.jpg");
radio.setSelectedIcon(lineIcon3);

radio.setActionCommand(commands[i]);

group.add(radio);

left.add(radio);

}
//设置默认选择为pencil
if(i==6)
{
radio.setSelected(true);
}

//为center添加画板。
//JPanel 是一般轻量级容器。可以无限重叠自身。
JPanel drawPanel= new MyPanel();
drawPanel.setBackground(Color.WHITE);
drawPanel.setPreferredSize(new Dimension(400,300));
Graphics g = drawPanel.getGraphics();

//为工具添加鼠标监听器,将group和画板传入监听器,由此在选择group时
//对Graphics进行操作。
DrawListener dlis = new DrawListener(g,group);

drawPanel.addMouseListener(dlis);

drawPanel.addMouseMotionListener(dlis);
//新建DrawListener类
public class DrawListener implements MouseListener,MouseMotionListener{

private int x1,x2,y1,y2;
private String type="line";
private Graphics g;
private ButtonGroup group;
public DrawListener(Graphics g,ButtonGroup group)
{
this.g = g;
this.group = group;
}
}
//实现相应函数。
public void mousePressed(MouseEvent e)
{
// 鼠标按下的时候需要知道要绘制的形状是什么

javax.swing.ButtonModel bm = group.getSelection();

String command=bm.getActionCommand();

type=command;

g = drawPanel.getGraphics();
c = clis.color;

x1=e.getX();
y1=e.getY();
}
public void mouseReleased(MouseEvent e)
{
x2=e.getX();
y2=e.getY();

if(type.equals("line"))
{
g.drawLine(x1,y1,x2,y2);
}
else if(type.equals("rect"))
{
int minX = x1<x2?x1:x2;
int minY = y1<y2?y1:y2;
int width = x1<x2?x2-x1:x1-x2;
int height = y1<y2?y2-y1:y1-y2;

g.drawRect(minX, minY, width, height );
}
else if(type.equals("oval"))
{
int minX = Math.min(x1, x2);
int minY = Math.min(y1, y2);
int width = Math.abs(x2-x1);
int height = Math.abs(y2-y1);
g.drawOval(minX, minY, width, height );
}
else if(type.equals("eraser"))
{
int lx = e.getX();
int ly = e.getY();
int width = 10;
int height = 10;
g.setColor(Color.WHITE);
g.fillRect(lx, ly, width, height);
x1 = lx;
y1 = ly;
g.setColor(Color.BLACK);
}
else if (type.equals("喷枪"))
{

int x1 = e.getX();
int y1 = e.getY();
for(int i=0;i<100;i++)
{
int x2 = 15- (int) (Math.random()*30);
int y2 = 15- (int) (Math.random()*30);

g.drawLine(x1+x2, y1+y2, x1+x2, y1+y2);
}

}
}

public void mouseDragged(MouseEvent e) {
if(type.equals("pencil"))
{
int x3 = e.getX();
int y3 = e.getY();

g.drawLine(x1, y1, x3, y3);
x1 = x3;
y1 = y3;
}

else if(type.equals("eraser"))
{
int lx = e.getX();
int ly = e.getY();
int width = 10;
int height = 10;
g.setColor(Color.WHITE);
g.fillRect(lx, ly, width, height);
x1 = lx;
y1 = ly;
g.setColor(Color.BLACK);
}
else if (type.equals("喷枪"))
{

int x1 = e.getX();
int y1 = e.getY();
for(int i=1;i<50;i++)
{
int x2 = 15- (int) (Math.random()*30);
int y2 = 15- (int) (Math.random()*30);

g.drawLine(x1+x2, y1+y2, x1+x2, y2+y1);
}

}


}


public void mouseEntered(MouseEvent e)
{

}
public void mouseExited(MouseEvent e)
{

}
public void mouseClicked(MouseEvent e)
{

}

@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub

}


保存绘画数据,且绘画始终在画板上。
将DrawUI中的drawPanel传入DrawListener中,则改为:
DrawListener dlis = new DrawListener(drawPanel,group);
DrawListener的构造函数更改:
public DrawListener(JPanel drawPanel,ButtonGroup group)
{
this.drawPanel = drawPanel;
this.group = group;
}
添加private JPanel drawPanel;

添加数组,存储数据:
定义一个shape类,然后让类Line继承,这样就可以将line的对象存储到数组中

public abstract class Shape {
int x1,y1,x2,y2;
Color color;

public abstract void draw(Graphics g);

}
public class Line extends Shape{
int x1,y1,x2,y2;
Color color;
Graphics group;
public Line(int x1,int y1,int x2,int y2,Color color)
{
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
this.color = color;

}
@Override
public void draw(Graphics g) {
g.setColor(this.color);
g.drawLine(x1, y1, x2, y2);

}



}



类似Line类可以写出相应的Oval类,Rect类等。

在DrawListener中的绘画直线的函数就更改为:
Line line = new Line(x1,y1,x2,y2,color.BLACK);
line.draw(g);
用MyPanel类重写JPanel类中的paint方法,使得每次更改窗口都会重绘存储在数组中的数据。

class MyPanel extends JPanel
{

@Override
public void paint(Graphics g) {
super.paint(g);
for(int i=0;i<DrawListener.shapeList.size();i++)
{
Shape s = DrawListener.shapeList.get(i);
s.draw(g);
}
}


}



JPanel drawPanel = new JPanel();更改为JPanel drawPanel = new MyPanel();
DrawListener中添加:
public static ArrayList<Shape> shapeList = new ArrayList<Shape>();
绘制line中添加
shapeList.add(line);

为颜色按钮添加ColorListener监听器
public class ColorListener extends MouseAdapter implements ActionListener{
@Override
public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
JLabel label = (JLabel) e.getSource();

color = label.getBackground();
}


Color color;

@Override
public void actionPerformed(ActionEvent e) {
color = JColorChooser.showDialog(null, "请选择颜色", Color.RED);

}


}

在DrawUI中实现
在foot中添加颜色按钮
for(int i=0;i<colors.length;i++){
JLabel label = new JLabel();

label.setPreferredSize(new Dimension(34,29));
label.setBackground(colors[i]);
//前景色是否透明
label.setOpaque(true);

foot.add(label);
label.addMouseListener(clis);
}

颜色监听器放在工具监听器的前面,将颜色监听器的对象传入工具监听器中,实现对绘画的改色。
DrawListener dlis = new DrawListener(drawPanel,group,clis);
相应的构造函数需要改变。
public DrawListener(JPanel drawPanel,ButtonGroup group,ColorListener clis)
{
this.drawPanel = drawPanel;
this.group = group;
this.clis = clis;
}
在foot中添加颜色选择器(传入照片color.png)
JButton btn = new JButton();
ImageIcon icon = new ImageIcon("color.png");
btn.setIcon(icon);
btn.setPreferredSize(new Dimension(34,29));
foot.add(btn);

btn.addActionListener(clis);
相关标签: 工具