从画图程序开始,走进GUI编程世界

原创 2005年03月01日 12:17:00

从画图程序开始,走进GUI编程世界

Java、画图

//以下是画图的Java版

package boya;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Draw{
 private DrawModel model;
 private DrawView view;
 private static DrawFrame window;
 private static Draw theApp;
 public static void main(String[] args){
  theApp=new Draw();
  theApp.init();
 }
 public void init(){
  window=new DrawFrame("画板",this);
  Toolkit theKit=window.getToolkit();
  Dimension wndsize=theKit.getScreenSize();
  window.setBounds(wndsize.width/6,wndsize.height/6,//位置
      2*wndsize.width/3,2*wndsize.height/3);//大小
  model=new DrawModel();
  view=new DrawView(this);
  model.addObserver((Observer)view);
  model.addObserver((Observer)window);
  window.getContentPane().add(view,BorderLayout.CENTER);
  window.setVisible(true);
 }
 public DrawFrame getWindow(){
  return window;
 }
 public DrawModel getModel(){
  return model;
 }
 public DrawView getView(){
  return view;
 }
 class WindowHandler extends WindowAdapter{
  public void windowClosing(WindowEvent e){
   window.checkForSave();
   window.dispose();//关闭窗口
   System.exit(0);//关闭程序
  }
 }
 public void insertModel(DrawModel anew){
  model=anew;
  model.addObserver((Observer)view);
  model.addObserver((Observer)window);
  view.repaint();
 }  
}

package boya;
import java.io.*;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;

class DrawFrame extends JFrame implements ID,ActionListener,Observer{
 private Draw theApp;
 private JMenuBar menubar=new JMenuBar();
 private JToolBar toolBar=new JToolBar();
 private StatusBar statusBar=new StatusBar();
 private FontDialog fontDlg;
 private JMenuItem aboutItem,fontItem,customColorItem;
 private JPopupMenu popup;
 private FileAction newAction,openAction,closeAction,saveAction,
                    saveAsAction,printAction;
 private TypeAction lineAction,rectangleAction,circleAction,curveAction,textAction;
 private ColorAction redAction,yellowAction,greenAction,blueAction;
 private Color elementColor=DEFAULT_ELEMENT_COLOR;
 private int elementType=DEFAULT_ELEMENT_TYPE;
 private Font font=DEFAULT_FONT;
 private String frameTitle,filename=DEFAULT_FILENAME;
 private File modelFile;
 private boolean changed=false;
 private JFileChooser files;
 class FileAction extends AbstractAction{
  FileAction(String name,String tooltip){
   super(name);
   String icons="res/"+name+".gif";
   if(new File(icons).exists())
    putValue(SMALL_ICON,new ImageIcon(icons));
   if(tooltip!=null)
    putValue(SHORT_DESCRIPTION,tooltip);
  }
  public void actionPerformed(ActionEvent e){
   String name=(String)getValue(NAME);
   if(name.equals(newAction.getValue(NAME))){
    checkForSave();
    theApp.insertModel(new DrawModel());
    modelFile=null;
    filename=DEFAULT_FILENAME;
    setTitle(frameTitle+files.getCurrentDirectory()+"//"+filename);
    changed=false;
   }
   else if(name.equals(openAction.getValue(NAME))){
    checkForSave();
    File file=showDialog("打开文件","打开","读一个文件",'o',null);
    if(file!=null)
     openDraw(file); 
   }
   else if(name.equals(closeAction.getValue(NAME))){
    checkForSave();
    System.exit(0);
   }
   else if(name.equals(saveAction.getValue(NAME))){
    saveIt();
   }
   else if(name.equals(saveAsAction.getValue(NAME))){
    File file=showDialog("另存为","保存","保存图片",'s',
        modelFile==null?new File(
        files.getCurrentDirectory(),filename):modelFile);
    if(file!=null){
     if(file.exists()&&!file.equals(modelFile))
      if(JOptionPane.NO_OPTION==
       JOptionPane.showConfirmDialog(
        DrawFrame.this,file.getName()+"已存在,覆盖?",
        "确认保存",JOptionPane.YES_NO_OPTION,
        JOptionPane.WARNING_MESSAGE))
       return;
    saveDraw(file);
    }
    return;
   }
   else if(name.equals(printAction.getValue(NAME))){
   }
  }
 }
 class ColorAction extends AbstractAction{
  private Color color;
  ColorAction(String name,Color color,String tooltip){
   super(name);
   this.color=color;
   String icons="res/"+name+".gif";
   if(new File(icons).exists())
    putValue(SMALL_ICON,new ImageIcon(icons));
   if(tooltip!=null)
    putValue(SHORT_DESCRIPTION,tooltip);
  }
  public void actionPerformed(ActionEvent e){
   elementColor=color;
   statusBar.setColorPane(color);
  }
 }
 class TypeAction extends AbstractAction{
  private int typeID;
  TypeAction(String name,int typeID,String tooltip){
   super(name);
   this.typeID=typeID;
   String icons="res/"+name+".gif";
   if(new File(icons).exists())
    putValue(SMALL_ICON,new ImageIcon(icons));
   if(tooltip!=null)
    putValue(SHORT_DESCRIPTION,tooltip);
  }
  public void actionPerformed(ActionEvent e){
   elementType=typeID;
   statusBar.setTypePane(typeID);
  }
 }
 public DrawFrame(String title,Draw theApp){
  setTitle(title);
  this.theApp=theApp;
  setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
  setJMenuBar(menubar);
  //一级菜单
  JMenu fileMenu=new JMenu("文件(F)");
  JMenu elementMenu=new JMenu("图形(E)");
  JMenu optionsMenu=new JMenu("选项(O)");
  JMenu helpMenu=new JMenu("帮助(H)");
  fileMenu.setMnemonic('F');
  elementMenu.setMnemonic('E');
  optionsMenu.setMnemonic('O');
  helpMenu.setMnemonic('H');
  //二级菜单
  addMenuItem(fileMenu,newAction=new FileAction("新建","创建新文件"),KeyStroke
     .getKeyStroke('N',Event.CTRL_MASK));
  addMenuItem(fileMenu,openAction=new FileAction("打开","打开文件"),KeyStroke
     .getKeyStroke('O',Event.CTRL_MASK));
  addMenuItem(fileMenu,closeAction=new FileAction("关闭","关闭程序"),KeyStroke
     .getKeyStroke('X',Event.CTRL_MASK));
  fileMenu.addSeparator();
  addMenuItem(fileMenu,saveAction=new FileAction("保存","保存文件"),KeyStroke
     .getKeyStroke('S',Event.CTRL_MASK));
  addMenuItem(fileMenu,saveAsAction=new FileAction("另存为...","文件另存为"));
  fileMenu.addSeparator();
  addMenuItem(fileMenu,printAction=new FileAction("打印","打印文件"),KeyStroke
     .getKeyStroke('P',Event.CTRL_MASK));
  addMenuItem(elementMenu,lineAction=new TypeAction("直线",LINE,"绘制直线"),KeyStroke
     .getKeyStroke('1',Event.CTRL_MASK));
  addMenuItem(elementMenu,rectangleAction=new TypeAction("矩形",RECTANGLE,"绘制矩形"),KeyStroke
     .getKeyStroke('2',Event.CTRL_MASK));
  addMenuItem(elementMenu,circleAction=new TypeAction("椭圆",CIRCLE,"绘制椭圆"),KeyStroke
     .getKeyStroke('3',Event.CTRL_MASK));
  addMenuItem(elementMenu,curveAction=new TypeAction("曲线",CURVE,"绘制曲线"),KeyStroke
     .getKeyStroke('4',Event.CTRL_MASK));
  addMenuItem(elementMenu,textAction=new TypeAction("文字",TEXT,"输入文字"),KeyStroke
     .getKeyStroke('5',Event.CTRL_MASK));
  elementMenu.addSeparator();
  JMenu colorMenu=new JMenu("颜色");
  elementMenu.add(colorMenu);
  addMenuItem(colorMenu,redAction=new ColorAction("红色",Color.red,"绘制红色"),KeyStroke
     .getKeyStroke('1',Event.ALT_MASK));
  addMenuItem(colorMenu,yellowAction=new ColorAction("黄色",Color.yellow,"绘制黄色"),KeyStroke
     .getKeyStroke('2',Event.ALT_MASK));
  addMenuItem(colorMenu,greenAction=new ColorAction("绿色",Color.green,"绘制绿色"),KeyStroke
     .getKeyStroke('3',Event.ALT_MASK));
  addMenuItem(colorMenu,blueAction=new ColorAction("蓝色",Color.blue,"绘制蓝色"),KeyStroke
     .getKeyStroke('4',Event.ALT_MASK));
  aboutItem=new JMenuItem("关于");
  aboutItem.setAccelerator(KeyStroke.getKeyStroke('A',Event.CTRL_MASK));
  aboutItem.addActionListener(this);
  helpMenu.add(aboutItem);
  fontItem=new JMenuItem("字体选择");
  fontItem.setAccelerator(KeyStroke.getKeyStroke('T',Event.CTRL_MASK));
  fontItem.addActionListener(this);
  optionsMenu.add(fontItem);
  customColorItem=new JMenuItem("颜色选择");
  customColorItem.setAccelerator(KeyStroke.getKeyStroke('R',Event.CTRL_MASK));
  customColorItem.addActionListener(this);
  optionsMenu.add(customColorItem);
  menubar.add(fileMenu);
  menubar.add(elementMenu);
  menubar.add(optionsMenu);
  menubar.add(helpMenu);
  //工具栏的设置
  toolBar.add(newAction);
  toolBar.add(openAction);
  toolBar.add(saveAction);
  toolBar.add(printAction);
  toolBar.addSeparator();
  toolBar.add(lineAction);
  toolBar.add(rectangleAction);
  toolBar.add(circleAction);
  toolBar.add(curveAction);
  toolBar.add(textAction);
  toolBar.addSeparator();
  toolBar.add(redAction);
  toolBar.add(yellowAction);
  toolBar.add(greenAction);
  toolBar.add(blueAction);
  getContentPane().add(toolBar,BorderLayout.NORTH);
  toolBar.setFloatable(false);//工具栏禁止漂浮
  getContentPane().add(statusBar,BorderLayout.SOUTH);
  fontDlg=new FontDialog(this);
  popup=new JPopupMenu("General");
  popup.add(lineAction);
  popup.add(rectangleAction);
  popup.add(circleAction);
  popup.add(curveAction);
  popup.add(textAction);
  popup.addSeparator();
  popup.add(redAction);
  popup.add(yellowAction);
  popup.add(greenAction);
  popup.add(blueAction);
  files=new JFileChooser(DEFAULT_DIR);
  frameTitle=title+":";
  setTitle(frameTitle+filename);
  if(!DEFAULT_DIR.exists())
   if(!DEFAULT_DIR.mkdirs())
    JOptionPane.showMessageDialog(this,"建立文件失败!","错误",JOptionPane.ERROR_MESSAGE);
 }
 private JMenuItem addMenuItem(JMenu menu,Action action){
  //重载添加菜单元素的函数使其不具有图象,不具有快键
  JMenuItem item=menu.add(action);
  item.setIcon(null);
  return item;
 }
 private JMenuItem addMenuItem(JMenu menu,Action action,KeyStroke keys){
  //重载添加菜单元素的函数使其不具有图象,具有快键
  JMenuItem item=menu.add(action);
  item.setIcon(null);
  item.setAccelerator(keys);
  return item;
 }
 private JButton addToolBarButton(Action action){
  //重载添加工具栏按钮
  JButton button=toolBar.add(action);
  button.setText(null);
  return button;
 }
 public Color getElementColor(){
  return elementColor;
 }
 public int getElementType(){
  return elementType;
 }
 public Font getFont(){
  return font;
 }
 public void setFont(Font font){
   this.font=font;
 }
 public JPopupMenu getPopup(){
  return popup;
 }
 public void actionPerformed(ActionEvent e){
  if(e.getSource()==aboutItem){
   JOptionPane.showMessageDialog((Component)e.getSource(),"版本说明:画图软件由博雅制作"
    ,"关于",JOptionPane.INFORMATION_MESSAGE);
  }
  else if(e.getSource()==fontItem){
   Rectangle bounds=getBounds();
   fontDlg.setLocation(bounds.x+bounds.width/3,bounds.y+bounds.height/3);
   fontDlg.setVisible(true);
  }
  else if(e.getSource()==customColorItem){
   Color color=JColorChooser.showDialog(this,"颜色选择",elementColor);
   if(color!=null){
    elementColor=color;
    statusBar.setColorPane(color);
   }
  }
 }
 public void update(Observable o,Object obj){
  changed=true;
 }
 private File showDialog(String dlgTitle,String ABT,String ABTP,
  char ABM,File file){
   files.setDialogTitle(dlgTitle);
   files.setApproveButtonText(ABT);
   files.setApproveButtonToolTipText(ABTP);
   files.setApproveButtonMnemonic(ABM);
   files.rescanCurrentDirectory();
   files.setSelectedFile(file);
   int result=files.showDialog(DrawFrame.this,null);
   return(result==files.APPROVE_OPTION)?files.getSelectedFile():null;
 }
 private void saveIt(){
  if(!changed) return;
  if(modelFile!=null)
   saveDraw(modelFile);
  else{
   File file=showDialog("保存图片","保存","保存图片",'s',
    new File(files.getCurrentDirectory(),filename));
   if(file==null)
    return;
   else
    if(file.exists())
     if(JOptionPane.NO_OPTION==JOptionPane.showConfirmDialog(DrawFrame.this,file.getName()+"已存在,覆盖?"
     ,"确认保存",JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE))
      return;
   saveDraw(file);
  }
 }
 private void saveDraw(File outFile){
  try{
   ObjectOutputStream out=new ObjectOutputStream(new
         BufferedOutputStream(
         new FileOutputStream(outFile)));
   out.writeObject(theApp.getModel());
   out.flush();
   out.close();
  }
  catch(IOException e){
   System.out.println(e);
   JOptionPane.showMessageDialog(DrawFrame.this,"错误","保存失败",JOptionPane.ERROR_MESSAGE);
   return;
  }
  if(outFile!=modelFile){
   modelFile=outFile;
   filename=modelFile.getName();
   setTitle(frameTitle+modelFile.getPath());
  }
  changed=false;
 }
 public void openDraw(File inFile){
  try{
   ObjectInputStream in=new ObjectInputStream(new
         BufferedInputStream(
         new FileInputStream(inFile)));
   theApp.insertModel((DrawModel)in.readObject());
   in.close();
   modelFile=inFile;
   filename=modelFile.getName();
   setTitle(frameTitle+modelFile.getPath());
  }
  catch(Exception e){
   System.out.println(e);
   JOptionPane.showMessageDialog(DrawFrame.this,"错误","打开失败",JOptionPane.ERROR_MESSAGE);
   return;
  }
 }
 public void checkForSave(){
  if(changed)
   if(JOptionPane.YES_OPTION==JOptionPane.showConfirmDialog(DrawFrame.this,"文件已修改,保存?"
     ,"确认保存",JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE))
    saveIt();
 }
}

package boya;
import java.io.*;
import java.util.*;
class DrawModel extends Observable implements Serializable{
 protected LinkedList elements=new LinkedList();
 public void add(Elements element){
  elements.add(element);
  setChanged();
  notifyObservers(element.getBounds());
 }
 public boolean remove(Elements element){
  boolean removed=elements.remove(element);
  if(removed){
   setChanged();
   notifyObservers(element.getBounds());
  }
  return removed;
 }
 public Iterator getIterator(){
  return elements.listIterator();
 }
}

package boya;
import java.awt.*;
import java.util.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
class DrawView extends JComponent implements Observer,ID{
 private Draw theApp;
 public DrawView(Draw theApp){
  this.theApp=theApp;
  MouseHandler handler=new MouseHandler();
  addMouseListener(handler);
  addMouseMotionListener(handler);
 }
 class MouseHandler extends MouseInputAdapter{
  private Point start,end;
  private Elements temp;
  private Graphics2D g2D;
  private Elements createElement(Point start,Point end){
   switch(theApp.getWindow().getElementType()){
    case LINE:
     return new Elements.Line(start,end,theApp.getWindow().getElementColor());
    case RECTANGLE:
     return new Elements.Rectangle(start,end,theApp.getWindow().getElementColor());
    case CIRCLE:
     return new Elements.Circle(start,end,theApp.getWindow().getElementColor());
    case CURVE:
     return new Elements.Curve(start,end,theApp.getWindow().getElementColor());
   }
   return null;
  }
  public void mousePressed(MouseEvent e){
   start=e.getPoint();
   int modifier=e.getModifiers();
   if((modifier&e.BUTTON1_MASK)!=0){
    g2D=(Graphics2D)getGraphics();
    g2D.setXORMode(getBackground());
    g2D.setPaint(theApp.getWindow().getElementColor());
   }
  }
  public void mouseDragged(MouseEvent e){
   end=e.getPoint();
   int modifier=e.getModifiers();
   if((modifier&e.BUTTON1_MASK)!=0&&(theApp.getWindow()
    .getElementType()!=TEXT)){
    if(temp==null)
     temp=createElement(start,end);
    else{
     temp.draw(g2D);
     temp.moving(start,end);
    }
    temp.draw(g2D);
   }
  }
  public void mouseReleased(MouseEvent e){
   int modifier=e.getModifiers();
   if(e.isPopupTrigger()){
    start=e.getPoint();
    theApp.getWindow().getPopup().show((Component)e.getSource(),
         start.x,start.y);
    start=null;
   }
   else if((modifier&e.BUTTON1_DOWN_MASK)==0&&(theApp.getWindow()
    .getElementType()!=TEXT)){
    if(temp!=null){
     theApp.getModel().add(temp);
     temp=null;
    }
    if(g2D!=null){
     g2D.dispose();
     g2D=null;
    }
    start=end=null;
   }
  }
  public void mouseClicked(MouseEvent e){
   int modifier=e.getModifiers();
   if((modifier&e.BUTTON1_MASK)!=0&&(theApp.getWindow()
    .getElementType()==TEXT)){
    start=e.getPoint();
    String text=JOptionPane.showInputDialog(
       (Component)e.getSource(),"输入文字"
       ,"文字",JOptionPane.PLAIN_MESSAGE);
    if(text!=null){
     g2D=(Graphics2D)getGraphics();
     Font font=theApp.getWindow().getFont();
     temp=new Elements.Text(font,text,start,
       theApp.getWindow().getElementColor(),
       font.getStringBounds(text,g2D.getFontRenderContext()).getBounds());
     temp.draw(g2D);
     if(temp!=null)
      theApp.getModel().add(temp);
     temp=null;
     g2D.dispose();
     g2D=null;
     start=null;
    }
   }
  }
   
 }
 public void update(Observable o,Object rectangle){
  if(rectangle==null)
   repaint();
  else repaint((Rectangle)rectangle);
 }
 public void paint(Graphics g){
  Graphics2D g2D=(Graphics2D)g;
  Iterator elements=theApp.getModel().getIterator();
  Elements element;
  while(elements.hasNext()){
   element=(Elements)elements.next();
   element.draw(g2D);
  }
 }
}

package boya;
import java.io.*;
import java.awt.*;
import java.util.*;
import java.awt.geom.*;
abstract class Elements implements Serializable{
 protected Color color;
 public Elements(Color color){
  this.color=color;
 }
 public Color getColor(){
  return color;
 }
 public abstract java.awt.Rectangle getBounds();
 public abstract void moving(Point start,Point end);
 public abstract void draw(Graphics2D g2D);
 public static class Line extends Elements{
  private Line2D.Double line;
  public Line(Point start,Point end,Color color){
   super(color);
   line=new Line2D.Double(start,end);
  }
  public java.awt.Rectangle getBounds(){
   return line.getBounds();
  }
  public void moving(Point start,Point end){
   line.x2=end.x;
   line.y2=end.y;
  }
  public void draw(Graphics2D g2D){
   g2D.setPaint(color);
   g2D.draw(line);
  }
  private void writeObject(ObjectOutputStream out)
      throws IOException{
   out.writeDouble(line.x2);
   out.writeDouble(line.y2);
  }
  private void readObject(java.io.ObjectInputStream in)
      throws IOException,ClassNotFoundException{
   double x2=in.readDouble();
   double y2=in.readDouble();
   line=new Line2D.Double(0,0,x2,y2);
  }
 }
 public static class Rectangle extends Elements{
  private Rectangle2D.Double rectangle;
  public Rectangle(Point start,Point end,Color color){
   super(color);
   rectangle=new Rectangle2D.Double(
    Math.min(start.x,end.x),Math.min(start.y,end.y),
    Math.abs(start.x-end.x),Math.abs(start.y-end.y));
  }
  public java.awt.Rectangle getBounds(){
   return rectangle.getBounds();
  }
  public void moving(Point start,Point end){
   rectangle.x=Math.min(start.x,end.x);
   rectangle.y=Math.min(start.y,end.y);
   rectangle.width=Math.abs(start.x-end.x);
   rectangle.height=Math.abs(start.y-end.y);
  }
  public void draw(Graphics2D g2D){
   g2D.setPaint(color);
   g2D.draw(rectangle);
  }
  private void writeObject(ObjectOutputStream out)
      throws IOException{
   out.writeDouble(rectangle.width);
   out.writeDouble(rectangle.height);
  }
  private void readObject(java.io.ObjectInputStream in)
      throws IOException,ClassNotFoundException{
   double width=in.readDouble();
   double height=in.readDouble();
   rectangle=new Rectangle2D.Double(0,0,width,height);
  }
 }
 public static class Circle extends Elements{
  private Ellipse2D.Double circle;
  public Circle(Point center,Point circum,Color color){
   super(color);
   double radius=center.distance(circum);
   circle=new Ellipse2D.Double(center.x-radius,center.y-radius,2*radius,2*radius);
  }
  public java.awt.Rectangle getBounds(){
   return circle.getBounds();
  }
  public void moving(Point center,Point circum){
   double radius=center.distance(circum);
   circle.x=center.x-(int)radius;
   circle.y=center.y-(int)radius;
   circle.width=circle.height=2*radius;
  }
  public void draw(Graphics2D g2D){
   g2D.setPaint(color);
   g2D.draw(circle);
  }
  private void writeObject(ObjectOutputStream out)
      throws IOException{
   out.writeDouble(circle.width);
  }
  private void readObject(java.io.ObjectInputStream in)
      throws IOException,ClassNotFoundException{
   double width=in.readDouble();
   circle=new Ellipse2D.Double(0,0,width,width);
  }
 }
 public static class Curve extends Elements{
  private GeneralPath curve;
  public Curve(Point start,Point next,Color color){
   super(color);
   curve=new GeneralPath();
   curve.moveTo(start.x,start.y);
   curve.lineTo(next.x,next.y);
  }
  public java.awt.Rectangle getBounds(){
   return curve.getBounds();
  }
  public void moving(Point start,Point next){
   curve.lineTo(next.x,next.y);
  }
  public void draw(Graphics2D g2D){
   g2D.setPaint(color);
   g2D.draw(curve);
  }
  private void writeObject(ObjectOutputStream out)
      throws IOException{
   PathIterator iterator=curve.getPathIterator(new AffineTransform());
   Vector coords=new Vector();
   int max=6;
   float[] temp=new float[max];
   int result=iterator.currentSegment(temp);
   if(!(result==iterator.SEG_MOVETO)){
    System.out.println("No Starting moveto");
    return;
   }
   iterator.next();
   while(!iterator.isDone()){
    result=iterator.currentSegment(temp);
    if(!(result==iterator.SEG_LINETO)){
     System.out.println("Invalid segment type");
     return;
    }
    coords.add(new Float(temp[0]));
    coords.add(new Float(temp[1]));
    iterator.next();
   }
   out.writeObject(coords);
  }
  private void readObject(java.io.ObjectInputStream in)
      throws IOException,ClassNotFoundException{
   Vector coords=(Vector)in.readObject();
   curve=new GeneralPath();
   curve.moveTo(0,0);
   float x,y;
   for(int i=0;i<coords.size();i+=2){
    x=((Float)coords.get(i)).floatValue();
    y=((Float)coords.get(i+1)).floatValue();
    curve.lineTo(x,y);
   }
  }

 }
 public static class Text extends Elements{
  private Font font;
  private String text;
  private Point pos;
  private java.awt.Rectangle bounds=null;
  public Text(Font font,String text,Point pos,Color color,java.awt.Rectangle bounds){
   super(color);
   this.font=font;
   this.text=text;
   this.pos=pos;
   this.bounds=bounds;
   this.bounds.setLocation(pos.x,pos.y-(int)bounds.getHeight());
  }
  public java.awt.Rectangle getBounds(){
   return bounds;
  }
  public void moving(Point start,Point end){
  }
  public void draw(Graphics2D g2D){
   g2D.setPaint(color);
   Font oldFont=g2D.getFont();
   g2D.setFont(font);
   g2D.drawString(text,pos.x,pos.y);
   g2D.setFont(oldFont);
  }
 }
}

package boya;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
class FontDialog extends JDialog implements ID,ActionListener
        ,ListSelectionListener{
 private DrawFrame window;
 private Font font;
 private int style;
 private int size;
 private JButton ok,cancel;
 private JList fontList;
 private JLabel fontDisplay;
 private JComboBox chooseSize;
 public FontDialog(DrawFrame window){
  super(window,"字体选择",true);
  this.window=window;
  font=window.getFont();
  style=font.getStyle();
  size=font.getSize();
  JPanel buttonPane=new JPanel();
  buttonPane.add(ok=createButton("确认"));
  buttonPane.add(cancel=createButton("取消"));
  getContentPane().add(buttonPane,BorderLayout.SOUTH);
  JPanel dataPane=new JPanel();
  dataPane.setBorder(BorderFactory.createCompoundBorder(
       BorderFactory.createLineBorder(Color.black),
       BorderFactory.createEmptyBorder(5,5,5,5)));
  GridBagLayout gbLayout=new GridBagLayout();
  dataPane.setLayout(gbLayout);
  GridBagConstraints constraints=new GridBagConstraints();
  JLabel label=new JLabel("选择字体");
  constraints.fill=GridBagConstraints.HORIZONTAL;
  constraints.gridwidth=GridBagConstraints.REMAINDER;
  gbLayout.setConstraints(label,constraints);
  dataPane.add(label);
  GraphicsEnvironment e=GraphicsEnvironment.getLocalGraphicsEnvironment();
  String[] fonts=e.getAvailableFontFamilyNames();
  fontList=new JList(fonts);
  fontList.setValueIsAdjusting(true);
  fontList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  fontList.setSelectedValue(font.getFamily(),true);
  fontList.addListSelectionListener(this);
  JScrollPane chooseFont=new JScrollPane(fontList);
  chooseFont.setMinimumSize(new Dimension(300,100));
  JPanel display=new JPanel();
  fontDisplay=new JLabel("字体样例:x X y Y z Z");
  fontDisplay.setPreferredSize(new Dimension(300,100));
  display.add(fontDisplay);
  JSplitPane splitPane=new JSplitPane(JSplitPane.VERTICAL_SPLIT,true,chooseFont,display);
  gbLayout.setConstraints(splitPane,constraints);
  dataPane.add(splitPane);
  JPanel sizePane=new JPanel();
  label=new JLabel("选择字体大小");
  sizePane.add(label);
  String[] sizeList={"8","10","12","14","16","18","20","22","24"};
  chooseSize=new JComboBox(sizeList);
  chooseSize.setSelectedItem(Integer.toString(size));
  chooseSize.addActionListener(this);
  sizePane.add(chooseSize);
  gbLayout.setConstraints(sizePane,constraints);
  dataPane.add(sizePane);
  JRadioButton bold=new JRadioButton("加粗",(style&Font.BOLD)>0);
  JRadioButton italic=new JRadioButton("斜体",(style&Font.ITALIC)>0);
  bold.addItemListener(new StyleListener(Font.BOLD));
  italic.addItemListener(new StyleListener(Font.ITALIC));
  JPanel stylePane=new JPanel();
  stylePane.add(bold);
  stylePane.add(italic);
  gbLayout.setConstraints(stylePane,constraints);
  dataPane.add(stylePane);
  getContentPane().add(dataPane,BorderLayout.CENTER);
  pack();
  setVisible(false);
 }
 JButton createButton(String label){
  JButton button=new JButton(label);
  button.setPreferredSize(new Dimension(80,20));
  button.addActionListener(this);
  return button;
 }
 public void actionPerformed(ActionEvent e){
  Object source=e.getSource();
  if(source==ok){
   window.setFont(font);
   setVisible(false);
  }
  else if(source==cancel)
   setVisible(false);
  else if(source==chooseSize){
   size=Integer.parseInt((String)chooseSize.getSelectedItem());
   font=font.deriveFont((float)size);
   fontDisplay.setFont(font);
   fontDisplay.repaint();
  }
 }
 public void valueChanged(ListSelectionEvent e){
  if(!e.getValueIsAdjusting()){
   font=new Font((String)fontList.getSelectedValue(),style,size);
   fontDisplay.setFont(font);
   fontDisplay.repaint();
  }
 }
 class StyleListener implements ItemListener{
  private int astyle;
  public StyleListener(int style){
   this.astyle=style;
  }
  public void itemStateChanged(ItemEvent e){
   if(e.getStateChange()==ItemEvent.SELECTED)
    style|=astyle;
   else style&=~astyle;
   font=font.deriveFont(style);
   fontDisplay.setFont(font);
   fontDisplay.repaint();
  }
 }  
}


package boya;
import java.awt.*;
import java.io.File;
public interface ID{
 int LINE=101;
 int RECTANGLE=102;
 int CIRCLE=103;
 int CURVE=104;
 int TEXT=105;
 int DEFAULT_ELEMENT_TYPE=LINE;
 Color DEFAULT_ELEMENT_COLOR=Color.red;
 Font DEFAULT_FONT=new Font("宋体",Font.PLAIN,20);
 File DEFAULT_DIR=new File("c:/My Draw");
 String DEFAULT_FILENAME="Untitled.ice";
}

package boya;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
class StatusBar extends JPanel implements ID{
 private StatusPane colorPane=new StatusPane("红色");
 private StatusPane typePane=new StatusPane("直线");
 class StatusPane extends JLabel{
  private Font paneFont=new Font("宋体",Font.PLAIN,12);
  public StatusPane(String text){
   setForeground(Color.black);
   setFont(paneFont);
   setHorizontalAlignment(CENTER);
   setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));;
   setPreferredSize(new Dimension(70,18));
   setText(text);
  }
 }
 public StatusBar(){
  setLayout(new FlowLayout(FlowLayout.RIGHT,10,3));
  setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
  setColorPane(DEFAULT_ELEMENT_COLOR);
  setTypePane(DEFAULT_ELEMENT_TYPE);
  add(colorPane);
  add(typePane);
 }
 public void setColorPane(Color color){
  String text;
  if(color.equals(Color.red))
   text="红色";
  else if(color.equals(Color.yellow))
   text="黄色";
  else if(color.equals(Color.green))
   text="绿色";
  else if(color.equals(Color.blue))
   text="蓝色";
  else text="未定义";
  colorPane.setText(text);
 }
 public void setTypePane(int element){
  String text;
  switch(element){
   case LINE:
    text="直线";
    break;
   case RECTANGLE:
    text="矩形";
    break;
   case CIRCLE:
    text="圆";
    break;
   case CURVE:
    text="曲线";
    break;
   case TEXT:
    text="文字";
    break;
   default:
    text="错误";
    break;
  }
  typePane.setText(text);
 }
}


最后还可以将生成的代码放置到JAR包中,这样就可以在安装JVM的环境下,使
此JAR包作为可执行文件了。

包的结构如下:
--Draw
----boya
----META-INF
----res

其分别为包、配置文件、资源

在META-INF中建立文件MANIFEST.MF写入:
Manifest-Version: 1.0
Main-Class: boya.Draw


这样这个包就完成了
Main-Class: boya.Draw

JavaSwing图形界面编程之画图程序

package three.day.frame; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; impor...

走进windows编程的世界-----消息处理函数(1)

Win32消息机制    过程驱动:程序是按照我们预先定义好的顺序执行,每执行一步,下一步都已经按照预定的顺序 继续执行,直至程序结束。    事件驱动:程序的执行顺序是无序的。某个时间点所执行的代码...

走进编程世界的大门

编程,这个对我来说有些陌生的领域,待我来慢慢撕开你神秘的面纱!
  • fmflb
  • fmflb
  • 2017年07月22日 09:56
  • 62

走进windows编程的世界-----绘图相关

Windows绘图  1 图形绘制      1.1 图形绘制的方式      获取到绘图句柄-设备描述表(DC),使用相应的绘图的API,在设备上绘制图形.          1.2 颜色     ...

走进windows编程的世界-----windows线程

Windows线程  1 Windows线程    Windows进程中可以执行代码的实体,Windows系统可以调度的执行代码.一个进程中至少有一个或多个线程. 每个线程是进程的一个任务分支.   ...

走进windows编程的世界-----窗口的注册及创建

1   窗口注册和创建1.1WIN32 窗口程序创建步骤1、WinMain入口函数的定义2、WindowProc函数的定义3、注册窗口类RegisterClass、RegisterClassEX4、创...

走进windows编程的世界-----对话框、文本框、按钮

1 对话框的分类  2 对话框的基本使用方式  3 对话框资源  4 有模式对话框的使用      int DialogBox( HINSTANCE hInstance, LPCTSTR lpTe...

走进windows编程的世界-----字符编码

1   字符编码1.1编码的历史1.1.1ASCII码0=127 7位表示1.1.2ASCII扩展码0—255 8为表示。代码页:通过代码也来切换对应的字符(数字表示)1.1.3双字节字符集DBCS使...

走进windows编程的世界-----入门篇

1   Windows编程基础 1.1Win32应用程序基本类型 1)  控制台程序 不需要完善的windows窗口,可以使用DOS窗口方式显示 2)  Win32窗口程序 包含窗口的程序,可以通过窗...

走进windows编程的世界-----位图及映射模式

1   位图的使用1.1位图介绍位图—通过保存在图像上每个点的颜色,生成响应的位图文件。光栅图:图像点阵的保存矢量图:绘图命令的保存。1.2位图的使用1、             加载位图资源Load...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:从画图程序开始,走进GUI编程世界
举报原因:
原因补充:

(最多只允许输入30个字)