
正文
java代码实现画板 java简单画图板完整代码
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
java画板程序
package draw;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
//the point
//impress the info of one point,the x and y
class OnePoint implements Serializable
{
int x;
int y;
int tool;
Color c;
int border;
public OnePoint(int x,int y,int tool,Color cc,int border)
{
this.x=x;
this.y=y;
this.tool=tool;
this.c=cc;
this.border=border;
}
public static void main(String[] args)
{
DrawingBoard oneBorder=new DrawingBoard();
}
}
class DrawingBoard extends Frame implements MouseListener,ItemListener,ActionListener,MouseMotionListener
{
Button pen,line,ellipse,rect,clear,colorboard,storebutton,openbutton;
Choice sizechoice,colorchoice ;
Label pensize, pencolor;
Panel panel ;
FileDialog storefile, openfile;
FileInputStream filein;
FileOutputStream fileout;
ObjectInputStream objectin;
ObjectOutputStream objectout;
int mode=0;
int flagtool=0;
Color flagcolor;
int border;
BasicStroke size;
private Point2D[] p=new Point2D[3];;
OnePoint p1,p2;
VectorOnePoint points=new VectorOnePoint();
public DrawingBoard()
{
pen=new Button("画笔");
line=new Button("直线");
ellipse=new Button("圆");
rect=new Button("矩形");
clear=new Button("清除");
colorboard=new Button("调色板");
storebutton=new Button("存储文件");
openbutton=new Button("打开文件");
pensize=new Label("画笔大小");
pencolor=new Label("画笔颜色");
storefile=new FileDialog(this,"存储文件",FileDialog.SAVE);
storefile.setVisible(false);
storefile.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
storefile.setVisible(false);
}
});
openfile=new FileDialog(this,"打开文件",FileDialog.LOAD);
openfile.setVisible(false);
openfile.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
openfile.setVisible(false);
}
});
sizechoice=new Choice();
sizechoice.add("1");
sizechoice.add("2");
sizechoice.add("4");
sizechoice.add("6");
sizechoice.add("8");
sizechoice.addItemListener(this);
colorchoice=new Choice();
colorchoice.add("black");
colorchoice.add("red");
colorchoice.add("blue");
colorchoice.add("green");
colorchoice.addItemListener(this);
pen.addActionListener(this);
line.addActionListener(this);
ellipse.addActionListener(this);
rect.addActionListener(this);
clear.addActionListener(this);
colorboard.addActionListener(this);
storebutton.addActionListener(this);
openbutton.addActionListener(this);
panel=new Panel();
panel.add(storebutton);
panel.add(openbutton);
panel.add(pen);
panel.add(line);
panel.add(ellipse);
panel.add(rect);
panel.add(clear);
panel.add(sizechoice);
panel.add(pensize);
panel.add(colorchoice);
panel.add(pencolor);
panel.add(colorboard);
add(panel,BorderLayout.NORTH);
setBounds(100,100,700,600);
setVisible(true);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
/**
* 添加鼠标事件的监听器java代码实现画板,否则,鼠标的移动和点击都将无法识别java代码实现画板!
* */
addMouseListener(this);
addMouseMotionListener(this);
}
public void paint(Graphics g)
{
Graphics2D g2d=(Graphics2D)g;
if(flagtool==2)
{ //qing chu
g.clearRect(0,0,getSize().width,getSize().height);
}
for(int i=0;ipoints.size()-1;i++)
{
p1=(OnePoint)points.elementAt(i);
p2=(OnePoint)points.elementAt(i+1);
g2d.setColor(p1.c); //////////////需要使用Graphics2D从Graphics类中继承下来的方法 setColor()设置当前的颜色
size=new BasicStroke(p1.border,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);
g2d.setStroke(size);
if(p1.tool==p2.tool)
{
switch(p1.tool)
{
case 0:
Line2D.Double line1=new Line2D.Double(p1.x,p1.y,p2.x,p2.y);
g2d.draw(line1);
break;
case 1:
Line2D.Double line2=new Line2D.Double(p1.x,p1.y,p2.x,p2.y);
g2d.draw(line2);
break;
case 3:
Ellipse2D.Double ellipse=new Ellipse2D.Double(p1.x,p1.y,Math.abs(p2.x-p1.x),Math.abs(p2.y-p1.y));
g2d.draw(ellipse);
break;
case 4:
Rectangle2D.Double rect=new Rectangle2D.Double(p1.x,p1.y,Math.abs(p2.x-p1.x),Math.abs(p2.y-p1.y));
g2d.draw(rect);
break;
default:
}
}
}
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) //鼠标点下时候,将当前的点信息记录
{
mode=0;
p[0]=e.getPoint();
OnePoint pp1=new OnePoint(e.getX(),e.getY(),flagtool,flagcolor,border);
points.addElement(pp1);
//repaint();
}
public void mouseReleased(MouseEvent e) //鼠标松开时候,如果是画笔,则当前截断,是其余状态记下一枚点信息
{
mode=1;
if(flagtool==0)
{
points.addElement(new OnePoint(-1,-1,22,flagcolor,border));
}
else
{
OnePoint pp2=new OnePoint(e.getX(),e.getY(),flagtool,flagcolor,border);
points.addElement(pp2);
points.add(new OnePoint(-1,-1,22,flagcolor,border));
}
repaint();
}
public void itemStateChanged(ItemEvent e)
{
if(e.getSource()==colorchoice)
{
String selected=colorchoice.getSelectedItem();
if(selected=="black"){flagcolor=new Color(0,0,0); }
else if(selected=="red"){flagcolor=new Color(255,0,0); }
else if(selected=="blue"){ flagcolor=new Color(0,0,255);}
else if(selected=="green"){ flagcolor=new Color(0,255,0); }
}
else if(e.getSource()==sizechoice)
{
String selected=sizechoice.getSelectedItem();
if (selected=="1"){ border=1; }
else if(selected=="2"){ border=2*2; }
else if(selected=="4"){ border=4*2; }
else if(selected=="6"){ border=6*2; }
else if(selected=="8"){ border=8*2; }
}
}
/*public void update(Graphics g) { //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
paint(g);
} */
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
if(e.getSource()==pen){flagtool=0; }
else if(e.getSource()==line){ flagtool=1; }
else if(e.getSource()==clear)
{
flagtool=2;
points.removeAllElements();
repaint(); //此语要有,否则今生无法删除!
}
else if(e.getSource()==ellipse){ flagtool=3; }
else if(e.getSource()==rect){ flagtool=4; }
else if(e.getSource()==colorboard)
{
/*
* 使用 javax.swing.×包中的 JColorChooser 类的静态方法showDialog(Component component,String title,Color color ),
* 该方法的参数,component是当前显示对话框的父框架,color是设置调色板初始的被选颜色
*
* 该方法返回被选的颜色,类型为Color
* */
Color color=JColorChooser.showDialog(this, "调色板",flagcolor);
flagcolor=color;
}
else if(e.getSource()==openbutton)
{
openfile.setVisible(true);
if(openfile.getFile()!=null)
{
int temp=flagtool;
flagtool=2;
repaint();
try{
points.removeAllElements();
File file=new File(openfile.getDirectory(),openfile.getFile());
filein=new FileInputStream(file);
objectin=new ObjectInputStream(filein);
points=(Vector)objectin.readObject();
objectin.close();
filein.close();
flagtool=temp;
repaint();
}
catch(Exception ee){ System.out.println(ee.toString()); }
}
}
else if(e.getSource()==storebutton)
{
storefile.setVisible(true);
if(storefile.getFile()!=null)
{
try {
File file=new File(storefile.getDirectory(),storefile.getFile());
fileout=new FileOutputStream(file);
objectout=new ObjectOutputStream(fileout);
objectout.writeObject(points);
objectout.close();
fileout.close();
repaint();
}
catch (FileNotFoundException e1)
{
System.out.println(e1.toString());
e1.printStackTrace();
} catch (IOException ee) {
System.out.println(ee.toString());
ee.printStackTrace();
}
}
}
}
public void mouseDragged(MouseEvent e) //鼠标拖动时候,//当且仅当 flagtool==0,或者表示为橡皮的时候
//才将拖动过程中涉及到的点全部记录下来,并且调用repain()方法,重画当前
// TODO Auto-generated method stub
{
if(flagtool==0)
{
OnePoint pp3=new OnePoint(e.getX(),e.getY(),flagtool,flagcolor,border);
points.addElement(pp3);
repaint();
}
if(flagtool==1)
{
OnePoint pp3=new OnePoint(e.getX(),e.getY(),flagtool,flagcolor,border);
repaint();
}
}
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
}
相关问答
Q1: java 涂鸦画板
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class MouseDrawPanel extends Frame
{
private static final long serialVersionUID = 1L;
MouseEvent e = null;
int startX = -1;
int startY = -1;
int endX = -1;
int endY = -1;
boolean left = false;
public MouseDrawPanel ( String title )
{
setTitle (title);
setLayout (new BorderLayout ());
setResizable (false);
setSize (500, 400);
setLocationRelativeTo (null);
addWindowListener (new WindowAdapter ()
{
@Override
public void windowClosing ( WindowEvent e )
{
System.exit (0);
}
});
}
@Override
public void paintComponents ( Graphics g )
{
float lineWidth = 8.0f;
( (Graphics2D) g ).setStroke (new BasicStroke (lineWidth));
g.setColor (Color.YELLOW);
g.drawLine (startX, startY, endX, endY);
g.dispose ();
}
public static void main ( String[] args )
{
final MouseDrawPanel mdp = new MouseDrawPanel ("Use Mouse Draw");
Panel panel = new Panel ();
panel.setLayout (new FlowLayout (FlowLayout.LEFT));
Label startL = new Label ("start: ");
Label endL = new Label ("end: ");
final Label nowL = new Label ("now: ");
final Label startR = new Label ("000,000");
final Label endR = new Label ("000,000");
final Label nowN = new Label ("000,000");
panel.add (startL);
panel.add (startR);
panel.add (endL);
panel.add (endR);
panel.add (nowL);
panel.add (nowN);
mdp.add (panel, "South");
mdp.addMouseMotionListener (new MouseMotionListener ()
{
@Override
public void mouseMoved ( MouseEvent e )
{
if (mdp.left)
{
nowN.setText (e.getX () + " , " + e.getY ());
}
}
@Override
public void mouseDragged ( MouseEvent e )
{
if (mdp.left)
{
mdp.endX = e.getX ();
mdp.endY = e.getY ();
mdp.paintComponents (mdp.getGraphics ());
mdp.startX = mdp.endX;
mdp.startY = mdp.endY;
endR.setText (mdp.endX + " , " + mdp.endY);
}
}
});
mdp.addMouseListener (new MouseAdapter ()
{
@Override
public void mousePressed ( MouseEvent e )
{
if (e.getButton () == MouseEvent.BUTTON1)
{
mdp.startX = e.getX ();
mdp.startY = e.getY ();
startR.setText (mdp.startX + " , " + mdp.startY);
mdp.left = true;
}
else
{
mdp.left = false;
}
}
@Override
public void mouseReleased ( MouseEvent e )
{
if (mdp.left)
{
endR.setText (e.getX () + " , " + e.getY ());
}
}
});
mdp.setVisible (true);
}
}
Q2: java 实现一个有背景图片的画板,为什么只能画出点来,而且一画按钮就不见了,这是源代码
因为每次画线之后,你都重新调用了drawImage把线覆盖掉了,不停地画,不停地覆盖
Q3: GUI画图板(绘图板)设计,用Java编写程序代码!!谢谢!!
只有矩形有圆形能移动,其它实现起来麻烦点,办法有的只是代码太多。
画圆弧改成了画曲线,圆弧稍麻烦,当然方法是很简单的,你可以自己思考一下。
双击13个颜色中的任意一个都会弹出颜色选择器。
有保存与打开功能。扩展名请用 .jdr
基本满足条件,细节可能不是很好,另,代码比较乱,怕不好看懂咯,呼呼。
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
public class JDraw {
public static void main(String[] args) {
JFrame f=new JFrame();
f.setDefaultCloseOperation(3);
f.setSize(880,600);
f.setLocationRelativeTo(null);
f.getContentPane().add(M.c);
f.getContentPane().add(M.m,"South");
f.setVisible(true);
}
}
class CVS extends Component implements ComponentListener,MouseListener,MouseMotionListener{
public void componentHidden(ComponentEvent e) {}
public void componentMoved(ComponentEvent e) {}
public void componentResized(ComponentEvent e) {resized();}
public void componentShown(ComponentEvent e) {}
private void resized() {
int w=this.getWidth();
int h=this.getHeight();
tbuff=new BufferedImage(w,h,3);
makeBuff(w,h);
}
private void makeBuff(int w,int h) {
Graphics g = tbuff.getGraphics();
g.drawImage(buff,0,0,null);
g.dispose();
buff=new BufferedImage(w,h,3);
g=buff.getGraphics();
g.drawImage(tbuff,0,0,null);
g.dispose();
}
BufferedImage buff,tbuff;
CVS(){
this.addComponentListener(this);
this.addMouseListener(this);
this.addMouseMotionListener(this);
buff=new BufferedImage(1,1,3);
}
public void paint(Graphics gr){
Graphics2D g = buff.createGraphics();
g.setBackground(new Color(0xff000000,true));
g.clearRect(0,0,getWidth(),getHeight());
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
M.sa.drawAll(g);
if(M.ts!=null)
M.ts.draw(g);
g.dispose();
gr.drawImage(buff,0,0,this);
gr.dispose();
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
M.mp(e.getPoint());
}
public void mouseReleased(MouseEvent e) {
M.mr(e.getPoint());
}
public void mouseDragged(MouseEvent e) {
M.md(e.getPoint());
}
public void mouseMoved(MouseEvent e) {}
}
class Menu extends JComponent implements MouseListener,ActionListener{
JComboBox sbox,method;
CLabel[] cl;
JCheckBox fillC,drawB;
JRadioButton fc,bc;
ButtonGroup bg;
JButton clear,up,down,save,load;
Menu(){
this.setLayout(new FlowLayout());
method=new JComboBox(new Object[]{"draw","move","erase",});
add(method);
sbox=new JComboBox(new Object[]{"Pt","Ln","Rect","Cir","Arc",});
add(sbox);
cl=new CLabel[13];
for(int i=0; icl.length; i++){
cl[i]=new CLabel();
cl[i].addMouseListener(this);
add(cl[i]);
}
fc=new JRadioButton("fc",true);
bc=new JRadioButton("bc");
bg=new ButtonGroup();
bg.add(fc);bg.add(bc);
add(fc);add(bc);
fc.setOpaque(true);
bc.setOpaque(true);
fc.setBackground(Color.white);
bc.setBackground(Color.blue);
fillC=new JCheckBox("Fill",true);
drawB=new JCheckBox("Draw",true);
fillC.addActionListener(this);
drawB.addActionListener(this);
add(fillC);add(drawB);
clear=new JButton("clear");
clear.addActionListener(this);
add(clear);
up=new JButton("zUp");
up.addActionListener(this);
add(up);
down=new JButton("zDown");
down.addActionListener(this);
add(down);
save=new JButton("Save");
save.addActionListener(this);
add(save);
load=new JButton("Load");
load.addActionListener(this);
add(load);
}
public void mouseClicked(MouseEvent e) {
JLabel l=(JLabel)e.getSource();
if(e.getClickCount()==2){
Color sc=JColorChooser.showDialog(null, "Color chooser", l.getBackground());
l.setBackground(sc);
mousePressed(e);
}
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
Color c=((JLabel)e.getSource()).getBackground();
if(fc.isSelected())
fc.setBackground(c);
else if(bc.isSelected())
bc.setBackground(c);
M.cp();
}
public void mouseReleased(MouseEvent e) {}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==clear)M.clear();
else if(e.getSource()==up)M.up();
else if(e.getSource()==down)M.down();
else if(e.getSource()==save)M.save();
else if(e.getSource()==load)M.load();
else if(e.getSource()==fillC||e.getSource()==drawB)M.cp();
}
}
class CLabel extends JLabel{
static Color[] cs={Color.red,Color.orange,Color.yellow,Color.green,Color.cyan,
Color.blue,Color.magenta,Color.magenta.brighter(),
Color.white,Color.black,Color.gray,Color.LIGHT_GRAY,Color.DARK_GRAY,};
static int i;
CLabel(){
this.setOpaque(true);
this.setBackground(cs[i++]);
this.setBorder(BorderFactory.createLineBorder(Color.black));
this.setPreferredSize(new Dimension(10,20));
}
}
class M{
static JFileChooser jfc=new JFileChooser();
static Menu m=new Menu();
static CVS c=new CVS();
static SA sa=new SA();
static S ts=null,selected=null;
static Color fc,bc;
static void clear(){
sa.ss.clear();
c.repaint();
}
public static void cp() {
System.out.println(selected);
if(selected!=null){
selected.fillColor=m.fc.getBackground();
selected.borderColor=m.bc.getBackground();
selected.fc=m.fillC.isSelected();
selected.db=m.drawB.isSelected();
c.repaint();
}
}
public static void up() {
if(selected!=null){
sa.upZ(selected);
c.repaint();
}
}
public static void down(){
if(selected!=null){
sa.downZ(selected);
c.repaint();
}
}
static{
jfc.setFileFilter(new FileNameExtensionFilter("JDraw file (*.jdraw,*.jdr)","jdr","jdraw"));
}
static void save(){
int x=jfc.showSaveDialog(c);
if(x==JFileChooser.APPROVE_OPTION){
File f = jfc.getSelectedFile();
try{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(f));
oos.writeObject(sa);
oos.flush();
oos.close();
}catch(Exception e){}
}
}
static void load(){
int x=jfc.showOpenDialog(c);
if(x==JFileChooser.APPROVE_OPTION){
File f = jfc.getSelectedFile();
try{
ObjectInputStream oos=new ObjectInputStream(new FileInputStream(f));
Object r=oos.readObject();
if(r!=null){
sa=(SA)r;
c.repaint();
}
oos.close();
}catch(Exception e){e.printStackTrace();}
}
}
static int mx,my,tx,ty,ox,oy;
static int pc=0,pmax;
static int sm;
static boolean ne=true;
static int mid;
static void mp(Point p){
mid=m.method.getSelectedIndex();
if(mid==0){
if(ne){
mx=p.x;my=p.y;
pc=0;
sm=m.sbox.getSelectedIndex();
pmax=sm==4?2:1;
ne=false;
}
++pc;
}
else if(mid==1){
checkSel(p);
mx=p.x;my=p.y;
}
else if(mid==2){
checkSel(p);
if(selected!=null){
sa.ss.remove(selected);
c.repaint();
}
}
}
private static void checkSel(Point p) {
selected=null;
for(int i=sa.ss.size();i0; i--)
if(sa.ss.get(i-1).shape.contains(p)){
selected=sa.ss.get(i-1);break;
}
sa.select(selected);
c.repaint();
}
static void mt(){
Shape s=null;
int cx,cy,cw,ch;
switch(sm){
case 0:
case 2:
cx=Math.min(mx,tx);
cy=Math.min(my,ty);
cw=Math.abs(mx-tx);
ch=Math.abs(my-ty);
if(sm==0)
s=new Ellipse2D.Double(cx,cy,cw,ch);
else
s=new Rectangle(cx,cy,cw,ch);
break;
case 1:
s=new Line2D.Float(mx,my,tx,ty);
break;
case 3:
cw=Math.abs(mx-tx);
ch=Math.abs(my-ty);
int cd=(int)Math.sqrt(Math.pow(mx-tx,2)+Math.pow(my-ty,2))*2;
cx=mx-cd/2;
cy=my-cd/2;
s=new Ellipse2D.Double(cx,cy,cd,cd);
break;
case 4:
Path2D p=new Path2D.Double();
p.moveTo(mx,my);
if(pc==1){
p.lineTo(tx, ty);
}
else{
p.quadTo(ox,oy,tx,ty);
}
s=p;
break;
}
ts=new S(s,m.fc.getBackground(),m.bc.getBackground(),m.fillC.isSelected(),m.drawB.isSelected(),null);
c.repaint();
}
static void md(Point p){
if(mid==0){
if(!sa.ss.isEmpty()){
sa.ss.get(sa.ss.size()-1).sel=false;
}
if(pc1){
ox=p.x;oy=p.y;
}
else{
tx=p.x;ty=p.y;
}
mt();
}
else if(mid==1){
if(selected!=null){
moveTo(selected,p);
c.repaint();
}
}
else if(mid==2){
checkSel(p);
if(selected!=null){
sa.ss.remove(selected);
c.repaint();
}
}
}
static void moveTo(S s, Point p) {
if(s.shape instanceof Rectangle){
Rectangle r=(Rectangle)s.shape;
r.setLocation(r.x+p.x-mx,r.y+p.y-my);
mx=p.x;my=p.y;
}
else if(s.shape instanceof Ellipse2D){
Ellipse2D e=(Ellipse2D)s.shape;
e.setFrame(e.getX()+p.x-mx,e.getY()+p.y-my,e.getWidth(),e.getHeight());
mx=p.x;my=p.y;
}
}
static void mr(Point p) {
if(pc==pmax){
pc=0;
ne=true;
sa.add(ts);
selected=ts;
ts=null;
}
}
}
class S implements Serializable{
boolean fc,db,sel=true;
Shape shape;
Color fillColor,borderColor;
Stroke stroke;
static Stroke bstroke=new MyBasicStroke();
static Stroke selectStroke=new BasicStroke(1,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER,1,new float[]{5,2},1);
S(Shape s,Color c,Color b,boolean f,boolean d,Stroke k){
this.shape=s;this.fillColor=c;this.borderColor=b;this.fc=f;this.db=d;this.stroke=k==null?bstroke:k;
}
void draw(Graphics2D g){
if(fc){
g.setColor(fillColor);
g.fill(shape);
}
if(db){
g.setColor(borderColor);
g.setStroke(stroke);
g.draw(shape);
}
if(sel){
g.setColor(Color.green);
g.setStroke(selectStroke);
g.draw(shape.getBounds());
}
}
}
class MyBasicStroke extends BasicStroke implements Serializable{}
class SA implements Serializable{
ArrayListS ss=new ArrayListS();
void add(S s){
if(s!=null){
for(S sx:ss)
sx.sel=false;
ss.add(s);
}
}
S remove(int i){
return ss.remove(i);
}
void remove(S s){
ss.remove(s);
}
void upZ(S s){
indexZ(s,1);
}
void downZ(S s){
indexZ(s,-1);
}
void indexZ(S s, int i) {
int si=ss.indexOf(s);
if(si+i0||si+iss.size()-1)return;
swap(s,ss.get(si+i));
}
void swap(S a,S b){
int ai=ss.indexOf(a);
int bi=ss.indexOf(b);
ss.set(ai,b);
ss.set(bi,a);
}
void select(S s){
for(S x:ss)
x.sel=false;
if(s!=null)
s.sel=true;
}
void drawAll(Graphics2D g){
for(S s:ss)
s.draw(g);
}
}
Q4: 用JAVA编制电子白板软件
随着Internet的迅速发展 在Email WWW FTP等传统的非实时应用日趋成熟的同时 广大网络用户对在线实时交流的需求不断扩大 如网上会议 远程教学 协同工作等 这方面的应用软件也日益丰富起来 该类软件主要分为两类 一种是以目前BBS和主页上的聊天室为代表的纯文字型的交流工具 另一种就是本文要介绍的电子白板类交流工具 电子白板除了具备聊天室的全部功能外 更重要的是 它还引入了绘画图形交流功能 使网上交流的形象性和直观性大大加强了 弥补了文字交流的不足 当分布在Internet不同位置的用户用白板进行交流时 一个人在自己的白板上绘制的图形可以马上在别人的白板上显示出来 好象大家都在同一块白板上绘画 彼此间的距离感大大缩短了 目前具有电子白板功能的软件有微软的Netmeeting等 此类软件在使用前需要用安装盘安装(Netmeeting是InternetExplorer 的选装件) 在设置完成后才能使用 相比而言 在主页中用JAVAApplet实现白板功能就显得优势很大 因为它不需要传统软件的下载 安装和设置的繁琐步骤 只要用支持JAVA的浏览器连接到该Applet所在主页 就可以使用白板 用于浏览器的普及性(大部分常用浏览器都支持JAVA 如InternetExploer 与NetscapeNavigator 及以上版本)使得这种电子白板的潜在客户群是巨大的 此外 用JAVA编制电子白板软件还有一个显而易见的优势 就是整个软件(尤其是白板服务器)无须重新修改编译就可在NT Unix Linux等支持JAVA的平台上运行 目前基于浏览器和JAVA的电子白板正处于起步阶段 笔者尚未在网上看到该类软件 由于工作需要 笔者自行开发了一套此类电子白板软件 这里想将开发中的一些经验介绍给大家 以达到共同交流的目的 工作原理 电子白板有两种实现模型 一种是无白板服务器 因此仅支持两个用户直接连结 另一种是有白板服务器 原则上不限制同时上线人数和交谈室个数 具体实现上可视服务器性能和需要而定 本文要介绍属于后者 当用户需用白板与他人交流时 需要先用浏览器连到Applet所在主页 Applet运行后会连接到该白板服务器 和服务器建立TCP连接 每个用户可以在自己的白板上(嵌在Applet画面中)绘制图形和输入文字 Applet会将这些信息通过已建立的网络连接发往白板服务器 并不断侦听 接收来自白板服务器的图形和文字信息 将其再现在用户的白板中 白板服务器的作用是不断侦听 接收来自各Applet的信息 并将其转发给其他用户 由于浏览器对JAVAApplet的限制 使得Applet只能访问发送该Applet的宿主主机 因此只能在该Applet所在主机上运行白板服务器 使得Applet能建立和远程白板服务器的联系 功能设计 一个实用的电子白板系统应该具备以下基本功能 用户在浏览到白板主页时 需登录后才能进行交流 这将提供交流时用的名字 必要时还可做权限检查 用户能够根据交谈室的交谈主题选择参加和退出现有的交谈室 并且能建立新的交谈室 可以根据该电子白板系统的应用领域和需要附加一些权限设置 用户只能和在同一交谈室中的用户交流 一个交谈室的信息对于别的交谈室是不可见的 白板应至少具有一些如更换画笔颜色 清除画板(仅影响自己的白板)等方便用户的功能 白板应具有一个操作提示和操作信息反馈栏 对用户显示一些操作提示和操作结果信息 这样可以方便用户使用 用户应能暂停和恢复自己的白板工作 为了增加白板的实用价值 可以考虑增加如与windows画笔工具类似的画正方形 圆形等类似功能 本例作为电子白板基本模型的建立 故没有加入这些功能 实际上 只要了解了下面要介绍的白板通讯协议集的设计原则 增加以上功能是非常容易的 通讯协议集的制定 由于JAVA内置的标准基础通讯协议是TCP/IP 所以我们只需在其基础上建立电子白板的应用层协议集 协议集的模型将采用服务器/客户机的请求/应答模式 可以根据需要实现的白板功能制定通讯协议集 协议集中包括登录 图形传输(分服务器发出和客户机发出两部分) 文字传输(分服务器发出和客户机发出两部分) 服务器要求刷新交谈室及成员名单 客户机要求刷新交谈室及成员名单 加入指定交谈室 退出交谈室 建立新交谈室 暂停/恢复交流等部分 由于已经依靠TCP/IP协议保证数据传输的正确性 所以在这个电子白板的通讯协议集的设计中应在保证功能的前提下尽量简洁 来提高带宽利用率 白板通讯协议集的细节可参考如下 注意 (S)表示该部分由服务器发出 客户机接收 (C)表示该部分由客户机发出 服务器接收 数据格式表示 引号之间表示字符串 (short)表示短整形数( 字节) (int)表示标准整形数( 字节) 登录(C) log →用户名字符串 图形传输(客户机发出)(C) draw →(int)颜色值→(short)直线起点横坐标→(short)直线起点纵坐标→(short)直线终点横坐标→(short)直线终点纵坐标 图形传输(服务器发出)(S) draw →(int)颜色值→(short)直线起点横坐标→(short)直线起点纵坐标→(short)直线终点横坐标→(short)直线终点纵坐标 文字传输(客户机发出)(C) text →用户在白板对话框中输入的文字字符串 文字传输(服务器发出)(S) text →文字输入者姓名字符串→该用户输入的文字字符串 服务器要求刷新交谈室及成员名单(S) refresh →交谈室 主题字符串→交谈室 中的用户 姓名字符串→交谈室 中的用户 姓名字符串→ → plete →交谈室 主题字符串→交谈室 中的用户 姓名字符串→交谈室 中的用户 姓名字符串→ → plete → →最后一个交谈室主题字符串→最后一个交谈室中的用户 姓名字符串→最后一个交谈室中的用户 姓名字符串→ → plete → ok 客户机要求刷新交谈室及成员名单(C) refresh (服务器收到此命令 会执行前面的服务器要求刷新交谈室及成员名单子协议 以响应客户机请求)加入指定交谈室(C) join →申请加入的交谈室主题字符串 退出交谈室(C) quit 建立新交谈室(C) new →申请建立的新交谈室主题字符串 (服务器收到此命令 会自动在该用户原来所在的交谈室中注销 并使该用户成为新交谈室的一员)暂停交流(C) pause 恢复交流(C) continue 以上为本电子白板软件所遵循的通讯协议集 这个协议集的可扩充性很强 可以随时按增加的功能扩充协议集 例如需要传送圆形图案 则可将如下协议加到协议集中 circle →(int)颜色值→(short)圆心横坐标→(short)圆心纵坐标→(short)圆半径 编程实现 程序设计分服务器JAVAApplication和客户端JAVAApplet两部分进行 编程中需要注意以下几点 服务器程序不要采用客户端接入时建立用户线程 退出交谈室时销毁线程的工作流程 因为有些操作系统的线程操作机制不够健全 在线程销毁时线程所占资源不能被完全释放 以致于在白板服务器运行的过程中将逐渐消耗掉系统资源 所以应在服务器初始化时按照最大允许同时上线的用户数建立所有用户服务线程 这些线程将等待客户端接入 当用户退出交谈室时线程并不销毁 而是清除用户数据 重新进入等待接入状态 准备为下一个用户服务 这样就保证了白板服务器可以长期可靠运行 当用户在白板上连续绘画时可能产生大量的图形数据 客户端Applet若在白板的AWT事件处理程序中完成将这些数据传输给服务器的任务 则很有可能由于网络I/O的瓶颈作用 使得AWT事件处理线程受阻 从而影响白板Applet 浏览器 其他正在运行的应用软件的界面相应性 解决的办法就是使Applet再建立一个后台绘图数据传输线程 白板的AWT事件处理程序将用户的绘图数据通过管道流(PipedStream)传输给这个线程后就返回 把网络传输的任务留给这个线程进行 在服务器和客户端Applet中 协议集每一个子协议的实现都要分别建立一个同步块(synchronize) 该子协议的全部操作都要在这个同步块内完成 以限制自由访问网络接插建立的输入流和输出流 使得当一个线程执行一个子协议时能够独占这些网络资源 而使别的线程不能访问这些资源 以保证线程能够完整正确地执行子协议 但是由于同步操作会降低线程调度和执行效率 所以要在确保子协议完整执行的前提下尽量缩小同步代码块的范围 由于协议集中的数据类型既有字符串又有整形数 因此在程序中选用DataInputStream和DataOutputStream作为数据输入流和输出流 此外 由于UTF格式的文本支持中文字符集 且在字符串中已包含长度信息 可以方便数据读取 故在本程序的网络通信中的字符串全部采用UTF格式 设计自己的白板程序时 可以根据需要换用其他文本格式和编码规则 但一定要保证输入流和输出流采用的是同一种格式和编码 考虑到目前NetscapeNavigator 和InternetExplorer 目前仍普遍使用 而这两种浏览器的JAVA虚拟机都不支持较新的JDK 标准 所以在本程序的客户机Applet部分中没有使用JDK 特有的类库 首先介绍服务器程序的编制 需确定主要的几个类及其成员函数 列表如下 ChatServer类 服务器程序的启动类 ChatServer() 建立服务器管理界面 initServer() 建立服务器插结 lishixinzhi/Article/program/Java/JSP/201311/19712
java代码实现画板的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java简单画图板完整代码、java代码实现画板的信息别忘了在本站进行查找喔。








