PageRenderTime 221ms CodeModel.GetById 80ms app.highlight 91ms RepoModel.GetById 22ms app.codeStats 1ms

/jEdit/tags/jedit-4-3-pre5/org/gjt/sp/jedit/gui/PanelWindowContainer.java

#
Java | 923 lines | 686 code | 112 blank | 125 comment | 114 complexity | cf6434d44ca6acaf60b8097e929d5ac7 MD5 | raw file
  1/*
  2 * PanelWindowContainer.java - holds dockable windows
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2000, 2004 Slava Pestov
  7 *
  8 * This program is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU General Public License
 10 * as published by the Free Software Foundation; either version 2
 11 * of the License, or any later version.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; if not, write to the Free Software
 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 21 */
 22
 23package org.gjt.sp.jedit.gui;
 24
 25//{{{ Imports
 26import javax.swing.border.*;
 27import javax.swing.plaf.metal.*;
 28import javax.swing.*;
 29import java.awt.event.*;
 30import java.awt.font.*;
 31import java.awt.geom.AffineTransform;
 32import java.awt.*;
 33import java.util.*;
 34import org.gjt.sp.jedit.*;
 35//}}}
 36
 37/**
 38 * A container for dockable windows. This class should never be used
 39 * directly.
 40 * @author Slava Pestov
 41 * @version $Id: PanelWindowContainer.java 5516 2006-07-03 16:27:09Z ezust $
 42 * @since jEdit 4.0pre1
 43 */
 44public class PanelWindowContainer implements DockableWindowContainer
 45{
 46	//{{{ PanelWindowContainer constructor
 47	public PanelWindowContainer(DockableWindowManager wm, String position,
 48		int dimension)
 49	{
 50		this.wm = wm;
 51		this.position = position;
 52
 53		//{{{ Button box setup
 54		buttonPanel = new JPanel(new ButtonLayout());
 55		buttonPanel.setBorder(new EmptyBorder(1,1,1,1));
 56
 57		closeBox = new JButton(GUIUtilities.loadIcon("closebox.gif"));
 58		closeBox.setRequestFocusEnabled(false);
 59		closeBox.setToolTipText(jEdit.getProperty("view.docking.close-tooltip"));
 60		if(OperatingSystem.isMacOSLF())
 61			closeBox.putClientProperty("JButton.buttonType","toolbar");
 62
 63		closeBox.setMargin(new Insets(0,0,0,0));
 64
 65		closeBox.addActionListener(new ActionHandler());
 66
 67		menuBtn = new JButton(GUIUtilities.loadIcon("ToolbarMenu.gif"));
 68		menuBtn.setRequestFocusEnabled(false);
 69		menuBtn.setToolTipText(jEdit.getProperty("view.docking.menu-tooltip"));
 70		if(OperatingSystem.isMacOSLF())
 71			menuBtn.putClientProperty("JButton.buttonType","toolbar");
 72
 73		menuBtn.setMargin(new Insets(0,0,0,0));
 74
 75		menuBtn.addMouseListener(new MenuMouseHandler());
 76
 77		buttonGroup = new ButtonGroup();
 78		// JDK 1.4 workaround
 79		buttonGroup.add(nullButton = new JToggleButton());
 80		//}}}
 81
 82		dockables = new ArrayList();
 83		buttons = new ArrayList();
 84		dockablePanel = new DockablePanel(this);
 85
 86		this.dimension = dimension;
 87	} //}}}
 88
 89	//{{{ getDockableWindowManager() method
 90	/**
 91	 * @since jEdit 4.3pre2
 92	 */
 93	public DockableWindowManager getDockableWindowManager()
 94	{
 95		return wm;
 96	} //}}}
 97	
 98	//{{{ register() method
 99	public void register(final DockableWindowManager.Entry entry)
100	{
101		dockables.add(entry);
102
103		//{{{ Create button
104		int rotation;
105		if(position.equals(DockableWindowManager.TOP)
106			|| position.equals(DockableWindowManager.BOTTOM))
107			rotation = RotatedTextIcon.NONE;
108		else if(position.equals(DockableWindowManager.LEFT))
109			rotation = RotatedTextIcon.CCW;
110		else if(position.equals(DockableWindowManager.RIGHT))
111			rotation = RotatedTextIcon.CW;
112		else
113			throw new InternalError("Invalid position: " + position);
114
115		JToggleButton button = new JToggleButton();
116		button.setMargin(new Insets(1,1,1,1));
117		button.setRequestFocusEnabled(false);
118		button.setIcon(new RotatedTextIcon(rotation,button.getFont(),
119			entry.label()));
120		button.setActionCommand(entry.factory.name);
121		button.addActionListener(new ActionHandler());
122		button.addMouseListener(new MenuMouseHandler());
123		if(OperatingSystem.isMacOSLF())
124			button.putClientProperty("JButton.buttonType","toolbar");
125		//}}}
126
127		buttonGroup.add(button);
128		buttons.add(button);
129		entry.btn = button;
130
131		wm.revalidate();
132	} //}}}
133
134	//{{{ unregister() method
135	public void unregister(DockableWindowManager.Entry entry)
136	{
137		if(entry.factory.name.equals(mostRecent))
138			mostRecent = null;
139
140		if(entry.btn != null)
141		{
142			buttonPanel.remove(entry.btn);
143			buttons.remove(entry.btn);
144			entry.btn = null;
145		}
146
147		dockables.remove(entry);
148		if(entry.win != null)
149			dockablePanel.remove(entry.win);
150
151		if(current == entry)
152		{
153			current = null;
154			show(null);
155		}
156		else
157		{
158			wm.revalidate();
159			dockablePanel.repaint();
160			buttonPanel.repaint();
161		}
162	} //}}}
163
164	//{{{ remove() method
165	public void remove(final DockableWindowManager.Entry entry)
166	{
167		if(entry.factory.name.equals(mostRecent))
168			mostRecent = null;
169
170		if(entry.win != null)
171		{
172			dockablePanel.remove(entry.win);
173			entry.win = null;
174		}
175
176		if(current == entry)
177		{
178			current = null;
179			show(null);
180		}
181		else
182		{
183			wm.revalidate();
184			dockablePanel.repaint();
185		}
186	} //}}}
187
188	//{{{ showMostRecent() method
189	public void showMostRecent()
190	{
191		if(dockables.size() == 0)
192		{
193			Toolkit.getDefaultToolkit().beep();
194			return;
195		}
196
197		if(mostRecent == null)
198		{
199			mostRecent = ((DockableWindowManager.Entry)
200				dockables.get(0)).factory.name;
201		}
202
203		wm.showDockableWindow(mostRecent);
204	} //}}}
205
206	//{{{ show() method
207	public void show(final DockableWindowManager.Entry entry)
208	{
209		if(current == entry)
210		{
211			if(entry != null)
212			{
213				if(entry.win instanceof DefaultFocusComponent)
214				{
215					((DefaultFocusComponent)entry.win)
216						.focusOnDefaultComponent();
217				}
218				else
219				{
220					entry.win.requestDefaultFocus();
221				}
222			}
223			return;
224		}
225
226		if(entry != null)
227		{
228			if(current == null)
229			{
230				// we didn't have a component previously, so
231				// create a border
232				dockablePanel.setBorder(new DockBorder(position));
233			}
234
235			mostRecent = entry.factory.name;
236			this.current = entry;
237
238			if(entry.win.getParent() != dockablePanel)
239				dockablePanel.add(entry.factory.name,entry.win);
240
241			dockablePanel.showDockable(entry.factory.name);
242
243			entry.btn.setSelected(true);
244
245			if(entry.win instanceof DefaultFocusComponent)
246			{
247				((DefaultFocusComponent)entry.win)
248					.focusOnDefaultComponent();
249			}
250			else
251			{
252				entry.win.requestDefaultFocus();
253			}
254		}
255		else
256		{
257			current = null;
258			nullButton.setSelected(true);
259			// removing last component, so remove border
260			dockablePanel.setBorder(null);
261
262			wm.getView().getTextArea().requestFocus();
263		}
264
265		wm.revalidate();
266		dockablePanel.repaint();
267	} //}}}
268
269	//{{{ isVisible() method
270	public boolean isVisible(DockableWindowManager.Entry entry)
271	{
272		return current == entry;
273	} //}}}
274
275	//{{{ getCurrent() method
276	/**
277	 * Returns the name of the dockable in this container.
278	 * @since jEdit 4.2pre1
279	 */
280	public String getCurrent()
281	{
282		if(current == null)
283			return null;
284		else
285			return current.factory.name;
286	} //}}}
287
288	//{{{ getDimension() method
289	/**
290	 * Returns the width or height (depending on position) of the dockable
291	 * window container.
292	 * @since jEdit 4.2pre1
293	 */
294	public int getDimension()
295	{
296		return dimension;
297	} //}}}
298
299	//{{{ getPosition() method
300	/**
301	 * @since jEdit 4.3pre2
302	 */
303	public String getPosition()
304	{
305		return position;
306	} //}}}
307
308	//{{{ getDockables() method
309	public String[] getDockables()
310	{
311		String[] retVal = new String[dockables.size()];
312		for(int i = 0; i < dockables.size(); i++)
313		{
314			DockableWindowManager.Entry entry =
315				(DockableWindowManager.Entry) dockables.get(i);
316			retVal[i] = entry.factory.name;
317		}
318		return retVal;
319	} //}}}
320
321	//{{{ Package-private members
322	static final int SPLITTER_WIDTH = 10;
323	DockablePanel dockablePanel;
324	JPanel buttonPanel;
325
326	//{{{ save() method
327	void save()
328	{
329		jEdit.setIntegerProperty("view.dock." + position + ".dimension",
330			dimension);
331		if(current == null)
332			jEdit.unsetProperty("view.dock." + position + ".last");
333		else
334		{
335			jEdit.setProperty("view.dock." + position + ".last",
336				current.factory.name);
337		}
338	} //}}}
339
340	//{{{ setDimension() method
341	void setDimension(int dimension)
342	{
343		if(dimension > SPLITTER_WIDTH)
344			this.dimension = dimension - SPLITTER_WIDTH;
345	} //}}}
346
347	//{{{ sortDockables() method
348	void sortDockables()
349	{
350		buttonPanel.removeAll();
351		buttonPanel.add(closeBox);
352		buttonPanel.add(menuBtn);
353		Collections.sort(buttons,new DockableWindowCompare());
354		for(int i = 0; i < buttons.size(); i++)
355		{
356			buttonPanel.add((AbstractButton)buttons.get(i));
357		}
358	} //}}}
359
360	//{{{ getWrappedDimension() method
361	/**
362	 * Returns the width or height of wrapped rows or columns.
363	 */
364	int getWrappedDimension(int dimension)
365	{
366		return ((ButtonLayout)buttonPanel.getLayout())
367			.getWrappedDimension(buttonPanel,dimension);
368	} //}}}
369
370	//}}}
371
372	//{{{ Private members
373	private DockableWindowManager wm;
374	private String position;
375	private JButton closeBox;
376	private JButton menuBtn;
377	private ButtonGroup buttonGroup;
378	private JToggleButton nullButton;
379	private int dimension;
380	private ArrayList dockables;
381	private ArrayList buttons;
382	private DockableWindowManager.Entry current;
383	private JPopupMenu popup;
384
385	// remember the most recent dockable
386	private String mostRecent;
387	//}}}
388
389	//{{{ Inner classes
390
391	//{{{ DockableWindowCompare class
392	static class DockableWindowCompare implements Comparator
393	{
394		public int compare(Object o1, Object o2)
395		{
396			String name1 = ((AbstractButton)o1).getActionCommand();
397			String name2 = ((AbstractButton)o2).getActionCommand();
398			return MiscUtilities.compareStrings(
399				jEdit.getProperty(name1 + ".title",""),
400				jEdit.getProperty(name2 + ".title",""),
401				true);
402		}
403	} //}}}
404
405	//{{{ ActionHandler class
406	class ActionHandler implements ActionListener
407	{
408		public void actionPerformed(ActionEvent evt)
409		{
410			if(popup != null && popup.isVisible())
411				popup.setVisible(false);
412
413			if(evt.getSource() == closeBox)
414				show(null);
415			else
416			{
417				if(wm.isDockableWindowVisible(evt.getActionCommand()))
418					show(null);
419				else
420					wm.showDockableWindow(evt.getActionCommand());
421			}
422		}
423	} //}}}
424
425	//{{{ MenuMouseHandler class
426	class MenuMouseHandler extends MouseAdapter
427	{
428		public void mousePressed(MouseEvent evt)
429		{
430			if(popup != null && popup.isVisible())
431			{
432				popup.setVisible(false);
433				return;
434			}
435
436			Component comp = (Component)evt.getSource();
437			String dockable;
438			if(comp instanceof JToggleButton)
439				dockable = ((JToggleButton)comp).getActionCommand();
440			else
441				dockable = getCurrent();
442
443			if(comp == menuBtn || GUIUtilities.isPopupTrigger(evt))
444			{
445				if(dockable == null)
446				{
447					popup = wm.createPopupMenu(PanelWindowContainer.this,null,false);
448				}
449				else
450				{
451					popup = wm.createPopupMenu(PanelWindowContainer.this,dockable,false);
452				}
453
454				int x, y;
455				boolean point;
456				if(comp == menuBtn)
457				{
458					x = 0;
459					y = menuBtn.getHeight();
460					point = false;
461				}
462				else
463				{
464					x = evt.getX();
465					y = evt.getY();
466					point = true;
467				}
468				GUIUtilities.showPopupMenu(popup,
469					comp,x,y,point);
470			}
471		}
472	} //}}}
473
474	//{{{ DockBorder class
475	static class DockBorder implements Border
476	{
477		String position;
478		Insets insets;
479		Color color1;
480		Color color2;
481		Color color3;
482
483		//{{{ DockBorder constructor
484		DockBorder(String position)
485		{
486			this.position = position;
487			insets = new Insets(
488				position.equals(DockableWindowManager.BOTTOM)
489					? SPLITTER_WIDTH : 0,
490				position.equals(DockableWindowManager.RIGHT)
491					? SPLITTER_WIDTH : 0,
492				position.equals(DockableWindowManager.TOP)
493					? SPLITTER_WIDTH : 0,
494				position.equals(DockableWindowManager.LEFT)
495					? SPLITTER_WIDTH : 0);
496		} //}}}
497
498		//{{{ paintBorder() method
499		public void paintBorder(Component c, Graphics g,
500			int x, int y, int width, int height)
501		{
502			updateColors();
503
504			if(color1 == null || color2 == null || color3 == null)
505				return;
506
507			if(position.equals(DockableWindowManager.BOTTOM))
508				paintHorizBorder(g,x,y,width);
509			else if(position.equals(DockableWindowManager.RIGHT))
510				paintVertBorder(g,x,y,height);
511			else if(position.equals(DockableWindowManager.TOP))
512			{
513				paintHorizBorder(g,x,y + height
514					- SPLITTER_WIDTH,width);
515			}
516			else if(position.equals(DockableWindowManager.LEFT))
517			{
518				paintVertBorder(g,x + width
519					- SPLITTER_WIDTH,y,height);
520			}
521		} //}}}
522
523		//{{{ getBorderInsets() method
524		public Insets getBorderInsets(Component c)
525		{
526			return insets;
527		} //}}}
528
529		//{{{ isBorderOpaque() method
530		public boolean isBorderOpaque()
531		{
532			return false;
533		} //}}}
534
535		//{{{ paintHorizBorder() method
536		private void paintHorizBorder(Graphics g, int x, int y, int width)
537		{
538			g.setColor(color3);
539			g.fillRect(x,y,width,SPLITTER_WIDTH);
540
541			for(int i = 0; i < width / 4 - 1; i++)
542			{
543				g.setColor(color1);
544				g.drawLine(x + i * 4 + 2,y + 3,
545					x + i * 4 + 2,y + 3);
546				g.setColor(color2);
547				g.drawLine(x + i * 4 + 3,y + 4,
548					x + i * 4 + 3,y + 4);
549				g.setColor(color1);
550				g.drawLine(x + i * 4 + 4,y + 5,
551					x + i * 4 + 4,y + 5);
552				g.setColor(color2);
553				g.drawLine(x + i * 4 + 5,y + 6,
554					x + i * 4 + 5,y + 6);
555			}
556		} //}}}
557
558		//{{{ paintVertBorder() method
559		private void paintVertBorder(Graphics g, int x, int y, int height)
560		{
561			g.setColor(color3);
562			g.fillRect(x,y,SPLITTER_WIDTH,height);
563
564			for(int i = 0; i < height / 4 - 1; i++)
565			{
566				g.setColor(color1);
567				g.drawLine(x + 3,y + i * 4 + 2,
568					x + 3,y + i * 4 + 2);
569				g.setColor(color2);
570				g.drawLine(x + 4,y + i * 4 + 3,
571					x + 4,y + i * 4 + 3);
572				g.setColor(color1);
573				g.drawLine(x + 5,y + i * 4 + 4,
574					x + 5,y + i * 4 + 4);
575				g.setColor(color2);
576				g.drawLine(x + 6,y + i * 4 + 5,
577					x + 6,y + i * 4 + 5);
578			}
579		} //}}}
580
581		//{{{ updateColors() method
582		private void updateColors()
583		{
584			if(UIManager.getLookAndFeel() instanceof MetalLookAndFeel)
585			{
586				color1 = MetalLookAndFeel.getControlHighlight();
587				color2 = MetalLookAndFeel.getControlDarkShadow();
588				color3 = MetalLookAndFeel.getControl();
589			}
590			else
591			{
592				color1 = color2 = color3 = null;
593			}
594		} //}}}
595	} //}}}
596
597	//{{{ RotatedTextIcon class
598	public static class RotatedTextIcon implements Icon
599	{
600		public static final int NONE = 0;
601		public static final int CW = 1;
602		public static final int CCW = 2;
603
604		//{{{ RotatedTextIcon constructor
605		public RotatedTextIcon(int rotate, Font font, String text)
606		{
607			this.rotate = rotate;
608			this.font = font;
609
610			FontRenderContext fontRenderContext
611				= new FontRenderContext(null,true,true);
612			this.text = text;
613			glyphs = font.createGlyphVector(fontRenderContext,text);
614			width = (int)glyphs.getLogicalBounds().getWidth() + 4;
615			//height = (int)glyphs.getLogicalBounds().getHeight();
616
617			LineMetrics lineMetrics = font.getLineMetrics(text,fontRenderContext);
618			ascent = lineMetrics.getAscent();
619			height = (int)lineMetrics.getHeight();
620
621			renderHints = new RenderingHints(
622				RenderingHints.KEY_ANTIALIASING,
623				RenderingHints.VALUE_ANTIALIAS_ON);
624			renderHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
625				RenderingHints.VALUE_FRACTIONALMETRICS_ON);
626			renderHints.put(RenderingHints.KEY_RENDERING,
627				RenderingHints.VALUE_RENDER_QUALITY);
628		} //}}}
629
630		//{{{ getIconWidth() method
631		public int getIconWidth()
632		{
633			return (int)(rotate == RotatedTextIcon.CW
634				|| rotate == RotatedTextIcon.CCW
635				? height : width);
636		} //}}}
637
638		//{{{ getIconHeight() method
639		public int getIconHeight()
640		{
641			return (int)(rotate == RotatedTextIcon.CW
642				|| rotate == RotatedTextIcon.CCW
643				? width : height);
644		} //}}}
645
646		//{{{ paintIcon() method
647		public void paintIcon(Component c, Graphics g, int x, int y)
648		{
649			Graphics2D g2d = (Graphics2D)g;
650			g2d.setFont(font);
651			AffineTransform oldTransform = g2d.getTransform();
652			RenderingHints oldHints = g2d.getRenderingHints();
653
654			g2d.setRenderingHints(renderHints);
655			g2d.setColor(c.getForeground());
656
657			//{{{ No rotation
658			if(rotate == RotatedTextIcon.NONE)
659			{
660				g2d.drawGlyphVector(glyphs,x + 2,y + ascent);
661			} //}}}
662			//{{{ Clockwise rotation
663			else if(rotate == RotatedTextIcon.CW)
664			{
665				AffineTransform trans = new AffineTransform();
666				trans.concatenate(oldTransform);
667				trans.translate(x,y + 2);
668				trans.rotate(Math.PI / 2,
669					height / 2, width / 2);
670				g2d.setTransform(trans);
671				g2d.drawGlyphVector(glyphs,(height - width) / 2,
672					(width - height) / 2
673					+ ascent);
674			} //}}}
675			//{{{ Counterclockwise rotation
676			else if(rotate == RotatedTextIcon.CCW)
677			{
678				AffineTransform trans = new AffineTransform();
679				trans.concatenate(oldTransform);
680				trans.translate(x,y - 2);
681				trans.rotate(Math.PI * 3 / 2,
682					height / 2, width / 2);
683				g2d.setTransform(trans);
684				g2d.drawGlyphVector(glyphs,(height - width) / 2,
685					(width - height) / 2
686					+ ascent);
687			} //}}}
688
689			g2d.setTransform(oldTransform);
690			g2d.setRenderingHints(oldHints);
691		} //}}}
692
693		//{{{ Private members
694		private int rotate;
695		private Font font;
696		private String text;
697		private GlyphVector glyphs;
698		private float width;
699		private float height;
700		private float ascent;
701		private RenderingHints renderHints;
702		//}}}
703	} //}}}
704
705	//{{{ ButtonLayout class
706	class ButtonLayout implements LayoutManager
707	{
708		//{{{ addLayoutComponent() method
709		public void addLayoutComponent(String name, Component comp) {} //}}}
710
711		//{{{ removeLayoutComponent() method
712		public void removeLayoutComponent(Component comp) {} //}}}
713
714		//{{{ getWrappedDimension() method
715		/**
716		 * Returns the width or height of wrapped rows or columns.
717		 */
718		int getWrappedDimension(JComponent parent, int dimension)
719		{
720			Insets insets = (parent).getBorder()
721				.getBorderInsets(parent);
722
723			Component[] comp = parent.getComponents();
724			if(comp.length <= 2)
725				return 0;
726
727			Dimension dim = comp[2].getPreferredSize();
728
729			if(position.equals(DockableWindowManager.TOP)
730				|| position.equals(DockableWindowManager.BOTTOM))
731			{
732				int width = dimension - insets.right;
733				int rowHeight = Math.max(dim.height,closeBox.getPreferredSize().width);
734				int x = rowHeight * 2 + insets.left;
735				Dimension returnValue = new Dimension(0,rowHeight
736					+ insets.top + insets.bottom);
737
738				for(int i = 2; i < comp.length; i++)
739				{
740					int btnWidth = comp[i].getPreferredSize().width;
741					if(btnWidth + x > width)
742					{
743						returnValue.height += rowHeight;
744						x = insets.left;
745					}
746
747					x += btnWidth;
748				}
749				return returnValue.height;
750			}
751			else
752			{
753				int height = dimension - insets.bottom;
754				int colWidth = Math.max(dim.width,closeBox.getPreferredSize().height);
755				int y = colWidth * 2 + insets.top;
756				Dimension returnValue = new Dimension(colWidth
757					+ insets.left + insets.right,0);
758
759				for(int i = 2; i < comp.length; i++)
760				{
761					int btnHeight = comp[i].getPreferredSize().height;
762					if(btnHeight + y > height)
763					{
764						returnValue.width += colWidth;
765						y = insets.top;
766					}
767
768					y += btnHeight;
769				}
770				return returnValue.width;
771			}
772		} //}}}
773
774		//{{{ preferredLayoutSize() method
775		public Dimension preferredLayoutSize(Container parent)
776		{
777			Insets insets = ((JComponent)parent).getBorder()
778				.getBorderInsets(parent);
779
780			Component[] comp = parent.getComponents();
781			if(comp.length <= 2)
782			{
783				// nothing 'cept close box
784				return new Dimension(0,0);
785			}
786
787			Dimension dim = comp[2].getPreferredSize();
788
789			if(position.equals(DockableWindowManager.TOP)
790				|| position.equals(DockableWindowManager.BOTTOM))
791			{
792				int width = parent.getWidth() - insets.right;
793				int rowHeight = Math.max(dim.height,closeBox.getPreferredSize().width);
794				int x = rowHeight * 2 + insets.left;
795				Dimension returnValue = new Dimension(0,rowHeight
796					+ insets.top + insets.bottom);
797
798				for(int i = 2; i < comp.length; i++)
799				{
800					int btnWidth = comp[i].getPreferredSize().width;
801					if(btnWidth + x > width)
802					{
803						returnValue.height += rowHeight;
804						x = insets.left;
805					}
806
807					x += btnWidth;
808				}
809				return returnValue;
810			}
811			else
812			{
813				int height = parent.getHeight() - insets.bottom;
814				int colWidth = Math.max(dim.width,closeBox.getPreferredSize().height);
815				int y = colWidth * 2 + insets.top;
816				Dimension returnValue = new Dimension(colWidth
817					+ insets.left + insets.right,0);
818
819				for(int i = 2; i < comp.length; i++)
820				{
821					int btnHeight = comp[i].getPreferredSize().height;
822					if(btnHeight + y > height)
823					{
824						returnValue.width += colWidth;
825						y = insets.top;
826					}
827
828					y += btnHeight;
829				}
830				return returnValue;
831			}
832		} //}}}
833
834		//{{{ minimumLayoutSize() method
835		public Dimension minimumLayoutSize(Container parent)
836		{
837			return preferredLayoutSize(parent);
838		} //}}}
839
840		//{{{ layoutContainer() method
841		public void layoutContainer(Container parent)
842		{
843			Insets insets = ((JComponent)parent).getBorder()
844				.getBorderInsets(parent);
845
846			Component[] comp = parent.getComponents();
847			if(comp.length <= 2)
848			{
849				for(int i = 0; i < comp.length; i++)
850				{
851					comp[i].setVisible(false);
852				}
853				return;
854			}
855
856			comp[0].setVisible(true);
857			comp[1].setVisible(true);
858
859			Dimension dim = comp[2].getPreferredSize();
860
861			if(position.equals(DockableWindowManager.TOP)
862				|| position.equals(DockableWindowManager.BOTTOM))
863			{
864				int width = parent.getWidth() - insets.right;
865				int rowHeight = Math.max(dim.height,closeBox.getPreferredSize().width);
866				int x = rowHeight * 2 + insets.left;
867				int y = insets.top;
868				closeBox.setBounds(insets.left,insets.top,rowHeight,rowHeight);
869				menuBtn.setBounds(insets.left + rowHeight,insets.top,rowHeight,rowHeight);
870
871				for(int i = 2; i < comp.length; i++)
872				{
873					int btnWidth = comp[i].getPreferredSize().width;
874					if(btnWidth + x > width)
875					{
876						x = insets.left;
877						y += rowHeight;
878					}
879					comp[i].setBounds(x,y,btnWidth,rowHeight);
880					x += btnWidth;
881				}
882
883				/* if(y + rowHeight != parent.getHeight())
884				{
885					parent.setSize(
886						parent.getWidth(),
887						y + rowHeight);
888					((JComponent)parent).revalidate();
889				} */
890			}
891			else
892			{
893				int height = parent.getHeight() - insets.bottom;
894				int colWidth = Math.max(dim.width,closeBox.getPreferredSize().height);
895				int x = insets.left;
896				int y = colWidth * 2 + insets.top;
897				closeBox.setBounds(insets.left,insets.top,colWidth,colWidth);
898				menuBtn.setBounds(insets.left,insets.top + colWidth,colWidth,colWidth);
899
900				for(int i = 2; i < comp.length; i++)
901				{
902					int btnHeight = comp[i].getPreferredSize().height;
903					if(btnHeight + y > height)
904					{
905						x += colWidth;
906						y = insets.top;
907					}
908					comp[i].setBounds(x,y,colWidth,btnHeight);
909					y += btnHeight;
910				}
911
912				/* if(x + colWidth != parent.getWidth())
913				{
914					parent.setSize(x + colWidth,
915						parent.getHeight());
916					((JComponent)parent).revalidate();
917				} */
918			}
919		} //}}}
920	} //}}}
921
922	//}}}
923}