Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/relayirc/swingutil/MDIPanel.java


1   /* 
2    * FILE: MDIPanel.java 
3    * 
4    * The contents of this file are subject to the Mozilla Public License
5    * Version 1.0 (the "License"); you may not use this file except in
6    * compliance with the License. You may obtain a copy of the License at
7    * http://www.mozilla.org/MPL/
8    * 
9    * Software distributed under the License is distributed on an "AS IS"
10   * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
11   * License for the specific language governing rights and limitations
12   * under the License.
13   * 
14   * The Original Code is Relay IRC chat client.
15   * 
16   * The Initial Developer of the Original Code is David M. Johnson.
17   * Portions created by David M. Johnson are Copyright (C) 1998. 
18   * All Rights Reserved.
19   *
20   * Contributor(s): No contributors to this file.
21   */
22  
23  package org.relayirc.swingutil;
24  import org.relayirc.util.*;
25  
26  import java.beans.PropertyVetoException;
27  
28  import java.util.Vector;
29  import java.util.Hashtable;
30  import java.util.Enumeration;
31  import java.awt.*;
32  import java.awt.event.*;
33  import javax.swing.*;
34  import javax.swing.event.*;
35  import javax.swing.border.*;
36  
37  ///////////////////////////////////////////////////////////////////////
38  
39  /** 
40   * Multi-Document Interface (MDI) panel that supports dockable frames.
41   * Panels may be docked in the top, bottom, left or right of the panel.
42   * Each panel must implement MDIClientPanel and have a frame that 
43   * implements MDIClientFrame.
44   * @see org.relayirc.swingutil.MDIClientPanel
45   * @see org.relayirc.swingutil.MDIClientFrame
46   */
47  public class MDIPanel extends JPanel {
48  
49     public static final String DOCK_NONE   = "DOCK_NONE";
50     public static final String DOCK_TOP    = "DOCK_TOP";
51     public static final String DOCK_BOTTOM = "DOCK_BOTTOM";
52     public static final String DOCK_LEFT   = "DOCK_LEFT";
53     public static final String DOCK_RIGHT  = "DOCK_RIGHT";
54  
55     private JDesktopPane _desktop = new JDesktopPane();
56    private Vector       _clientFrames = new Vector();
57    private Vector       _clientPanels = new Vector();
58     private Hashtable    _dockedFrames = new Hashtable();
59     private Hashtable    _framesByPanel = new Hashtable();
60     private int          _lastX = 0;
61     private int          _lastY = 0;
62  
63     //-----------------------------------------------------------------
64     public MDIPanel() {
65        setLayout(new MDILayout());
66        _desktop.setDesktopManager(new MDIDesktopManager());
67        add(_desktop,"desktop");
68        _desktop.addMouseMotionListener(new MouseMotionListener() {
69           public void mouseMoved(MouseEvent event) {
70              setCursor(Cursor.getDefaultCursor());
71           }
72           public void mouseDragged(MouseEvent event) {
73           }
74        });
75     }
76     //------------------------------------------------------------------
77     private void addInternalFrame(JInternalFrame frame) {
78        int w = (int)(_desktop.getSize().width*0.6);
79        int h = (int)(0.6*w);
80        
81        int newX = _lastX + 20;
82        int newY = _lastY + 20;
83        if (newX + frame.getSize().width > _desktop.getSize().width 
84         || newY + frame.getSize().height > _desktop.getSize().height) {
85           newX = 0;
86           newY = 0;      
87        }
88        _lastX = newX;
89        _lastY = newY;
90  
91        _desktop.add(frame);       
92        frame.setSize(new Dimension(w,h));
93        frame.setLocation(newX,newY);
94        frame.show();
95  
96        RCTest.println("MDIPanel adding frame "+frame.getSize());
97     }
98     //-----------------------------------------------------------------
99     /** If frame is not docked, then bring it to the front */
100    public void activateFrame(MDIClientFrame frame) {
101       // If frame is not docked then bring it to the front
102       if (frame.getClientPanel().getDockState().equals(DOCK_NONE)) {
103          _desktop.getDesktopManager().activateFrame(frame.getFrame());
104       }
105    }
106    //-----------------------------------------------------------------
107    /** Submit frame for management by this MDI panel. */ 
108    public void addClientFrame(MDIClientFrame frame) {
109 
110       // Only add frame if it is not already present
111       if (!_clientFrames.contains(frame)) {
112          _clientFrames.addElement(frame);
113          _clientPanels.addElement(frame.getClientPanel());
114          _framesByPanel.put(frame.getClientPanel(),frame);
115 
116          // New frames should not be maximized, closed or iconified
117          try {
118             frame.getFrame().setMaximum(false);
119             frame.getFrame().setClosed(false);
120             frame.getFrame().setIcon(false);
121          }
122          catch (PropertyVetoException pve) {
123             // Ignore vetos
124          }
125 
126          registerDockState(frame.getClientPanel());
127       }
128    }
129    //-----------------------------------------------------------------
130    /** Remove panel from management by this MDI panel. */
131    public void removeClientFrame(MDIClientFrame frame) {
132 
133       _clientFrames.removeElement(frame);
134       _clientPanels.removeElement(frame.getClientPanel());
135       _framesByPanel.remove(frame.getClientPanel());
136       _dockedFrames.remove(frame.getClientPanel().getDockState());
137 
138       if (frame.getClientPanel().getDockState().equals(DOCK_NONE)) {
139          RCTest.println("Removing undocked frame");
140          
141          // Delete does not work if frame is iconified
142          try {
143             frame.getFrame().setIcon(false);
144          }
145          catch (PropertyVetoException pve) {
146             // Ignore vetos
147          }
148          
149          _desktop.remove(frame.getFrame());
150          _desktop.repaint(0);
151       }
152       else {
153          RCTest.println("Removing docked panel");
154          remove(frame.getClientPanel().getPanel());
155          doLayout();
156       }
157    }
158    //-----------------------------------------------------------------
159    /**
160     * A panel whose frame has been added to the MDIPanel using the 
161     * addClientFrame() function should call this function after 
162     * changing its dock state. 
163     */
164    public void registerDockState(MDIClientPanel panel) {
165 
166       // If docking
167       if (!panel.getDockState().equals(DOCK_NONE)) {
168 
169          // Hide panel's current frame
170          MDIClientFrame frame = (MDIClientFrame)_framesByPanel.get(panel);
171          _desktop.remove(frame.getFrame());
172          frame.getFrame().setVisible(false);
173          frame.getFrame().getContentPane().remove(panel.getPanel());
174 
175          // Add panel's frame into its requested dock site
176          _dockedFrames.put(panel.getDockState(),frame);
177          add(panel.getPanel(),panel.getDockState());
178       }
179 
180       // Else if not docking
181       else {
182          // Remove panel from layout
183          remove(panel.getPanel());
184 
185          // Remove panel's frame from docked frames map
186          MDIClientFrame frame = (MDIClientFrame)_framesByPanel.get(panel);
187          _dockedFrames.remove(frame);
188 
189          // Add panel's frame to desktop
190          frame.getFrame().getContentPane().add(panel.getPanel(),BorderLayout.CENTER);
191          frame.getFrame().getContentPane().doLayout();
192 
193          //System.out.println("layout="+frame.getFrame().getContentPane().getLayout());
194          //System.out.println("count="+frame.getFrame().getContentPane().getComponentCount());
195 
196          addInternalFrame(frame.getFrame());
197       }
198       doLayout();
199    }
200    //------------------------------------------------------------------
201    /** Tile four client panels in a grid. */
202    public void tileFour() {
203       int winwidth = (int)(_desktop.getSize().width/2.0);
204       // The -30 leaves some space at the bottom for icons
205       int winheight = (int)((_desktop.getSize().height-30)/2.0);
206       int count = 0;
207       for (int j=0; j<_desktop.getAllFrames().length; j++) {
208          JInternalFrame cwin = _desktop.getAllFrames()[j];
209          if (!cwin.isIcon()) {
210             cwin.setSize(new Dimension(winwidth,winheight));
211             switch (count) {
212                case 0:
213                   cwin.setLocation(0,0);
214                   break;
215                case 1:
216                   cwin.setLocation(winwidth,0);
217                   break;
218                case 2:
219                   cwin.setLocation(0,winheight);
220                   break;
221                case 3:
222                   cwin.setLocation(winwidth,winheight);
223                   break;
224                default:
225                   break;
226             }
227             count++;
228          }
229       }
230    }
231    //------------------------------------------------------------------
232    /** Tile client frames in a cascade pattern. */
233    public void cascade() {
234       // Count the not iconified internal frames
235       int wincount = 0;
236       for (int i=0; i<_desktop.getAllFrames().length; i++) {
237          JInternalFrame cwin = _desktop.getAllFrames()[i];
238          if (!cwin.isIcon()) wincount++;
239       }
240       if (wincount > 0) {
241 
242          int w = (int)(_desktop.getSize().width*0.6);
243          int h = (int)(0.6*w);
244       
245          int xpos = 0;
246          int ypos = 0;
247          for (int j=0; j<_desktop.getAllFrames().length; j++) {
248             JInternalFrame cwin = _desktop.getAllFrames()[j];
249             if (!cwin.isIcon()) {
250                if (xpos + cwin.getSize().width > _desktop.getSize().width 
251                 || ypos + cwin.getSize().height > _desktop.getSize().height) {
252                   ypos = 0;  
253                   xpos = 0;
254                } else {
255                   ypos += 20;  
256                   xpos += 20;
257                }  
258                cwin.setSize(new Dimension(w,h));
259                cwin.setLocation(xpos,ypos);
260             }
261          }
262       }
263    }
264    //------------------------------------------------------------------
265    /** Tile client frames horizontally. */
266    public void tileHorizontal() {
267 
268       // Count the not iconified internal frames
269       int wincount = 0;
270       for (int i=0; i<_desktop.getAllFrames().length; i++) {
271          JInternalFrame cwin = _desktop.getAllFrames()[i];
272          if (!cwin.isIcon()) wincount++;
273       }
274       // Tile those frames
275       if (wincount==4) 
276          tileFour();
277       else if (wincount > 0) {
278          int winwidth = _desktop.getSize().width;
279          // The -30 leaves some space at the bottom for icons
280          int winheight = (_desktop.getSize().height-30)/wincount;
281          int ypos = 0;
282          for (int j=0; j<_desktop.getAllFrames().length; j++) {
283             JInternalFrame cwin = _desktop.getAllFrames()[j];
284             if (!cwin.isIcon()) {
285                cwin.setSize(new Dimension(winwidth,winheight));
286                cwin.setLocation(0,ypos);
287                ypos += winheight;  
288             }
289          }
290       }
291    }
292    //------------------------------------------------------------------
293    /** Tile client frames vertically. */
294    public void tileVertical() {
295 
296       // Count the currently active internal frames
297       int wincount = 0;
298       for (int i=0; i<_desktop.getAllFrames().length; i++) {
299          JInternalFrame cwin = _desktop.getAllFrames()[i];
300          if (!cwin.isIcon()) wincount++;
301       }
302 
303       // If there are any active internal frames then tile them
304        if (wincount==4) 
305          tileFour();
306       else if (wincount > 0) {
307          int winwidth = _desktop.getSize().width/wincount;
308          // The -30 leaves some space at the bottom for icons
309          int winheight = _desktop.getSize().height-30;
310          int xpos = 0;
311          for (int j=0; j<_desktop.getAllFrames().length; j++) {
312             JInternalFrame cwin = _desktop.getAllFrames()[j];
313             if (!cwin.isIcon()) {
314                cwin.setSize(new Dimension(winwidth,winheight));
315                cwin.setLocation(xpos,0);
316                xpos += winwidth;  
317             }
318          }
319       }
320    }
321    //-----------------------------------------------------------------
322    /** For testing/debugging. */
323    public static void main(String args[]) {
324       
325       MDIPanel mdi;
326 
327       JFrame frame = new JFrame();
328       frame.getContentPane().setLayout(new BorderLayout());
329       frame.getContentPane().add(mdi = new MDIPanel(),BorderLayout.CENTER);
330       frame.setLocation(200,200);
331       frame.setSize(500,400);
332       frame.setVisible(true);
333 
334       ClientPanel panel1 = new ClientPanel(mdi, MDIPanel.DOCK_TOP,    MDIPanel.DOCK_TOP);
335       ClientPanel panel2 = new ClientPanel(mdi, MDIPanel.DOCK_BOTTOM, MDIPanel.DOCK_BOTTOM);
336       ClientPanel panel3 = new ClientPanel(mdi, MDIPanel.DOCK_RIGHT,  MDIPanel.DOCK_RIGHT);
337       ClientPanel panel4 = new ClientPanel(mdi, MDIPanel.DOCK_LEFT,   MDIPanel.DOCK_LEFT);
338 
339       ClientFrame frame1 = new ClientFrame();
340       frame1.setClientPanel(panel1);
341 
342       ClientFrame frame2 = new ClientFrame();
343       frame2.setClientPanel(panel2);
344 
345       ClientFrame frame3 = new ClientFrame();
346       frame3.setClientPanel(panel3);
347 
348       ClientFrame frame4 = new ClientFrame();
349       frame4.setClientPanel(panel4);
350 
351       mdi.addClientFrame(frame1);
352       mdi.addClientFrame(frame2);
353       mdi.addClientFrame(frame3);
354       mdi.addClientFrame(frame4);
355 
356       frame.doLayout();
357    }
358 }
359 
360 
361 ///////////////////////////////////////////////////////////////////////
362 
363 class MDILayout implements LayoutManager {
364 
365    private Component _desktop = null;
366    private Component _top     = null;
367    private Component _bottom  = null;
368    private Component _left    = null;
369    private Component _right   = null;
370 
371    private MDISplitter _vSplitterTop    = null;
372    private MDISplitter _vSplitterBottom = null;
373    private MDISplitter _hSplitterLeft   = null;
374    private MDISplitter _hSplitterRight  = null;
375 
376    //-----------------------------------------------------------------
377    public void addLayoutComponent(String name, Component comp) {
378       if      (name.equals("desktop"))            _desktop = comp;
379       else if (name.equals(MDIPanel.DOCK_TOP))    _top     = comp;
380       else if (name.equals(MDIPanel.DOCK_BOTTOM)) _bottom  = comp;
381       else if (name.equals(MDIPanel.DOCK_LEFT))   _left    = comp;
382       else if (name.equals(MDIPanel.DOCK_RIGHT))  _right   = comp;
383    }
384    //-----------------------------------------------------------------
385    public void removeLayoutComponent(Component comp) {
386       if      (comp == _desktop) _desktop = null;
387       else if (comp == _top)     _top = null;
388       else if (comp == _bottom)  _bottom = null;
389       else if (comp == _left)    _left = null;
390       else if (comp == _right)   _right = null;
391    }
392    //-----------------------------------------------------------------
393    public Dimension preferredLayoutSize(Container parent) {
394       return new Dimension(100,100);
395    }
396    //-----------------------------------------------------------------
397    public Dimension minimumLayoutSize(Container parent) {
398       return new Dimension(100,100);
399    }
400    //-----------------------------------------------------------------
401    public void layoutContainer(Container parent) {
402       if (_desktop != null) {
403 
404          int height = parent.getSize().height;
405          int width = parent.getSize().width;
406          if (height==0 || width==0) {
407             return;
408          }
409 
410          // Bounds of desktop pane
411          int minX = 0;
412          int minY = 0;
413          int maxX = width;
414          int maxY = height;
415 
416          // Splitter positions
417          float tpos = 0.0f;
418          float bpos = 0.0f;
419          float lpos = 0.0f;
420          float rpos = 0.0f;
421 
422          // Remove splitters
423          try {parent.remove(_vSplitterTop);}    catch (NullPointerException npe) {}
424          try {parent.remove(_vSplitterBottom);} catch (NullPointerException npe) {}
425          try {parent.remove(_hSplitterLeft);}   catch (NullPointerException npe) {}
426          try {parent.remove(_hSplitterRight);}  catch (NullPointerException npe) {}
427 
428          // Add splitters back as needed
429          if (_top!=null && _vSplitterTop==null) {
430             _vSplitterTop = new MDISplitter(MDISplitter.VERTICAL,0.2f);
431             parent.add(_vSplitterTop);
432          }
433          if (_bottom!=null && _vSplitterBottom==null) {
434             _vSplitterBottom = new MDISplitter(MDISplitter.VERTICAL,0.8f);
435             parent.add(_vSplitterBottom);
436          }
437          if (_left!=null && _hSplitterLeft==null) {
438             _hSplitterLeft = new MDISplitter(MDISplitter.HORIZONTAL,0.2f);
439             parent.add(_hSplitterLeft);
440          }
441          if (_right!=null && _hSplitterRight==null) {
442             _hSplitterRight= new MDISplitter(MDISplitter.HORIZONTAL,0.8f);
443             parent.add(_hSplitterRight);
444          }
445 
446          // Figure desktop pane boundaries based on splitter positions
447          if (_top!=null) {
448             tpos = _vSplitterTop.getPosition();
449             minY = (int)(height*tpos) + 5;
450             minY = minY<5 ? 5 : minY;
451             minY = minY>height-5 ? height-5 : minY;
452          }
453          if (_bottom!=null) {
454             bpos = _vSplitterBottom.getPosition(); 
455             maxY = (int)(height*bpos);
456             maxY = maxY<5 ? 5 : maxY;
457             maxY = maxY>height-5 ? height-5 : maxY;
458          }
459          if (_left!=null) {
460             lpos = _hSplitterLeft.getPosition(); 
461             minX = (int)(width*lpos) + 5;
462             minX = minX<5 ? 5 : minX;
463             minX = minX>width-5 ? width-5 : minX;
464          }
465          if (_right!=null) {
466             rpos = _hSplitterRight.getPosition(); 
467             maxX = (int)(width*rpos);
468             maxX = maxX<5 ? 5 : maxX;
469             maxX = maxX>width-5 ? width-5 : maxX;
470          }
471 
472          // Lay out top and bottom components
473 
474          if (_top!=null && _bottom!=null) {
475             if (_vSplitterTop.isDragging() && minY>maxY) {
476                maxY = minY;
477             }
478             else if (maxY<minY) {
479             //else if (_vSplitterBottom.isDragging() && maxY<minY) {
480                minY = maxY;
481             }
482          }
483          if (_top!=null) {
484             _top.setBounds(0,0,width,minY-5);
485             _top.doLayout();
486 
487             parent.add(_vSplitterTop);
488             _vSplitterTop.setBounds(0,minY-5,width,5);
489          }
490          if (_bottom!=null) {
491             _bottom.setBounds(0,maxY+5,width,height-maxY-5);
492             _bottom.doLayout();
493 
494             parent.add(_vSplitterBottom);
495             _vSplitterBottom.setBounds(0,maxY,width,5);
496          }
497 
498          // Lay out left and right components
499 
500          if (_left!=null && _right!=null) {
501             if (_hSplitterLeft.isDragging() && minX>maxX) {
502                maxX = minX;
503             }
504             else if (maxX<minX) {
505             //else if (_hSplitterRight.isDragging() && maxX<minX) {
506                minX = maxX;
507             }
508          }
509          if (_left!=null) {
510             _left.setBounds(0,minY,minX-5,maxY-minY);
511             _left.doLayout();
512             
513             parent.add(_hSplitterLeft);
514             _hSplitterLeft.setBounds(minX-5,minY,5,maxY-minY);
515          }
516          if (_right!=null) {
517             _right.setBounds(maxX+5,minY,width-maxX-5,maxY-minY);
518             _right.doLayout();
519             
520             parent.add(_hSplitterRight);
521             _hSplitterRight.setBounds(maxX,minY,5,maxY-minY);
522          }
523 
524          // Position desktop pane in middle
525          _desktop.setBounds(minX,minY,maxX-minX,maxY-minY);
526       }
527    }
528 }
529 
530 ////////////////////////////////////////////////////////////////////////
531 
532 class MDIDesktopManager extends DefaultDesktopManager {
533 
534    /** Don't allow internal frames to be dragged over bounds */
535    public void dragFrame(JComponent f, int newX, int newY) {
536 
537       if (f instanceof JInternalFrame) {
538          JInternalFrame frame = (JInternalFrame)f;
539          JDesktopPane desktop = frame.getDesktopPane();
540 
541          if (newX + frame.getSize().width > desktop.getSize().width) {
542             newX = desktop.getSize().width - frame.getSize().width;
543          }
544          if (newX < 0) {
545             newX = 0;
546          }
547          if (newY + frame.getSize().height > desktop.getSize().height) {
548             newY = desktop.getSize().height - frame.getSize().height;
549          }
550          if (newY < 0) {
551             newY = 0;
552          }
553          super.dragFrame(f,newX,newY);
554       }
555    }
556        
557    /** Don't allow internal frames to be resized over bounds */
558    public void resizeFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
559 
560       if (f instanceof JInternalFrame) {
561          JInternalFrame frame = (JInternalFrame)f;
562          JDesktopPane desktop = frame.getDesktopPane();
563 
564          if (newX < 0) {
565             newX = 0;
566             newWidth = frame.getSize().width;
567          }
568          else if (newX + newWidth > desktop.getSize().width) {
569             newWidth = desktop.getSize().width - newX;
570          }
571 
572          if (newY < 0) {
573             newY = 0;
574             newHeight = frame.getSize().height;
575          }
576          else if (newY + newHeight > desktop.getSize().height) {
577             newHeight = desktop.getSize().height - newY;
578          }
579 
580          super.resizeFrame(f,newX,newY,newWidth,newHeight);
581       }
582    }  
583 }
584    
585 ///////////////////////////////////////////////////////////////////////
586 
587 class MDISplitter extends JPanel {
588 
589    public final static int VERTICAL = 1;
590    public final static int HORIZONTAL = 2;
591 
592    private int _orientation = VERTICAL;
593    private float _position = 0.2f;
594    private boolean _isDragging = false;
595 
596    //-----------------------------------------------------------------
597    public MDISplitter(int orientation, float position) {
598       _orientation = orientation;
599       _position = position;
600       setBorder(new BevelBorder(BevelBorder.RAISED));
601       
602       addMouseMotionListener(new MouseMotionListener() {
603          public void mouseMoved(MouseEvent event) {
604             if (_orientation == VERTICAL)
605                setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
606             else 
607                setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
608          }
609          public void mouseDragged(MouseEvent event) {
610             if (_orientation == VERTICAL) {
611                int newDevPos = getBounds().y + event.getY();
612                _position = (float)newDevPos / (float)getParent().getSize().height;
613             }
614             else {
615                int newDevPos = getBounds().x + event.getX();
616                _position = (float)newDevPos / (float)getParent().getSize().width;
617             }
618             if (_position < 0.0f) _position = 0.0f;
619             if (_position > 1.0f) _position = 1.0f;
620             _isDragging = true;
621             getParent().doLayout();
622             _isDragging = false;
623          }
624       });
625    }
626    //-----------------------------------------------------------------
627    public void setBounds(int x, int y, int w, int h) {
628       if (_orientation == VERTICAL) {
629          _position = (float)y / (float)getParent().getSize().height;
630       }
631       else {
632          _position = (float)x / (float)getParent().getSize().width;
633       }
634       if (_position < 0.0f) _position = 0.0f;
635       if (_position > 1.0f) _position = 1.0f;
636       super.setBounds(x,y,w,h);
637    }
638    //-----------------------------------------------------------------
639    public float getPosition() {
640       return _position;
641    }
642    //-----------------------------------------------------------------
643    public void setPosition(float position) {
644       _position = position;
645    }   
646    //-----------------------------------------------------------------
647    public boolean isDragging() {
648       return _isDragging;
649    }
650 }
651 
652 ///////////////////////////////////////////////////////////////////////
653 
654 class ClientPanel extends JPanel implements MDIClientPanel {
655    private String _dockSite = MDIPanel.DOCK_TOP;
656    private String _dockState = MDIPanel.DOCK_NONE;
657    private MDIPanel _mdi = null;
658 
659    public String getDockState() {return _dockState;} 
660    public void   setDockState(String dockState) {_dockState=dockState;} 
661 
662    public JPanel getPanel() {return this;}
663 
664    public ClientPanel(MDIPanel mdi, String dockSite, String dockState) {
665       _dockSite = dockSite;
666       _dockState = dockState;
667       _mdi = mdi;
668 
669       setLayout(new BorderLayout());
670       JButton btn = new JButton("Hello World");
671       add(btn,BorderLayout.CENTER);
672       add(new JLabel("SOUTH"),BorderLayout.SOUTH);
673 
674       btn.addActionListener(new ActionListener() {
675          public void actionPerformed(ActionEvent ae) {
676             if (_dockState.equals(_dockSite)) {
677                _dockState = MDIPanel.DOCK_NONE;
678                //System.out.println("Undocking="+_dockState);
679                _mdi.registerDockState(ClientPanel.this);
680             }
681             else {
682                _dockState = _dockSite;
683                //System.out.println("Docking="+_dockState);
684                _mdi.registerDockState(ClientPanel.this);
685             }
686          }
687       });
688    }
689 }
690 
691 ///////////////////////////////////////////////////////////////////////
692 
693 class ClientFrame extends JInternalFrame implements MDIClientFrame {
694    private MDIClientPanel _panel = null;
695 
696    public ClientFrame() {
697       // closable, maximizable, iconifiable, resizable
698       super("ClientFrame",true,true,true,true);
699       getContentPane().setLayout(new BorderLayout());
700       setVisible(true);
701    }
702    public MDIClientPanel getClientPanel() {
703       return _panel;
704    }
705    public void setClientPanel(MDIClientPanel clientPanel) {
706       _panel = clientPanel;
707    }
708    public JInternalFrame getFrame() {
709       return this;
710    }
711 }
712