home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / in4wjcxu / src / como / commlet / draw / draw.java next >
Encoding:
Java Source  |  1996-08-14  |  15.6 KB  |  617 lines

  1. package como.commlet.draw;
  2.  
  3. import java.awt.*;
  4. import java.util.*;
  5. import java.io.IOException;
  6. import como.sys.*;
  7. import como.util.*;
  8. import como.awt.*;
  9. import como.io.*;
  10. import como.commlet.*;
  11.  
  12. /*
  13.  
  14. Draw.java Whiteboard Commlet
  15.  
  16. (c) Jan Kautz und Ulrich Gall
  17.  
  18. For every user, there is a Group instance that contains the objects that user
  19. has drawn. The local user may only change the objects in his group.
  20. The GraphicsObject class hierarchy objects are very autonomouse-- they even
  21. do the event handling themselves. They get the events from the canvas and
  22. have their own handleEvent method that defines the way these objects are created. 
  23. For example, a line is started by mouseDown, ended by mouseDrag and will be
  24. accepted (sent to the others and added to the gorup) by mouseUp.
  25.  
  26. This way, the applet can easily expanded to support moving  and resizing objects.
  27.  
  28. */
  29.  
  30. public class Draw extends WindowCommlet implements DrawObserver {
  31.  
  32.     DrawCanvas draw;    // a draw canvas that knows nothing about networking, but informs <this>
  33.     DrawControls controls;
  34.     // whenever its objects are changed
  35.  
  36.     static final int MSG_DRAW_NEW_OBJECT     = 1001; // arg = new GO
  37.     static final int MSG_DRAW_DEL_OBJECT     = 1002; // arg = key
  38.     static final int MSG_DRAW_CLEAR     = 1003; // arg = key
  39.  
  40.     MenuItem miNew;
  41.     MenuItem miCut;
  42.  
  43.     public String getCommletName() {
  44.         return("Draw");
  45.     }
  46.  
  47.     public String getCommletInfo() {
  48.         return("Draw Commlet, V 1.0, Jan Kautz & Ulrich Gall");
  49.     }
  50.  
  51.     public void init()     {
  52.         super.init();
  53.         draw = new DrawCanvas(this);
  54.         add("Center",draw);
  55.         controls = new DrawControls(draw,this); // needs to tell draw what happens
  56.         add("West",controls);
  57.         draw.setControls(controls);
  58.  
  59.     Menu men= new Menu("File");
  60.     miNew = new MenuItem("New");
  61.     if (com.iAmMaster()) miNew.enable();
  62.         else miNew.disable();
  63.     men.add(miNew);
  64.     MenuItem miOpen = new MenuItem("Open");
  65.     MenuItem miSave = new MenuItem("Save");
  66.     MenuItem miSaveAs = new MenuItem("Save As");
  67.     miOpen.disable();
  68.     men.add(miOpen);
  69.     miSave.disable();
  70.     men.add(miSave);
  71.     miSaveAs.disable();
  72.     men.add(miSaveAs);
  73.     MenuBar mb = new MenuBar();
  74.     mb.add(men);
  75.     Menu menedit = new Menu("Edit");
  76.     miCut = new MenuItem("Delete Last Object");
  77.     miCut.disable();
  78.     menedit.add(miCut);
  79.     mb.add(menedit);
  80.     setMenuBar(mb);
  81.  
  82.         pack();
  83.     }
  84.  
  85.  
  86.     public void createGroupFor(int who) {
  87.         User u = com.getUser(who);
  88.         String name = u.get(u.NAME).toString();
  89.         if (!u.containsKey(u.COLOR))
  90.             u.put(u.COLOR,Color.white);
  91.         Color color  = (Color)u.get(u.COLOR);
  92.         GOGroup grp = new GOGroup(name,color);
  93.         grp.setFilled(true);
  94.         draw.addGroup(new Integer(who),grp);
  95.     }
  96.  
  97.     public void addUser(int who) { 
  98.         createGroupFor(who);
  99.         if (com.getMyID() == who) 
  100.         draw.setCurrentGroupKey( new Integer(com.getMyID()) );
  101.         else {
  102.             // Somebody other than myself joined us, so I will send him the contents of my GOGroup
  103.             Enumeration e = ((GOGroup)draw.getGroup( new Integer(com.getMyID()) ) ).elements();
  104.             while (e.hasMoreElements()) {
  105.                 Msg m = new Msg(MSG_DRAW_NEW_OBJECT,(GraphicsObject)e.nextElement());
  106.                 m.to = who;
  107.                 com.sendTo(m);                
  108.             }
  109.             if (draw.colormode == draw.COLORMODE_OWNER) {
  110.                  controls.updateColormodepanel();
  111.             }
  112.         }
  113.     }
  114.  
  115.     public void userLeft(int who) { 
  116.     // TODO 
  117.     draw.getGroup(new Integer(who)).setFilled(false);
  118.     controls.updateColormodepanel();
  119.     }
  120.     public void newObject(GraphicsObject g) {
  121.         com.sendToOthers(new Msg(MSG_DRAW_NEW_OBJECT,g));
  122.         miCut.enable();
  123.     }
  124.  
  125.     public void delObject(Object key) {
  126.         com.sendToOthers(new Msg(MSG_DRAW_DEL_OBJECT,key));
  127.         if ((new Integer(1)).equals(key)) miCut.disable();
  128.     }
  129.  
  130.     public boolean handleMsg(Msg msg)    {
  131.         if (super.handleMsg(msg)) return true;
  132.         String name = com.getUserName(msg.from);
  133.         if (msg.type == MSG_DRAW_NEW_OBJECT)
  134.         {
  135.             // If this is a GOImage, load it. Not relly pretty, but what else can I do?
  136.             if (msg.arg instanceof GOImage) {
  137.                 ((GOImage)msg.arg).setData(com,draw);
  138.             }
  139.  
  140.             draw.appendToGroup(new Integer(msg.from),(GraphicsObject)msg.arg);
  141.             //            draw.paintObject((GraphicsObject)msg.arg);
  142.             draw.repaint();
  143.             return true;
  144.         }
  145.         else if (msg.type == MSG_DRAW_CLEAR) {
  146.             draw.removeGroups();    
  147.             Enumeration e = com.getUsers().elements();
  148.             while (e.hasMoreElements()) {
  149.                 int id = ((User)e.nextElement()).getID();
  150.                 createGroupFor(id);
  151.             }
  152.             controls.updateColormodepanel();
  153.         }
  154.         else if (msg.type == MSG_DRAW_DEL_OBJECT)
  155.         {
  156.             draw.delFromGroup(new Integer(msg.from),msg.arg); 
  157.             draw.repaint();
  158.             return true;
  159.         }
  160.         else if (msg.type == Msg.NEW_MASTER) {
  161.             miNew.disable();
  162.             if (((Integer)msg.arg).intValue() == com.getMyID())
  163.                 miNew.enable();
  164.         }
  165.         else if (msg.type == Msg.NEW_USER_INFO)
  166.         {
  167.             User u = (User)com.getUser(msg.from);
  168.             draw.getGroup(u.get(u.ID)).name = u.get(u.NAME).toString();
  169.             draw.getGroup(u.get(u.ID)).setColor((Color)u.get(u.COLOR));
  170.             controls.updateColormodepanel();
  171.             draw.repaint();
  172.             return true;
  173.         }
  174.         return false;
  175.     }
  176.     public boolean action(Event evt, Object what) {
  177.         if (evt.target == miNew) {
  178.             com.sendToAll(new Msg(MSG_DRAW_CLEAR,null));
  179.             return true;
  180.         }
  181.         if (evt.target == miCut) {
  182.             draw.doCut();
  183.             return true;
  184.         }
  185.     return false;
  186.     }
  187.     public boolean handleEvent(Event evt) {
  188.     if (evt.id == Event.WINDOW_DESTROY) {
  189.         draw.setCurrentGO(null);
  190.     }
  191.     return super.handleEvent(evt);
  192.     }
  193.     public Image loadImage(String n) {
  194.         return com.loadImage(n);    
  195.     }
  196.     public ComObj getCom() {
  197.         return com;
  198.     }
  199. }
  200.  
  201. /**********************
  202. * DrawCanvas
  203. *
  204. *
  205. * The following methods are called by the Commlet
  206. *
  207. * addGroup
  208. * appendToGroup
  209. * delFromGroup
  210. * getGroup
  211. * setCurrentGroupKey
  212. * setControls
  213. *
  214. * observer is informed about changes in objects. 
  215. * User actions may only alter currentgroup
  216. *
  217. */
  218.  
  219. class DrawCanvas extends Canvas
  220. {
  221.     public static final int EVENT_ACCEPT = 150173;
  222.  
  223.     GOGroup         objects;
  224.     DrawObserver     observer;
  225.     DrawControls     controls;
  226.  
  227.     GraphicsObject currentGO;
  228.     Object             currentGroupKey;
  229.  
  230.     String             colormode;
  231.  
  232.     // Color Modes
  233.     static String COLORMODE_OWNER = "Owner's";
  234.     static String COLORMODE_OBJECT = "Object's";
  235.  
  236.     // keys
  237.     static final int KEY_PASTE         = 112;
  238.     static final int KEY_CUT             = 127;
  239.     static final int KEY_COPY         = 99;
  240.     static final int KEY_DUMP         = 68;
  241.  
  242.     public DrawCanvas(DrawObserver d)
  243.     {
  244.         setBackground(Color.black);
  245.         colormode = COLORMODE_OBJECT;
  246.         observer = d;
  247.         objects = new GOGroup();
  248.         currentGO = null;
  249.         currentGroupKey = null;
  250.     }
  251.  
  252.     public void setControls(DrawControls c) {
  253.         controls = c;
  254.     }
  255.  
  256.     public void setCurrentGroupKey(Object group)
  257.     {
  258.         currentGroupKey = group;
  259.     }
  260.  
  261.     public GraphicsObject getCurrentGroup()
  262.     {
  263.         return (GraphicsObject)objects.get(currentGroupKey);
  264.     }
  265.  
  266.     public void setCurrentGO(GraphicsObject go)
  267.     {
  268.         if (currentGO != null) currentGO.handleEvent(new Event(this,Event.WINDOW_DESTROY,null));
  269.         currentGO = go;
  270.     }
  271.  
  272.     public void setColormode(String m)
  273.     {
  274.         colormode = m;    
  275.         repaint();
  276.     }
  277.     public Dimension preferredSize() {
  278.         return new Dimension(640,480);
  279.     }
  280.     public void paint(Graphics g)
  281.     {
  282.         Enumeration e = objects.keys();
  283.         while (e.hasMoreElements())
  284.         {
  285.             Object o = e.nextElement();
  286.             GraphicsObject go = (GraphicsObject)objects.get(o);
  287.             if (colormode.compareTo(COLORMODE_OBJECT) == 0) go.draw(g); 
  288.             else go.draw(g,go.getColor());
  289.         }
  290.         if (currentGO != null) {
  291.             if (colormode.compareTo(COLORMODE_OBJECT) == 0) currentGO.draw(g); 
  292.             else currentGO.draw(g,getCurrentGroup().getColor());
  293.         }
  294.     }
  295.  
  296.     public void paintObject(GraphicsObject g)
  297.     {
  298.         if (getGraphics() != null) {
  299.             if (g != null) {
  300.                 if (colormode.compareTo(COLORMODE_OBJECT) == 0) currentGO.draw(getGraphics()); 
  301.                 else currentGO.draw(getGraphics(),getCurrentGroup().getColor());
  302.             }
  303.         }
  304.     }
  305.  
  306.     /*************************************************************
  307.     * Adding and removing objects
  308.     */
  309.     public void addGroup(Object key,GraphicsObject g)
  310.     {
  311.         objects.put(key,g);
  312.         paintObject(g);
  313.     }
  314.     public void removeGroups() {
  315.         objects = new GOGroup();
  316.         repaint();
  317.     }
  318.  
  319.     public GraphicsObject getGroup(Object key)
  320.     {
  321.         return (GraphicsObject)objects.get(key);
  322.     }
  323.  
  324.     public void appendToGroup(Object key,GraphicsObject g) 
  325.     {
  326.         GraphicsObject o = objects.get(key);
  327.         if (o instanceof GOGroup) {
  328.             GOGroup group = (GOGroup)o;
  329.             group.put(new Integer(group.size()+1),g);
  330.             paintObject(g);
  331.         }
  332.         else {
  333.             Debug.msg(90,"DrawPanel.appendToGroup: Not a group: "    + o.toString());
  334.         }
  335.     }
  336.     public void delFromGroup(Object gk,Object key)
  337.     {
  338.         GOGroup g = (GOGroup) objects.get(gk);
  339.         g.remove(key);
  340.         repaint();
  341.     }
  342.     public void acceptCurrentGO() {
  343.                         appendToGroup(currentGroupKey    ,currentGO);
  344.                         observer.newObject(currentGO);
  345.                         paintObject(currentGO);
  346.     }
  347.     public void doCut() {
  348.         GOGroup g = ((GOGroup)objects.get(currentGroupKey));
  349.         if (g.size() > 0) {
  350.             observer.delObject(new Integer(g.size()));
  351.             delFromGroup(currentGroupKey, new Integer(g.size()));
  352.         }
  353.     }
  354.     /******************************************************************************************
  355.     * Event handling
  356.     */
  357.     public boolean handleEvent(Event evt) {
  358.         // We want keyboard events if the mouse enters...
  359.         // under some platforms, we need focus for that.
  360.         // But, under W95, requestFocus() also pops the window
  361.         // up, so we don't want to do this under W95
  362.         if ((!System.getProperty("os.name","").startsWith("Windows"))
  363.              && (evt.id == Event.MOUSE_ENTER)) {
  364.             requestFocus();
  365.             return true;
  366.         }
  367.         if ((evt.id == Event.KEY_PRESS) && (evt.key == 127)) {
  368.             doCut();
  369.             return true;
  370.         }
  371.         if (     (currentGO != null) && (
  372.              ((evt.x > 0) && (evt.y > 0)) ||
  373.              (evt.id == Event.KEY_PRESS)    )
  374.            )  {
  375.             {
  376.                 if (currentGO.handleEvent(evt))
  377.                 {
  378.                     if (evt.id == EVENT_ACCEPT)
  379.                     {
  380.                         // This means we should accept the currentGO and start a new one
  381.                         acceptCurrentGO();
  382.                         currentGO = currentGO.getNew();
  383.                         currentGO.color = controls.currentcolor;
  384.                         currentGO.filled = controls.filled;
  385.                         //currentGO.moveTo(evt.x,evt.y);
  386.                     }
  387.                     paintObject(currentGO);
  388.                     return true;
  389.                 }
  390.             }
  391.         }
  392.         return false;                
  393.     }
  394. }
  395.  
  396. /*******************************************************************************************
  397. * DrawControls
  398. */
  399.  
  400. class DrawControls extends Panel {
  401.  
  402.     // modes
  403.     static int MODE_POLYGON     = 0;
  404.     static int MODE_TEXT        = 1;
  405.     static int MODE_LINE        = 2;
  406.     static int MODE_RECT        = 3;
  407.     static int MODE_OVAL        = 4;
  408.     static int MODE_IMAGE        = 5;
  409.  
  410.     static int DRAWMODESIZE = 64;
  411.  
  412.     DrawCanvas drawcanvas;
  413.     DrawObserver draw;
  414.  
  415.     RadioImageButton drawmodesel;
  416.     Choice    colormodeChoice;
  417.  
  418.     Panel colormodepanel;
  419.     Panel drawmodepanel;
  420.         
  421.     Checkbox filledCB;
  422.     ColorSelector colorsel;
  423.         
  424.     boolean filled;
  425.     Color currentcolor;
  426.     Color fillColor;
  427.  
  428.     public DrawControls(DrawCanvas dc,DrawObserver dob) {
  429.         drawcanvas = dc;
  430.         draw = dob;
  431.             
  432.         setLayout(new VertLayout(VertLayout.STRETCH));
  433.  
  434.         drawmodesel = new RadioImageButton();
  435.         drawmodesel.setLayout(new GridLayout(3,2));
  436.         drawmodesel.add(draw.loadImage("imgPOLYGON"),draw.loadImage("imgPOLYGONP"),DRAWMODESIZE,DRAWMODESIZE);
  437.         drawmodesel.add(draw.loadImage("imgTEXT"),draw.loadImage("imgTEXTP"),DRAWMODESIZE,DRAWMODESIZE);
  438.         drawmodesel.add(draw.loadImage("imgLINE"),draw.loadImage("imgLINEP"),DRAWMODESIZE,DRAWMODESIZE);
  439.         drawmodesel.add(draw.loadImage("imgRECT"),draw.loadImage("imgRECTP"),DRAWMODESIZE,DRAWMODESIZE);
  440.         drawmodesel.add(draw.loadImage("imgOVAL"),draw.loadImage("imgOVALP"),DRAWMODESIZE,DRAWMODESIZE);
  441.         drawmodesel.add(draw.loadImage("imgIMAGE"),draw.loadImage("imgIMAGEP"),DRAWMODESIZE,DRAWMODESIZE);
  442.         drawmodesel.switchButtonOn(MODE_POLYGON);
  443.         Panel p = new Panel();
  444.         p.setLayout(new BorderLayout());
  445.         p.add("West",drawmodesel);
  446.         add(p);
  447.  
  448.         drawmodepanel = new Panel();
  449.         add(drawmodepanel);
  450.  
  451.         currentcolor = Color.white;
  452.         add(new Label("Current Color"));
  453.         colorsel = new ColorSelector(currentcolor);
  454.         add(colorsel);
  455.             
  456.         filled =    false;
  457.         filledCB = new Checkbox("Filled");
  458.         filledCB.setState(filled);
  459.         add(filledCB);
  460.  
  461.         add(new Label("Color Mode"));
  462.         colormodeChoice = new Choice();
  463.         colormodeChoice.addItem(dc.COLORMODE_OBJECT);
  464.         colormodeChoice.addItem(dc.COLORMODE_OWNER);
  465.         add(colormodeChoice);
  466.         colormodepanel = new Panel();
  467.         updateColormodepanel();
  468.         add(colormodepanel);
  469.          
  470.         GraphicsObject cur = new GOPolygon();
  471.         cur.setColor(currentcolor);
  472.         cur.setFilled(filled);
  473.         setCurrentGO(cur);
  474.  
  475.     }
  476.  
  477.     public void setCurrentGO(GraphicsObject cur)
  478.     {
  479.         cur.layoutPropPanel(drawmodepanel);            
  480.         layout();
  481.         paintAll(getGraphics());
  482.         drawcanvas.setCurrentGO(cur);
  483.     }
  484.  
  485.     public void setCurrentColor(Color c) {
  486.         currentcolor = c;
  487.         if (drawcanvas.currentGO != null) drawcanvas.currentGO.setColor(c);
  488.     }
  489.  
  490.     public void updateColormodepanel() {
  491.         colormodepanel.removeAll();
  492.         if (drawcanvas.colormode.compareTo(DrawCanvas.COLORMODE_OWNER) == 0)
  493.         {
  494.             colormodepanel.setLayout(new VertLayout(VertLayout.STRETCH));
  495.             Enumeration e = drawcanvas.objects.elements();
  496.             while (e.hasMoreElements()) {
  497.                 GraphicsObject g  = (GraphicsObject)e.nextElement();
  498.                 ColorView c = new ColorView(g.getColor(),g.name);
  499.                 if (g.filled) c.enable(); else c.disable();
  500.                 colormodepanel.add(c);
  501.             }
  502.         }
  503.         layout();
  504.         colormodepanel.paintAll(colormodepanel.getGraphics());
  505.     }
  506.  
  507.     public boolean action(Event evt,Object arg) {
  508.         
  509.         if (evt.target == drawmodesel) {
  510.             int md = ((Integer)evt.arg).intValue();
  511.             GraphicsObject cur = null;
  512.             if (drawcanvas.currentGO instanceof GOText) drawcanvas.acceptCurrentGO();
  513.             if (md == MODE_POLYGON) cur = new GOPolygon();
  514.             if (md == MODE_RECT) cur = new GORect();
  515.             if (md == MODE_LINE) cur = new GOLine();
  516.             if (md == MODE_TEXT) cur = new GOText();
  517.             if (md == MODE_OVAL) cur = new GOOval();
  518.             if (md == MODE_IMAGE) {
  519.                 GOImage img = new GOImage();
  520.                 // set name and load image
  521.                 ComObj c = draw.getCom();
  522.                 String n = "default";
  523.                 img.setData(c,drawcanvas);
  524.                 cur = img;
  525.             }
  526.  
  527.             cur.setColor(currentcolor);
  528.             cur.setFilled(filled);
  529.             setCurrentGO(cur);
  530.             return true;
  531.         }
  532.         if (evt.target == colormodeChoice)  {
  533.             drawcanvas.setColormode(colormodeChoice.getSelectedItem());
  534.             if (colormodeChoice.getSelectedItem().compareTo(DrawCanvas.COLORMODE_OWNER) == 0)
  535.                 currentcolor = drawcanvas.getCurrentGroup().getColor();
  536.             else
  537.                 currentcolor = colorsel.getColor();
  538.             updateColormodepanel();
  539.             return true;
  540.         }
  541.         if (evt.target == filledCB) {
  542.             filled = filledCB.getState();
  543.             if (drawcanvas.currentGO != null) {
  544.                 drawcanvas.currentGO.setFilled(filled);
  545.                 drawcanvas.paintObject(drawcanvas.currentGO);
  546.             }
  547.         }
  548.         if (evt.target == colorsel) {
  549.             setCurrentColor(colorsel.getColor());
  550.         }
  551.         return false;
  552.     }
  553.  
  554.     public boolean handleEvent(Event evt) {
  555.         boolean sup =  super.handleEvent(evt);
  556.         // TODO: This is not necessarily for currentGO
  557.         GraphicsObject cur = drawcanvas.currentGO;
  558.         boolean b = false;
  559.         if (cur != null) {
  560.             b = cur.handlePropPanelEvent(evt,drawcanvas);
  561.         }
  562.         return (sup || b);
  563.     }
  564. }
  565.  
  566. class ColorView extends Canvas {
  567.     String name;
  568.     static final int SPACE_BOTTOM = 6;
  569.     static final int SPACE_LEFT = 10;
  570.     boolean enabled = true;
  571.  
  572.     public ColorView(Color c, String n) {
  573.         name = n;
  574.         setBackground(c);
  575.         if ((c.getRed()+c.getGreen()+c.getBlue()) < 384) setForeground(Color.white);
  576.             else setForeground(Color.black);
  577.     }
  578.  
  579.     public void paint(Graphics g) {
  580.         Font f = getFont();
  581.         if (enabled) {
  582.         g.setFont(new Font(f.getName(),f.BOLD,f.getSize()));
  583.         }
  584.         else {
  585.         g.setFont(new Font(f.getName(),f.ITALIC,f.getSize()));
  586.         }
  587.         g.drawString(name,SPACE_LEFT,size().height-SPACE_BOTTOM);
  588.     }
  589.  
  590.     public Dimension preferredSize() {
  591.         FontMetrics fm = getFontMetrics(getFont());    
  592.         return new Dimension(2*SPACE_LEFT+fm.stringWidth(name),
  593.                 fm.getHeight()+2*SPACE_BOTTOM);
  594.     }
  595.     public void enable() {
  596.     super.enable();
  597.     enabled = true;
  598.     }
  599.     public void disable() {
  600.     super.disable();
  601.     enabled = false;
  602.     }
  603.  
  604.     public Dimension minimumSize() {
  605.         return preferredSize();
  606.     }
  607. }
  608.  
  609. /******************************************************************************************/
  610. interface DrawObserver {
  611.  
  612.     void newObject(GraphicsObject g);
  613.     void delObject(Object key);
  614.     Image loadImage(String name);
  615.     ComObj getCom();
  616. }
  617.