KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > utobcast > draw > DrawImpl


1 /**
2  * Dream
3  * Copyright (C) 2003-2004 INRIA Rhone-Alpes
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Contact: dream@objectweb.org
20  *
21  * Initial developer(s): Vivien Quema
22  * Contributor(s):
23  */

24
25 package utobcast.draw;
26
27 import java.awt.Color JavaDoc;
28 import java.awt.Dimension JavaDoc;
29 import java.awt.Font JavaDoc;
30 import java.awt.Graphics JavaDoc;
31 import java.awt.Image JavaDoc;
32 import java.awt.event.ActionEvent JavaDoc;
33 import java.awt.event.ActionListener JavaDoc;
34 import java.awt.event.ComponentAdapter JavaDoc;
35 import java.awt.event.ComponentEvent JavaDoc;
36 import java.awt.event.MouseEvent JavaDoc;
37 import java.awt.event.MouseMotionListener JavaDoc;
38 import java.io.ByteArrayOutputStream JavaDoc;
39 import java.io.ObjectOutputStream JavaDoc;
40 import java.util.Map JavaDoc;
41 import java.util.Random JavaDoc;
42
43 import javax.swing.JButton JavaDoc;
44 import javax.swing.JFrame JavaDoc;
45 import javax.swing.JPanel JavaDoc;
46
47 import org.objectweb.dream.AbstractComponent;
48 import org.objectweb.dream.Push;
49 import org.objectweb.dream.PushException;
50 import org.objectweb.dream.message.MessageTypeImpl;
51 import org.objectweb.dream.message.Message;
52 import org.objectweb.dream.message.MessageType;
53 import org.objectweb.dream.message.manager.MessageManager;
54 import org.objectweb.dream.util.Error;
55 import org.objectweb.fractal.api.Component;
56 import org.objectweb.fractal.api.NoSuchInterfaceException;
57 import org.objectweb.fractal.api.control.IllegalBindingException;
58 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
59 import org.objectweb.fractal.util.Fractal;
60
61 /**
62  * Shared whiteboard, each new instance joins the same group. Each instance
63  * chooses a random color, mouse moves are broadcast to all group members, which
64  * then apply them to their canvas
65  */

66 public class DrawImpl extends AbstractComponent implements ActionListener JavaDoc, Push
67 {
68   private ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
69   private String JavaDoc groupname = "DrawGroupDemo";
70   private int memberSize = 1;
71   boolean first = true, cummulative = true;
72   private JFrame JavaDoc mainFrame = null;
73   private JPanel JavaDoc subPanel = null;
74   private DrawPanel panel = null;
75   private JButton JavaDoc clearButton, leaveButton;
76   private Random JavaDoc random = new Random JavaDoc(System
77                                                 .currentTimeMillis());
78   private final Font JavaDoc defaultFont = new Font JavaDoc("Helvetica", Font.PLAIN,
79                                                 12);
80   private Color JavaDoc drawColor = selectColor(),
81       backgroundColor = Color.white;
82   boolean noChannel = false;
83
84   Push outPushItf;
85   MessageManager messageManagerItf;
86
87   Component nodeComponentItf;
88   MessageType msgType = new MessageTypeImpl(
89                                                 DrawCommandChunk.DEFAULT_NAME,
90                                                 DrawCommandChunk.TYPE);
91
92   // ---------------------------------------------------------------------------
93
// Implementation of the LifeCycleController interface
94
// ---------------------------------------------------------------------------
95

96   /**
97    * @see org.objectweb.fractal.api.control.LifeCycleController#startFc()
98    */

99   public void startFc() throws IllegalLifeCycleException
100   {
101     super.startFc();
102
103     mainFrame = new JFrame JavaDoc();
104     mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
105     panel = new DrawPanel();
106     panel.setBackground(backgroundColor);
107     subPanel = new JPanel JavaDoc();
108     mainFrame.getContentPane().add("Center", panel);
109     clearButton = new JButton JavaDoc("Clear");
110     clearButton.setFont(defaultFont);
111     clearButton.addActionListener(this);
112     leaveButton = new JButton JavaDoc("Leave & Exit");
113     leaveButton.setFont(defaultFont);
114     leaveButton.addActionListener(this);
115     subPanel.add("South", clearButton);
116     subPanel.add("South", leaveButton);
117     mainFrame.getContentPane().add("South", subPanel);
118     mainFrame.setBackground(backgroundColor);
119     clearButton.setForeground(Color.blue);
120     leaveButton.setForeground(Color.blue);
121     mainFrame.setTitle("Draw example");
122     mainFrame.pack();
123     mainFrame.setLocation(15, 25);
124     mainFrame.setVisible(true);
125   }
126
127   // ---------------------------------------------------------------------------
128
// Implementation of the Push interface
129
// ---------------------------------------------------------------------------
130

131   /**
132    * @see org.objectweb.dream.Push#push(org.objectweb.dream.message.Message,
133    * java.util.Map)
134    */

135   public void push(Message message, Map JavaDoc context) throws PushException
136   {
137
138     DrawCommand comm = ((DrawCommandChunk) message
139         .getChunk(DrawCommandChunk.DEFAULT_NAME)).getDrawCommand();
140
141     switch (comm.mode)
142     {
143       case DrawCommand.DRAW :
144         if (panel != null)
145           panel.drawPoint(comm);
146         break;
147       case DrawCommand.CLEAR :
148         clearPanel();
149         break;
150       default :
151         System.err
152             .println("***** DrawImpl.run(): received invalid draw command "
153                 + comm.mode);
154         break;
155     }
156     messageManagerItf.deleteMessage(message);
157   }
158
159   // ---------------------------------------------------------------------------
160
// Utility methods
161
// ---------------------------------------------------------------------------
162

163   private Color JavaDoc selectColor()
164   {
165     int red = (Math.abs(random.nextInt()) % 255);
166     int green = (Math.abs(random.nextInt()) % 255);
167     int blue = (Math.abs(random.nextInt()) % 255);
168     return new Color JavaDoc(red, green, blue);
169   }
170
171   void clearPanel()
172   {
173     if (panel != null)
174       panel.clear();
175   }
176
177   void sendClearPanelMsg()
178   {
179     int tmp[] = new int[1];
180     tmp[0] = 0;
181     DrawCommand comm = new DrawCommand(DrawCommand.CLEAR);
182     ObjectOutputStream JavaDoc os;
183
184     Message msg = messageManagerItf.createMessage(msgType);
185     DrawCommandChunk chunk = (DrawCommandChunk) msg
186         .getChunk(DrawCommandChunk.DEFAULT_NAME);
187     chunk.setDrawCommand(comm);
188     try
189     {
190       outPushItf.push(msg, null);
191     }
192     catch (PushException e)
193     {
194       Error.error("Unable to send clear panel message ", logger, e);
195     }
196   }
197
198   /**
199    * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
200    */

201   public void actionPerformed(ActionEvent JavaDoc e)
202   {
203     String JavaDoc command = e.getActionCommand();
204     if (command.equals("Clear"))
205     {
206       if (noChannel)
207       {
208         clearPanel();
209         return;
210       }
211
212       sendClearPanelMsg();
213
214     }
215     else if (command.equals("Leave & Exit"))
216     {
217       if (!noChannel)
218       {
219         try
220         {
221           Runnable JavaDoc stopNode = new StopNode();
222           new Thread JavaDoc(stopNode).start();
223         }
224         catch (Exception JavaDoc ex)
225         {
226           System.err.println(ex);
227         }
228       }
229       mainFrame.setVisible(false);
230       mainFrame.dispose();
231       //System.exit(0);
232
}
233     else
234       System.out.println("Unknown action");
235   }
236
237   // ---------------------------------------------------------------------------
238
// Inner class.
239
// ---------------------------------------------------------------------------
240

241   private class DrawPanel extends JPanel JavaDoc implements MouseMotionListener JavaDoc
242   {
243     Dimension JavaDoc preferredSize = new Dimension JavaDoc(235, 170);
244     Image JavaDoc img = null; // for drawing pixels
245
Dimension JavaDoc d, imgsize;
246     Graphics JavaDoc gr = null;
247
248     public DrawPanel()
249     {
250       createOffscreenImage();
251       addMouseMotionListener(this);
252       addComponentListener(new ComponentAdapter JavaDoc()
253       {
254         public void componentResized(ComponentEvent JavaDoc e)
255         {
256           if (getWidth() <= 0 || getHeight() <= 0)
257             return;
258           createOffscreenImage();
259         }
260       });
261     }
262
263     void createOffscreenImage()
264     {
265       d = getSize();
266       if (img == null || imgsize == null || imgsize.width != d.width
267           || imgsize.height != d.height)
268       {
269         img = createImage(d.width, d.height);
270         if (img != null)
271           gr = img.getGraphics();
272         imgsize = d;
273       }
274     }
275
276     /**
277      * Adds pixel to queue and calls repaint() whenever we have MAX_ITEMS pixels
278      * in the queue or when MAX_TIME msecs have elapsed (whichever comes first).
279      * The advantage compared to just calling repaint() after adding a pixel to
280      * the queue is that repaint() can most often draw multiple points at the
281      * same time.
282      */

283     public void drawPoint(DrawCommand c)
284     {
285       if (c == null || gr == null)
286         return;
287       gr.setColor(new Color JavaDoc(c.r, c.g, c.b));
288       gr.fillOval(c.x, c.y, 10, 10);
289       repaint();
290     }
291
292     public void clear()
293     {
294       if (gr == null)
295         return;
296       gr.clearRect(0, 0, getSize().width, getSize().height);
297       repaint();
298     }
299
300     public Dimension JavaDoc getPreferredSize()
301     {
302       return preferredSize;
303     }
304
305     public void paintComponent(Graphics JavaDoc g)
306     {
307       super.paintComponent(g);
308       if (img != null)
309       {
310         g.drawImage(img, 0, 0, null);
311       }
312     }
313
314     // ---------------------------------------------------------------------------
315
// Implementation of the MouseMotionListener interface
316
// ---------------------------------------------------------------------------
317

318     public void mouseMoved(MouseEvent JavaDoc e)
319     {
320     }
321
322     public void mouseDragged(MouseEvent JavaDoc e)
323     {
324       ObjectOutputStream JavaDoc os;
325       int x = e.getX(), y = e.getY();
326       DrawCommand comm = new DrawCommand(DrawCommand.DRAW, x, y, drawColor
327           .getRed(), drawColor.getGreen(), drawColor.getBlue());
328
329       if (noChannel)
330       {
331         drawPoint(comm);
332         return;
333       }
334
335       Message msg = messageManagerItf.createMessage(msgType);
336       DrawCommandChunk chunk = (DrawCommandChunk) msg
337           .getChunk(DrawCommandChunk.DEFAULT_NAME);
338       chunk.setDrawCommand(comm);
339       try
340       {
341         outPushItf.push(msg, null);
342       }
343       catch (PushException e1)
344       {
345
346       }
347     }
348
349   }
350
351   // ---------------------------------------------------------------------------
352
// Inner class.
353
// ---------------------------------------------------------------------------
354

355   private class StopNode implements Runnable JavaDoc
356   {
357
358     /**
359      * @see java.lang.Runnable#run()
360      */

361     public void run()
362     {
363       try
364       {
365         Fractal.getLifeCycleController(nodeComponentItf).stopFc();
366       }
367       catch (Exception JavaDoc e)
368       {
369         e.printStackTrace();
370       }
371     }
372
373   }
374
375   // ---------------------------------------------------------------------------
376
// Implementation of the LifeCycleController interface
377
// ---------------------------------------------------------------------------
378

379   /**
380    * @see org.objectweb.fractal.api.control.BindingController#listFc()
381    */

382   public String JavaDoc[] listFc()
383   {
384     return new String JavaDoc[]{Push.OUT_PUSH_ITF_NAME, MessageManager.ITF_NAME,
385         "node-c"};
386   }
387
388   /**
389    * @see org.objectweb.fractal.api.control.BindingController#bindFc(java.lang.String,
390    * java.lang.Object)
391    */

392   public void bindFc(String JavaDoc clientItfName, Object JavaDoc serverItf)
393       throws NoSuchInterfaceException, IllegalBindingException,
394       IllegalLifeCycleException
395   {
396     super.bindFc(clientItfName, serverItf);
397     if (clientItfName.equals(Push.OUT_PUSH_ITF_NAME))
398     {
399       outPushItf = (Push) serverItf;
400     }
401     else if (clientItfName.equals(MessageManager.ITF_NAME))
402     {
403       messageManagerItf = (MessageManager) serverItf;
404     }
405     else if (clientItfName.equals("node-c"))
406     {
407       nodeComponentItf = (Component) serverItf;
408     }
409   }
410
411 }
412
413
Popular Tags