pax_global_header00006660000000000000000000000064124333420240014507gustar00rootroot0000000000000052 comment=f6c5fa02aa796b4d6ed70b628d37a859b965a24a vldocking-vldocking-3.0.5/000077500000000000000000000000001243334202400154525ustar00rootroot00000000000000vldocking-vldocking-3.0.5/.gitignore000066400000000000000000000000561243334202400174430ustar00rootroot00000000000000/target /bin /.settings /.classpath /.project vldocking-vldocking-3.0.5/README.md000066400000000000000000000040061243334202400167310ustar00rootroot00000000000000# vldocking This is a fork of https://bitbucket.org/akuhtz/vldocking ## Why ? Because the original project seems to be dead :( See https://code.google.com/p/vldocking/ for more information, tutorials etc. ## And so, what's new ? * Switched from ant to mvn * Renamed package names to use old vlsolutions instead of vldocking * Released a 3.0.3 version available through maven central * Fixed issues with read/wrilXML on multiple screens * Added new empty ctor to `FloatingDialog` to make floating windows appear in taskbar. Extend `DefaultDockableContainerFactory.createFloatingDockableContainer` and return `new FloatingDialog()` * Fixed LAF issues e.g., when switching Substance skin * Fixed issue with borders not being set on single dock windows until an ancestor change events occured ## How to get the released versions ? ### Maven Just add this to your `pom.xml` file: The dependencies: ```xml dk.navicon vldocking 3.0.4 ``` VLDocking, the swing docking framework The VLDocking framework is a commercial-grade Swing Framework providing rich docking features which can easily be integrated with existing applications (and of course new ones). VLDocking has been created in 2004, and is licenced as under the LGPL terms. VLDocking is used by companies worldwide and open source projects. ![](http://vldocking.googlecode.com/svn/wiki/vldocking3.jpg) License ======= VLDocking is licensed as LGPL Contributions ============= VLDocking was initially designed by Lilian Chamontin at his former company VLSolutions. Contributors are welcome ! Contact me through the mailing list at google groups. https://groups.google.com/forum/#!forum/vldocking Documentation ============ The VLDocking tutorial can be found here https://code.google.com/p/vldocking/wiki/tutorial1 ## I found a bug, what can I do ? Feel free to fork this repo, and make a "pull request":http://help.github.com/send-pull-requests/. Ideally, write a test ! vldocking-vldocking-3.0.5/build.xml000077500000000000000000000120041243334202400172730ustar00rootroot00000000000000 © Copyright 2004-2013 Lilian Chamontin. All Rights Reserved.]]> vldocking-vldocking-3.0.5/doc/000077500000000000000000000000001243334202400162175ustar00rootroot00000000000000vldocking-vldocking-3.0.5/doc/vldocking-3.0.2-doc.zip000077500000000000000000037227421243334202400221500ustar00rootroot00000000000000PK ^Bcom/PK ^Bcom/vldocking/PK ^Bcom/vldocking/swing/PK ^Bcom/vldocking/swing/docking/PK ^B&com/vldocking/swing/docking/animation/PK ^B0com/vldocking/swing/docking/animation/class-use/PK ^B&com/vldocking/swing/docking/class-use/PK ^B&com/vldocking/swing/docking/doc-files/PK ^B"com/vldocking/swing/docking/event/PK ^B,com/vldocking/swing/docking/event/class-use/PK ^Bcom/vldocking/swing/docking/ui/PK ^B)com/vldocking/swing/docking/ui/class-use/PK ^Bcom/vldocking/swing/docking/ws/PK ^B)com/vldocking/swing/docking/ws/class-use/PK ^Bcom/vldocking/swing/tabbedpane/PK ^B)com/vldocking/swing/tabbedpane/class-use/PK ^Bcom/vldocking/swing/toolbars/PK ^B'com/vldocking/swing/toolbars/class-use/PK ^B'com/vldocking/swing/toolbars/doc-files/PK ^B resources/PK ^BʹvJallclasses-frame.htmlQs8o澃SI{7$H=(eOXZDOJd:z?㿇nW~5yq/I#*)1 ԘJ9y岵}<2׷uٳPx5MzOF<.1`SIԆD-LyD/#ˆo:ȽѲ @fUW ޱf#%ؔ$jO5~2NUeqz)'enY>NJZe8e xk>pZ!mr=;\ږϝM[Y P7}vpD+!;G"h'u>]z#5T.s(jAT>G%C@ `ǒ} %Gt6?dA=|yUvA#W"QSmEZɁDarF=aӻq$ta&v|}Sr|xtKs-ٹd hq=#Of䳢 ꑜ{|Δ *>ŕ _,}_ܮ^d8(o轻j `6n!ex9>dȋk~/JsϪ\,0d飖-Z Mys S,fT(|I!B:uteòFFyhЖh;iqT)Px_jn{Zuo2JbQ<5c0^P^U *KAH# pWQ75+)pKNUx `p>Wjph%A> I,uٵ3i&mƞ,ң!c:;8wO3__W< TpH ,84UGNS>WZDȢ;HhXu(!"Zv M\ŹDMd/FAޯCum!s<8./SnSrGgK+夹FffgkbI~q0=2/4E#0A"0cȕS{"5Ȅxgs>a8ħ2:Y$>_?Dƻ[ֽT#-(P/cD/&-t2_[@ώ$[nAe#2ju5fl8Q<"C՝3`8Dip,3ܰZEor`Z%)LfIӗ@JSl@ٜq̏_BoՄǫz7?U+k&T8Wn%<qή꜠C]„sFUgiP_ޥ(~t Zl|LMTY1#֋(pj61[p.erb{oCBXfT؁((ziU<1Zl<^j.܉EABa}VHU85.:\@L "@T?vߐOۍͻN߹B6 5y@6g6Bg/Nw"m}̕e"4o2,/Q4;M<5_XgDpxX'om-AzɪY枳տ1RߔжƲMm4.$*h{N6bxƐ [ kLߘz nI%!/a2|d݉y气ѫ.YR6"|@uޅ2 sXʢX|4_AU= w' K{"8 i气P%}TLZl8.x>*ȶܼ/[{ #d}hCŐ|rrʀ#SQF8! h`'B=ҡwًpw+>EjAg۳Dl"]t hSVzM}7QHzNJSc伡TΥ{w?=d+kr5ӽj749:ZHLLVkwnRk"4*JN)M)~APT(3y(IB2 L9~eJ+y> i)+R1q)LkXO6#GPԎ|8&?9Vλ|W=闾[o  oW_"0q@C~J*&0K~`C/JIlFRacb[6\1mj?dwnGNN^ zƈ1c Ңr.i"k\DQjPK ^BB-'K B.com/vldocking/swing/docking/AnchorManager.html\o8Wv h4±kIS@Kt -jEڮn>Wb) p,p7CROvܽD7_/4S4=m#ԍq(<. N=o2^!{1q87{g?ULn=AժjQ}!3 8H$ƒ7E1*c w\tDBtzݴʒT2RoW8%bTޣO1 Љ{͗3HBRsPA>% eQ"`4|@1a5G)#b@tF@)7B8h~q]/z\s:Y3x0UHY+V,f >V*. ݯBEH Yj5T=G5'1 ㏆l#K: yh<q7Gnj P{ yG1|"Hybg13dRSWşSof3,"?$Pݘ"QNs7 cG,TeuHOVWAV)%cBl.|]=oD1TXRuxb,uူ d>e1zv9ŨID'&32FoP VWZ !MykETMp`x1Ӯ1RUG9q@K P 5Bmlfu Z_WO@=bpGéXdͳX8$DnAE(!+qֿʷ^^&ӥʱ5f$#KPYA_ V4:y" A}0YoA ҆<$9Ғ ⴘ;[ǀaODs.qM`iO7Dk$wu N K]o~-((#hVCBpɬ%| (+brq*Q*%?+jN-jTHbg>tl:%h;8N@V{:*OaI^5[HCh4JdC+Fc%XZfxޟ7iw&R c(&N=~3J%wgVYLd@IRe5lB}u"z/*͗3jfO3 {OP~ZԀ2X^o UŰ4@#"a $4rҰ^jC!aJ&F|}wE=+? MQ@0@nh T+ף.Bp2DuFPpӴ T"B,\BbBP ^Wߩysѻ"eAqPO5 r6kN5LUļ0 R;9Ł40 0[X= " z֭W&LH5AwX2$|iU]ʀ̓mT'N`qd0޺ džG[h,K&}Tj =0'MPV6ֶ(1\kC-i^j`])jk4@B2)L(&"Tg_coPTJ-fl7L9Gtͣ^vk SˁEej݃SQ,.mׅ$k{hIO.,*^9:3̧Cɂؘ M ;<W"D-1"?P 4u 5ORNĂhl:6>PI%SwOdRYTr-(űhP> x/9C~Hlm_XUky阄(He(?xpT֋قf5y#qde~u'B/6|V@Oì~J,V 1iٽU5G)6FJEb JD(O(v[5LTf'x% j٧g#%4 ?}f n5`1h;oYB[B.i^9j0b@[$&%4lD+4Z(%ZZ-9m[yd`Nœ gn uN i|n[ޅ.Udv^vnvGZ 皦V*;^vyCH01DO쮯PUoFTc `yl;]-k ޴h R rՓ1aNnE*#u iZ mҳeK9*ر刓npn'*Nn.m3f%snmˬ 6V|/haV]= 3ny LZ\<<!,A$ʞvJYtQ8/@Eěf١IN:4[pĘze(4o5B{\,Ak9z^.cj2"w{7IK>owOz|X [l#^d3ﲽ.l/]!F۳Ѷ(+uJrIJ(1#5y4U6﫟>4|D9Ut5xCICU%jiM9|?PK ^B;k h5com/vldocking/swing/docking/AutoHideBorderLayout.htmlks6{fPvg,ҏnX(sqǯ! 1Ddٽŋ$HvdǞ!AboKxA}i󯟎WAQ[ۨSA 8<" ~w8 AGtٻ1'~(BO2:%s|CP,[d/ptSHtmX57|øJw$0iHc*q\[4AS%8EjG$]"0K 2HHT<9RyjF(%q"<$^-=II~7jw)r_Ji"%tW|m[XΗ4 Y+e#)ȴ"uU*aOS2u兡lz5ڿ߾ -@,/xpһ0K=IQH9n2 :f9I@vUl.3jjZ sS|,]О32`ݴ84):gBv@uGo5mrs { 0ǔll%Q/^_ZW=3͊GP$u <u[r~alGd _q Yӻ$%-m iYkʠʘ1}$vK`Y S(5:aڈܱPi򷽫ENXjju W 2AeyJ|^-˜dZ !]ڊ<W8N#xB[<8!dQ.Ob_a414qT[5~= '}Qx1eFӋ6`:Q=dD^~z8 KPሶK 0W*Иa侊>kBLo0NFqDrX3ahϫޥ{DM|i)tƞ~M|8i瀁Z"N?f#̩u?UX).0PZhtlPM\كNXOt%KXqkLLpd&IRo<4S|gFngǺ\},x'vgB36 BIQ#@ȗN${K_\gooHS3[D5DUK_س~ͼa%uvhbʗjBn,dG|$pA1yBT^u&Za;lP[t'U=jk2ҲAƭ*yFR|<F j(]O"a[ѿZCfk6 rĀJ&8 --u CjM$WvrS"GRSyۃЫ,,9Se3h ?[qe#vIV}QL5xR3,Q#8$@ KF?q6&9!iFWs/qJm$N[X"|JiS嘵9آ^'gLi܉ trrVs9zU$S5㌺MmQqι|$i[Nei.4MbʹJ6Yxv շq7x$J6Y&Z!mu&Cd2D;q5J-#*Op빬ڟ))@oq|4S".+Be BWlO`5kkj7D7\X' h|fi<:UQ]4=FwQY`zF{4Y=L4sujӳs}'9) C!#~qX}I> EH[ll}Bo:Bu.hsNqj. w.^W7]ҿ[/Ǻ=;\yULqhTHqF=ufM^*Nx p8:4yKJgT̜]T 66-; iܽVף|ve]A$={kvp&]?Q>̛4?{Ҩ Rcx\*.. Aju<.e;Pfa(0])16?aXCy\y"p7Iy=7iYz5mf͌.K ""%3ՆqmF|鼛Pt3$gĊU !DXBD\ՈJTCe͐o=VJtOCM:; |Ugl HQyYj# 7Lln'K=ap>![STbZ̠nf묦jf1UnoSͤ[ի;2r"beBZXG~-Knm)-"('&o- 6O0ե*M2T_>]-dGWvR;r}q;UK|ɽb^gq)$lpd(vS m9kN5άW+^܊^Q>L(QxU(yVTtPo$'lu}z;4'(azUy uҵkcZ,2bJ=YӪ?_E΋uHh]|tnWv}Nk1f9]k.yÈ W@ʌȐ] {5MeBÜ }WԔ֌}$8+p-mgl )#\O-QE9efͩ]:ήtv98Yqv2|>aX<[?*~dד_O~={Oyzޯ{?S WcWc2A:.h_uViAG$Sbweo): (|$ BpHH>j\A(XF ?PK ^Bq$[/com/vldocking/swing/docking/AutoHideButton.html][s6~OUWSuvj,%96kKYRI&/.Z,)RKP(n$Ll6n| 4 u64>.b<N~3XăoKtv3w?t:m׻,睍خKPVo>̘Ǚy3veئswBgL+x' e完#xmonA/oww1޾x1,wo޾eطQݏB{ߧt/?;wƥgnѣolCGPQ-Má,e\Gbe߳wع7wVvo[ v3usZ/Yyx竬Y%.o1xmݕZ ncB_!џ_W?-ogzT6`otDtTq~LY01,L[-=s :eJet, )cN1JJA0`sWD˲[=v'#:G~PL oT3btnPg9C:R9f|my}]?ƫ 0vTMV9nrK\Q ?tz/K:'yV*Lǂ N%\ޥ6_w6^NhdN/O1At,RM,j-Tqc$f?boO)]lG-1oJ{|a1> &lr.CNS6+5e>cesw1e rZ~?txm/kӘɩ1,lgMZ3U *4^ }mb^#oC}ȓ}i]CӬK*OpO#IggSy iyMX!ޙY<{qM^+~M[b Y J^֡/tzD+/In@uXnC#'943@/Yr&^U7.z2oƅSqJA"bb>OgכߦaU&q=ĠOj2Z^PW!Y"sۖr h?0DZJpQ,ְ  KWh hv 7{'鿮El50CM3)6D , t:Yf7ߖ7 "@:d0Mt2-GӉ rԟ?'7IXN7˛izQ\ͨS4Y470d%QXd08z+*UhC,Aet^ƣ&Wz$o#h1$lxx,3N4觏eP&蚆JQtPr"Xҁ,('( { -ot>m:Y:#*(ao0R!je> `caΗ1Pt7=8yX'9?  FPk @i npR?[onl5 |96 F] |%hNo0RXGUjZ1*Eњ9Me hYdDTp0$Qi ^{WuA8,$8H2VhDv1-ϣA!TEid_ygW2 g2 K))\ (5M^=ԍo"(~Q>%bGǢ8(dʌ<&Wx9Ih*,C95rjvpZ2/)fXl)-Owev ۜ#9⸩%&VkB,JCVCMn{t`|z5t3[,E-Q9e+]_v]߃?xc'YѝR_שe<YJ =>Oz$e݇M>fQ\7 Ԍ,9. `J,u9+.NRG/6{ʹ$#WIaZ]v|qVQiD]IqTÊT%)u]i,V>X4Ȓ?qXVH%Vr7^oA-L{ȋ^s*1*9ӯ~J. ՑT Zt=;c`E:Ax#EiO%Z*²i;KHz8?ZP=*1 V_ YWں^p <|uaGg;>c'l@}ê'sW @:'a# c\.0#HW0J)+Y,&Mc;&??Zb)egzV8zU6$\3unh&rV+]D3@jlWx$۬pV4@Fu@K1J49ùR"J0K%KUگu\t7r,﵄;$ǁ{; >{Q|@*SsV.IJ3 z_hMFIhh냞d@?!e3-([d:P\ Lv{}|IV~4+Fz)0r$ey}@ CR/]^be)V!d=r tk졙*zvQ}m=,\l)EOe9<1%Cc2!$;-_ЁޣNĦUH 4MjH XAҌ.9ч|d并]sD 6D9Qa7 튮kZ2R}̜ ޱHՙPuym(#~<J|_[N蕻'hd $1&& ~g@8PS„s_j` +N ]b,8(ܞ5>ep@?z r4=̹V`dM9|P"ZƮ?chT@w6` 2)[wWqdȫV9J㵵;ܡˈ [Jq #KWT]2XHlWnv.$v}mv61#$v`?=^nC䄝^y젯bڙd#FPȣu3mVIZUۺRIy:Uw&z@nXeeJZ!8ZhR3`4A·^z Quf5?Lu֯}YrZ1Ⓔ~$~J78<ї.IM <)%^*q#/CW[GULRP\@Rv .L$?K\]R4!+"dݟ(2d9!IS3maN#KvӞE$I7ΑjIXV},OH/F^pn*C);!.P @Y[EL%2W  o@g4 {vqu3_?k]_Dg$HQ4솴 =+* -YYXtCSE&rd=Ր,%Pz| K4Wz}Mi$B ǫ *c$Iر–ZhaxjBi=sRB, qp˪@԰ )ZH:#Boq4;NΎ#]k@93ƫbOr` ݈?~Uc84b\<g.K+4:VC\t1x$8(6]W*A?)pqRpg>ag~v(:\5j6aXLZJ Yz w|dWnE=VY1lq`aWMx5d{- 2f6MO.R!As&-1RlE&|zHJ(`MU \f,;`[ٵīRWNNC$Ѐp,AS3P`!e '8@Ϯz1x2Ug{bn563=pHܴ:NSs~r+G2c% A$U]ҠQ˦oxj%ſf#05-^ov#G(ݤ1恊%~]!Ul#^t *t̓_Pk2 vT@N= bP*b-@ v!*㻍_- ] /VgjVGjyYM7wqٷVPJ}bǥq `BZ*S{t`S.-gW2z7, Yՠs=w"3Cc.}%4-[3F<3jMy2u``u4|jnjjIVtX[rCnN]u `"iEb)–.zO`QeCP=3aZOETO &ӓrrOK>UɁ$_Β&z-ID $E"85Sr2e-]rAJ3fʔ|-U\QQXR%*ju i@`k"[ga2- X#XrKp)0b4 .30 -PƲ#[>VelէZls-ՕH?`z9KC"h}v\Z!07G$P:"aʧE'$5F>멖Y 1"9rt$.#k9V;.FяrTj(Y(0I/< s{mqC 3̑c9.5@=VVC3i.,\~`3k8I*9@- 7 IdB ;r {:$CS?~UY IG Τ}U2I ~UKM-Ϋ\}3Ҏ]E1iuQ?$+Hf8A|޴#A,5? r+iKɐ hE1ɦ=,4"s\:UU !|ۣY4=@TxUq=-{D=ze/'^-&-Xh87O[n_cd[7gX~2` 8pdBWw[ZwC+Εmp'*:on$3q)=ҠO6仆AFw: :b_~eGfw?X~ٙN dlS]foZVִ۝:u#+Mkag Uo.:%;C'Tt,ce@AquOTS'yJϦݕ*3b9/ݫd~ޓcAZ6=BYB=)\٬Nˏӌ!Re,9U̲S2Dmc6bs̶*`Qc}Hju#@fW@ d,#9$\+ kͶБm{EԚkr)x cZn9jk w'j; =fLnjm Ϋ[ T<~c(;y@hDe|~F:Ut4 ӱZS d^ 7Uʻ |11Q]9%NktP"+ޢ@/R!~j5VFC ˙頏xŦ\͒FnjV}צJyjo@=5G壬Iu|SyRPS&èobN]VJtanow8y& dϳM[\$!Rl rT7 {,{}0d~Bjc& F{F%{ȋrvGriEw&ð)rJc>6oof3J4nďe9ƻSo|-u8K?-Ơ=}c͗r92&O{_.ۉ9í݈GY/5(|) ;"3JYci=>5 K?{ܥ3nMO.D^n ؙ{%fnHxaz}doV H&E!=\ty`!j@VleԃnرЗ3Ӷ%]! {wFH/UYj J< :Se'3wsfz0d휧Z#3ӑfjsҊ;Waf in|w^zZ+`iB:oQI<#3]l[Tn&domJ;>lըEd iL-q[6%m~^F|^Kx~N+O&FmKIs7l:lO<"t}2&:~qDWn!1Ќ", 2ܸH9Ő:vP0ב2DZ"ҋ]b ]H+vxžݱZG0 /!_@+^44*dy1YVmeyO *FwwwfSTpVƏƻ7o;{{cmL-ocn]N`va"\el(yuvkfJPK ^B+B!h4com/vldocking/swing/docking/AutoHideButtonPanel.html][s8~ORu֩\ffboɒ^N?N)x'){w% 5+)uWv6˸m9&~-hcJ}Z'|NN7_ ڦUY/Yl$W˾:nݴNPiBF "ܦA|n|4GKX t֝Fctz֝oPhaТtkざ`X07[QRcl=Xlk߶Y[lcCS,?u\+ݡ"xSa?3'OYZ۰,g}=YZ,{_) M!y B\B ݊K忄4Iipv"IM{XtYX̕~kW1 :c# eؾV s!~>,ZklH;PXjf;fI,Bx!}T˜Nm/[4x :=wQTo!A2Iz_ׄ$QZ!4#S$kI,3J6K1M&B8sDڲab"$IrBttќ*66gHZ*GVoQyWΔja[daYnTTSXP ܲ`_=,!)]St\cW>t~m涵:2u~xŰ:&)[(,1ђ ^ 8NhR#ϹmmA \צZ, *J\dO2dm>MO藥T~bR6ik.kMk%r;!/a>`:;N~M;Zij{VŻ;(\b؎z_g Bɯ3uc-Rqŵ5Q ĵ*c^6(CRFO8֦41F~(9>_8S#ZWh۬v91SGv&-U5Ca_ut?3N0N^[]mKOn[4@ۖ]%+1_MಿWuSyC᲻LBs7zB l۞aQMOZlk6P[d8t@ نX|HhS Rlr$3;Xs9۴@.\^GN\Ӣ|gP>X^i:!##\!mG, ;蹶+܇܁t* ' hA,J6>7OՓyt^(g18C^'`2l4&ӌe9!1[a`˛ o݅wp=Z%%w"ة[}nvciau}ͪǰq'J JE[YӨQا߇06"9J^mLla+V9.ogl/_uC X:7|x=Fl8A{Lg|ԻrWcC^txL2gm 0?xCsuzE, ux/&(l4nß<6MX߰8h1&l|VfieP蚆9KLP0F ]ɖ2Swk&V.cU5//φ.HAs0& 9 IjP,#:8f45q "8rj8-ИtTC28߆م&JNSfAt6qPm2ug8q3EgWWgxqTdKr-79ԣC\`" ^NZf~Tl{N3"+ç> k_^ S6OOs}k~j0տ>Mg@1mG2hZ E.I1k^{p-p1z AH%ʔ?Ǜۖy5]6y\{bSN;\G&8᫢+ 5YA}YTTP.ʚ~gW\w_-'^܍Hw__gSuI,`Ekxm}X5n 'Hxƍp`Az=OE7Z YX*|PͰi\kSHx٩OInZ Dn<{KCWbivjjob^T-b VO#2 _qνN>NA{ S BHXzpⱱ8av&60 j>z?A U#C) aG@|f y6%hɲËk2|"Q)r8y}J<Ai6DoJ0Ͼ᭬R m9,EcҴ~vǴq2Y]#Bbil]45s 0q-=0Y ]v[w+E,Aq(fIyS ʌBBh%C@Jk+W!5b}C `1FFV~ѐmJG򦡸nvB}e6KO1#F3EN(m-%!Nn5v}{5C0Sařxm*wIQ@O2㤶pL`!EN|mޡd%kk~הJ e6r؝L4oqr* P˼01W^H"}w˰HԃA|&1Tf<:葦$Y\a2㎦-+)b#F֚ݼ F3; cB}Kw^aȷV,a,$- ZWö؉6BXV܇y{lj g[Yc!/8H~q^c3~"CT voDK󌺶]^ r=ч5~ч6~7ˎ{G~[>뛞kP0MޢAePNְ^x\l) mۏ]NRr5|S8JזxE9fE׫e{;/ٹW&4J $@`D30-94 qW"Ӂ@5 > 2!o[wq`ȫ9>^[w9!_:( ~ %AY72s嶔KKI0=Ս$b,ml$ T a$c <agw>;nC]=; y +^xe,3LF,́$J 6+8 _,j`Hd,n.jA45ޚCӂ"3R].O)RA (ٝ3QokܻTc[X۶{[TL/.bxZk,(IGJ-E y$^j¾/V[qU}@9ɴD)U P$qғ<2mܥ[K+-A:aZB$(AS L/RJo+r%R苕 oZ97. hb5?)Rʦ{OGsŽ38(V5lL"2ٝU$ҟM2o^>#܅ c:TLi/c57 -}9B_յ+Np9$p9=3mX:PŃ/H3jl;WizFXU^J0j5 \ RuTu#QLI-݋p?߽0"<^ '}LP% syA#p<ߕkbM :I{jl-:#vw@@Psf0|ayOO!jZBז|F|Y:X^w_D4M{X迨K5%3XiGTm 8T{>T\I{5q;LYrboKpUɁ$dgIі$&"6S(M9Q %Refʔ~-U\vLRJ7-T:d2 O'.6J@`k"f]ga" X#XQrsXv;\ah"]g@ak xEFޗelJ{Fχ9u^0pPZch].X-SHcF#1ܨ'xPӢ nD z%GDX[9H5?  $\> if4ꗶ SeЃ'QisXv[< st(GKu3PGU -edG`BGpOR_ܩZmK$h&円A%r[i&Z|iIor|49]vSκ(V)t֝Xz/׳%ҫMե r}m<(c< Vj~Q&wL ;{ٖsOh.>#ۥ3}|S2ަì\dSc?Xlk S[ {,jRT3NQ${ضO0-Z>˛?PrDN7?-1Y߼jaZ:fj$u?zZذCC 1mTbfu5Sl=5/|ϗ ;55`wV8Wae~B(Au^ I^r]F!ˤmǘOuNz?^z@>zaԧ^oxA^^^/?v]7-Sv]Fou~8o''膼GNNx!xgI7B-~Ɩ;GcP<yb}A>|}|GUO}7Zdm;F_:+zOGԿԓcE|xcO :y'"İg(t0/e<,|.0@sEs,143%/'lZaoms6VX oVMc;5zolX*鞑}|~ =2ĆTԃn9`;@:e^@Rt2Ne1e0\sU]mK{7:Ko tf(2ygϟ2`o]ηwXSCƅq|UF#{[eEWˍ C:yۄ=aʼn.xq-8|ez7(Cq) {)vh|; =]2,n_yW]6BQOO'ClF:Cb9a'"&%Όgo=U@%(ܕ+j& )/(ߎ2փTe9JLA }׋/r `xtce_֝񨽫xyB !I%I7S8d. }tZ8CYuڔ{]~ hh(u!d[" ?tjʂwȊTCΜdfe?> C^SBυz?\B+=6Ouo=<^9}(3霅?_h?~{j ~ͩ!QnРJ͉UR_#QD$Q^KnUk-ĺdh%b*d?KrKC|ΞlS9T0z{MMU.Ne{#w;C2ԓЂ`?hEWLDqB`wd@ G4 fhz0g V1Ht8!5Sl<<+^Ak8$DwRԠ8l^鹿D`Bzpk{01n<̧hF0'vGach%m BPfa4Y21up07c/Kآ\"8&9p2Ԍnr}ݿ-=* vǢqpG!#b0cu!{*~U(b--R!q̛;w-=ꠚa,KEV % Vcipf 6f4Ƙ~[[(/hހÇFRV)u8\Nmi&ذIaKaο#04%~n};AY,7msӜ}iuKK*~jTļbckU`|4ZsJrIoeJQ?y-#onƷûo_o7s%EKa-@jy:-:`'6&hs_ЪV7T Fgfp%5dCE->)tb xq v˱@*q]{4"NIL=EsA3NlthhR(^yFI^,[Zܖޔ忺mćR#]ÏD}<Xnuur|z"F!DE]74*˫{*(&qi+ μ|lTxކ?Zjcj" ?NcwJ=oܿywtv;ƇKNd[np]m#(~6;*em6h}ؙu(ʼnd.~RG|/?6FnAɚ8fަ'Dw^VsࢲFܫ(͖ﶀgIV>?Σu]pG/;BgIzo'gNOa%?ǂxęţ}cř;45֟YނU#ЂlTvR]`gfdn ֋yda^ *OwgQ.!`hF}Zg"ٶol?c<.ՖA蝭$*Xl+IU$|g'>o.* oQlX6FX9xoƶ.bk{;t#r3#-ew2qꌔXPCwr' ADVy\9>J=h~OWf3O`YTR)}w̭>~ nKr&NA}?҆y?j{x%cUzbmcd▿+HGZ:ݬGatP5}ܡs*qˤ]? <\*aY$Ie79E8޸>]l<$3 ]wsaAwS`v* !yk/rąGr4#cê&fIm33)]V,=>Ó4&-GnUZٲ%Cj В%[«kĞ{g9<>%GG2MH*fc|-N D,/ר@XwSBjG'JUjHjoձI4 L ə>4S7>r&OŮ956HHYmc`o2vE7SK,Ȍa8; B}aSx6b=~<Δ +zI1%wH4-ʭެi>vǢ rYk@f ~7~ʝcioK 8-cdzt3 ?eR8Vf8CUbiFT׀bF|}G b ~Րm4V tQ.Qmߺ]k6 M9Fk -uh ;|SLz_x>C25krcoʔ`kJq#V%IPB|z+w8yLLw]okǬ .j{o)fřVx=ڦ+ި+@mj>n; |gXvBj1;ي Ч؃'2&K$))b%~) !_5̫kfQ3x5d&0R6p7`qħ4W<"BѬ+[q5#5v#[VRf6 [ HDx՝g͢{4Z6xJuf0@&c-w-9,`mO{.8 kٚk1jJmY],myizl]>[8ZE]p/Yi~!TBOkӘEA}n/1u^3&g9z.?*wt,5)N>sA_w:*~2Eq@mQ辡~ia]ӖH1F\RRg.,yX'-y7CnEwT_;{\;_ʱ89F*ʌ2s%fUڎPLD(bT+s]aV9 uzn?k[w!K&uÈjUA:(bލL]n҈$cxW7Ѽ,7`aXϲ,<`#MX~ٖ͌Q|!v FGq1ʤ]D[cq{P9./m]) I{W-cLQ_~S+o b//32 vTlp7#rl=3aĪE63!ږejL_` G"FgdWfpD_sYtFI%)LfɃa;v?jʒGMo)+<|sIUA26$Z\/bM뛐XrŖu0|JeO;3ma+H*~ ;Ul=Sl on[+bmD,񅆚;$G(B}~J^#KT'9 U27*$fa5 ^:8Ψ/1Ձ~՝!m9|%'yyAK Fݒq$Hfz,,,]|6wզ=Ր%H6 >)^*6(E"NQ "6Im]/_]b3i{[O mA+\Jk/8t>ŃsqJ(+CaUMp/ Z`uzI=N70Ȳ3"@jV]izhnt@5ܷMΟ F4s.jЉPFLgiD%aim5/</jy8AzS0ơf|/z3-FcR2. m.6?0,LݮȊ6=W <ԯ|e{Py"fo)pmx+۪̈́P&s?UrDb:rO7]> ^pD14ɧ:07$QJi5F0ˣ𵆙!Z.$27LY$a\o-(mXfi@dD{Raa s:VS}y ~ gVr CY^GÊj/0i ϠmIBIA9STQokܹTc[clymTN/P\WۊWw[n9xZbJ*,'PK1>Saoϼ Th@6]p!ǚxpxFmSnu,*/(7jl;|Y{M*mD'J:3*>Njflʣs07Σm 䙩#ZO_iƯBKdR y8?߽02=^ uTDt=_yLTڼH u!p"ߵkM :# SA{n n6MIB7 z}ީ0iM|g4Fi hr9X8zV00;j7NiwnpE@eؙ=B* NlDд$)-U 8]?rPTq7x8`#Ic:7(LMiL?N<( џfRD&A'}&>E:@W}4(.eЗ"i| }1efcfjZ:M6$><=~T c޺[ lt$(**tATPVсk~t6R8~q$d K"2Flg=4&+"cKZ0ct탌}AM:F遴&Hۇ(.4qp'K3F i~[ 0L}&I Zo#D<@f5UL `_Fz_[pp$%sv2+CeZ]x<(6_t(rFTIx'0w$J^+Z!kܐD+yDO%H Id+ON50-]r(-3Wsm m+X[}BS&t!eo3.aLeYaQ[_WPbWXejF62p6(Ly K1(^k0#[UelۇZgh^APr^ 8L钅!Ul sԱHf*H7Zt6O{%GR<Z,#k9V7\6%ũM!ͦQ-j)*gQisS+oha6stŎNWfL f_p^ L3pcfP+٩KEc_7Ie@wtwe#"iZ#^U?e$? =ӹFA߯k}]MsfۃY`W= #T+g9\dM0^\o6H9K|mDgxjM.}дHt4"[bp˞v9O[\p?\6̈́7t8c$uEOнZfXuhx5@??Qo~Am=H}% [ApPFr]?,G֛M  .5LH19!瘹5g,[c'+ A}?`lMˊn/: Cિ"oܺ1m](~Hj*MCY96(n|;03j( 7 r$ "rB"_$#Z=EwFuXeT1Udzw1ߥa-_(6szċS9q7Lr66rф6Yy_9Qν.'5NxFF )y; { 7iь@w7cyK4d3o=ў{Zt]uT=9@uĈx% 1 mR֟4kgI x .2.AaM.Gzz`Kwc[m5k6KIL!E3BLВZqG 6|h,?"ރe!6R1wEPtDb;Bsg]4rxMF -x5MH|ҵ#x"Mf= X;ԘUaIFWRKNWp歴\ /Rjc{,#YFvL*UƖth=E(l۽ u!Qs`gZoQ=TqŮWl,ۇQ `FdC>vGO!l".NL2/bR0 םout¨̒4$|g&0C!:^᭚=1#6")QvVqw-#x+Y h2HrJJCNab8[%+#a6: D}Z ;[=3y KyKɺEhNy-lgjrJ; k@U4U]p#aT"1VCA$h]P=l??|u'|7aF`PhsNNSĠGq\yhqŗB fxXא03 0r7ޜ{hv9'( *ZVf ʻ2Uɚ el.(Fւ b+d~/V҇gI91 &w d_.:D9 /ܕ.G(0# 0sDWk܋1x(J`iؑpX'[Ϸaֱ=gɿx4TF b$?Y`)EpTle&aTJjU2,׎Gj c 9J; vCn ڱx&2RZ" aa:Qf`Z"#oU\DD{$L}* -9QcVѭHuec'0.;2e+ ٢W:%O&hПQzoc}4t:F7/;x?^b?6=:y(O=aOt}|?0 <Qz"sJzXPdœnRw+.gJ^NfV ۲iHY1n$Q 9.m#Ni,o d/oӲ,鞑}|q63a氫8כnu3RW{WO.xmc8o_)ę9[ƅqn<GHgsy9c+EYF!jvmHqDe}ۖ՜ A 1 wA8B| thã ]x(ۑu\,ۿrFtq *ܗS>Gowɟ@ii1ʑ. n~阃_yq'ƃZ(ѳÍ"~[B߿?+jSK'u!;"`u9H^@:s] PK ^B'~ C:com/vldocking/swing/docking/AutoHidePolicy.ExpandMode.htmloHw^iHG&z^QB{Zb7 !0tS{o{fE>t//w bU ivkt@QH|)F؎;{r_;<=YW*f+zH#8pU-9>^:,d #1Lɡ7*/Ð%'oޜD]rtpxlp@rVe!UwlczHE3rO耍_9@0IISYčBBY][$aj 9LIq +%{+Em;ٶ0WVMo&A,gA#UCn* #mDl;򏁨:`2HJ*{?z-4 ʞUTUqM5~ w/x{; A{? %H>sp2UMM~%۹"wA\NFq>SG[(61ӴLA\<$NIQ6N [Hr5ު`4̰U+ʏ)KuT wۄ,-ڎn7)ͤL|ҐakIMOi&IiԸܐf['$SNX.֪-r!+nz%kyigC:|TMfb!ϒ_et+6Go¡q&8X8gTlz.E #ݧ.ð 6jkxs.}#G=BSV9b%?՗ Pw'ODMާt2= Pxz>ur<8ŕL "xDyoŞ=Adf!l܈PnFV)E=OCуVH`%+/Wd!6K{0@xK*7__*D*&Ⱥ'D0I>I)Ag`QJإI"αװlPr{?<]ݚ0(T%itڐe g$̹8zCVsyRdi̱HOUR&yL=z:נ񮺆 {ͣ# >nMiD QӖKUҥBY+,гjil* WY)@1Das"9g{ $D9$~,n5 }:4]Af̒]R%#CVft-fJtLɕΤ&!)xp_p@j1v2> n-,dgԊ/AUm&vKۈrpu| ˈu|jO*mV~~zzb>b^2޺_v;a87M$oGul3*( *_U0LEf;O!?`ئa`h?eɦo϶ 7m KW~Y|Zd{ $2"+%t s(>J1'%|\.~%'Ň {%Pl`GCiP_HݽӒ4B=l`v2yҁ=>|ǹ M:R `K}>QDc ' O΂{P5tPp],f3|(h(g>MKT!$f{JwE8X0:]ގJ*8y30D1TUo~]k_\t}|)Ui TsvGy=S[.K`)oܙ;;w JO1l ,h9F<9[1 !݅|m9翧ǿue^$e4}NZU83o^Bܷ⾽u7%w% G^f&FyN)T>ۈ1hd J\8%8w$G+K\<'j 5 HTia`94 ePK ^BU+/com/vldocking/swing/docking/AutoHidePolicy.html]msJYRd;쭓0] ({Jt,$V&E@8'i鞞OAKuAc ?-T?߷dٍkتn!˝~U Vھ,{!+#y鮌dò,iVi}sZ v.0R WI,ye?a۪54ݡgUfmGHW_.|.D7?hV{ޖn47kxhl_zmk to+'^nPsؽY-®L(RhS,Ŧ[6jWB{`Q8cj+6+$-A[W2%,{ZڎufväJ?U kIaI75u0EwjP۠ͺko_.Pj?.Y6tToV笘(+߾eJ>VYӟYtiN hzgml4mV& 0Js=RCo~k@ q@ֺ><]T'p݇0dc|?"p>oc2mDžΉctMpAf;8+ƘVcR4b<4Tൻ{Klk`M| W7áBRt ZφSv͓zZ5jb!ZVOET$ @uQ083'yēY(ܬ0cb0@xwT{aaU'I9-O#SH7I&7Q39iiL9i#mcc`nժ _HWA?EKt\`ZLa,}b6i8TU0>fa7gs?0x %1ޛ>Uo -zOlY&R6]V# } !(Ӎ405Z|={x ):0o? V9vSizbC"KlWJ#ŏ.olz@&g5@n.9{OO)' 񿎬uZ@&sy0 XLx-=Wg 8B?J^og"r).(nkDx1bKڎ GULh_vH"Щ5]dI aĔA쉇- 0$"gOAIB `, XIK[mRV)txa[%w~W6{5x2wSi.`QMUY ~@Sa9Oqٮ0$a rھB+yN"qꚻd닥d~ǮMƃ#_FT> ݹo~)Oa![jf 8Zw{o@kPvC1=t۝` =#mS({ARrj FU3k>AG^o3(O5 i[\t'5sĤ=vAY'{Hpigqwh̓w糥k/b!k .PU%X5I\*v09ڶ,ߣT$ i^3J bK "YG.ы$c#>` TFh6{I]W QJkݍm:4-5bwɇ ' /ly)ywBB/[O %Zݐv *@H驈x=ci&2ġJ'"qs 5"W}&{@rB2$Gw(|7^DNNmO9O!Z&S$z?r嬉/We$B̟;p"syR"6 P /`SmV=xihP/f-9ٮdw)+^K"XV{Up9%偙WsƑIPJC𜑲讓l *28$u){# XlN~wPLǝIX$Sgr^D<޲Uodhp_n*M_*Jsl75G(R>,uU_}GZ}Y/wΓE{31n>t4mC5j^S}nbhx& g{ObΞJ!T z+EiXpB㳃rm6T<, 9jdkyh覆T%T\bc]kZ اB$#Wyߴ3+[&r5SL&,Q|ŎjCRL\k]iܓAIa} H5rVA/cgT֜ȡ45{,p׀, "v^$ N^r¦+'&v]܅>"4k[.X+J_rܝ%MwnxR†5-21*0+>x#㝉r%OYP.@OIW|tckS/:y;nkxn@/cT${NT;sEv.P ^,nbcfN]sh6ivA̒',' .tΏ6=C$ȓHOT!ߚo (-GIeȹr@MRT|)3>h9]CSn9{l"ogQʨIHfi_lDhg5QgƫH6g͖F&ZلXIYuQ!'JA 3 6AtriI"1jz"F31˚-gP̿A:7UXvx炣DhIU ,]\som/!i}-h*85Y[# `㴉d>27/k%딣ZKXFC6{zrLHOQEkʒDVd4(7t TFOh nѐi<`O߷W20$pCqʨ~?NO1.Ԫe=kDue >:E[y Qrж2W3qpyD 5NҷZBC1 O{szar43Q4h 1npwUN.4f$1ޘ\7XUahM,|U-viB_LߗlK `fs~xi:b+]٠!\/FR()Ś+xCսΐ.̙)= N{I, w0-q)(n қQE(IJ:( y)|.…+GK.;wX 5Y M} %"t_)h*io]o&>bl̉Dב]a; P;,0{6i h VQY1tLDz4)>OCB}nRcNxVYzg |rҹk6ꭅ۵I l"ћb m{z@EiN( lc(eAd|Fg2vh*[@ ļD%kdLGSPeG IiK T N#x|5H@kx'P r<,, T0O~PS,5t`c^#AٜtQ,9 76xlF"5=mI>\)MZprt֝:lLV3eUz}S0\`YfWg34e9dKnLQ@Yz#u\&ў'7n7#Y`md(K҂!%\ 21W*,RE6zV])M0{^{\? @m=%Ų154Ao%i9J(,yZB&4u8aDh0Y/-!ĥ0QZ󴜍jkpEGe'W[=X+*%#;ǧ)|:?:GǏ?>͟2=5O4c[e Wy,{znKG OeVM}38cŽMq<]S;,jmRsg;T5ʸ״ɔASGxӂ..#?Ou;?܀,|=g<<|~g;\|&>,{zuB#0TWn`xNv@(X~qA w }8+d`n1I.i&309̳f>]5"TqݡCϠ\(ڹ čȁ>Js I@a @0iotQ\K.?+yU PXc"/h.s;O$o8i4!Dz=Wjn~\p띝To_ İ&jv=ȟW^y%g{%[?/./# ީ_&Fe}| !Z_{?j{,non?=CAȆXsF KX K8K5au7PK ^BCխY y91com/vldocking/swing/docking/CompoundDockable.html[o8TKqiE~ h%H~3$eΣDq?{(uE1|ӓ68unG;w݄R(,sRM&wFɍ׽j(^m쿮O. zFh,i:="MGis倚HWt`Aq]/v rаfE~"bUdMb2NjG D}FzsiaW>z1t\*.^.^)>FW΂R*Cu(Kod8qS{>+maيhqPONwzw%>O:q )+kМe #0 ^&yk,Yd! 9F…hBUw[=(p/&* p%sY1~A\^E{)a4嬉nWKitJɶ Yj.'~mMĠjIY+3wuZv1RNSe/H*m@Z _VuL()c*ιe3‡y:cWQrm>p=H껟LiRӛV]"6kVCJp |>[ T)MV9>?TZ8?/mڧt'|FRtZKbfwZm0y2K^syhW1iD7I7rx Dl*3uAH-,W"F;Ilv&9b&q P Mk*Sn~ڀ=#̦A:Bkb &B a0F˔87܅dwXc.1s6=N &[/OAE$ĘC{ԃ";b 2Tw"P TB 3۪&κ9 hvU-&-\2' CGa5'wY022أ{T)e*(u!ݹEj͏sdd+rIӓɯAM $V$#7wj%LhnΧ ~l.C̠ (´LJow#Hn\hd2exvsVﶠai [0Ċd'nRTzV(ۄ=Ѯx:!Kj^M8,Z6]dVgaQMn'QA/i_fHHY4I-}0DpBJ-J tJCq7{YBVhm\Y՗v :_Քypz2>K]}j,9I@:u :5_=> [ *[@+dr8Y+fYW[ ǡAʄvK쬲 .BËb-Ь0 Q^7{jj$)`uD2U ~?9bF3,UvˊF둛U m ?Œ}-Du*kL3TDT|eFa%Y -GRՄ狣9}ζ]е;eDmw^X3r3G-r~9rϙRR-3ϊ/݋H"Qg_NxP|?6刺Ӆ W/_QUOZT/i Q<6BkO}4wu? OE 0lJ.c^, W\b%}-//Hs$^PK ^B}sw"d5com/vldocking/swing/docking/CompoundDockingPanel.html]s8JՍSKyfbm)=ьm$9ٹ/.J,)KPVt^H >ZަRIWQ9 ;g-l̖-l=NoAgX -}8k۝.u[9&d KhF>8kQTm+ # tй%-2nF ;tuzk+tvN߾BPg\6J)ϊ~x(OcW.D I f ^[̧ǎH,X=: ɴ7nu˧8@sb%G^aH&X"ΗxQ%#0_[\ϵ4Q>QZwFyKz$xs֫oۢ5#Zp Ϛ?QoD1,Ye5Ý,Y2X?Kƞڜ:05 z[lP""Kxei1NY;V𘎲Lh>qNWGVa3|hk U]2D\nVE[h'̳%WcǏHW-R6Z;AύExqaf ykǬH|)Zf˿ǼQHYW\S)W@DWw̓}Gq҅N}qT)g毵XМ.EO|~K{`>JvQdq«æ32۲ns-Ϫ5%~`ᢴ.uq4d(cW˝1,xbƭ]X]b7 ;QtCU*hL[EXExK=uyp41okt>[R{G{%6!qZ b&-Y!$!ԞpdlB`z=SW7AoCg/1~k c`+))]N/'Qꏵ[E=yn[t{@olX :bj|=Qwwšc\V7zf[5p6ZW;b(D !DV m$FTݘ>It7ajgy)flFlp^Rb=X{[1 lЉϿa&ٺ]b|GݦKTq{ר|#'+> ь)qޖ 0α*+F ^UڙVa9c)XqN@}Xs̈Cm*N䳗4j җkv㮷9dʜsf 9ڬlak3wv$1l|ROF5M\j7k 5Eb$rA, 0bc,g @>Qtu_0UbR2mEjN,&(XrJ EW\%];cfXq@#bn[j(xM>DKҘ#$Ps1a4A_+eiN*2 r- O__;+䂳LAh ,Yh:1>Lz5Oϸ2-R xWJZAzEOדɚ5NdiiHV)$||Jlr7n:t[qOU=2agUK+]}`z[AFx% AFwӻ7G xML |p]d9ꯟϯzt4]]ft}~=5in`2霍k:0(˻1=u ux/i4z_<6MX2hq>.4M4i IA|.2E4Q ܪn'vMMT$[L)|M0ޗOqQ% QK0OOy>Ɔ % ċqDYFtpP? iSniNF>$u8~6D)iʬy!>LǷ}>w:?<;׿JfiZhF}g7-4ǎYMy\>8FbECg"s,wwknI?!:9vzkT)˝3ryԓ9+`h,ej>~r>uMvv`"ď+K8m\"ϤC\I+3 =BJbaX}f9|Ītf5)4Yiw kv*/G9[ΒgsINrI=/<͒cvPx?.˒ek{2ܹ%4KBh8[2ƶM>iO;7ca\B,${E'J[\\Pc "eb"^TGTHn [_qdtW|TqrĽ%e 3 ހ::]_1ف~ŽYr$ CM=(L2HIz(.1vʕHa.VifҠ YAӰK<)v-x9ގf &(w'*2_Id,d޼(rjJ܅ c>ULiRL_n|jF |Xq*Np9&Xsg͈C MdmfD_8-P {R FM2pz`"8(!z kd=gӰq*tH{X_d7A U,$ i hr;P8Q=ZSWoμǸ$АpP3P`.e 8@ήz1 2EdZ-AE@F5q+߉8@50.MwO0ħHͥaսCMC_ʠ"x46D`J&M[$oM's#*bepK`c-5# 恪 SUy;&ct̓4_f'Pk:qET@GL!I1)U1bn`H@ wD!(zIF0ct̓ݠfZIR@PCM\e 6M<ɒ;cPj}ǾI `$#hF*oE`W3zUFz[.B8et8(p Ivz Po`9@WeE<yȰG`@}m9/D]%3HzT\IxG'0w$p-5N$%;KcIv@Rl3Ҕ)+ h R[fLRɵs+X}BC&t |p"`T DF&bep*r܀Em ~]N05.7eF&"epvXt<`dkC_Ʀ.>Ԧg|y!*Pbc<2B.3>]Z!(HdPQGvpyMI&HQx(|W#9@H|fA~D؏{#p@KSC!͌Q,}ʿ z,:*-y #0GYtnuhd5 •Oz#Q>We`PK)%pDrH&Qw@U#5\K4-~W˿@A`7qΤ}U]M Ȱ|0+ &y+oAQ0KH &J`Oz9wvOTͧ1`-'VTE ¶\ iE&BY $&Bf--ӢYd. bkKQ@*|pXE§ma&,QEbpTIh=' wu><^A*9ڨ]b'\)ERWX 4yHX'\\jJMizH-y%FW n2!At{2,ǡdCԕgT\vUjt?rƽ;,\̶>v[> nj_Ȕ9MDTQ"ԛ:*> Ii>.sX-*՝`z~gU;nȪ@S#iH^4>YG5+:&J?.qk%U_h}MGe%~ۭRp, Xy:CzK SŻ B @htjh 8yɩl(z\Ⱥ*~9G9d1O.QFEfx$P$>*9`i2BU t5_,O-;c4JW3^ڼ?^54rW{D^}J +T,"Vv*1E|6q #6G>zCלJk}uWkqREm/b R0-C7hDy"CO$Æ['щ`5žG7v4Tʪd ]UF |R7:}fDaB8X.۵-$dEE&٫82.P7AoCn,=L{Hi4u˧%A@WclZ3˿S4%̗xaM'+>#ʱi[9 #ҕO/ٮh%+ڀ_oA."/UE-d3@&v:+S Y9$p,u8ЏޅwM7_ mTy >*v4D#ւ6•b zwD6VE-1"\x/!CH+B=#c5V8sv[A#ל׾B޽y7oߣKnKkm;qHHˠ 6i^O"Q{+6PK ^B xT@com/vldocking/swing/docking/DefaultDockableContainerFactory.html\[o8~Q\Y4=pd$by hҢFfwE7[[1Ԗs>NJ'?;_קC]|qBVq]{p&W #)1Я{Lj|<:j5:沂@)!E#S| 8jJnhK^.Ɯ8 $p"""ĴײىHWy5*40]аf}nΘgĕJ\ EcG{i}uD(d3|bF bN؊m~ Rjy:"Ȃߨ2?жPC~+H͒,7J>揨 ;H&eqy\BYFW@eofٌ=jHvF/oC҅tu86)%sor\`cz.&2OVNwR>8/#Iվ HkXhȮ?}+`n)!|ye|;G2č 7'+B s,_E]G=%aݐyiK{Υ49>)R+!Z:X:0c:D)g>]@%!T}q..j7{MT/ dK"kֳ sD.;< (YIYTa6Ac!MKfI8c|Ёޗ>;8UGRN:@m:{,% *.Hښޔ먌^{q׫%7"9k_6qS.$c~{h}Xw&8Ɯ[~zr)H/ڍpܧLj 㲅ӯ;R1|KQ/ry1BGC B7}܈@"6c2F)d<>$!q! 5f"ݘ&.%iEaqeb5.NӶqݏ͛R B&❭, LndEpzGوr G'~RS s$:Ț 0J6ZzQ`ޘoO{تlwUظ)$^]'wsgz&fBqТ1ūU|r)wcLB[.ď/Qzl;; PMÒc=(أ(\ yIMVi2i㪢'gˊbD}#H(:mA|`jik[q'b^WsI}-{|UI94S: S'J&89 [rP6B*:UVWYOκftzu`3ŶNQ S}·vi&f#͢ 7GoJ]鵣4Ƒ4T"HONk=m+>%JzbLR&f9sN\l<)'z>mJ{2\>?}LٝiS7~1U̹MPlıަ䂚dJiz<)Zt6іҠcHdL}` (}G'wzeGL6*|U< =&7?h[wD1;<͌ 0V%ps_$J/#q\ I˪Wf41&wW7Þ:t|u:y_1Miw:Qhyzzj?}hCg>Cv]V`.ύz8?gWSm:-gȴgFYboܙ4v'x]oAeb{?xYV]Q`.=gow<׾AOh|hm7AGl(G.ZE2 'hR_ 6v -mD-#{2@_ΒnwO֌];a,\k@eͪI\m]J;+v&k6+ }9C>mϋߢ?6..w Z3}*hvþHdIu:U:,긇]BE 11,L̅Muw;aJe"g_u?_u]MBh= [1w ӿ#56$Yd|Ew<5 NYoqI@*~n($EEH5<`S̥=hG[l7߷Y/l]eC,_}2vu5m&\nڡ2 P iGۜc[M<Ӊ@Sf'>R"UuDGeWC9&1lj1x3dAܴ+bi.غhQO<玻bI]ڶh u/hlľ^Y|H«3 tqA/FC_ym:yEtL}ڿ *JRH3CǛEUf&_΂x?ei+j*]YF\gUv_&lȶrxPUj3 /]<10b1t>v-}Ck6l+ 'Y!$!ԥpdkBTj0gOaջfF;S/6E~+=͙Yo]Q}8g$a+ OѹWN!21K7%JYGTbMN O=jetغ3^-ɩzb ]E3 [1UA"g[(Uv;3jMLo. uN@}Kگ ^`NWk;ƒ]#rli"77kOGva0PFNCc@eG($eю/VgIa"Sb"5¾>9Xd>jc6:jh_ n a#dtmKqZHUS(8_eȞsZ^+QЙh;\SJZ`QK h0r7NK 8l+*~[N+  Bɯ!bX'ĆE̦\5`;Xz 5(z*K 69`TڷJ +JUI`;4h˼v9O1Sav&-Ѥ5Ca_uQyedS%"B'Whm[]Ᏻ\mW+,ys}m5::߸zz8U9;?@g^X(c6 `),DRaRa*(W) [k-l6=t(y|=}8ctW+$+3A"Z1sc'XJs>χo_MC b[ n\G}o<Hd9/7w7(n'`4yn`2ɒK:0è/QEqWt\h],j4VGB~=,qjO+ljȒ.ȵ\Oe9<1%C,}E[x;̹v_ў>$)KTJ(6~pX꧿CHV+H`+01%'o(ܵ@hrF0xvE5%wS0nT] EPlL e/1A>ozkT!-G%(z,7ҧYaw,̴*5X}>j0N@T0E7]&_NpC.xB3~Xb 2 COʛ06( qŞgښ̕\` YEC>,osU=z{#_u[߅lPߚ_f5*+PhS-{ѵA[> < |hM8euI_1=blDܑ#ĨO3bhQ?d1sk, prt7aoE ` +μB{uW< Em%j> 7{#.şLDzK,@d*_"P[|V`d&M9|Pz2`+XkT@{yOwau}s;& #&}wK5]$E$5 ķ2h.iJF[1%t%A wjNC*(ް} r簁abRhau>ZYE<ǺkqZSD;E%: ϦY [Vi!ze+!p``M nxq5-9u@yOO@*w 0W>+wF(u, vx)0G85G8uG8c=M5f(- ;,WX#GP98 \J +owf;?t0 -̭ˎI"9V 3k8J1r̊2-v:CM'%.N2 TJ8 #؁]5 T2]q! o@g q|efΧ/٩^ P Ē]ⴱ$+n{sqB-5X-=Er{}{Tpn*r8‘]|Dug" ̔VX8~qǰWw:葸,)jnHk Y\В%ʼnKo]^ϳ}UȵuWCG]]u.M_[%֣@llLk&^_]`V4ؽ1X譄'IŽ\7J/&8@ڿpNȓVӋe)e3[VN UHBbt g7-H *Ю$=l?-ܵz =qm,[p=h񸿉K&tv#1M#ų j\Ch5EG@񪒕U5~iOŒCMox 8.FcV01 Va6]ngE>27 v2D,$8N4KM-Ps?|@`8r_7径YPAU\2Q|,3MF,́$J2/4,j`Hd,o.jI45yޚSBӂ";RCv'ň> srw'oJˉVX$ʊE9u:8 ;,pְ ]b3 j+),g2٩>[QQ Fx6㾭f"Lqsū[ ꍧ\۳GgT4="q'N즖(1J1>ar(1-rx@ xIDzr'T#ziz~ED%DJ 40GEC e}Tbțj ƔU4 kFᆮR=f SهN( }sBR$V&=XE"m8EK;R.d8PѥbB}]jˁ#$x#>p] ]p)+ݑ虞608:Pai|5UZ,וϤbFxz-WAT۫00%VAʣi+xTFb d"Dx&7/)|ˆz= BE$k䟗,C,v-T ]G4x>[B:N1:M=5F ]kX>qu<#p}jbd"-:q70vDN-N 6#]A7b jZds~%l& 9]. UC>8T?LZxcPvLb*P@YwrjW*WNG$АpAS3P`.e '8@bO^ jߡLM(MLZ 87-) e&'ܹF XFGٻ$<:1Qj+\^K>d45O_-C£ylCt&ӵMCSw)<"R!¼q9*FN8l8Q5g{Qk6;Sl/8~r$d@#RUCuG\x"Ql ~XO}jTAM:P遴H{).$qpgk3F igSI҂VH==K4Z?jMv%w^ewUY'$.[北i^J,vIAϦoءC1/оPh 􀁨 5g+NG-8TsU}[KJ2rz蚯KkMOKtɴ|+D#AŵFګET`oH0fU>U["J$xKv4;ڒHH8f=SN"kT.HLJ2)VⶶT JLf"EFO5.YFuGKu9%tR`ī;]+Md (LyrKvye+szzi֍aBB`U\^G/xdxthVG#U4@e9Z~5-:y F<"Ywb!qC~Dx-jk\> if6/mLAQeЃ(Tn ZaB:]j VFVC3/,\xkD%2čPK)a@7BG!ޱ7e}(Hnd:əJ0 2+G/7#ٵ]Z֥"j۷jiS)'cBؚ*@ ͢\aBf| Ydk{n f,ix%( P~c ؞̢,<;ਊOвGԣ,cpxP`bc9^x4OzMtSZawxg2Ʈ.ӂ>ctF[i=%_@v=d%ftc>Si.(-Gva㥘}FnwFtW(WHbuDeHJ>vg.!LnO~R?*j>btn?hZ,ة:\-ަVpv2j.;BǏyژ?e]&&::˴ *.0yD/G+VEXm鄚"=v֞a{~ˉGF ,Mm5d̀q6Cm)tDhvpI:$$B4Um)P;oXɊƏB>mwڇVQ\atvA:CETC8ᷮmEfx0kwӝ͌~w5yc6N|>5FWݩ{^/ p7#s̆s0{q+ODm>;(սkۢ3!H'K{=6?m~qlIːnm5. Z Q6b_C,_?1FxuFr..h%6)fqm쩶Y"W-MxZÿ *JRH;i酌 oaTś d+vBWM~Y  :R #;LM"TbZrdjݫb GD+67vt͋tsA7_JRMO[9Yp:5 W^Xa6z0홹>q_ג^`}wx߾``S[:am0s1eOcxզDxµ 0PK ^B-k l11com/vldocking/swing/docking/DockDropReceiver.html[oH4CG)yj2 奄~5v1n_ 60 !>D#_˞W'_Os_N<=I(Db;t ,=dN\!^ QދP i}l%\!fFh,9!gA1'p2@ 1 1 ÞmCes;ýۃݽ+¿JpGH _i,JIyƑg!$8(H2d-4wGHMcB3i+3~yRZzٮ9[քB;}L[2J2iRuڤ75hXc7J~5Tqle2jAs5k/e7=UGC753V3A4n[5b֞\B_=h2* ?unzp zWpzܹ)Zt cQl+qo8>1eiƔo]6Kgq$5@PH,^mI檘gHe3>3s0hq'MFLN]:Nk<\D"eܥUftqQIc&Oxp W2,/?&W&9{s&JiƨH;݄>HMv]o0qe}2/w *k|Vb!y80S,Htn3!qe(H\D z;j*BL%3A4x-~{<&OR鋉x>pOSƅme19YѾTF$.RY1\}[<_LĀYpwhf yXJf[0 JӘYP_#CǠhPG3bj,-wu@v11"+ADNJo6 /-hsː5Nҏ%T\r okoú0yP(o68 } V7d*WI  Ax9WEbbqz٭N/f Fy<99B@kmBBYjs~%0isXv,2tLtMtI1 p"KDF22SIgԜ{;-Ze)lA@$cI۝D3*i[T,2ڍ L,"p8 HH(G N1blc r@ 4%vKjNs5eJ"t0EyP4gI1LtCԀͶ5c~ 9nĕ,A]0ǂ $plPD݊\KǪB_J74kFfI;AE.'ߜ3L9E4MDUl:de;ȅ.CCR\)Uɺ5$U^i*d)~QBCj>&&"`Ѧ[Xu"9|v5)PZlxJW ]A:+lj>gF"QdH0}a_/'zDdmdDpHf|pRLnppZ8`<̳ sƣ8P?*%V: q8<)+c!ʴ y:g!=LPqOvN'GixoG̓.$4\q yx%9?U ~HR1GKhX0b7#ǍBLrx_sbHoǸD*\`; SBKs a/_l掳qCCL\;ua5YO :uiZ@䈅asnݿ1t$"T˜݁Y݋,X0I#ZvZ6 C }u,`C#QX.(ubV*}1X'!ۉ8*U)-QWqhiQ #VU?E䔂#Pe5{p&V*]E* gNBf&oެYHp8هahY9z ưN16I`!`s[:&0>fVFBC:.[JV6+Vb̽d6ǂ:3 ^43 0DrcdHGA=eS#[Ot/\U0 `I#耹ʨ,5*h SN(|eA.y>[Nϯ9,50y" Z{%x]5H2.i)J[sPY$kPJ4.ί;W:WӉRT2Ϭ\Mw&6b_/i#CDl:;0ip\Y7oF( @ K4H?C+/>ձ٨bq YeYQ8 VZMLuOD" ͒\C;sO 4S-$CCHBa/Lz`lh5K)D\TZ%s_!7\M. t@ Nm2ĀmF!.SQQaRJ%h{jJɷ}Ir-T!絩Liםfi=RR}/<4L̊Pgj:~k}>n x3;xJi>x>7=dWg LPmb%ڥJ-)pW:2e"vN Zo*W<v%j!B1sB$$! NzB>3q0H"м[/};dka@O/}brе(nfy]φ"k7nir]nYm@ϮiUa+!:UN䳋h㨿|P)¶l,P-24n Ua麤V .K ZwggJh D>rk/,N.[RuQG]<Wqפ.:Xme֍t1jg벓|R`"H+ -?SWڊ\ʖ4k8Ϟkޥv=7HG`JJ󷅶iaĸ~ <% |ڀ.DC|I$hQ~޾g-KRUGu Xok<HllBd`T%U<߽+CОE sB.fv8Sh75ir>u@UNebVtl_gg}) UTL{֥7c^x;+/:k1 İ9Q+|8@~vos_)8/9v _ :O9yCU7UJ)B֧ᑈ'ʆ}և 6'?PdogmC/24pxG:JZy$b"? XS~Q.PK ^B  (com/vldocking/swing/docking/DockKey.html]ms㸑*,3ZJilώ5DbL IɣMӍHѐMzk#Q~h4ߝ^ >#/'v=~!B'r|rݳiMh}||<}wxӝF3!ؑwv\k랒v[ĵ^z)lOԣQVҲ1_ ɛtt@˭,~i-kRȞY8r,7xU-{w~^8 :]P(sQe܄@_B.ҡp1YcտY](bn`J]z!VpB] 㼺EHI/!-#' (oc*l:Hҧ*uaӶ\W>U N;o>WXwXe.ֵ8gݥkq &FqAӐS%! n։*:8[^L% ^tI~ޔQ:F#j_[5F%B:06c7CeN"+0p%tgXıu%/}-\ ؽ`=]J0) 6'0{=xdz6v` j`|տuCZ{T)3)c[ *n}{oTpICPT2&Sġ}'T6 hKMcd1 )V}_,Nrl={;(,Z=)n9ӧg@ C-C$X 3J?O`?@Q!{$}7r 5)fNGG`ǰN4gǩ3Q_RTr .`*>S’CMa-;{P~96_ce]#hI7؃vmm+pBmKXQ+ˇsd éEB"5g}fs @Vn;KAq9+Ro Ωɩt-BtINt@0 e3zGB P2ZN8ƾ*zG02{"ه$x {XhsN| u_Dd@jde]6| Eq03}笍gݔ!fLM W.WLLsҝ[6 zǿ2hҚ!C&e&R4 L@5 ebJ/g8EUPg҄YŔ;xu?h0l|UN~܍V#:M"Y+d 9>3$f #`)Sm 8ZS|˽on > >\S'dN}fԲBJ-}F=a-"6[y'xx3B Wn ԓ۴Dg9vpsYdyzuW,Æ@I56J[}[_~I$:2$WaJόq3^g-R%~5&Evz[>XT̜_:,gU՘Gu4nKrW'ṦO$+ױ%E1I Ký#U\b_RO YKFjY- &}7wǺ{}woNciB|UׯR9Gu7JӝXA ( # ?P U| }l;*oyĵ5$;\?1AUpwbPNєO6*n$$3!}ir 9-C<G!B4gʡ *" Wmv &O|afT"ME\䫈:uF)*ةM`$K{08dhNẓ,re|(|JxU MR 9mxHw:%db ~y.u(uמ4ZQ%AEC#φiq&&;v7NNSB|"£|ڟ"?}D1f֘>¥pG5'ax&Վ-Z@9#~N@5ugۼ'Fi"Сx OpX2QO000\Z&u7,+V/g0>vu Obd'^Z7^ty]i/"u!5(reČ_.a5mGT$%Si~1)6Yp(j$M_M?ta!ل5' rMBxFVPn鼎R)GX2;Jkй1,v 8>[kݶʎt.⻦izYeTE(Rix/D,A=RJ^8B*׽Rq+s:b>4[Y`c0Dĩ.le` 8xuM'ӳ &_ߨs?hUZ~qh(T5R$|ɨ)eJ#"dWIKI=0)iSO2 h2u 'P2J~ހMOu57y kOCeT©Mp j8v\٥>+\5|k%v1KX e,S*gb'X?DS⌬CӼ8/]]θKm&׎Jl"|<Z0_xxKY)$if(CN9l°`37 ;Mw۷Й;06y8rMֳgv4V[2F8 《-c=?BœJNUiZ:X|cALM Z cMq @"דNt.ěŲ1/koP<4#=5ObΧ]:,L{s 8UYۣ"4YEgDyZ8\X?Ysj$8Q6&ʗsn< kPcCŪK5w{+i' kvf5y1}Uzp~`%DRN Eq\1T[4vI3Lۘy߂OrGIxRþ,U~-Y%Gse%: /Ucdā0nB,]q#(ل2Yf1[n ]sP5p BۥrM"^ͤAZ^\ [gqݻ 1 BeP.Sa P77K$.xJ"?F. :[FΜں2lJM9%؂#2;[\X * IJN33AZ!}PH[JrӪnVq'b; SYz_G $r&ۯ*U4XZW5Vu(i~3&TDR|w2dWxM\V؁ݾа͝p|)Lk,sů3%8 ]7,XMq[M1m~@ i,h1^Idbä(kK ,myȥQ jj0Y8@!nuy( P( J^t}Ph IgT=bg)o0t&BQ`U΂=r|'F666bE¶(_en$hiv/ڃѝzFh*RFb4q47[[=2񠧊39{avgQu}xJRJxu%,(jd)?{|ϙx8Ax.\{'{TxX93 ֥Ҽ@`), -R -BܚkR bsV&qڲX$PWrRv=ɫ-U% B_O7qB%e+i+9]77 ^GRP3 IJ &YR>jM{F 7?U⼺] d] kͬئXTVgUî؊R}~4VUo{9h7d/"^{qop9WU*9/5ȝ PY!'a-2쨚ADd4ֽ\7Fʾ8eq_:PAE v`SULUGNvJИT UkxD*VNm5e^8*8ib+$/LRBVUlM'x_7!pQ9 )&`u`TM>?ŲWk\}$'[r:HJ4}r; Wgr9h㮝ȟ]ZK4Z7Pc~>8D-.{fxsZ8T7@16eSq+BQ/ҡp1Y?/·1_qU-0i5R`'uP` >Ϋ8jgXZ/!-#' Xuv|(Rk9~RpJyT( Ŋg.ֵXdėq9&6]窤.)tι_[^=D0G)2Tt "Duql]Kd v8vfixxEL =xEgg. 8pVsv )?95]`3:|RaunwGșjγ^t@z0Z#oM1Ҫe=ߣJnWhpׅǹ [q -%pI+k2=M0˝P/7JXj Gfѵ2CZӚkO-w(Z yF)$-Z|pҡgN-;zg M&/֓eSrDœ}wG%۳1eY̟>ɄڷG+|x"ɏwHCOP :d{!“qW.x$I/.esJ _@oaoX:;t]/3ǜq/ol8Pe$vN ; 3#?պXplm8;a@Gh͓0X 9~DGK+AP~7_zEz*~<x#ì z-2 gFT;'d4ߍc.Uj Sb j_XOPyQ[{ yD,|M4,yOP;2gNB0r#@s0.&.B*aMU2zϓCj.P>z@ak3TiH uQ>.?^1K+,3PDzz2S-.T>V;ѱ庒W!Swy I}*Yoj+Vĩ==oXR٦:q-1eSv7b-> VMrL^)BYzUMdV@a6NVVe$ϣT('Pa+78'uﺢf ˗]m܂2$+QOH<.ŏ_.G|qf|ra-ͼ. 3Kz:/Ő/C]FzG҂Nf\U?7a˿2XQ8ޜ>B< &;/a_`܉wMA3@Uk5J+A[MC?Ha50JZLw]U m^m#EEMӎ9JDߜOi~2\G#rI4 g4䇯1ÝzHuX̘(I*ܓPݑ}4gr{T.ӗݿtߡg=kz 'S1;3 i̚Rx)Ȥs ~1b;7K0i^ >ucEܞ i/[BBx@0 4L{@K5f5-i7>T\LQ-|BvX/*d?]mޜXNsޒڀa䯂)m(Y/:OͪHSP]v]੡r8W96yMU[CJW`A\"a9~TԷ5SÜ:K/5b KΘg#/[^ȚKi~r:nI)7{te@OLQ'ދ@= DfouLΌ88^1Ɯ}CMMOXOV' Ow̤<s)Yg=8 ά < Yb 7p{#B"w >_hFBLjP\\_z z׿?_~C{EZM&Bxd+*N| mRwS7N嚞؏L|p7O>} j~S}和 !6XJ7t)>__~z H轊76Q:AHJ> 0%^lQ$ۨS2n {q-LC2Rh`i~hiJ|[j_{@˭5O0*JN߽93 o5lI[\~5Xctidee%z-F]P;`:Q+z-wÏٌ$^C Yn uuqIKm,"i(OYv]|+GQ|MλR]Z`P;u;.?養![p?"l?`%SoMERnzٝ(A.#r{>aMo̻ @>)LTp<%̱y ,Ph{ baw}1}$d_~(&;d~v7 psudPolQ~VD%DQ \皵]kb|/WKliaY/AST8^-L C@?phI; BF{rݷS}t(.ib辫ꄇFSJnM2]%՟:Bվ´*,.f#r >T`/ZZzl1$'23?>em-#Z-ϝ!س9µbe7: M|:t0r#Xɞ%6˭ p*!mWSV4\VZAO:G܆oBJS:VJgx8[t 6GlсrL`|sv~qys~v?ޜ]/7: M38wË󈣸ޜYߍ܌$KF/Ἄzys68WucҀ؅(ևxx}߿Z`@zu~13Mmw?2Cmm )]1ͺ*YfUJYPfK0?Қm}]fܿAPyu?Y$1B}Sn` 7mx7 Y_D*S8oο\?tPF40 @N` hYpKBenILyјn|9ЛD40`}=Ar7u|%ncTG5Qsc>^)aE Әxq׿>Q19+NTۻ-Zs Ḿ k}Df˳JP%MÛ`"Khi1ja6yx0i.w,~0g"1>? 3 +;'QhqD]jyٟҊ+ߓ3_.=?ĉ)5x26|:'dhcUo0Rހ_K9j$I#ړ{\]{Bl>y x][.o'ʼC~D)gn {P.ni >H''߇3nzwOu![_Nwѣ+7u f i2+p QpXj6" 4Tu20ٰear^}4pk9- ɹXpVꎖ}!`ASξ2pB6JS>9k{z.}i B9vM1^BC 4Mxyv섈ojLê^=k3Ga*Leg^U}.h5Yf_w`_Uv>n0!蜄/< E*W%rfb'L.qe6B#8roH<-M3%–R% yM+QeWGZlH.b2y ɴ>H%((2l"Ds9E?D($}o!L[QmR@~6է"[FqHzUzcyxhMtbڊ7;zjY!7aB|`7:}х9ST[B^dĘ0z5i= 1_]Kd%n]9PȺHᝆJQܫz/l_P{"Dw+ND"NCYq _1*Cq4eH@2064n.j`F:b}O^168`W/ϤOo_]Ÿ3mkҐ(x:Mp^/1{QcRh`]Z#D4*F¦@p1 XW#컚 mc`P4xPh`e팔v}Jg;`9{ VfϊTWxz0)R#[g ѓwm LmhC-7 MGfE!m9mRMn-Xvۢ ߹`E;m;`Mm}'VK1xVnA~m3Y7|+!ji[!uGTmQBlB Sn!7,5ޅ+ѩY6dfuLfBbu׶̌ Ń>P_[ߜj15Zǫ65\=W^Ɛ |hͫvӃ)DԮ>)jCԎENS}?kbpruYP91!ralVqlY-鮄vyF L,dy[c7O_ z|$[-@9+c>P :v8ɩ !(5?-jf74&j‹L`tؙMZ+f_J<iJRՌ<זg=5t%Clpic9[L! Lsq!1#íx ӛE= ʺYcGw_*Mk흸Z] /Q\6ViM]b6<)-@6‹9 H&łx ۉ q# {ډ A 6-m)M%q Z4iiQܜ+}~;z)N1sA8%Y@ZP989+ڬ-0ii+%״0>lK$VT`B@̂O|+Ilk?)H1+[\"x^-/.Ŝ|u9ٿ(3  ^Y;\1 Q;PF؃(``w}AZgKW83Mܬ1^[ ![Kԍ(٘A$wtk83R+ad˰KK#cT7Ѥ,4`v>?X*s@3FfX~$2na(RwBţ8ᏺmyY)eU_ǵS=Jꎠ%|Wv}A 2q5$y]Ax.sk'0˅+S2rQm35&>&.9o8`% !ϟƮ;9҇3/;ͲGsDԒh>Uz窘s,}δfOғI]ؐT2<]2&ͲgMӧ #bk"cY5d7>sbO2i c0_IlW+^sfYDīߜ{s h{ #k9ivέVe( Չ:1QMt /_IG$0h}ݮ*b6KWt ksł%K1K].ݗXef!YY[,y܈VK/mSWی3jSׁVU&[;44"6%7 j^)f8n;& 3*Iᡭ =@éar&): {>YcYhvM-ܭnc-/[m]UkO#bA[:njö; NӴaijFZԬE'WFVVe}м^n4qyރr^'^h7b*&8\'U;DF%B4€Z 1+ʃ}ianƒ8-4Ӄ lV3*L'y@auɳ%̖*lz+3W Ց!27Y~\I UXh Jʿ u1p<յoSW7?32į{ AJnfીU\V3SӵmCS3tsyy2B|rx +FNux,RMN>PU 2>3-]G@TRt'S8|$d F["R!6 p} ^9_- A*WVg$}6n%>KPJǾq Z_Q #}DdW211M.g3%$.{mQk{R5{uPsPf4y zh 42A33Gm.ح|mF^F@u on5t uQy?xlP5^cvAaPVOګETðH0SVSFOܐDZ"i_%IH I -'~LEEnrH ,)TYJ¡ -U~B.͛klՕ`Fm+lFS֖fX-+)`bWZejFmd+lP-+-Šx[nWVٶ%rv/.fޭԺg3G"`MB C˽b X9 1 C@봲 x,1D## ܸ4Ӣ$-\_ބT"G"HJ=ND77cXYz^#UrSh E"dv-6U1 dvy~^tp 0lOX8؞,|ʞX㨪OЌ haUex}[ <XX1+2nn#&q^#oSi <5+3s|-ׅl "Ű)貎ɶ>Q#Wg|ܿRPOMgu{\.-rߊZ$`Sb]> ?e@1+~Omzp&=j*&Ms@H!%^W^pvUFǶ~K|j7Qqӄ,[VE`9^-hȊ }wcB PU!B,}KG?+Ȏ޸U0qM@eҪHhMt`3Աд?;ᜄqem3Ob#r%.UAR6UE)Z- VH-F%:kF᫧IKZ2ތw]62ScЇl4u%[*[m4T3&3mPbT6Ӱ`XkTb򵱞̩1վKϦ͠_F;ljle=I|5JuG EqG5c$u"&?P$d= }pG['Mw(*r@P: Knۡ nkRfW/k'ߑVT[=yTo; b%X}1k6>w8(XMMmM4.֧ KUO?[PƗ>Sx?/ڧXU Jd׃[@O.`4I9Gć_Wu"H_Wy4rڭҷvD$Qǁu4pNsJH 4yG:8hAwJ [+St+,"(` *bh>,O'1kAh PW؀nFq]r@aK7kDψL)v}KxYlV02A"3()NqCj8~r,nSy]~v`S=z[&Pt" ʛeiy蜎(%}>h6;HB3vI e>"/[')x&+DžT8XY] W"N[qv-K: d*oBOi{fBus'` 焭q@c"ѝ\#2Eõs.n @/n{ wұR5zY_%| +t+Ξ*,^Leɕ!U[vDdxjk> ,7WĚeg!SuqWX9Xa3h^q EӤ -Y@ @AdmAټp?#991x #LN+L=99%m C]"#\{vrg&ԋVF .X.1ɡGte] `vB+ǡc ;F.@?25opx\7*M٬-aSn\%zfNU Rnpzp 1nMyISKtdbs02*5k,rvhL)6;u[F ' 2̹Pq0wbv;tb'T0b5JH=~ېQ&+T2t+8uYz 2{)+n'K42+F>tLcwA7){6e_ewʟ cp F(޳}뒦/l?4+*;mRw9R{Uk`|3/}0bb@e aϳmg/]A/A6Vu:-ڳRޙvcul`.}8AsQ _Q9lH=6;4%: sZf"NɌy]i^^WBY> plʪhk)?fOj@c+-ruF~UoMȵkLp<Z{&n4'>jR1ld0ʼnnٻdݬ\ޓcE`8IKnEy:;N)?(;HTbub1gJ< LᆧEAe$)Q+̰ J ]K ިil8F#b~]ca{S/(ı!gW ? 4yJkp23u(1iDK2=|}(*"SGfڙתV1-(\.ZM&J5JI qͿy>1P8nϜ(P\n9dw+*+?B0tY a.$[a H|+wKb+Hd,ƒyd:`Sk,@Y%\Ro 9$.Gy1q8MIzRx OEF#n7Yߏ*u?'Ahxs* J9F;dEEĥHU" 0 +)o XZ4Cu+`_0:U|ft0cXZ6 ; ,~Zwt[RlE ]CtJVU&\M 5a],CGʷ}"e* (gko`r]0JrUsMdxI璼W*0IGPıO:1eyW&rBt3,QsuEBJ-&/$|Y_ j`*!9]$'8^[  ǗK\!#gv a''T&#wYn$wBĄs_փ]!2f:xqD7Wn$n4+Ќ7?xBi>{KG#4z]SH*GȐZRӋv1HcVu)ޭtjؚF5HKŋ4'OA,EshjU4UJ˨2]`u=sxǁ0w$W̭ xe0v[r~ОPK ^BH)*Ө)com/vldocking/swing/docking/DockView.html]ms88Ʃ$3{w}XD3(H.An$A @REOF?p|2)<8'W7G'w0|d0N⋟oߑihỷ߳Gz( > ǟ~x7^y>};{G?}rI;J ",ee dDb=X?'4dP=y۷|MĊȯk#yᔼ'YWD.=/}$_oǻ#g~xO~'W<hdl@#sߋ8xGu{RǢ'%QDOPF[43#ː.{ sƃUfzHdU'? $߶p+09f.=, XY P_d2=ORc~~pi=@ŽY3+I6W Is`' | 'dWT\1P9wXsT!/Ŧ#z뀭W++|ck95OD OVxB]5=Ey5X$FS6 B:GKrBJa >p,ו#\pIF U忤R+z3:ƹ<?OSk6vWA ܪ0s} Ԙ`ŇW!} *-Nԋch[y & jwqbI"l 7Ŷ^dT؇=Paۜ+18V'uuEk/5\uHN8diO]~z%_YC!o0Uf0GދV|*2"bak?7cGX۸ oIC,B%bW.>N0:u[iA?c5Jp`'a5l-} yvo6<6֊BB-`L^CTXib!k9&1M:{B/O]Ʉ wBǔ͙kwD'pc ^/q/8Ix!cysaZP>?]h ^` x:.}ܔ0k kNq Qg_M y $6R04(D MMz 6 i$7!4|iYSS-mbl*x掇2s?È[U !Xvc]Ƶvv %ݔ靭>#7atNfxT>5LK[kv9pfYx0Ÿ}C arl zuW`?ݰ\Gr|]SP5sfDOco KX%3ⱶDoR>{0 oS8L(%.?${XJDR9)B!s#ԛˍKS&pooS,O;_Jqj,ӓkS ,v0;'փs2 _p;#8^YѲwTrυtEW3*Ȉ89n5J-BeKQ?pS6?g΋a3`fhxOOc'i5t"[ _j_Yr FY6;3KU* v:? 6x@\;&0\OFۓp4/u@@d:ݞOn&r#܌$kF/%U~]_oph;ܤW5[içt:=>ryQm y@O@]=?=ր%uP躆9_ډaLBJd˙);ȾoɀUĨ9 ?]&HNciLA|FS 2z|uz=6hJhd\c2s@Ϛ(9MmLAf /NoiTTWT9hvR|ٷ?VO(ABىx"}DOIxC>sU;}U,H|by^E|_D))K-{7mfu^M7+ːq2KUqIK"VT4#>kFպPB*oTEnw[XN~|`rJlvk&U4 T&|R+6מͶZJ @0m'֝PE|@c )3e (8壆#wMuREo)ͽ=H2x:\=k\m+#5:2]kV@^玕s8jԿj \vs7a4]|.cwlB:Z;_>몧٭ Yo.o`#YqX9ХQl.Sw'wɡQ9!FHO _ti=< MECqGhk @ļIj}%,EOYdqߋ!٤ZǿݪsRw(4Yڿ85jjKooj 4Ru-ε݀ǃ>/jͫ)vBԃ-OC'xᢘ5mhA,jz[V0ƙ|eeK:rm;Qu VEN/Fo"md?f :W`*1®12vsjfMJcS) & hmT"*bm/7U8^bIO2C.>`%t*bBH\#nvjь}c0 j#H6ݩV<=>4&-^ɍO}$,%!f /Fo'ƟjYɓS Im>і4[ Ij Cg~}{q<_]XJi )68>Ԅ4?j;Vsə><SHwSZChy xwj7tW jò91)t%027ކ2ט7ؙ!.KhKgtBD[ŠCPB5lg>Sn% a?o 78C:k4^.~sP56H2#+>h6Uy.jӫ\BqO[ʯ1b6Pw:WXiBk GB{ OO-v/52%[O [Ss!kOkyɢH)bb G֢Y"EmP3~o3ج8:w жFo h,SCc`?[X, 櫓'PЧVh Pʘ,EISS SR(Mf2A_;ZjT5Z3>x5d&0:lAۺ5Om91y(3]u%uHS"f乐`+9b3xǁ׵SBwBS%lpe4ޱU6͢he]̂,⩣5Z磽V0:xbWUZhنy12Ǧnxu'KǵC=eI8Zr|Yy~;!z[;!lҘyEǮ^`c r;14kch8mиq%~O<ꛏ5)fnP0E ~oHrrspij;t q+F[?F&<}VhGORbVt_؛GXK k1'_ TJsH\P*3 [;B11 Qy8PQ wK#+xc&9 y&7+QvM"%3䮂n t&P8L}tv)`iD}Lf`f3 IaٻmfJgw!VP\_02<ǃQ/XtV5y+&cCU֝AKA=ٯ#>)$մB8#&f zZ4d /ՙ MƤQWڧ%c`Cʄ22|PyM]r= Kb$7˟ &xd;ƌe-7{ULRTRƆ5풹4i?2\exu3#f(39Tu0|ҐmS'w˜?WlW/{!ĚCbgYr6~s͵%eje20O0AF_T! /j56w+4xI6LQ[&0}]mq~İ7=/Z"4lD#-B$_zU\BKb;ns|8Ĭ];EjHVVA璅t3 >%ޠ*5VzT}s]@R+ *֓vV“$]C[8qu5@`p lzq=sRDYK í }S*lК3#dLqiU&;#Vڭ78@ wYp_3v`]nB'j@pSqizYwEXZ1cA񢑕Uuד[ f8`WT} Ux ݈1x6 ])52?]v>mZi/y_qg*|P2iIpkx+͗ lV*TguUC+%̖*lyC+/ ~#KsC9:fq)XeM"{t5$L\%5t-Ҝ7y"^o09I[}y ~JMVVeG+,~: pE27JkXb]îL2J뙆<$UZ4;Okܚ?֨l/ָ=%85M˭[:b۳"Uf[ڀHjRK 1>;4ILbZ0)5̠H'7eBKܤ7 oQ  D|%DҔԭd苔7%%V2%ʐw-ՌT Ut k Oktgt@9nC. GʼnX3u"j[@(/H3jV4_6ޓ05\t^%5SYh9Uytz4{f)a<!oR{8^q=䃾M/TDHzeTJn u p> ߦ:I:# sA{ZI9@_4y|̲kK~i|efcfZұu6ϟ]N辈T0\a ;-5G2[ сuR?l/2pչhojJ\/ҿӘCT(z-G?`*t݃TޠۜYRP끴fHy).y^2ۦbG# @'%S`#++^E-u&Gr@2S:H#./ IN%ߣRaQ=j͖9 qʳ%NO"\23)&Ec-S(5֡ǸNȗT3)Z"9!S5-Dz4 Y8|ف*r}łj7.,7k2D<}7"LDf5*8z/GY(SVN<=.?2~@\9vKvGRw({1IcNhLo7A$3_SUVإ)m7W3 n{%My(^'l3p0+: dͅa3o1ҏS>kmz zQ6/I E̳ʧ3>pG$*Z.lP Yw0AM>д#0M {h _k{stܜp2}%aѨZBz#_sEȣ㺸$/lZ'Rto=G>ΎVkuvD,{2= > %px׮(R>x;S r (v,tc" <jZElFm_QjZ߁=N ^zL]gǖ %hn`%Zӊ3ejc۽gfkǵ1iaansu]rG (pGnLnI9iA)ߺsDIrGN`E. _F,yJp<<=΄uY ;9/"Rh6[s='M|ԍriS|H*p7> dg&K.3(V8푸!0puDfs*=cFh40&+=Eo'ޑPKd䕷K F{ F#y2'JGz-L: |LNeLH"LnVM.0BqsmZ<}9cvnj#'Ǔ OI>K)O&)4N˧k)G0znWEt+vqM+` u{;5. d\.ZSClZYP)K+:J, FQ]Y" h uwV1rbm %lKan]PZs~_uػG0RZl+O6K!})ݴxebD:hBR=r^ 9}h|<:G>"8WӒo|ȹ:`mOǜ>ApU16$A|PK ^BG!%۠8com/vldocking/swing/docking/DockViewAsTab.TabHeader.html][s8~ORT\f9%KD3dg_\YP$h/FHM&n| 4n|p:Xz32>.ۋz zb?}X\Fل{||>z}o1m­C8 6Y<ҞHvk.mx`qovoD 3 y3CDuotQDDn=/ ϲrXЊSo`tA=U7OItɣL9qIMnԴP%)] R],vvc.'7"Qc&@|JTЈ5tBLb)RQjs=" A̴2T47E8+ym;:f;y w6X3Ja'qے^XLH*pDc lE;Kޒ1Лiπ{o=:eM9;|~^@:@ym Y.I^i)t ۇӵlޗÌĊ $b£1k"Rh p~{}ݟ*eKw2rXKQXC!Sw䯼L+)!A|@6樬W $]p[؋h×&PBuuSyE*([j s4g'ʍQVfp,%J/4@W2Eu&-EKYcZ395҆L[J\¾:I!J8C /| }b^`3Sg97ұPYSjL=.ǣanFRwRvDf!Z{qwQtv0 %`Fu u[:gQ@ݢqwuzPZ@ClUTyֿ, i6`~[b0!No*sMSa*Sv+ p.SbƤ݌e 1❭qgC` Ghx7Nx:QY@?nzyw9d4QOrI䬌^ЁY}Oʈs;+:b}.uf ժ TFhtrdY%'ʺA8{+CQFQT&c,BYuX!M˲iشw=Y 3AmҖ$k wL7 20w\EM$kuΣ@)bB%ei&\(WYe.M.M. K&8N8?B+ω]u#aUA0ɫ.|0'fTzL3: i\̆͟_)k?}dE&<^HK|gddx =#'˽a?V4X㰜腩@=Vmغ(U 5c1, w+MGZ\HG5OZCObv\Iƨ2A[s|aR\ XCj}% "Z~4ӂ!:n ´!7R4WbCMf2W_80>]l eA +z:2iYQ66e=D 7sˋUK @2~@u XUť dE9Fi +og:>έ`h=>ߕqz|x^?JTVv u6nwV{MmB='?ܚ%PlmRm*sv.蓏up}'Ѓ USk5ax\݀ژky XUEo!R]R}!i{!-GBB8 $SIIGq:& s$˯tdꄻ)T*!$u܅Π+f'Վ8\%AʎXQt ju5rqtTM@} =oLbFo5&ók1E"-rV;oh!H]U9mtިQb7}rA7~ ,:fF:՝ ŌP|FRћA%)0*!z1w5rwN9`]ngXUH!Z#5iT0ksª,5K q-TwA-*T`;uNqW)qCBXDSǡP?ڤ.5CQn8,g 9&cU洣zĥ-)nѧkmdΧB]} - ysvǝ+/f$Z]3J'E x#Ɠ" ~ û'SXV<+!7 cXq:Ѳ鮄ֿ"D ph1f= 3 _(g&Kљu^J `2r#@$϶nq2* Pۢ0dW^DCoG4b^,5 +J<_)JRFk5IZ ]v aho0^Biߟ:B602ܘ&U'yzX&ZS"^تRiZ3D -Z]'ӱ6i!fkn3`` ÝWa 6cmz |~R=七8nEorA2Y~G!cOG!h@u,#٦ EǠA@ǠI~A{N]+SP0;HOI҂A'5-0ih+%Zkߴ%DSk:*2*;DߗXS'[[mƟ$Qeq[XhA-{'OL ijPV0ǓW5$QPl9P؃(`[qꌜ x~&uQ#GC^a(Lڝ|c2`A*pDndc)u{ cV5h vb)b+ә9Ri@ef}U,% P~Yn*߈%piIϫmsʶZȱIdV>@1LZ;4"ivH3_9Q`ˁ́L RKX*N# AuSZYc@ K;KxcS wۘze5`׾k*paDL9"xWYƊ8خ/ݭKfseeeeFfu_9crD0ӤP{|.ރ]:Fc^1! fjp]. 4dn d:#1NR>$P<ᔡY2qRDIQF6{~)q@%ɔD+) P$ČzPI֒II@T&B꣒)J(1x¤!\bۖjorYJV2ޒt)}b.1 T ;$y91hhT1I[)K8OcSp1K͑};¾l-, ;p,YjS{"ŨmԈӪ/r:tZu/PU 2jƾc] ՗m5uDb* GW' #mhD  գ0pю:D}W&|DL}ҕ?ř&Q"mjUY7@ i'Qz(A}G%p_О [6:UɢAG K^{(yصgR}ڽrԪ>zk^A`jWaz<6BC{\t6gT!8HPQGq*$E%n$8I ėH`jA~T؏Znh %zqdj(4_TguЃ:U܅/0øNcuZrVC1/,\x+pD‰ øEP{T M&25QwFr i|_ 'أ.}׺]MSȰIg0k x7%qť]X)9K`OzrTvͧ1LG pȖEɟm9ѴHTE4"ۘx3WsdM\/{\=Q §=ULpX4=ʋਪЊ{ԃO@_QjдQEz3|1,3c8ZWGu+ŤVq= Ik Yڨ Il s%D<`2(%4?~豤hP؇MDͦhq:VDͪ'kJ*fRx[\OB>T얎/fpɤ?ccjƃ':!d&=,Q9" l+Ϸm{,3v{TLz't+d|Yz)s&(VB lpcc3o34L"L ˖ 2J0 ͹ؠ`kQ Mh'4W+/F"EϵXT9la9L^pYxc:ź&M${E+p}cE:Hڳ9ъJk{tB:?B 5^rU MOFݘQ1ꊧ'eTF*˻s>ci iӆl |:>>iDQV8aU{@On5=WxkW7Iߣ &^473DVyd+Yb0@BirXҘ=z&8zLn㟒%>G|ML_ UPOSց 7z0Du FT12_.EۍRL1tzgAճ]ˀX \V*&gV*a[g5wyYV ѩiBËPz>1½O*g<[RD~0H1`x ~lG^dz3RHЗY]dKLInb8@t "Kz~˘1f@V97@E^ Q)*DȺ1 LF0<Ȉ CGP 3D^cj fMLwe6|=|3AԄv4dHKEt(dʏZF9Eñh4V4W~T`7ݒp>=45޾~oWc<ؘ[ mkP311C,% ҳjYPK ^BT).com/vldocking/swing/docking/DockViewAsTab.html]s8pJmRKIfv6lؖ˒D˜"ew5$> ;3SƯƫ/W]OPI7 ă?ID$;"V?zAxכ\]7r;G?/?^9w;-9avݿaN]4}B9ЛR(}{Ep1v"G>|}|GYVD" tLћ/Y,cޣQjSOGÎ :h+| #= wءѓ㨃PF[ԛQA;n/_vK>mθfO_: *RY3#^!/9Һ.]m4'BPQz-o h^&;ë^OGO e? 풇_@PL=`iExHiw_hEH0h~ی+689+NZv^s˗]2$sֻ/iO=~? 7އ@!L8y]sVEuwދ(.K>VHs>"jlc~WJW3>n9[鮙Sm0'sS3vYDЦֳ(S~b- ~v74qHH* W/&-/6x\Db}sz9$ttrѠ?҂f/5a>s'pcΛ|Z' 9cAw)PAn_M- gxý D]̋(g/7gb 1u BܙacRQ+e<;Ǩw,W)& - 9$C"|c_7Ԅ$ Ir|5, YU -1_CeXJ$-\).bO;SIﻂaćJ `?M ], j!NV#VP%@0X]&|*7vpƞ,a)CM aƮr 릺 W`$8V#ajWTԷ3vMɔx$zU xߺKy&<cDOs: >rX\8Ȓvs'&H>y!_W!>Z rW<2}VsjUJ? (O=f'kGj5, P&@9_~S{V~B89)PB+iu ]yءAlA4"Љ-a'E%[Dh/`PT9O1 ``&plas'Y,yG (wNxsC5c/$=h*5TJˉG)O=~C8G>^ \b_ޥ^l {ruxM[,<ONr`|sqѿ{vtC$w+wGd\+H.}x17?;4 B4Þr\5֌_sⰓWżCl/ H'x+&#ga8YVJ9Q$m?f@H@3g[`г.r\tb  Ǵ=Yvp$dYfbdC jKa{ DÌ ybTRc=n<4Lo`)ygszI4!Y#Z/X0P 'tl, l߭Jd\XcFbTˈ bqf^Pj2 4-5Sb!idea.a.^c 3cpHPෳos#x,@ydMEva6y6<=lL233EG?ԊN)9ԲSIYN!M!k S9?quGf:?LkҒP, tӴ:bu/;Zgo  g:d=\:GY6{UF@r]h+eN 6aOJЯh{qn"G|Ah64<~9%0D-x`"6BF6]9Ȼg9ȹE'G߽u\caFX1+j)3vVߡgteq~l4UN" č'7'0j{nĢ$}S 9e&(˞PP6wNáu{3} ڭ7ndpQ TNU77V3^~[?tyџlѢ&rtr-L-۸gyG{;qnVoʣJooo*%!Cp/vY0] ~:4ĵT?S_~L05 '͹cdm[{u(Y^'9kТkB 4ܯgiT"pPM#;vGPZE!v"UjDkG!kʹׂ˾ +f8`W}#I_Gb9e!ulZ0ݨR).,J1t"b7*nS^NE9>%jN{]g31 V4QFS'XHi IƠ5a6s;W߁:66r:N9( K& ilAQ6qXT]'="s7! ẗtbm<@cC +k7*6rت߾d1\hsB/A HPH6Vw]AĻ R=o$X̭Y(,~n#{JnѵqJ]Msa d/ 鸆qþ(R#ǎ.U  cN(Ǘ';!%"ESvr.XF 5t*.{:^I@3#7wՃۿ _5w/ ?n Zz?{z *r&η@}34y3l eB )mc\w*Ѕc;zg /s mJ:V`fHN!g9B: ϫ960UQ2^CZƊn{\F2%s̜ƵҺ3%'hC+lY-LYEI~5KV岶$OwHn*5sgE1f-!> ÌCm)x%2j|na%,aZnp|bB8+b &;^M15G@Ř8Yq!t=e](N}Thw1Kar s>cSVhm%~u)%p,G1|6d]i]`M2IckK~$n%Ѩ-!GjL;<&AZ1KBK8A$= KSKS-C6033xmӊ*P{@ l/WaNDC8!<15YB̻>P⛌ۍd7ZT5ݵ:Sx d60ҏsv45-b>t֕t-CIڑ ޭ`+b;xG+kALe a$Rx Bќ?c.`cG+ BbIo($`U1 j't{MC#bU簰vbMA6ЮX֌C<16 @vË;Y =m;xڕUzۋ I%Tڋ aV {^x58Юs tm6CQ$:H^?Uzp|P|">*;*6+ojKژk[mC%݊`]5[m`C8#4pBW5ԖCntT_{ W2xm'%/Ş|URZIP(;.3+v-ĸkND"ˁ@=qWUFغ79XBpV2dcU0pLg8ͺI R.9,H9P]lVsP-}2TKPⷩ߅طfCn-xU≱ViakU.fRl2$QYe5ʜ:"^W0e_ AqDHEA(cI<:Xe"f7ZFv q#VCm}/g˩~f[_Kb$7͞ ~RI G~86iՎQe~\vK]ؒT2<_&MGf뛐C݌=EҜ#O{jyf,|HB${&'*㷷 KVڊX+5#*(B~G*8Je/d:G κ_(}L`Zb La3Vfgm+zOyD.W^KVX[@z,,,fyVSbEfr=5% *fKgZ9Q.E P dBKǫ *S.wV“$mCMjH3lNtNȽVӋ&JƠ3 ) s^a&XA Gq MvV :?wQp_;R[pxX]nd8qh1)e\$uueCk .<kyYQy{=yyS0uRP7ӟ=_ R#TFc\26 ,=.³?x0,L.ϊ6B, }_Tdfӓ8aؖDC~3:êui} 8 SohY2Q|-7MD$: fq0SD"$\%--"eeo Ef2b<`a svu'QSsy,/̬*˞fX4YJE\& Zd8,W xIx|mîdk)).g*پ{XQFe{N&Lqȯ -[3:`N+# lj "qY$H҂ px/5# xrx(8ɝzP9Rn[W\XK##A: ="FBhIS b.NoK rio-Ք;T! hlg%̟RK%螰kqw48|0QvZE!I~'TxDbeHd,3o_>Cb 1L3U뙑m7K9jָgLG" KxfX_sЕ4Fm<=Rݫv`*S*^Gۨ$#Zӧ&(.Ϥy8?/^ݬ?SQut9 sT5 n$jiS8"pIЅFgdfcCD@'4 \EFS: 0@S;e B͙فd RV9ꁾh$%\ }mwqn=ctsEB68SR%5]1i#w`vA¡u!^9aPq'"*Na$L*_+>U%$Jv4cIRRKRdlsIީ&S^kU.)a2eKe`I4*Wcc2m M%4BFκvnkiEm!]A vk;]a)vk:W;b.EaZkWXEZnWTr/c[ޯԦgB;Gb`uB-C5˽b e% K@Բ x41R"#)ܤ,b&5G>祝y lH%|rk3V~P-Gnzl KSm!ͦQ-j)*Qis+nast*G+u3P@a.\~4;7k * ܨc}1Jvj"x4׭@2w61־U [VAVNhKoͪ'$9l\Jcpq^H{F˨1 .B6R>NP6wcX;z UE9'bv| ]d .N]d~ .AaU/j `- *kUZ v<fE]ru1aˇbK <;DXn+2nUFB#D횶9*`W57Ou)Ŷ%_'6 CC?t6<=?sV[R`iū  xҪׁ$sb|U[(:K<ҚRl%ԇ^lUX5hD"CSDVW$@+9͘nF~|?b}Cbv,ޟ3 f> (VBRr++>mE 3ʊ"RLVYQ%VdQ ! Uƒ PCv9Ysm`jwGLg!Y1/WD YGW "ƫB% 0;/Kw]]?Ѵa}Yz]ʉ%=0FGV[ѾBsŠXZbŮ?-ѕB+3jS:ൺ8L3?99ޣu"u(׏<5]N:-"d_1ޭ S-974 }{vK\8RAb$R7[XbJ` B²XqԹp #S;&&|H$8QS|¹c{-(`Vx0_X^OWG0dre99 <% b 0JSAW!7vK3^xtߓ~]dwCD7 kĶovUَvk9x,ݾy'\:wq}mS䃋F(=a&9_#}Q,/%wNx+UzR!=Y#`@l#=R}NIs΀[R\eR4gx< =pQ1*P]: O}ƠZx`YQ Ż@E! ZGYh6ؔԃnw+H!.CZ *YYer+5m%VmCdme:r_¨F2!-L[v8-Rnm( oczN`J<\ EO+vNj]3p?BʐC6\.|*原b1"7P nxxF,.<܍O"9$`Ⲵ~cדN]ȘizFX8xؙc}LY> V:mfT6A[8 )O/PR MEn923[-xSI"t +Da9䍠Tހ(bezNK0O_aWn?||GtN<^d,?"~VޢO]0vH0G?PK ^Bw .1com/vldocking/swing/docking/DockViewTitleBar.html]ms88Ʃ$3{W}XD3dg(HAѾWAQ]GЍэc0:~}F>//ݧ)z_:wd.Cs ;< S駮z<\8?ckV䇃qtDӵ1`)C]^fN +. ui`"%hXIizݷo[#$F.yg݇?û?'YWh=x>'# _.y`,z@\`յx'8B2޼QhhR;F7 Je1|*m 59Аz<Ãw#q$!S?%>,Y/r?Ҹ3ɢ R[XW-z%:h=[}66&]gp5T6l`.b݄Sso`7,X2>#O4Z1;xN n9&m a%T61OmF00*jZ,<ʥR0b[o798r)V' 8uK^o`:$ rI2@gŏCk>CP=d3 K3Ah?a.4CZ2f}^-gMV8N2xR>n۝'[dp]I7(kMS:ֽNk=JGAߋ RSͽLݗZ^mLlg]+ -^1ybJb' I%Oήӥd”-ίN/dqk·ƽVdNޞw4Rt|d6'xQVNq1lWMGv!5 "P]]w?uߢg=÷y~zߩ)SF_/ ׂL:'ǮW$vx {n!nPR ᛜI& $I IP˒pRqHUwɭ|%IBK IfD+n ! %zP­f \&m:9_j{Cwr{ & [v.gk,mA^R7jxmz+ 9,d9m[0Z=;\us,a%KLx'<=cۑҥ媳 k ѮL}v!2؞+VϻG*;:|3mH=b$@rh}xSAe@AGFFJnqF6ͻ! .Jg(üIKV-Q|cZJ'`V"fœ!2`1 b]ݎ2u{wyٿR ˄_xWw?ɠ؃Z_%Kqh5A֢lf?Ynܸ-]5 v@/{xE{ą+Z3cF;^Z(&m߀8G m-Uhul1;s9[[L; -J[\~۠hFxCL?QX}S˦6ģe{ȋ}Pv.o k.+mS U(NEJ2O2$CL8aa$/eǝ\5W $0؄m6 |g[n .9Q$beD_(ثxy88뜬<z(uA{# = JMĮ}ER(bt{6ȨT bƌ`T:]7{ꏾٲ6/FqF{K=Sl53uonIxCf2UU(YWr*%MR"닚 c xg8AQAZB'@7(nx5 Rrn{ =FLlQ#†(1Y Jъ f1HJ||T3fP</ԪLTu/v 劾T{C.Uxb(L7Lq!23=su:sQ F!i+?EҶv[lIrl_ZcQM&нd" L"hFjYyk =|@#;nKlw&ėT01uI lODn x1_5coĄn~&QY~[Ќ ӽٚMgaZkw ̑evDjbU&/On'cWwExk%0D#9{AsRWʴ0M-8̔it1L X =sA|; <4Ep7_1,r _lx}I?Vc@rx2m\ހn ӈo"q 2xe-wi P3m)cwN5ntPE~&!!&tE즤 y&$6=h?`9t'薗P!LX/ 53-f૕YG CUfA)Bov۾Hu`l&O*D:QWсߛ'=0Yv 䃒,5<9$ǿߋD<ɏ)%O{W(KS37s/.A6&ISU^V. !K c\|_ա&LXaaJ!9B3=u 0Ưh6k0Ќ7 nmJ296kmWB #MO~ghN q_ßfF e9,uR6UڰiU)kMb $f0$ԇ2&O /Š#ۓ* #M UL\}Ki8pІ܏&kP7}@Ĝ@5ֆP2'+?k6K]urqqd"lFj~)!ZšOٔ3ns)&W3#&8'U$ZWM[2_zgQU[]wjd>9jMo;ɢH})c xE$ԄDb{A]vZe;f^qMeh*x[A._p-b@ 5_,B뜺|@,@5+mMR*"sIޓLPW 89&ywwlƄw^Ex16xXx;Ԡ edN)JRU68'A(c-@)02amGZ$&Nʒδf`ugx`r o7LE}7͇Y;Omʝc ym;x{W,3+œ$ 5)VkZGK}NWyJPkiY A>W~ѫJسt2QgU l~UK(-,:U]7(s@kulhڧ,.ջ*I]Cڮh*%H tN_;^`gv,N!@3ܦ?Ч8 N*#BN'ȿ82Vi*Pn"pzjkϱz/-8h[}TUn>$"=ܩ=n]Np}0)͑ꀊ<Րf(uo+BeVc`gvf)5o_hSi8rò҆@cj s-3O lA'wyiy&MgPtZHصPY*ݛ:S &{_ܾq/J 0#ػ$x0ØOR'\׾)审y2ex.6Ӓҵ!Sw+l 2w.˰q`;-5#9[ w%?1C{av[WL]QnJѓ$'1iԔbpP=.Q= {6(U=T3OjHjtPs/R[$=۹QB)iv ^V)4IRj{KL4~TJ&[#]ppՀs=w"3ChڽrCmfQ}y!v+9}JJ&w?ƹ-]*_w0^$4TaD Ӛ pV.H8j@}#(^*n}Sr &Ӭb9\6%$xKv4/ʒ(-')L*tKStJ9Y*Swe 4ɕ*T] ULɉMJ []E zEκzѕnmmEA,v\v+\v%5 üvhog#_˸oWj;zy1mj{E8g'4eJO,4meXcddpP3עI'ܤH6GW%9JHՐkIri?kuJe_^,_ZlۿEcR V,*yFt%zNFÌ+YPL.xZ+qK|Lܘk}1Fv{RX`q-]djWGu̽soj- ՓO. f!}W/⼚7֮ӬȤs"[q2zj86pN nQNmXa \1naHD,-^KYL[dӥ .AU7fmyNo3'n. k@T;U rZe?O^L+0)4v2!ؤDĞ.w$ޏJ, 3)1dF*_۝s O>2pc, <Rwcƒp^?sYp"x{>:hD voMB[b)= q.bc۳,L0~oh]0d/ʹb[hŰ7_~ىeI/״ؖAeaљlY1bZ/ۉq%_yeDhw s`h/Fq}#0 ~F&740f\V[nBNGW㛻覸j%"3􂍫ӴlŚ,bnyv V1D$FSN&F@]q,iH3m#nba&s2Z",z=.@/ {N2rbvڦ`>OMV.~r@N +NL0 %';E䄶c.s0?oK ,7iNa*ff$67Fpdu!s%O7mVlyTʧDlTTxl60^E|ãg[SK(-v7Ec;9A1rz`4 BbF,*-x= s㑏FXE@};FRx"ɵN _eDCmqʵW{11aR6PXH[|f4@=p87Ğ^:7(lk0Jǂi8Ca78rAq*鷦,}%bMSi R0jMZ_i&LSh$$.v[QAʅ-04VsaLtF)Qr-4L&,)*}b'BFr P3s >Bl/uPC?^ݖPa)t\f`K`֮lפE`~}[cw~=F?q-Zn,Mnb[5Kbl(@)_^{6Кdzw XT> /k1< }%]!f:4p:tRďlm<^(/MDes5 p X{k:1|p~yVkQT!Tw=%_uB!`|,B h= E>|4`]SQذ<`S<p+|aC 8f.dq eNjػ'&iTd׆[5UPB+e˱5B(yΧdfCH!Y@4'h(hplj1BAp9 D>ܱ>2;DւHYxV1p3O&h(["wњFޛ X4:wFM,A L x^}QXJxӃ7ެh{KFۧ$5Z?RsxBWc>*UZ#r\{C? _3h$ƭ EIXo]ɲHRICe甴:X'-[:`oe T#,4ɓwұ7^g yhw8 "~;v0 xfo7tӹ[czbu|1 j h°(o|A{eYzmWjv6;k'_K2 (1Ym:s'BU\3@2F<#ѺN6tźn(Ce68q]+ou]``C=*UY[y/IՍޔvgA~~.46|M_ˬOEܑz`s81K[ ĒHJjT̘f#Z?t|bUPdaޖ;)֛9٦b-`~FlML>f/+_^Sb7I)VmI-i/ǥE!<)x {5LAr^sk4߉n{S[wEwήdtNN/dIL<oXh<]O+]/ ŕX0ͻ?uD{؃=&Z}IMS;v~ {]:bbaKaA<dY̌V϶?jI=Havc:sG%g%Nâ 7R[XW&ǂgcc҅8idd,}$RklnuSY B%M%ԕuۈX1AIȓ]waZ99e֫#\*#u)_uUbDG7G4p)i lKw:@'|*1uHNX1.A3OˡuX- #{zʰc". w1aZqu6 7/&/6l2S6']exǍw`S__]|Oӄ!8goD.l{:7u , |ϑN JDN8#ϛЍ;opM4xQ$+ih@ϯFV ޵j g~/)pٌ3Hd?m S! ~}\p?Po=Zw.aS>{8tt=Sr|ƁQ*Co!Aˑjp9\91b*Ey#)$|r\ hWCh-熖5a/0+GU4Ǭ:m2ދGD#Fr+Bxp3\ .tҹΞh@0 h(-rfCz`֞< {I/ָZWr3gwhWU g8[(=HssΠMuxV겣Mn,H`cݐ{&8ݐÔyNMx [Cq5~#f(ǀYHe y1NHuȗ5E?h 2 Y _){1ljU("PB!g+uk|.=}'X-(4 c :Z;4G[-g(LhJp5J]eL*aq0bʜOStOCig 0>=GFPQD.`b,p@"=5YC=+Ye3aRIE0E/\DG1bj|j{?%yJY(lS6^V̤r4)tRf!w:蜝@7p3zw7'vAo}Y-czKAURfs>hR«ߣ,>(bG/lvtzRqHRqR\1*ih< x k<ϯy_M^˞=R:1j4N#;txA9h>_Fh9w櫆sT Ftkp%lkYZ^%Gs^PK ^B J9com/vldocking/swing/docking/DockableActionCustomizer.htmlko۶{6<],=I7/$.)%"HÎ$iܦC"(>|ˣW'4Z#=oҍi("\4HcTԙ9"kwF7B2W~jV\0ja "  u!~W*ތI'iNX,axپy U8$?\wΞKqαh/`h,4?o<1ȞëSХDX Skg=w$fA!,`rȘj5R{zR60fvq_= 6kn¥gWz1T5˴6:W~x4Q;bAs̀G\[o%sTQe1ۻ eY3=O+Z㴵mX-Y,osǁc:߂^Fr+sM5IZۇ.Poț:Ѹp%abt_m C¹saH5ԃFp'(4|ˆbh2C6ȩ1yE@(`[JO Wl$2Sޫ1  zzՐp0AO7$dҞͿMiU`"O&\ruND1j~?I1R܈>kH|;4!E| 9 u TBwnX0Z8tvwEx+b);}e+H7xpHǎ$&uu兦撒ˋǣ5x~~xbR4*I WO{6ӝM!kFfdi!Kj7!aAyq\3<- =Qp,G҄04l 5baot V ` i2\B B'"4!6#YYpડf'xh Y L2O h)ªuy@J60[z#$0>*/̆c%ж269?vy>2;0EM`~E\Oqu^υ"}gbh"`4z\Mz-zIZͮ+5S)ä 3E<dZm&XL%TTZ"߿:[] 5m,iUK]yYx̺Uc;RKFjb5s8T*LcNuMJ?ŬުڷI@vϋQKIvu^Pmt2\قs*W|>#7]|UM ${jVn,eQ-A qm! d:0Y$ ka"c\rkkROaGHI ,FAn:"Ve6S[[\ ["U\qĥFczV[6a=t2Hkӧumf梀W `X/}[Wa^^LU(K`Kِ*%0,ge UA:a^ڔV!-Y/eS*Ta/@8j xii:[qR`&9 #?{h~{xzD:{DQlU X 6Bա7qɁ8PQٖƂ؞fCc|R3Օ2^>ۮҞkVj:_Pˎ qK iO $d7l!08h9V:KD @;iI'Bs|㑝gp<'($ҕ#chEc<`COl-*`bF$Hx%|OA95_>\Nf{dg^j/rVm*Q{׾؉,$B׹_Gl>o/NpT&D΁Y0F):JY_WAuA3Z\Ezv25t9ɏ̕<묶$UYѪ|UpUve{y>_嫞P0+S[#.ȗ/w_=zN /v"(ʃ4(I(aX48 s;{`sCEvߴthHGXy4k%5 0Jˍ4)x?PK ^Bq w/2com/vldocking/swing/docking/DockableContainer.htmlZo8nìuXʣlbTmBI~Çdْ - %3xC >.Ӈˋx q'}?8 U‚oTzܟ\]0V6`KG*Zoj?4pMdD-0ML1%Q7PA`xCw{=iG_NnX*V<'F;ifٔQ 8+7iq;l6N !M3_Y/) یYV]1K~+"oτxXDž<2M1 ,p(o2IMxB qV"z7 dk*ѝޞǔm|Bv0? ^jWrFcaF V:8L+5eVSI #!B+4/Qƍ@d)iȣi` ~ NV Ƚ].2Vx1D4lԉ2J&)&$Y;kL@ <9&{,L & z AE{ӅPP=bBD?3ʓP2d?f/lFb 0J1|aޒ{ e&]lIA TDMb4F4 ^jk6dSfևfs`HE #:c!<Ȭx˔tJTlzB=ɝKZTy٨ M5`ń, ljʍB Wg7]}jQxnO⟗EuղŽG}x00ozXQREslyn:AbQOb\J;!1坵 'sV{D^++東dzj&c˫KvQ֐"lG0/R/INSSueiFEƃ0,k%J29xXUQ=.vENQt_gX&Zfī$ߒ)$r;WnɌߛH}MMpuW> C$&9yT`t0auU@k c !4_LX% >Q6Mui>41Јb p`vuYMFek 7ҡNK{`jRiEq,$gm=l&ơW"S/I{o_\Fl@j8xoK\ sMor6V߰aEW QM)a9+(&. 2* +*a=o Vbm칫`Yܕ~oW*]-?]}oV?w] R|RyƾaKzcm^|;m {=rz6n ,wEd$舰O+M8ӸS A7x4VptpaΓ_,F |6u{I:0sH6GPK ^BG< &LDcom/vldocking/swing/docking/DockableContainerFactory.ParentType.html\mo8nvIc%v[,hK--D:n II^ȉ&EĢəP^㪃>ؗy 5tԲ_1g[l63gG& G}mybLX1NLWFUZ u d(FuG' Hq`>[2UoIȁ=:0aC6 ;tpp/m%6s%-,W8$_n~0BC<&3~AGyW{&4D`@Ⴀr,qm;5-_PHhbN nr',sy! ӴMCq}٬[̝ X&-5[ U)s4)~ްk0`=T+ML0t,?DmAƉeiYZ~1`Ϯ fs9r}.'lAf%;KRo7m{6?k^F>4C1Z6[hgG0 nں?/9)[lpgy \390"MXDm[j|:c0\F5+,!1`ɌҭAKE(=&іl.צX%,D!{qUedGBSn jh|.3#tRuì)U"_rY>(-tu6n׬ggJ3c3!e*Rf'8HW!EOetTFvG}e!vv72fWdA. $p8"4X) 櫴P]WNn݀ ɀ*,F6EѤT۠4ʅJQAP"? T8U0f:4&4MTބ 6x/: -Iٱ ЂXihXv̾㟂,9Jp<ܷG#.p n`4:ЌZQ*R}BKcz^ٶ!i~MLdbKƉB6(H1$m@I3.>j7&LdJB#l Fc &z1P+m'#4 >\Jw۽OK*L?MU>-/_]7v۹NTi|Z^i7~i)χtDC8 Ș ZڲP^|/ϓaKtNC_j΍||2E -JW-xUfP) BJ_@ahD_pM&m%ήWJ/% pJA}8ҿ]#?zbʫc_rBxf^ɓ GJ/^*+u{4D`w,"cb Ľ vwrMy_D4[zH5!کv!ӏe?*-:TQجDx.E#bʫS v)dv#cv)׈ u$kDx.XL. f!J0m"V#_gFgGF_^r55-5_;n훟2thvΝ7}f Y9wZʺY3߭s3^w8e8޻/{ӆEy[Ws?RZj#dh cM+ZNX:.lƏA*ǨZbAe7cUs.dSaNBHiPuN*Zw6 FYZ=zz~jŖm'O+ rSoH]Й~`·4gQڹ!r4 "< r핀 4!d*S,$Bu4]VQM)@hdS B:KW(>'G迪,W=0m#uYs琉k8]EwV<KVOa[PAwJShLVL SY'\eLk/*,+vֳe~Y؀ ƅWGp^|mrm> ^ܹܿw$(ETH%Fqf4U%$#Ɂ$C tՅO}Ζǀ*~`"Xe/ CmE"ZDI=)PK ^B&=. U9com/vldocking/swing/docking/DockableContainerFactory.html\mo6`ik'Ix[S@Kt̆uw~3$fK8Hg8yf8:wvyB~:#?}yv=ݽ}ҏixeH睜;%Ityԝ2W(R17Hff%e+؊޶6#F,d1MX@3;I '?ݽv y7K.{}rhJx"X';:+ÄrJD3 ț2#{@:w=C,$&-'/&-{k}'"hθJ~γ.,sيpQMj2xW: {YoեZ&*]&vroݾ9Q̫bɗČ}Z׼E114(RЎդBX{Q<?dD, 8Ui%&˱w/㨞gkAFb"_<>#<88v3>_n0/cvO, ~{%n K `d.keVZ2Z6oLF&>鰫ԺsIenfrf(؝Fە[oXm>,3[$`'AF]=maiis U$ r0ޙO`BUiCiŜY eP൉G* oC h76#𕍁 N9A͜=MLD\ν/.3Ll$zA:Ţ6DYm4vea>DRrsrޫN}>ϕgk;U,afbgqjcuKl& H]r ^惚&yBC-.0Ib}wchuW:w曜;tDƤ4^ξ\H%fpX|N Giޙ c_aqȷPNa7P|&4` D$M|E+<]4BگWɈc_f1uI"3ǡcѽC0,*R9;?c …(9JgM1`#XK*kx,iJ #' RdȘŪ0KB;ˀg&FN8 C|% A5c#<ʲPlkl-όVbg톈xGLk$=҆ {ǑIʹ vԅWX٤dXO'=;^sVCezW0:iMaN={kLW~m㐁ZLذhp;4 -7yGpMc'vZx=r{TE}J`ҭYI84inȝA& K\zH9\<3cF^>;NYPy&gI,7wӁYd'RHR+p5Κm jӀZtu/ίW_yw} W=q{ ?އmdc!8t颷B|~^n}z`ǴvU8^/r6C53<\},C4VYe Kh^ç˾S|?+He+svLF%`jf5d EKIWA@r{fv3@|-`s7t7ֻ4V!{[_+i7rS,z3:7|QyLG,d8TgHCb8;8tWd/G3A_qOlk篕4qշ]ӂۮ/ yͷE6Lr)Hsh?{Xh wzv<{O>`݋y| K0[=N1C1U Q_`ˉhQfX"`d2‡.nɀ[ vqj)j[}_k%8T41Jk][[k{ɃgVIJV5J~5 p)vi@:,ml n0)gDY6&)T1r^/m60fە/d Z,&0ק *Tcki8bYU~ĥ\c;϶_bO]n N۲Rm% MjD1K@ȠɁʞ[fr)8/b;`KxF~yfGJ˭J_k gv:/q|gʅ jQ^}a|) )O7]7A݃#++ițm߳~ v$9>^Ѩp1}ZP"1OD8R իEt JCF1R!|%|p\]=CKn8]֌>}<_'"NˬPfi_B3K]vPU:=H u  -,ɘ.f_nNa׫3t:︘YPE#J~"g'GUP#nu׃ vu=<RhI߰)0wĦ}|Q[*+Oi& , -%oB8a\]em̛ RI_Ghe4˱7 E=5]f3kL``~*{eYh2a"9SW3uYaMO=onbMtﰈZj۩yq;_f*ZnM)KKE:ŪUېɍe>+"h8zO qպ z$$|+ +߬Ρ *pz=9]>^$5tE gepk%)#rX_My~PMi#iEe,yDPǿD}+ W^|ĪEC4'[ 浾_W h#ϩaeQ03xV+{ hMwȣ<*gWnڭ^ + B8աGiIy,S^"M arprpd8@pEᲘ9/1}a@'I+,ql>RQ73kM#?)/8l(`+zmu)8|?r{S+ӛhRk O̯0*mܦlReFn,oľx"m^ Jd~olE%"ۜϟ 5a!2ƚ %` P( pڡ~Y(,荄* ,Q6p/BDA*O8B~ РhTW2-ph%Fd tw!_Źۃ+b$rc8Ƙ)  HV3}/P`d=&KL"}G=d$1P̮9(lh`$5/n?O͓jCICT%r iv9<G&C1EGhӱ |"')Ih|F‹:4LJ?ҞSc n.- hym[wdfU7,N-C5 >;Ts7VG0fA c=>μhC)]jOJ!i`z9s޹=E2zZN-ʠ.0@ ;)D񉗎Y&Q {Vx`!PK:5M^JPV_"`i=1|{TYβMUKbbuL d+(Ǹ2*G$S2 6-ē窼8)@ >#|J1%eXlmb 9_KjCh4{TCOn睼֡w^dP/ U)UcWt'}A' D.ށ'(BO, ȡuO@Fߜd4s>?Ks|FNNJN^SDJD/ˠ ٷ6|7s+$|"H4yoZWA  "ymR!.c= *S̜ge2kZW,;z GVD63ue%J|Z?\] _b:Mjb21{Č۠0G4Fa$)n0&FءɰXKG3Cb4\Aؤ>ߖ* huvM\/OYc2iqV1Lcm^Hd̄>0w} s)@s ^/a ?Xn3%qѷLN[m7n,F1*eĕF]$8}.EZަRIW`<8GWקz_? z|>}ͩ2ϵ^otAU{㇮Gzioz1ܵsËO8:BʺHcw4+la_`-փe{KSƳG꾽y׈?̬q?w> ] wt^ |2W˹xA;tF5~=}}WןzSq`!'9R-=7npY8ĽG;lVl}NoAoX(=t.uW9wfd f[-)8kQFmD/Gn+[ZҺ".qmmrGŽ82?FkE+vyǫ$;?+~E꣧?]oMN~r̔t!0-ym(ZPa89?4s49C9OïZ/8t,x!z.jzXX􆿏i%z|KY=;YH(q:[BYˌ8!PNsNXseup-co;?zmmWDz8·xMՕz$<;λ)%:xG{ }y\3bSE`c0,G/EM=ޖ!БH ;oK365;lʙr\zރccgZw3޶,C"[kq[w#F]ɨN3r#\+{L ;s6Bb̊^j2RTü{QGTVTzO_z(ˢP$Dm,vGqz";}Q嚛VrCs:1%.~U+^x|_F]yWv]YuW]ٿ0\\#cm>Y-Ǖm,r9O%^qSvqWzkF74~#&P1>rcvAyxH/ ޚɚO{cs`|N[]w%C>s NW`͸[ߨ"+"^$Ωo=k5qHS xߺ |b![ dYQ&C d*9/JfUKY? )a;DśyjuG Bu46u_O 4~dBJ>H:(m[[oAk#%pbf!88n"LW5çŴx*5 U1v9kn!PgFZ{>Gnyo sR++4z8Y/d@Jپ@z5Zn}[ ,}0F}yE3ݘ}āeu,3G~f6^zVKS.Ghg)닋o鉊QT&7'j=<|h&5^ԨySY#ZPs8gf]z6ndh5a+E *Jly*K3l1ao+s38%+j_WkRv:orkLk&4հIaKUiÐ םZ ;\ A)^Yī7 N7rmyssⷄ:˺ظ${|~63Cw]43XgZ%1"%:uVI=E8%}JAO&7|oC r8:_7p<O.M@Cytyӿffrvs6\$rn"d9t`8Q7_ǗWcMʎKux/p:'7/Z&lnptM+M |t63I6UPچ9\U:a.dK);nȀ:U"x???g t:4pϦQ~ iSNFxdZ;B8I~ QJ*k^Ofσݮu.@lGtZH׋Zb-&|k)w ⸓AbEC.gʣr;;;FF9 WDDH*}KؙKeKϗt+pdj>4c9s<5*Ǎny=ꗉW^g<^K`@Cʐ=x$S~?ɣޞf AuK:p;T,)JOߧhy~HS*7p|ҶM-k,ڙ8|iM Iǡ%K[:%f}30lRuIGwJe`pa;os*)6e;q+>R;Vml .^4]+ ΤFXy>YU%փGCs+e 5^{y׼'a(z]#d5E!Ek1@&C>Iaަn)xnPmVn Zw2t3iX4[M qhb ccc\C~<OSҷ'4#l#5o|Nqە$c# 7d!UCMhkH3oe}~LŸ)A:MNn' 9?A U3C a@wK(iU-[-D ~ޠMnI?dlZ,~HTɲNd# }c,i2OIQy7y81HޚE|A {8%RܹbP#Rh1_d3siP7D9N;Z aj`{@#:9fIqڬL(bz=mz y a_2V c9,E/"U+}v& rY5ċ]aM1km[Z453 .0q[xi >zdLۙϘܭ̷ƱZgMarT8+b MYW\Cj0 @bz~֐wXU\dv}Uhw! 7ެg|g1Z(ĭvG Vܜq-7r#j< kͪe6 'B¹cJ]I}@N1i4)2p@@cք@8BD=$kLQjmaÊ3=ڦ T vm %d[\mg˵ =j9;ʉve>Q P L<$󮩀1&c䰞L<ǯV8%B^m^]M]j-d5A`$lmp6A|.1Rnu+CIsaO[AWR0x'pRA! Z\0I?c.`#ÕšɊW+daQO(ZYE<'kIZSSE: /Cĉ17@닚 y>6 @s Vı)v@99B;sAd*Ad X^fw&r6`18#6IH#ġ(ox+W}{Cq Ƴ<%ݔ;*2Yxv mLdB smDql?vV z³kK ߠb:y=rvP\ N $@`DU+0?[qjA9E,A {9 qW|UF·8 l^2Ko@/@?Aֺ%I:<2 $P4^W"@dT<׫F8t6 ^X;y_ $+ʠu(ήQpiz}QSmCxɤ\K+q&EE 햸vTs(4B 81!;qP(+)C0ܪp8a8 BI?q ,;RN#0ݨ@5WCΟV#"pߕu&Q@R7XwIXF!cAm-+g>h^ۥS>N3I 5HK FYx$;]?8|Xtx]mPl  <ԯbg>G"}z$lRm݈7T)Oo?SSZGNMCk \RՁbt0ɯ&0(%Hx(|abC"qL fւY2첳<HMF'Pӫ;Q}5x hfU^4bRVT/Y6i j+؆ޣ+U3hv$09U C5j3|pƽnZ^:ġ|W-7)=؞%)QzDVHG#Qb|&Ztڪ*Hf$ZH!`"Ҩ ̑2K ob DH|4"A % WdsP}]a+\yR-A5*a-Wxy?^SZjs'Y,&(w'g9-U`e]Id,d޾(rj*܅ ZJ1*4)/WԳ7K#}qoXqjNp9$Xso-C  MdmfD_8-P {R Fm2A9  ìd1\_+pInΓfX))'\y4dZV傔(料+STi@rܡrJ}6*E߶P"<]D (U ru9a\77`Q[_W`mG+FceˆFD΀´׮0@ZnWl_/ۇ9: , 8&|##4$k2 UjbHud7)^ܴm%}5#T*Nl$Kڮݽ7  $Z85h/m ҧ=ϢҒ& NW0 stŎNWfPǁFV0/,\y4=7 qC|un X_\y3Ʉ@fvtbx\IZī_ IGN҃kݮdb> )]XΉJ`OztvOͧ17 `d@*%Ҷ\ iE&BY $&Bv,xeW+d!M\/ [\U˄j>*fB^$GU~임ߣ}Ƀݫ8cN8|z=Oh8GV엞x-(=` eڰ ybreT|V%$xS|oYD*O= SMXKoW5LO75jEֆǤ!=^mۋ Q9d9']b :'tWR$MOdnx5g?8J&[ێkBGR^Xdْ_|D"ueJM$Q2Y!Da9 +6.}]Dl *? \l}!?vKr+^l?dB*ɮʙwT͕|T +bejsBNf%{]>xV@>W3bQҰMO}& Du5`!?H-vXI]7h;iCGDLg\kS ǐ G;g5EżQX.__Ak@&CJ_J5!,"b yթGmLϭ v |BNHGC49Clyűh6O"d>\%K o}i=ˮrd?Jw?qN"|sr%T''jfu[DAA~1*Pt݋'eJ )fնQNlt)z%(#ULQ =;7wN(7PEH|w-_cvE\V{AkZ`ׂNUu-XyhNܢc1;݈yi n{0tٻ< k'2X"!<xREV+ulH !OگNZjg1^$cY1B` ˈbk, 8]Lyh?3!Q";h4.޾hƹbY+&d=*8d22g+=¹_ܜ+ LHpIQʃHKTi+jwfuف:`‰G×vBc=x٣^>i8@GUxft~Howm'Uܰq+@)Þ*9xI+yaDpn,M)gd2~= ҌM48IwctBΝ~>F0b[v1'DphvE>.oy.R-=[n6wEA/7lu ($1Uʑ(3|bn1'ZŶ۝y %`DC%H i&@PPv#{d *b^WME6dp/q n/ PNG0p$zH#V@J26dVBVwPMlj|>aLyEUu_Ʉ]ѢZ~oö-1ط-ǻ. ?v+E ؅J;DX SslƃȰCe|8%TKg}(۶kLUVƴ:g5ɆO)3{ߔO^'C;\^oԛ6U?u"tZAioڡq|w{dOnSKu7 x  -nMe_O-Ycև@=/Mr'm}[>哧Az μp]yH|M|=koB$͂@xwv(`+8Fv&#[4\<+EH4xĂS3@1]BҠZlX&q_kגxSHhTd=o0^:7=PsgҹsGd3gfo3Kb`K )VSUY_OR ]A7n4f|,B;u}[WV/wkX׋C×chU%(U#if_t1inezp"zM*"s+AԽ^%7Ӭ Rie_|PK ^B ZhN& K7com/vldocking/swing/docking/DockableState.Location.html\s6Tw%3/4vK :EF!'Y6C n2`}HWNU|]^.Ī8οN5o#ҋi(D!j[:d2''v:kǗCQ$IϪ*}U6\[F*|mbj3ꙶ?T2zO%{ ۇ7?RI~rttwGߓf$c@rVkFs֕@ؾ\s!_. %c:d(#'}LWg dLRB Q(Y(U9G5w$fj 9LIzJ W1T-vYk[P#W.>V#~MSq0QXUCQ* ̓8{ X Zx̾= *31L-xp4Zo5_Gk,ee^p_& zi4I?&,!^G:IsE_կͷ r*H3=<}ԤI͡L+kq*3S5s uj);Ϗq3b!arE17B@tv:Dbo7lRS=ҪuNJ-:ϑQP-u;0 56qmվ2)6d=ƝKZrYYyxl3cN8:4SU(Is_ޕݜ1WXZĪhsO#&奯X2ƥF AohmNň)`*f$=~_[G0XJc!;` 1q):6 ߏ>oDAAHVLjGdIZ`17sqq0p9ג.?1P\%i‚ٶ8wsATEjy0OVچ|4t CY}Hw:lݾaiqj`:4~m@o,p<p#$ MZ FXjkʏlKugT.o6M?3vͤxf}n4:.?5Yl-W"&+i$+E\$BAaxf7A8Ul!J% (6?هCGj`?Őu"5 j饭E="HMoiJh_f1׭|\Wb/$+f,c:12L+~iR%H7XSh.AtA@἟n4Adf)b^-l aUSڒ3Jߊ=O?VHz[MP $kk?V;7,jq.<,CI/Jۘ.(|4v @Gbv`BHi1,LTЖ9 |$NLG//׿Zh8)[w ]?Q sbHD@: a 糕zU3W;qOɀGT{W"Z2qآ>7UӟXF?=R7vAL2}Gۥ4!}_](G|Oi<1-ze8?|ܮ|5eX. C鈙\xAin5O$9bĩijO|:rҕ1t:jWPb} oT SՃUqq R9K C@m}2 .1 Sa`R ? 87t ы1w"a@D]kTJT Q[O2g9i"n? Q=n򻚏  g#a򢶣}ˣ͛V*E&l^d9\)AF:5}-M& Ψ& .t'>~$v KI}r%#v6a'_Q댏Ewm&hdI~VϞpwSٝ& SnbJHFqF\F&_&4?G6%+\Fl k1nbK#vQ䚯r5[Ş\%j\+ ES&)07i. + W&{bp O Kk[rh`4R)T%WSS*2U]TO^ ۫hzO~fj.RLjif +jeP)Y]u]]zj/U- v+ I* `fu@LR*F/ٞ/1kTy3"Ya['r!PLIVxuܹ h"NK.y6?(iyItB=aEò{%-x ,|k1iZņWۃ{-ⰺظ8n%8_s>O,zLIc! 듳 jB_.0X!|[ʏ 3JG'/dLCؽOcBt @#)!6kW!wpz[]>ѲL O/^"x9GU)z9ߪrRxѝ}-aJ l"h9Dv6"SIc`\ٞZyVWYػN׹/[<+֏`5,<.Z| u/濜rn˹sn~&@ԣrz_5@DEǀh47%8n}IT_x!,&Jk&-UEB)NuRD .PK ^BKaum.com/vldocking/swing/docking/DockableState.htmlksF;U&lUR5`g˰}q i0N#`yMrB[-v}ޠo[Z7Lk/GǨ[#]UA0>3lfN ?swK)Æ8w:ó{ zᣐkyO*Ę!=a s5j GOV~x=:>>dz}NOZ \lSwq7 ?A't[#<tj'ܔ``H*`/hTOދ |6, 1(afX }e_ȸr)yG\8k<\bwjDa aA]QН):F?7UuZe~©YlrR ®{-~: _0l&IUH>֣{p7ƧWSN6 e+tdN]GjfuA $VZ8` >D兘 >"y}}`+E&iq7=;0*Gy!$oK0xi{Iey[=E[BiTAiSV0oьG|9%+隹b Pnm+n/]?ίZA Y'Cgnl~O QǦf8'"?.l]iϾl!K$z%{ "Δ}S`2AoˠG R'{+>/E:!(#" Gz-hjB ='\޵c0E ȍ~x|qZm.!m6iq1ܓn`SFA!I`y6^R*C`9#ni`t ~Nɡ+#꣄p fxhHx) %7RTK[ھ5,͍ՅiVyG EZdlBA7)"HJ)_b+C_$T/D[ne )8M90eٛ q<)6eG2st#{|1wx ƒ18Z*|ܬHX @~nSIM< ^@{oEF 銃 !,`b!l_Nk.3̫bhhJXz:5P^:pwe[ۋc,73Ls*NA#RSQǑKV>8>ǖ^^:A_mWX@ P XDċ2oU&m0XsMeC $,t/62؃:d@@9^=`0Jϓ{ڑosMAX._J8 (5m&WmEY*R3ϥaf H,L麧 SXD:-)Hl i[r:wVPnfyيo_33K+f jZRv KV /WInM,71(dIHpvA2C`<`gPlqc9JN*Z^Ei+0*ዟˣs̃<^f_[>}x&60gYњAz=/ sP0/_:^.jQIɏ~G"Ar%6fepGbØ 5y5ne\ߊr}:&h m}ҙM3ՅdF췟$I0ًۢ* j%(p@[+qeq-D~cw_2@%KC,A=%NĨDeU;!ʸ9? HU8]<>egޙ{+K-LࡃM\wd?s `WSg5? ߩmi2kY頎},n:!jwZ?]ۗwaUL^`OG^Pd"u%P29WPMxwЏjx~Fqng8(aa.\!J4v$,emJY@`fC B!.-{4@lHgYևm(g*vAiZb3x 7DJ|Av5yF~J`XRԄ/CH [+Z<ԟ^W7/!D{eH)c\Z_ɈGxey{m28 ' ,'/eD]~y:vx`[QM(6-_>†1 eWe@\ QA}8{T}y@Us. `^WT եMq^o!Dx!0~bGp[o'2J؅!] =`lņ-u0sd0_/9%pImf`Bڨ 3+ _lvdKowq}S~G=-ϣT uYjh`/֥]μ߇#}#I6evKח[q{%+Ѿ.Wo~_DQס{/rDj^, “]Qh*f.ktUc]eXaf :jM̗2:gZnwmʟ*w3zlE֊[cuɞXx$U<ۿJav`'Ѧ? Jl~>Ix#AYdi.* XjJWȡEt |قgrAܿu!ulօ[bso]X.^xU^XidD:"ʊpt3sx$yN֐0@'GGe7"ql + cJXX`_&^PK ^Bj-4com/vldocking/swing/docking/DockableStoreButton.html]s8pJՎSK]l+Y'-$7E EʎnËoR"h)Jnh4NF=|P·Oݷ3lJ|؆;}^czioozP5}s@x?ᩐeOl4klA_=&Zߌgt{eu_^#cf׭~ z?wsw?|[j, |[gncb?~{`@6Kr1Z:m3x?Ea u١tAe>vëN G"3^P@ t׏%%vx9~w?B疳4xuy]bdu={J/}o./Ż%-˪`_ z=Y7=I~e̤"P|l=OYp- ټ? O}uU:xePʊqgVAP"aJ#lqMsX;z&n7uy[\McLjS,\NQ=ȧIk`z7ŬDqobKq/GTN)>0VkQxa𒛚 O°,E=^v>q~TnBEsa_Kg{LF{gwoC*YM7|Slv2g*S@=ǝ%&Lw@ XjhY,DE䅒YR|{¬vHWZTe;(˨P]_ۅE҂܉܎@̘|wq&WuN3X|zvTz= Wx\׆L;m)E}Q31+:__ ^EnKau~gy"߂* VlQ4=p2nDb%fGhfSZD+'8G5%/c_kFDŰ_Bވ)P<3A.73:z٦fYK $6%=Izj`t8>>q 0F,3C: c:?ތook*L~P dz50fjI1\9Aa27k;4Uk0Y)Q[s6Uz8V2W,$Mǃz21bjK +pt[s9@f&Nno'at/:d.UJ \<ǒ,$lNӐG>ue|k#pn-(S#(Z'wVlM vt33I6UPچ9'gk; p9^{KDSDTP87kljv `5 F] |&H4&"40䊱·44cT55Q 8y=RRM28HAfڿU(ːQI')STnFp`gJu<r@(MSLh0ͧɴ٘[A8}I 2 ⚫4p<{ĖI?<+̐ K,=2a#յ ; 4Dl: &.BP:#0UU pIEL& &6RqEc%vk{עP/cXMfle :!œq_8]M+pZpPP+缜T53ce+VfR7V! Ht7422йȜ([d>i#"іWs_14wIPDZŁH:)f}{#13쮤% cl<Zzwp 6kWɆɺ\lM滼jR"j8o !k"=ϝ/vA(2ֈ?q3pq\SRZ#TZ" BvݦĉV!-T!mPT>uUHQ)^Q5paJui6$ڳh`fhlzc_iBТ)f%Ӫh(՞$@l@2?6m2I8ކOڅ`D G'V6VH+z_9'Zjf"B8\WɩJQ{4+ljF~r918˦iB#ȡҟi~VyeeoqOL?F|LiLMSMM%٢h2;ëѸߌorř$+ck"mVȇtK|lMZT7ц:[zSKm Mܠ tT847j )[IP6pãN$1؁1U*ẆglO4F:Hog,z8e0_o3\Z-яc >U*{q`9㎥֙־H&0k6R@E4L#C[=ҼJ^14)W2\ o\+pTWɂ/\Ab')L,L{Z8B/|p1D c &cLoX(MS9js0 =̼#1'{\]+kJ }jW~ l:,UDum`+Mr3> !IkHbue )UB"m@-E?27|cؚG`ZwH<#O"LuHvgR-q&2+lxd9M9l@L7Ϋ$!q׾E _q x=8TQV/_ TE 86Ԁo *@wDuVAT}>REvDYftv,}: ,OZi":T'>Z>j@ja?2fڤW򟁽f_Sݧp8Z|(DF): ŲoއN?H6ɞbxγx"ۃh:+)b8b=lLwg;N 8p3F"պgat#.Pْ"gkM3Kg%毤VP#.ZrcԺrW+XiXY׍]mH}gƓ( d^-F6{7+4\څ [1X<u-Ӽ Vi{ ÿc5<}"8 Jk,"6!wOD3_ iu <Fq='A*s?A Ք%>lÓ4i]QhPMp2r'Ge9<>`ga2`Nv7T 'BJ(Xw() 4([ߡKϱ #Z q51Sw|3q4cAnO^rI뎄BF@ao#W3dkcc -ʃn;loudXaMҎ[H!^l5~7  |, aocw8-?c=@PLb2 c9O 0.ߴT!"Y=O6W#C7U`1F†5h6Uv\Q.BóA4a+6@dؘBH -h޳'bW HѵfU[29[B¸cf%IP!'nXHcq/PPdm{SB{o)ưT Bm*{P[@O26eaVB@ۢC{S%N+0Y&wM|oFZB ̫  x5d :[Պڗ&aI1Ž:|)IWyHaN\\J*(>0oz{ "TX# YzXhG1NS"[0h5"*狪FT˲ɰGhE,&⩁eznt |97l.VVqpQd+&5`IQ߲؀An&d xSу6^7Ĕ~;1yV kP05MFON :*2YxڢY3|s'[)Dm5-e2SLᙱHcfE׫.E\9=/+QU w(b1WvW a: |`zn @9;pq9-<˻L]rXH?w§@ڡ`OzAvsAϻ0'IH#(lsQWlΙ kXW,c r|D> gkyZg szv',Od*ˑFXڙ)0 [臆g6 33P2A>sWɎNٴۻQc]lvY8H*,]mWX`7iamp3Aab$@s3U@$a5I%A =[w" iVRȃ P$yP"rhC ob DH"A % 4Wd}P}^cl+B_yR-ApY%A۰k2O'3dASQGѫ9t)fL"9$EC;ZyZufCŔ&sRK_"~r,'VM .kpO"2 Ҫ;N 5OQۨ8)?)`U8) ؐG+\oGۨWH9;Oi'!)dyqDEFk'*Jzҷ4H׎?,S"`NFc;irwuv0$@@&񫞕iFy#`7z0GK^AA4h@&d+_%i&7ܴTcE=X3iy`a$RMx - 2:pyzl. M uC?L?z- R|L(&5U!,p`:ت&8%P]@m:{ Ğ-=+ '6"hjf lrA)PÃ<^jbC"N2}ol4`xXk4!dE,7&09"7"JEB4[":q֧ħZ{)X }- w>\Z)Ib4mmHĦI:<-EFHPTN 8$Ե1F>Hi5bh_HpbWv#Ȁ K 2F CpJ>e@oS f}Kt3I 5Q 5A>ĽJ`Ý~JE>O4ALt6};~@?3rvH?ֹNN :Y H]2۩N c9yg7|i hxj 4zA4Z0٪F}H\*ro/Kk5mpb/?tؚģ;uDCCkxøPgqTq>+H4N$8O荶$)ͩiɔt)Ql;cLRm#+Z[}Bn! |2`T-Dy+F6bp*܀Em![A00 #Fr8 b<\k-*\Q0|/c[?Wjݳm̑DjNCՋY=ԡ ޒ* 9h$ k~>3-: IZ=T2>F$$\MٍkᆋܠQ-~] in7UЃcs+ha9rLcG+u3PG@C48vB[Ǎ VSkEcÓ@7\B޾#ΥTuh˯^ {1<ӹ?n%S2Z=7'I]X9Ε"KZqZZLGU'aL?RVE"ki[.q4"! 9dM]%]dN@UF8[c{1ʆgxzD'Qݓ{ԽL?Ajb hwƪS ~6~'S4xuKǦ=J= J"mY܆,>O3cIsbLnɎ!u=|nYJ_#Y ݓ:"g^{\+gr5Z/" :Un405KzK@6@TqZIbD/*ΓjO]crboy"Mr\K3=?X:X3*P̞`6zmd SIE&cy_G o#?3t>2'E6~9Cu#K.3dEX>{)KUjPTeA8/1yVW0jFru%d m|Ҥ n$I͈$zdVA膬 fT1F}:~kY;nkbx0u]YV!VCe9и8nv֍V0.LZEU׸(6e[I0=7ž+Pq'29YQIr`=Gk,H`e}qVnu 9X\puMWu.{7V~iއ 1fq0m< X"B;g^ Gb2:Qȑal9"^I2X_pkCeayxa&<e;p6:ٜf**r.T7 `L̬ . 0CLqEt\qY\.یURWe7K0QߓP2,UG ͘"S,n5!zpL)':T՟2Bct< (*VYlSd2AYѵaYl$ueX+^ f\_tH=WfǛFPw]WyCV6w'[b-4gE#浩U6Ŕ9Sz$F  {!T 9AS3p~jDZV؁`z<4CsVb,0tlie| 'A8XbsANׇ(~93Y9r^Vpc,M"m3Ą[3 ,@1.6Oe)ڍӎEs'37ʐsa. {-K4=eUl(XLl6?,lbƆMOgkD^Mq,NKTRb1Buru$79ZÌOVړd5H[_U-40 f\}1Qz[6:ηUyq*Εnq0J67X ׇk[xnfJ r?hlNpl"a5ٞnՂO(JUݾP%QmiqZReGL{h]w씥*.N\E\3F kz=s[,/yصr3vY_/jl\EOTtfֹ-A*?ܻ? g34(9霧;ttݟDxm8p7slóm'TD sQ-y3/tNίM9$gpA>M^[ֻ)fENieyL wB!hl(y0L̚撯\C0|ZM°,E=^v>q1tr,Q .$g_xݕg@K8\@ssS\6s.L %L;ncaY.2*\<1k .lgsT*g@Ɂ_. !粊坤SVD~wCqe&]mqnlY*1KVHi]X_lMDC?0Rvl#2@r)L`]-G=^٘A)Q$~:UFQr=K?ӕ"~NKuu)l˳N  C@Z(BBuZK@zؼ8@20!ز귤J\@_WeYyIq*z>*PhW0QD M>)s%G+.px^OMM͑2Q>hƊQ##: TTիy.yup nj+kSeFFΩ PhK a_OФ109`'e<&Bk␶QM zx` [U,rxEG [:4B9p,Me|ǠUz,"DŽu}b Wf!)}_C_,mGy+ nG/hQQmH5üݰ|O1a};#"'*<^Nam k;Pf %W4Ƥb,"Àqp6Jo ΤTyJ!=Ìqw;eM͜^̈́=LY3B䃰)]}cZ˳E5Cc<\zHD9 hL8r[FfO e5 >XE|Fa@F@ apŢ~Tj4XiD1nߥ73%̇p +.F! gjZU9V 'Q-5t%|20% xrqS1g*i2ڔJ%Tۈt8 jxΔqp#\J1N' ,`}j $\2D8u[8oǐ]C{#*;8bT߈|ID| c1]"E 饭MEamݸNzd$(C#16sr/;򮐉_&l` @{KJue.!&ŽIٱv2v,Wy7ŨdًQ9dnOxlٯ8&n&Z,]"qSRXBZbGxpmX.{,*=ToUwW V cq Zr>0D:\&OX6A*pp |SFOV/}AAMs}edxd,t7rzj_KwYk\dg*J'rH8$%fB )Âu뭂u\y51Cr$bdxvT$pmbbft eOg4mE@8yQZ~4QmEuS5Kj ʸA#V81<ȭ[q|r򸧠vDr>i4P&p[d5] Ύڍ8Q"^JO1TSx$zCLz3m FX7I֛@0 "1ttg+t |/ޠnɎTƭU6ك>d&C3;ar_o^(h@VtqmfZ齂#\HϮBgOr&yr~ R٤p)3J`^2ds(K`^6f2s(K`^ 9x] 5* j9%0/KYSDWgk3:D,AZ]ͩZXjuzjuIe2 UیC}#B*kÓ{sUbHMZ34OÊ ί^`㙏S`2fs ui"s#kQRYTV&ZD\Q {;M1ŕ+.e>Eʉm# HRyvc>ێfr/eG;;Zžݿ-;v.#>4[.K?AzLy[gn2ٝr6B5ͬ/oT/+f ;^pw]m*\ To쩌vs j7 ,Y9N8g8{] ̔n?ӚaYs_Ϛ:~ =^$6,\;Xwt6khn ;e^: c߆g.]IȐM ۙҦU2bf0L/6e5,u!S/I-J')HۙB~6@hTVNߨ 3Kܯ>^gcwzz=5BÎcQK|WAs_}wbXUS}wmW<”$)I(aOZ/@h_qͱȮ.O ۸' l$ Nb0g>*\N$)M9 wPK ^BL1&6com/vldocking/swing/docking/DockingConstants.Hide.htmlZo"idV TT'df O&}HAxq.iu_oM~l_7W_ΚARE 'Ĵ!/2=||] {0#y/.)QorY(*p2y$41$$ÒDh@ G}'hr2j FDL\)Bx(Ȩ~-}M5׼ւDC-ԯ3ʢhV׫|P+JO|JQQ>Qk2NP_ë>)`>a:Q V{oEj&|َ̧gfIC^v_i "V'>~@-4~lܹQ'  :'x6sF-󕸧i@[AԌr fB))s@Mtr؊a/(t2Wѫwm׸nM*S%Κmm5}y*HկO<NfQI3Sf"Co2fr_Cc2-l'ӡvҭOc'Ef1Wic5*^Z >W'9JcyWC(Qhx;wF9nٵh|?5#1cb:.ѦSD4y纛Zh5%G9#:|1[[?,Ձ+p ) f{ňj^.':9Q yy&\tCJJ^*o)ޤ?aʛXd_5E|m2kt`f1sP{QktJy4 «~9ZmLֱ[p32VW#4~-Hw͠~6L |H#iQ(4G-yZdpӥ1" s:Ϭ,I%#A47y"$Np{)U~i)2=:sk)j^\xL()6<$dUk~+a4Ga#"$)PJMz32lWВ}5c/ѐG -ŒZ):RW~U4ȷU#X՗ٔp|U'迆V8`D5,ǩh yj&|َ,3ˤET!/4CÌ OMV /w}[irٸG2,h<%6Ol.,4c7➦Œft̀oe F4M|NYhTBNaqlvӌyUL'-\#k5,X8]FukzWJ/q$hSAe}!t2#Cs>"f$T1@UCo*fR_Cc*.Kdޔ/%/ӡҭOb'ތEFϞiCidՙ;h1p|\ǵO"IYufdWE'f;qZsOGHlL 8ëإ#u8sFn]_RT>R⬿73*zadXNm}T,X#y*;DG0IE*\e|BJJ^(g9ޤaJHd_5 e|}2ǒotXfD 9(5P&<7y_m.eae+<}[ӬVW&` *2"舒LRux72Ukrb rA`m` .BvAE1WðS/,0ʉٍVN"5nٕzM($2>hzFzUĵlbcK^gv1z9/Q=&P>WzxC=LT |HyQ(4R^Nࠧ c4ϋ,"n;,y^d t83P5;=/6{2q y1ǠRD8MToG@+=GiBxg#;طF@ƐG˚N [ZC6Y~Rb5*{g?JMRZm 3$u#0#.??=vCܓB<9pই}Eu|RΝ€20TLG ^7,I Fa@Tr€ Jܡe!!@a |eC ӴfqmS-/-~>ԉ1KjF+q7@~`n77lzKvxt${Y4!r%-:j'#~$˫LdeIXRX~W~d=\~'Gᔒsc,̫ISw޸<3 {Vq_۸xeйskAQ6k=kBa,[BAd4уGQb!)cMQ]y8?hgKJKf>S\,"DնrY&\2"u}V1Ju߯C8$#J]m̚rI_g/j GֽJ [t?y$jaaJڹD; F挋)|q0^G)uԳ\z.)L6RqY)^z[QFULkhhҎ!-ߢЛ.sLQ oN9zv3W^`6e4 PۆOC=X"Gr gqo) QhhC@oA|J֥ €$H3abϛE$ 9,x pv#X(NI0Ƥv=Jb4qXA@5 ]zCy(p0yivr%tE!U* pE'_?}݋`t‘hѮgC(Y?ΟjjUK(X [6fgO4f̲53d'KJޡ*$P. Y95G'1H^sj'*X7-2T #ZxJSA1W\Tܼ1Z7 Y:bHLg'd]{2"Fq.PmLI>kLJ@n/w^'o.yǶ;WF%q)"#JumHٸj\rKMk1 sw]j{-\:_vZdm.o# ؖtl7sQ3UiC;u;no C{ (I}]O|]x|CX=1?g|vq뮭buC<Z%_DYY\@8b;o. w5K/;;m9 kg ?/r /" /|&ΠZݳkv[wvek4Wj2K$_w&N@R+ ٟofĤKv$FTvFtհ/;/4ʍ{܋v紹f"qUlg\ yԆ(;際c- 7 A96+K?i6+-abSO4f%b:;LlV d!\%~~h"eyD4l=G*^$MVm}g A.1 Žl _[۷LFm`92hGӐXW$ W{yPj_,hngnhn_ (Sp$vY~\8_@1g _xXnbCDzL-7Xё%oTY=u^SD.g@ְKg6d'Of ߊ3[RO {l*/*{*kGR)9ZC28+>K sꇌ̃O>Up|=ua 'n$`Pz99+J'UYIΒZ_>~-?psWμ|B8n +<|е6ģ0`^`">E]B! .yYc!>_?PK ^B']/com/vldocking/swing/docking/DockingContext.html]{sH|^jWa;3wk26[;8vʐ읚r @UK|{N?'J% O_."onol~~m.SMiZWuR՚V5 w-u95_l[:o)i6 "/e&ԴtPf@-2X͙iCҘQCqp/=3 r9=}NF_KV/#s] 觀4>ި'oNK8#G-Y Oi`\-NH .Fg?y$>/$i$!|Q#Hv&J Xݨ-MG}E#rqAG?.L:jS8l(?JZR"-*~tfBGz{qs`@ 7wy #$΅Cz}ܽ!u^469Qt[se혳?DUkXL ȼfp$>xfl, :8Зm<\QcohkF AmԄa[d.̞&S_8;XՂ9|Y^>MWJ0ԶO)h!4T#8]USJq!ꖦ èj_FOiڶ}TPklRdVh@ Z̶Qy6S#%"75"B dojN+(2#TKaT-e|*l6$01"Ч| p<"̺c2:pYMas ۖ#[ؾy9cm(J7hf/HdW6ŏVc G QD` xٺ4qCdlg h>#(9-[qZ`=-9pI5΀{?&0qK9(/_ck5bԶ6|WCT~8 \?/t_Q7;}%.p EtեN@ց(6tsu{YDN|uo:;bC>'yCG[oP3!iU|/I gKlrñjL iNyC@-8" *h2=& 0Ji ~Cbu3F#sH"VH}4$b_!7Ö\VF,*ՐK̼_%_^8P%6˧/j8uZDI`% A#c@ ğC>pIgSC,p]#?Qqw1be'c逛 ~sO̔ Jb %ds}7*-%x:[iZC5,LcprF=p Ɓ ^bĜQ Xl(:fHY5d m[/;б*W+BrמmkcHj:MK#4)^ryR"[H#%fUO=֩nߞZ<#[ɊOq_RCz8Df!sL $x&w++9z$z`xe쐞7nKЪC_">/$쨣n>I~N7Um1aWabC+!hSт11=:d#6 O=+MIf=ϰ4( 1cC.˫cry r㛛NݒC_knF"5/ ˧_BJ2o[Eb0gMKx*x:X# }V!Ԥ~[{dzzs_Agx%yZY'f`_xԝѭ6SUݹZ'-NMx%-m+އ_Ck؊AbV_UF{؎_ײ#_ -0twKm/]X+?b{ e$]d\@i;M**&[:ѭ+y&| ֵX:UEXa-`DegPζk@ Ւ_d>aÉ>6facq ]UN\iSJ,ɥ0H+Z NRm58I)9߫3g_ͺzX]&b.WAtDlu7Pi*2KdĴ*݆"nZCG-}&;4m x&%r9bF엳1 &:lbI g~9s܀%k|:9cPi< k~9,؄+,8B0:F&`-rVZnHU.뛊 4v˼ "GӦ[S(LJQHh|c'/T2DGy,X )6'HjEY OWїi?kBb\F?Sh2L4Tv2JN 9*NzjrdyX!Sʊ)7%gTȚNB*Gp͙QM(^O ^hrSW23GlUuQ:99~^ym&^+|XKeULj̙T&IJmQbZO3/-:UyᆢI<:B(^KMMbopLOKΌSP r$9ix>k,J jrX7vq:pL QrHqe¡LUR)!Y܀=hP!>yp?N1:w@@(yxXMϯoժ @7T.(]~|]Lib~vArMcD>P5jp~qWF)) < Ia?zt7x' " y =Tj?T˔Y/v~ӽ}ܢ݂.)w*6%rZ.>t`Nkʌ6zܒ7{Ѐ_#~.l9m2-0ջ^`R#ll,sT~MwY:ܕoڥb{]I3M^=.W:qt解o0koy 3|]}R/>}Кp[uՉU&#m.M-[jzR%oQ8U%n&Z%jaV$*u,#Z1Dθf "["WDhcR eJ_qmYT vꑓ(ɩ=GjW p])5_W\C+G`rm+' u v V8 Ȕ'0:*3nz]雀WC0xsŻ^Ȯ(6[P}F gGhkdo4 ܆ QM=1#t7(1SNq@d1<$ꔆht,pK65}']Y9ٮi sqs4 O!KЈ#,B Nk;M&r|h7:^كB9F͉^F0\{v}th`s]3!R$k\5SS1ú~\ dN|%䰔pzP+=DWYqS2]S2('OF")WX+e:=ZPԇDq"iUzL*:%{C7^\vM(Oz}˿ޑם{*C79KdpOE d^3]^à?V9V ZzaJVߝ&PMLmԊ3 =3FMNmߩ2ILԘfjOӕ 6.{:Ë"a(m@9]USleœ`QKC<Ѵ=-C94m[վe*N5azok n<"aU}x`Bm<۬>%|2֏~W EO%]C:nALt~+A%yK;Eim2\Rq:q֕·>-<%Ex)H !ZhCQuJ.S ݠW6ŏVcy~DBlAX]4} *;LCmNE-QR]13‘s? TƯ/"dR%ortJe^XU3+/sb#REueLV:Ֆշ蟮{Zܑw&"/I;IENz<=6v 9ku~$NNk$7f3s j9}8h<*PK ^BR/com/vldocking/swing/docking/DockingDesktop.html}{s8uGlq={w r_afvb!S!(4/3 HحH"H$l ʹ{??pŋ?{ b7~G7$If?ϽzQ'4c?"z^a;>vnȜc|_9>g!}3a,v9Åwsb;zЁn2y_||ݫd]<}s?%9J>q=G'wӻßuBQ&,L^cZ''f},'%NAɄ}N#IƯ{}A5Dfy /,1Ic''؅s9Ê{~Ϸo}~ X :Ckաߢ,o|HdͺrO g{/А<;a|#3gO}Iw^9s979Wo%g gC/F :Ou> #<,b}? ώs ?R;:>'иyB+']dd̞'=tƋ[`p}Y+u'f ߸ W z Ѧ %+y*TI̘zV}nf1l9es DnҗN f0dw,֟w8%{ g AM{@/`f>sCɑOL wnȂP@+QʁhhMםč(BܐUVMiT69W޴q:֧A z~0CR"hE7K!=_z2܃g jK'z aguˆQȌ% 1˳"nBT߄',8Grrr.XըήNRBťl{dp'+YO } e߀}Ū*y\]?PSޑ G TJ̫Ca̧Fby;E1iznT ?"s?3i-2WO95AфReh^nur-Lp N~cBaP6)'ƺV.31~R!$}{k- %{; ӚGakeRa qt? =޶6! [bq26FN]_vItw\&rXyқ_$m/$mh;1:nhD!~ܙKl賴!^C%"#Mlh`M2|}pA+"Q܄9}O98@0 GOH0Y #||$Z l[hV= |  :<.C跁?"j9tUyA_WϝUI:ʫ WD~/wF,fX e38DA 4QT~DEw޳ S'ؠb{(czsT/BoD*"O=m(£gxryh{ `1e5 ^rX<5Ԫ}YwHArPDY%lr<{C%d}7WhlOb+mF0YuObR+BY1к!93AI9vF._mi0#hár@Ӣ, sa\U, '^RiX4c7Hd\V6]uügAfkR ',Х34rʔ0P;T o '-BF:<;OY{H2$j5(dVWmL籭kH`vIɳu 2햿1Kqp,Erk,5XzJ=*^jͼ+`FvSPxnM&pȼh>qi=s:w9P,f@1<*,72velrk;;FMp~s~_.\Q>ӟ[ե|{z}fpqӢ_KMU} lI;hoOQλӫ9LAKXoߵ@Qpʙ'2 B.xb<Ĭ`r6pno>.>.\ˠ vl"%'?`hSơ$+:r I4ubaOaYAѲtA//!T[ȡ-ME89wG8V-"sWl=\v Z;$qS{[qU.]yxP$ YX~Bs"puB<~gՂPoOKc+7ѝg׍0Ό/I\Q^.A,剩"qa 5EQU*Z)X(J؅aW Sgı(uGO /J=Qr+ұtFP^e,^9~%vSC4)-O9aY $E~6h 7tF)ڰTttVE1V95YH9s$iz VPdŏgb2[y:`"/V6c\`WUT = }rYbd{!OwWgqcF܁D!Z"I!9iDds]9-t\]M|< 4$:fq̾/|\^m羅wnRY:>x Cٔ";0?4T$D.޹Gt[@^]:Lom_뼶{fB}n90*>DxZjZ#M5)%Rm 2c+s~tHf,&΄N*l-Y"!9`|OIyOF\5l쐝)&E-OXmE"#o3P̶<ґlrʔ X(g 5 ";3t&dxi6yP_p }$'GwnO:ABM60],k?X7V,`KZ-s`sPZFFD;Ɠ܇W緦Q" {#y`/`^:gW5@F0i?65͹OWKݳ{u閹y7]"S*̞]޴%O"X<xF6(^h\:8*I#cRV)S=h)]m)j~(⭘s mx(ܰÕ\r_3_f_g\gghg2Gn+\ܩeY Y1Agߚd :UBR=/vBO,fDA:aޜ}`{C]ͪ|:as0 |(Љa#>8;Fk *z> &{9P+΁#AV|<\6f+!ԏzl<$xz.zEO?ۛ M(xUشё2a!~6i`0*g6 uATv٬휘fiA cCm0k/*$eo>QCqș,vdaZ v Fl%{<`"ЬUxGE=mYQˣ;R^<42dꝮS{֗O%b/AȌ2Jr&6VM}|Wo~PSe9@˕]oaMi6~;a\%L83ҟV' ~-wD?)/ Nf[ĺv;It$mdGVQ]ѿSZ̴E6,D61g߹]8G೉ӈ 9  ÷4`|OewK3h[]=>2frd!KҫE`vIu/!Ah8?'jvSU~gf)[=g3 S^?s@_P? fvWz-ƏQ EZ')K|BPț!yEpN$/멵gY/B!%%!;Xs.`.;!i^4kH.efH/OJ@K-|wFy%7@zC/CP\C_Ә;ڣ<Ҿ YrOM_Τߵ׉]>ATzvof O3wsf g:ގZ3U37yf6Xrvjɨ:n*GMэ#ḋvF@ BОpH@cs'Lp;O,}GiLy0)\>lҼXmrBUOy Sh9t"K}sT#6\ LIJy|L(\wɵ hr"ȉ^2iϒL@S"?1 ~@o7]NgAM[O'bvPj-9p */]zS'sl d @MZ32EYSib2 /ş ֐I*hg -vP-Lik9K Q.F-dnoS] a65%4{z+Sn5-XB}ST-~mZx6͹TAMZZ-N9gO|Q r/-[⻌-QIs̲%4;5SroDݳy 6e뎷ڌEg ,~^BΕ%鄗꒖ҮdAB>pcxz5)km)sIjVб ï1rLPnas^[ǻOu&oCx >?\o1jM㈲ B30ݖV)-)j=x}|ۂWrGa);0:%{byocF-fQ.H*[Zy"͔a%$` |MAem;r >{T]@W/k R)|``ݲZ:m z9m qL-;Qe-خp;mw)c10W siސ7lN9q *!-33g*63°v,sͦdPҰ*5~ he >q/Oȩ+Mwȯ*cñk_y=VUe"'fCJ̝ΒŽF*bI&qm4m ?=bEakr ,ɮ񍹻H;c%;ir6P ]\FXwu)!i%f>MqY |/1^q<`+<FnsCGc>6"ʝ!d yjWqHzMXҘ_!M[Q$lE!MW :֚`Fy=yC,GbYRȾT,Zb`Эb|r)<Ɯ_$j5殿qе` l:YRBc[VBy6t8kVo^@1޴jHc]\ɳQ+8 ƳVIoݖrɞ.&,#гԆ2'Ӗ}%gS^g!6m=^ u3ܻƍ1-ӆYSai#_Z½$&nhׁa3oז ɫfBV|=0[RϑW{Qkտ}(8F"MGtW8Tf({qI}׵]LӼ?ɺ qPB\ʿh԰r[n]^z{g`m^$4eo,fE+[MغĹɹGM"^GzѪ,ihc?ȝ&2 9 zp+,āY&V̐%`n[V3 BMMVL9 6NBG/ҀNݸ-.hSvՋ/-(XXe,>}ki~dnN蚰>+h=׃U x-)kx"T̲6 n޴azmډS-N-/s6<fG~@5Av׽`gi0ora"}-5Stn5laiSi9@漙BwlèVoZ˖ \dߔ,5ۤn;Cb*D9MnaeQ bۖw[n[98'̻mWK>%svYփm:e5 Бi%DIF#S&ԬjNedJZh;n<,U Q*hl0M!$ԫUIfа_Y(5(gtUՄFȔ sic4oR}0,mWt$Pa&lr '_i^[<r?5촂-6׉^\"7`|$21hQsbB[;wL8ИV1Iő75◔MϪ- Mtg%@7,kMFW26Q}s(g]7ځily%346z,Sk4\$Lī>Ox'Q/J)#7;ڔw36O8yĕWDL5Y7"@-[LlQn(~>0!ҒLϢp?b \ XMЗ!罼)LQP\IR-PF.p~=nElԺ!^2}`u7|P, F1c-grf-Y6slAی5Ц,q ΍YSE5 %l+́֐+l~rB0Q Sw.Y&()gk#}ΥpR3j@"r$qR1KWA;i?C*apkZv@cg+D~^͛LN]ֶ%ٵA zlT9ƱBqq1q>H{6$5L U$#5߶HFj"qsYk7[Ԋmi{7TVm]6[de)q,+u*mVuVoQܿNXU`aYWBNcle[Zn ]E v,vi^׹ T4cJ([lUbynWUmelAzn Sq Yk8k!tOY.HXfm::meIꑿgDKM6O6p}yy>vfȭzy#K3KBZMcK[,&(6s*M4ăFNs#t2c+FvRi^oF *A|(nNXڊOD v8HE dBGmI$&i˵dC3/j{U M\K[~j8B{;ჹ`D]cѾQu*'׾l%oFHa: lHAa(>Y[ \fa*KD*YdO΢*YdaE\ TQؚ.=uLXDQݳWԥ< Q˫~X.9o//ΝF.YůsJ-'PIܐUQhOLP,fn3O}z?d@Rs _]bg3@.ޣ=k<=q@be'S)^Xg и5eJu4p1΁H1;J 6+fTGso| C&Mԕz,Lj"7Ώ3J@xāv9TMqCsH‰Ą4<\v t c1sPȼS d){(-9fˠ&t(> zt=A Lp-9%# {ڄh ֎.p`L,AB{g%4Q[G7"~IsR Mfj~ZdZ|6Q7Qc;ZB¾aW:`0L2 1Vu(I.TR7{sMZ 9SQ 6124AI7w7lt=_k}sɑw!arGWzAjO|ENqƸz K+F8oXzqArJ2>])>}<(Jђ YeyD#<6j(rd|Pۦ@8r7z} [ ˑ-dip6XԮEˆP |2tIo5L;:GҫU,I)>nJ ʍr1SѣɈaKv$Z$t'w6cnbr ̶R ;H'ha{X]>5Z&/v%boWs;5)vb%,)yѲ$ !'#TC?ep!J]g#B1OctS{r6 iw"Z)k5{Rކ=q6Uă9 4 y>dU Q'K˺caTD+#PIiq ,FtpdqԂMtFݟb*4e5i=4ЕT'Z%,!̈́)LmyaCksjFUQT;rhȏ_) 4$%݈5B;q0&ऑ{aOh$<T',\;yQ5^|drpl uD[oK>ZquiD۰T킲UIt|UA vUբUg*Ir$\SX>ډ Lb"~b_#!FI̥j1ْL&yB͓T<~OÓ(aΏOP8:/x9<E~nP)FQ{,C {bQgVdg3mf*ޭhY{]NQ%zߜi}]~ 7W0JZ躺rW노5o*Ame:Kvћ\B'Ёƀc<٪a7*'m0#dTZRyW+^ jTԖFRԛͣ:T>ͣ @bA3Qb8(摦n2K2U %# 0 eLsB9iߔ":37)Ai4wh6s=Ir]S#rBceFy\Prl=a0gs(M'A4~^|1Yg6TTs -F6BVǯċ}}p<u)(R HH)B$vbG#$HlXTb0((n `sGXFrr*02uA0,WOh[^cT5G3 LBOlmD_x wP6:!NMWzCTXrw#bxT&PW f0ŋ\=xLd)56=@d_Z4ҵQݩeTmL{!^-Xk3CmЛ$c$0YSj<9U{ƤdLTh ץZ=&szմ`l$ׄP+˄Cshi˦ fxMHgLA&P64.yӆ8 3WgiT+4g6h< ik(f,a2jud֖R؇bآeA& [0}'&QDU*g`0ۤ s-uBԙ2&̭e0%KR  OQl 8]fǮ-C-Aۭ2 ΨhL̐bX-(_f#\f4Eow5X/˟ys+!UD{HT^>UdX.bYGaFe8>FË6;Ʈ!"]>\9./nȹ>onO7?ګa :V=3Ol'!~$B?v)K0›Cxi֖+Ʒ5aH6(%M9i`ښp@nps[F=F'W&=֌gfxMEaUuh˜ԥ#8^FHl\dyyy6ZG54+WfD!2ܐ%h#@ Gܸ4 fz[J+Xo|,yf:g-u#7atNܧi ܂7^%Aׂ]v61|Dw5[`|#܄8͌{̛t)cޓ'r vO⹸&+2jJND״*z/[TZ(,iι+2n1-Kle7# [5B<n22\u.Bjo;\{ tvb {|or}@[KGR1PLA |vmIm92v.A7lIʤ) s5jSqrXiH9FO2*PN[V^hS` mdF[OugC\yѷr(v!%)k1ȈdݩjmS~XTK1g<%)$6r[3#z&8u2_ D{LqJ>Eh.fH%szxsFi)EI; O؟Df*?ΓqlCByHэ) '7` 2}c)p.CSި\:V#$g#fJ%:s4Ӥgb]+Uf<QFq~ T|=,>褃='p}Pxtխ \qS6r#HB,b}XF0$FEUIeaٷ(I鞾]9`OnDn64ߣWɳ<pe)1n>UEY*zBL$fUMѽLZ }=LU"eN_cs1:g :˧Bc!PGzir )4LZj]~4Ԋp IP>zXr.>ME DJ:Tٍq`%3 I)/;dNG+F} m 0gf)>Szt50s -Hx;/\b2-3|2uC] Cq3bx$Pk@yN.(2W+Ik>29a.eΞw8ʣ7֝]ѐ]ĎtTL |vI{XDŽjY|nYe{ʊX$ϴ  XE8Aw%YM0x"hr$)6qAHUpIM'o+œK#%9Q榾=͓VuN60DmNna ç>G] '):D}[pDK|Oi]b"dg:*,)FknY3p>ѧ|[Pq5DEsR%E-$q~cuzC;%-ZٕiDHMhoQHEGDbm:#_‰Gc݁Peڵ 0_V"{kr֤!Mq* ?E ʚݒ&wEErRYEpZ\4<Kd^&1 |bIDRo9VȿҰ}JDܱ7u/ UԖyF)bGI֐jjd\Kh J%ve Q $G"E9-a'Óe:: ;:!Nd@HOCHV./4gػ_ZeM&xVaIE̘J]LSKfk6jm \WHu*r]?Oq /tngw`><.F7R:߭@X}p_^`6; R4_sv-qkVD'4~ʼ:Ky G)}BYyٻD@_WpY0 @U<HLSYM(rwTΠW1 T7*/aGrhzJjwAψL/Qe xO1ۭL@x{)F3{tq̗фIxS.%bIa?3yG ; AF"Db}""'(#EPY.B&rZ2DDH1">)GPg'zcWapԾ؂*DE)S3<Awd*P|8K샐лF! %cC6q1R4>3Og+qgS"='sw8L,XUx> byRt;72cq c"" @2$K7_b+U\&D֒Hh4n\mD"*8v3+&ۮBWMË\%_V$\ث1,Ɉ&M4 s wsZ%- ŅQW&+,x3G`la:20{<:mHwIWqs"K՘[P"YIj#3/3 1:5 &(:?rK:җT["gS!%;槌G@3 ,Ri}c0 JOhr Ry&La2im*R~-#KO$zV%UZBP+OCT qЁ$b< gD'7"vf1%B0Z̎" =hTwP*eὠ6NS|UU1Hh-o*!ȦKze`jil5ߙ|Z:q).2T cE+7E$X)R%q^97[9?;~v0vnN{szd7ݸO'Biū2~# ώ߫q|W@?YttG+Ynt-˽Qƫ|:u;»Y ITOJ݉B7n|Ƃ==ecKe 9[*@'s<}XrtzRr1eK]3O{?bap*qMK9aY]mv1{rKgjl;.Ey \J9ͺB( C=n Gxg^m5DNFe{LXUMN )Oa8oJ H؟%NP" vI}{s>߳;{J{;"$y.Z!Fނ@PK ^B̏"c-com/vldocking/swing/docking/DockingPanel.html]s8JծSK9ffbo)=ьm$9y_\YXSh)R&x}M5h\ ǃog]| P~ gCh[.#zgWY{||>R7VPp/>]kcFBޝt+Ӭei.hE,.͟_!0E޾?~x't=wo޾y$p.{wmAG_.3:5~=z}}ףW{q`!'9Q-`78?Kq f+  𷠷`V>^t^_+SȜO:SZ2%3Vf xA("s* #KtЅ%+2ˣ?v$7 :~ SъsA7kFfRSS@ş./\0dft㣹O{"`d $dh6FW/ -1^Իxх5Zs˿#Egd_{'GsVN>8EvI|p2?7N\D\EYh%U@1۬ז9VgXx➷ յz&Jd8o'@-o%IgqScz,J,{>^rBm[Nt$>$Yo_Z6sz/][n=.!f\PdЭdO\gF嵏rLɔ.1E z_!V]f.uCKb}Gaޣ(#(+*'ɯ(P("I|mSt)ӊwUk.ׁ<4 ѵ#Ҟ9Xi; }Y oi] wy9֖gՙ^^?pYZ8A%yZTkOTw)O#^quqW'ҧkV70~#fO1מ<;v.\ДcUanouw;>L[Q;{nYX8E-1–*jO8ȎB,!Mztv5#EdxP5Oh؟IJ [fxwN]heCI׉on >t~WЭQ<^خsw9;vPzw cw|$aYLSx7PdGޙ;㟗M"tN?_h&]]F F Eܜ!5dhJaD{#)nڜp#O dc5Bs1h9ITm0SC$>e>p[vЧ/0ym)Tgz7n3Hl]ɐO낼)+U)o C!Z"sTԷȜ8$oK>Kx |&z>>6s,TCsɴ^ͪB62? eH`{&cOv$ilEd%;Xa*˛ %8PhwD"A|VtȥZO" 6:k[|cg+3өx.%U`nrmuN0Oxe=Z_o|,؟n,@;k .b~Jm6b3n;t[SO&N3*a{awUK+]LPZ*XwN I:v6uvo&`w!o ts5<;] oh6_!@mjp6'f*Q\^ήf&B< L&1zMseyut55FáS^ّ0?_>gmbef \<&f zqv>3M6UPfچ9_W:a[Ԏd˘);ؾnȀi<)$!jIqi4TTp0&x>_U(ˈ3a4 q*"8דd6:3-Иt\C28_GgCʚ⓸lr3fsA8( QxLH9mtt;g6'ޫgY ̿k'̐5+"Fk9eZXN?$Ek$"xg9 SDDH*yU]ޥdF 5>,TXN0Uΰ?՝ۨ~&ڢ~|s*{$tTuJkG/\rY6u']ty6BV =z8ᅵCĬ &(#+,Xhx>+Oз?1RNjݙxM-K#RpShC:&>q""p7d1d!9$>>#O>H+0b{R V *T O]lLcJO*˿o}@GL_su)$Λ?b`FSS,ۼnh뵋/#%5Eɇv©:՗n~ S@)!ӝEp-'FrCNvZ3ĬA[Όxf"CxDkO@[_)5jGĬ?ќ&$FlZ,_Oe9<>%GGXt9X:xe85HޚE|A {$%R35Bc:VhafH!g9@!"'u cZ Qj`S ,#Ɠ9fIqڬL(bz=m$z ;($?"D%oȲzO1V]`]3e $7wGy7 8]X,5s8-Y4`=@PgLV[m HproT8+b MV\Cj0 @bz~֐m d׺jnf2B3D@ ϖk;& z rv+}&/1,yI]S()Ma=x_qJ* Pۼ滻05^H!pMWm5K B,b>ʥxu+CIsiO[AW20xǞ?B~?-As& &+ֿ.=,OVVŬaψZD攭V簀r8"fh=Q5$0Ǧpn728&@jwG5 oW6wJu, T/3;Nx90G8 G8MG8 Q_Vf׃3g"pRkT \Vo?41ZK*)DS5[d!7ϩQp5*0+̟ػGXvP\ I $@`DU+0Mí85 qל"ˁ@=> *#C_h>V/-rX}vrB<\wQAwLK8@NGndF[J%%$0c42h}te :K@ac T <gw8tCqِ; y.6F$ :r['%zm*.c r*|DHW7qꅹ ǗEiV1gzT °[|rUuf5)4Yiw bF@wW-g3$p'Y$JR@fñQ;v<e =@ &LRWB@Riv MeW!CLXe9G[R4d'B曱0 .u@ {!Vl=Ȣx-on=.BK2QӃO1pA/У}'ZK*j_pqt /|Tq6t^l^2Ko@gw {vqqAֺ%I;Ğg; $ءiH ?*?,,,nSFUm I(g(jcɸWWLZL/-ݔ;zi-kG5B+Ѐ/ Ae%eH3[Uz Uءk# A8}ܴ,cYqig@nkkE'ÈʸH. 5:ր_t9x,<(6^ֲIF탖u]8C0ӤPwӟ=]){ U xÈ1-OtxǴp@K.ڕQѦBUL&mv' ۆ6T@a[7 U `:S ֑!5̆Jlx}Ձbt0&0(#Hx(|abC"qL fւY2wyHOwX@aήDş\य़lUz9 EKYQgSۤ3@bGWUg6 IPKIa>3W'֨5&skjebz+^]rxF`{bxDI`IZ"qRDIQ`HdFI (:)zP9I)wRⓑ :aFB(PAS Nb.RJ+rR"o[4CVE6 /Gk>J\K-ND<9IaP7BVfk ̗eENXeA@}̧MJ˵OH_bͷ~&CO4Ga`y֜8$ `BD_fF5p;O`'b6j,/*:t>I 3119ě6%qT6a,g!-#{qdNFg7kToeg*"[Q?п0wFۍDP- t .M.Rt 3U4xSv19 xtvAM;T)4Wh `זMG-6:7) 冎3&]N1<)İui"x}!>M:@o. s%lJ/}m!:S6i"yېM&8{1T `޺.[$lL(*LAFT9Vz@Lе|@p6Q?U I2 HLCuG\#b1A> r i3A> jř&2"mjR.SYNWTcRӴ8mMR$A}7R)px+  6қ:wq)AG+IK{(UXg|ڽr(k|=(6t(2F<ڷy> B-FQk yv+1ꁾl$$\ }mwal=ct헥uED68S%BE5]1i#;z֡سFO'889a#tU kkIr -y_%I8&S^ҵ*D \ߍ2+v+X }BeC&t |p2`T-D+F6bp*r܀Em!~]A0Ů0eF6"pŸvZt<`dk}^ƶ.>Ԧg|y!:Pbc<2BC.3>]Z!(HdPQGbQO"$n$(I2G>𣏕y Rq>b9r,#kv7~o.HxyI8|Ij(4_TeOWAz؟EG%M@za4K@Na_Xiv@o *Ӈ ̱j%=3Ʉ@fvtb읺) [ qG7OΥ}պL ȰWp%k_%yU+oAS0KL &SEd۷rp)W $OcXN'8rI ҴLċHL4"[Yl5e1+d!M\@U$~zOc{rPDzDWbQ {l ~_aj"wƺS= j: f xu 2^` mq>ӢLv!!π-WF^z0V?&y|=zCjDcO|O׈d9WKBjp_-Exբ`OֈcTve") ުnvKErTZ§/MQ->PbD,Fۋ"'OR^J.i426'Ksb#JC_)PˆACbC^YCSQW&Sq8-@;8U۶өdIzLhfeLII ^`~ٌB*BdoUqzӤ Qŧ=Ij,7xU)ƨ0*V#栊 4Z 1KCRħ%B?r t^imiWq[+(mB5lO,<< D-C}nU҄& ;c@]3n" *./"KO54+/GBSCa{ NN]g%/@ѫlB%Wge9!y4u1,7r.2C"a5U8o%:T0KWMZw/|ϊzDC<9(!g_yi$r{ER|^q =otd^Em+5xPUdD١ת8_$z$)9r`&9$N8?]oi)l[$xPp^ }t*tE' )Tsx(iht$1Xhð^boKTv4Tɪ ]1b2]|to*E lz-]cD1b qAÀls]feZg[/qUn&hyi rV;uv5Ds4Oh؟Qv#MgL4ƗSRC&t}e=$VD\anS^[%'q:}XS3| wov{:>'%>>ټ9laVWQ.kc;f&˦"^TdYøk6MqN0/Z[?o/a)LN-%OXX|@u,bha 1ix.CŽw[d˻l3Jr|L>T \C<]2%pz_!֝2.uCY22Pyҹ9=VTtO_QˡP Dg]X$nLtҥQvKj'8.dOF>yhN܈1sݬE'>svd',x%+O2˿˂sjv${iM1ӕ|R+9zҕ۰ =+T!6~'>>w4J,hʱOnNw1[ڻvZtLpo !iCI&oFN w3V5oOHE,S߽͛y]p;XYk>'n 1`[3nͫIsjo¦?PK ^B E V K3com/vldocking/swing/docking/DockingPreferences.htmlko6:@,屽I"/$mEH I/ɱSg_ p,{7g]|88?%^#~;< vm_I'˘ 87:y2`U T̏t^Ԏ~h4>#`/"hoz,6}FyTt': I}Rɾw;,&?zgrCKs-X-oRc)CH Jަt2} @ow C $.M/<XX7=g3 2iI}AG@DMa8ӕ0剞e[E!Eq>^?r8D:؏;$_ ? ni$ lsvzoL`ů~&sg],%TK;P5r9뷤s}C=9: 1H(RI\00wLG]C{āYaTZ׺v͆Hhֻuc[f<)bGOllӿ),+CA()cwVuEĒgXE:ccjP!9>8`"iU9w8 dq=* -ՆUC9 F"<?4fn&^~p=:r'v|Z/kPy Lۜ W +u،F9 }ZjO4M >Ʃ*9ȕ$TNrfaռXc!,K;]_/7&)"L0z29p{uE$&4o~pDgP"Py]6L(.l,c6Z g~^,g*y3WL[z3QT`Uo]HZy^-O oXA`</gWL5fOSӋ;>fen) KxAVA)e!e &`|Hj,(Knhb?{2U@n:X@? X/.Bd=2 ⵊo>F eWE/#u yR7%8;*ob0Դ+xhXF/j8-Yyf]s3~t1 bZizVdC>.Nj*BD5rj\jE( @sG04? !,VSń xlD 53ŏ&c}4@ʒD\n}!TPpWĄRWX4'IG T;I*j1$53Ӄw9 uW$ZG.O8("0rE}M=[ 9J#Ycƃl4#Q0(0..DQbإO0$gwmr7y h".Ҫtpb+qĆCU{>|^z>YۃebBС};Mo1` XjApAGȺiURL9lV aܳ8ZyrT0ǩӘ'b3WhCFYj@F{]D4CcPVHhuDS\pRtiGFB<-mh>%BAʃyj;^kђpw:XĐbI}6.w]~3僢}(k/Ei}kcC 'K"9&CmT\ahP+(ƢZfV*|yJ)גkU+}f@NsF~bܔ?̠)ψ,6r^>ɕlɟ1gyS[֟fJ]"n[0;uSб?z.YxZ=v+&FDb2bq$:W3VVJ?|KpiQ~n1O4RrSC:ݖZhL/ /Y^mЮۯTpvyxbhH#L"0>V~V ߚ_乒1.O+2TlŇ (yɌxBx?Kr{+CbbV}k6rgVJd3~]S2hEB9gE&sF J]I+7vy6TcwK}oflBxwԽێ`}/{qonXĖ[ӱhyz .$oI^dT7 ҎTxlv\6a^nBJ6,y^TA&mijy)N6B| ؜0z^ڴ)DMHa1z'gˤjxiEbB{vEmapG>_l }Q'S:G ^@M2KJ w T`Z +g+ɠpyZt•A>Ylze3! 4#[VVO\r(AsM^TȈMZ9ls#,ɹlyw aڬG3hZ3<|?Q;|s!`c:Q-ЮOr =QAK,lT9I@Q#uŶ=S)ԒVnlzVl4-JJkU[t}T/^bվ9*f|mTK4?)EꨶɐVC)uOU#Ewޒ۞>Yk`?U65{(yF53#ߌEGrE%I"?Fh}t3G8\gGX_PUAl*!o7?AK}ٹLjW҆q|)93Wޕ+VrWnzUӹ^|W ~AKWwpB~_v/wg~3_~77_f<,a#O@8u[ Ԏ{{?U]p{Sm{)rDrnXAb([PK ^Bx.b$Y}6com/vldocking/swing/docking/DockingSelectorDialog.html]ms㸑*.u%K743DbL{+{xlO#i Nڇ 3tn.ZrY&lXZL 7lrA}>r.$8  x2@߂֔hvh6[<1b9VXDlmؿd^fe%6ڬ$;?{N<,Z`v'S:J %?-σ>I+a`?$B%QVKOK f?]m٫T& 8T+ho -R0M qg8k0<Η0*SB {pE0r&#Y2Qoȳ+Z)k0%! N8}P2N$򹏲Ŧmie9Y.4Y{l5բ >6zoD +w"Z]:7O$W2c3+Z|4eιCKSRyx&uGR߰79uҔQQij=|#3;!ޏiEvia6{3B~dM6VAd_(kO&39֣'|ԬpvK/1+y[=jξbZ<]aC򅤙ZI$͎ iSn8E~kiuo;upij1ݱm̺F{O;}@j׈;xORjjtO++o5I&HΝQNXjd?>P}wl -^ |9+;Rg`Iahc '`µus-3*k4}kg[6ӳ}k=4K'PYbY(Ők+Z.֔l܌ #┆U48:(^qGz[UrUvm_? H5l$6#xȨ)faG^هh'^iYC,}Dڄ~g[Ԧsl +pZLhu=o:+3ymMh0e`wL;9/FLH ?%Y,?CdReѲE!"PLlQ9ϼ=+1N l/ooS~+c*b1xEM^ntzXMn/|ZNsNI^eh&Rɬ>]8B,yUK5`=תWfz*+[8AΞvH›:6odat'aLDlXEِW9) UNXz ղYW[R*vxܿ VT^{GtFCt1N[;TрnhwsKW;'tz`8k+AT<:h h : ?1x94Ӈܞ}ȟyWy 7V,T H~ k9HCkn̰Z9=4={YdDW 6 A.L@BX?H_DNW츺D챩|ғbsP\p1փĩCbO̙m7ZYkdYsȠcA,GjlĤJ{0/uIFaW>7i;Rt~'$MLXouqX>XFٵժH|ӕʴVΆp &Ug9!εa;wo6{سM@TtHcY=kQ_n!=xV\sĒ׊&J4 IQ؈,gZґ N|t-vp!OqPC c#X:DbgC7Ҽ,29؜ sM"n&_D 4}hUZH9E(B+4p?LԞHQ ,BhĒ׊'W܈q)N62OygtgS|!?؈&Vȕ6LO5IgQYޅDSUʅ߯tI&bIK7#~JbV h,$+9j?EWKP"-i?h8R2L1wß i@cW(H 1sHZQ=<ZN|ƕ@!NNVo#ãr;狐ap/A8 :C零|q-]]oJo1*u + ]Q qĥvx uRMv/(+Ug``/Gqu<Z 6Zr-&PjVe8QgTF+Z+q6&?I]mDcM_.Hkǹl#i̠.0B a sM:SvV` 2p3p<x12:}qXN - ZH#>ЈNM%45#c@gj`] mZI͸Fs3"}m-ZTZ1zz ?Ӊ"&Ab`cȡ^bajX`e6Pn̘ImMly*tWwFf.d:T#1a ̥f"' fMSNUr WɩVI)M!}҉+2 V T 45m ɰ󉲄 9bb -QBU n.6Bjc(#x/) fhn~:m(5 Q@/=KxQU$(j!N*rv*cy<\\fԼjL.0 KO. ҙKA՛$B*0ܢxlS8IFV5{_Kv ajv{(7.A,h Ӷ*897/;-rYmx`VG/ zI텗$(g/iPmni޶AZBp`Vj U:%9?޾CWu?He%0Brt\hPKN貍>2 |S2<ԯlP*5TAX7E!eaj[9a%an4]IՉbKeP7S0cd C%!ge!{x7JMF=`o G%ɶ 4DڻY!'П7b\@ɴDaRȃ̠HSѩg DKzQ3*r0ʿݙ , @짹 f4,.&( $'6! }.q V4FGNQ!:X#Pr EijxX Gu|PcAiE8{0]ڋ[Eca> QU1]U{6 Ú5/cU6#iӮ-r'31\+T n1.\҇P-$ubtTN-8sﴡH;Vl~_'Z9`6uKIS7gaLݴL_^iK߹}'?Y 9 qvsY_:Jq$ CnZt0-duFNPF7cS~Gh C(g6/Bztd!M̻Tu4"sq`6: T,zRXpXzrCKQ>YK W vHC{0@?ܪ_[lȱ=* C.XWmɐ{-'=9„,e9F`BfN`eC?yIhr^Q{ghM{›VӾI3E!:/Z3$ҲFEي}P-@[dO=~z/.(߶\v>DZ4.-"78_AgȂ"kFȚY3|JGiDWBpqrhY)(R}_na<+L^^Aw.bZT+E*ZY1?wǃaw-յr%`ݦfS˄ULUnjmE4 4{J R*p lA'j6v0`?vo>ޞ!:$=]6 F~rFGvUUz7.sc/;'&^h]!d 1;f_ͫ=c-j㇜ gFTYN}JCHGU.PIm{uq3N %8c̕~@Ê-]jKb|յƅ)Yi1= lxf[)_ue&hRso*OWWW[p-W&[CAF&}h& %q/l"m3a~ݲ _odyg^~ȡ?st{U'L"Ns8!dj$;$Hz# e<$P?,YB{]dpic؁V򃰋GܶgζP}x%g"mfGlOK%Оqm`! ެ! 8-&t+k3|&%Lk/ Uγ`NOS֢7ŽrE[Q#B9h-Sb yUK~lu&1NO\㞽} A3^g Ɲᘥǃ;prXz0ž+e&SE yx9'pe?ұghKia2S2aVQ.RxdX@#@WQ1* dJP=q"qъ.o?vMGHfmd%WBNF%u/zZ9tI}ÞΑ&>G,{1,'\[Sb_9eF -+ KK'ρB̼BȹvCol<ұYHV s.Lm]6׈w9j>_# 2P9q!ZzgZ77 P#<ǹ.׍Z Kd rhǒKˬ{=S!?*hf;v߯h*#.gs'cT1+ '#As0oLS~iJ[uȲ9RM\uٌva‚TOڝc_kG1 G6S?v#]ĢʷW#@jj U6=\ZcsB}Fέͽ Ð(h&*F؝ׄ{XeBc{]+EKB#^iesR,s ѥ;1xT',L uV HUL}#.RqH }? 4#䓮g*Z챑9g{P۲1eŚ/{Z@&_j>N*X<|pEyi ށ dPj–<xet-Y2+D⎡$̎!۪i Fa}ќwR%5ċ93hCSnD|4*Kd+0 0uq5kyϡ) NYy?B9)ZaTMq](TK=oMhK:d ACf=i?`4ȿsq@ )&/CKà/p /:4o׉Ww"0xnVD̀DD}5n#1wsJJEaя^ " a" `;Cvz$aBBh{OC0pVv*L%7ؖL1[0Ru1]pGo"F#XS 2s^K .E7ce.d@?rz BO(%9͑cA]StpDS&ڣb& v{C%`8#9q[zC|v.ƍ#¬CadЂ}`3O!>d < !L e1LUxڸe/W-K_7Y~`+@\eN_wr2.r>yB\0xuLزl#x^_7 a ;7ΕzX 5A(U{XF>:X닮IabFm$f}<7LTʼnzV+~eS740LƞqcipD3J0P&9ҵ. Y{XӼ/ 1x#etcg=x$u8 A`  FIm7q#/4ȄD+LW֎*PI%Y]S Bm#%2o-'p1;$(Uٷz=#(K;A.`עD>x.%" V!/Ej3όt-w dFL;mfl4fjB=|B 7ȆxY~>r!"d,_Ife|(4VP8nkIe{C`g U&v_F>}VY\t]Vm5ךdU$oSqgљCIWXz'f?uնkDh5ʅn'vHdY\8ŵ0,qd1"Crq e)}X-UH*mdy9Og VSv*DkJg0+`!<>X#hƲXGۄz0%$EX6lo10(eԪGۀ6<*Cý0Ͱ%P\ź/(3 &~g0 !rK%JFg{0d8kMOc'#_@Pa&/J؁MYQCDk#7*KO"+iYҞ]H<}f %* 0Ok($z:d&G?#,WwKxAp-,<A<Sw~V5[0uwD#{J:lcG=Ij {n]BBG߲{FC!:!dBnC|js{Y):Ypi:z9Uϟa5UV\w yDB lؘU!]h=qP+Q:iK[,RtJ~,>GSy0qYl@q2\x.Ddm]ҝt(І0j95X\zEgdֲļO0h.vmS%IAFO(z AF5ګ0e J'T9.Ο ;!oɿ'(%2+0(l˾ \t:l@K*u%y:aݟ—\5)]1]<\>.g3l{p%ʿG`8ɕC2kA@sһ5nېZW-*.$0|rj+>3yOL:fTi׾̶̻u5hQmxиLec-/w6c2,4E˝ Q%A.O"wLzYp]"T$:\M's{0'^:Ss!օLg3C_~ҲPߗZpc8kR-}ʕ5U/>IYOd<‰WJLl{%f2 +_v?'gD'ԚٔA`} l 94weYN/.zi@{iTmM}Z-"UQxC@`~T}X`Y*u0r\-bGS?9q ~MpUmzg~V@jbbfN$R0,5DѡղY~-8]1/llzr g&JKgg/1u_e:#9 CH[4cճ yC]n,{TQ(#f ٔ"焳gg#uKgoAynBҋaÆ%88X~73RTplre"h>(ra3=u'y}r Pg.H] feQe,kvp],s;岷0rrQ_SN,w8LEucq' a"P,9REHq|(hY (N ))F5 /h-oa.UzG.\K- =[Z6|rbR6/1^rEv΀m /w{} ſN( !Kq!<_{\g ߲͘R+n9a Fv)2:C"`oXf2fqgꮅmFf+Gʣv?w:_]OG+1<6AfO}R4/@[l> NښBmC+~JKOlT١Tgw)q6Ud4\)`^?VGDIZiROؽ$=3#I[N@ZJ,svC|*E@>JXioU7"Wg3Z- >Jb!e~ %=w-dZg:}pZ?ȼ4g2b5aK\('Q@ xGvՍ'EƵ,"qPJfǐm+|LSfu;TuYj|7\7),hk=t)CmhJ`LQ]xW_Qƪdw d+0 c_\@ZXRC uƑMG}xme?x,Ɲ<$7&4%@)ކ.O_󡽁EW$er_Dɠ/`7ӜZ)iAu}qP2&8 ?=}_=?={nAr]9SCBOH8o"6kZXre\~jPK ^Bf=1.com/vldocking/swing/docking/DragControler.html[mo۶^S-jI{4ɚ!omqEMlq'ـ#R<9<(y>q;J59[ xEسsTLTxE0sE@m][% Jd*]2A݃eËjH*HK-u']B5̘>Quc%KE`k6JCX5cGEfwr]Ko=eGb3+= 85 ߶e%d쪫utiV_I.mR ^^5>xǤ/8'\cJқ`@ݝE9ȁb]05t{]- ЁDED9Vt w1x>~W{GS/;E_ґiEVK- GÍwase䟳q߾QhH.ۓ,Z0ً,܉DYLЀl,!ȟc*E~7=kޥIHLOU[5r JΎz_.:u{ ⟇]YY{6V"_Ӈ&v]hxħW^= <GSg|pDC*0bbsZߣ$.YkhSd,cU֐L:Gt@ЀzY@x茘3 8 3ЙE !Hs)3xD 5;#+- ޅv S7![f?ۉ-4spAVZVYS*,7B=q yMz;W$$tBc]j/p_@V~ݍqJ!*/x> 8y d/w%*,b9>#AҡGnٵ1m_nHUܾ\EVYb>,ߕioZ%Jn\e"7/c[KN;+~3Mu;Sa}q3\DHt<cs/7p2;hZ'h,,!bǣ\eWRM{:N'(Κ͕WP7T MI53WGnRAzJz}"S\^mXkP˖%eYTELEZa Lgf6`,_T!iSCË^ vjgUen׽ _o|?'eEx}uZT.H:bF#0mBgڭ?/N)1VԞR$"7|0%+H5R ?PK ^BG735com/vldocking/swing/docking/DragControlerFactory.html[mo"9>oK$3w@UQ`"mn_ IJAt]Uzq;'?gs]9h!y:ny^6޹C84<:rq}|Ώ].F^cKq4^:ZE2#Uբz!Q!3&8HFB"pL4Xxʌ ãCnMi>Ï<}tT;h \xbg쨞|P߼9wQi&yjx a)A<0xg,n=5gd<uw4:Jv`5#lDC< b SK*tN:5 [8%N&X,\F6kX/+xڴrOhoHxթ$^Y١HrXb{r]4 +oSe LKN[T3f/6c¢*,Kndޔk9ӁR{4'ތfzr Ĵ(x;1>A47qS;j0 T 3d7PSqH5[\je7k~z^G1#!^:1nͦ*D4;`溙%ǸnE5C5&cFʥ[.ӥu+#tqT?С+uhL`c )bxC9w&d[ڐ$GZs˿3@Fr!|isJڇY|TYӭuR  MoumH([&hVCBv ֒e M1y9S4yreCfkUᬆrNcLᎏ-y'ͮ =!=Zlҭ(0 -Vh8&8Ɋ?Ŋrr_ 8t߻5#;x2񺃯7ˉRE1qk-yo[..;dr뭼},t)!SjDJCj9Z\_R +Iͫ(5Mt%vhH Tу!9Q5[{:L 2exL^A,kO?}" 7_Z }j:v:QZ݌7֝ hu-Jd}4|Yݩ#RJ96`kx-RRj| MAbz1t2?4/ , Fgl0Q3K+gu!Q@h v-/kZ>"Oƍ댃%EȴMW{,+x~Q)\$f-]%4E6rsYB_d!p .C=P5[{H fƻR"phia#-.UjO fC˼HxmH)&ݴ_nM [&)Ǔnnfq%{Y'ySP.Gj>͔y&Le_j,OBLdӧު\# ݧtsrksLpv咷%˧~{U|#zyOJәG۟pP{9Wr\\]C]){9]NmH,2$*Kh&JM' jQ2 n5p4tZ7D7DBj@"44pPK ^B<VN7com/vldocking/swing/docking/DragControlerGlassPane.html]s8>U?p]*򘽫ڒ-y-,%ٹ/.Z$) PRt^ >ZަfdD7~ 4h|C|5}20>no˛:tt|ScFLbiw:Qh|{v]%쮳Ou)j[Ç?#Kd'-C4sӶ.BBwZ~F:*RyZrֶd3 ~JڜnPс .pٴTz"e A[C-R>^.vgǦ.k9bb.NU!zE.CKOd؈#!ѻҼ`4r4\! l]Lj'z<玻)uٶ,X /pblĿ^Ybl‹3V%`Ñ0μ-6<ܳZl}ۿ)*Jf Do*;tKnpe}PY!q=/o|riP! y$Fcϴ5ӧ3gʵXފGu<]}fa;]eM-ABȲH4M?LW7f="h)" 5q{h0Fv7 4XZf7? iL(mPjk:s+qn6/on9 :|? ͥeٝ\F-zaD.I~mK~-}k EP\!ߔzMnWJ59ҬyM2޽iCe09rG~nIFkO l9 ʎg=Zt 36uVƶ`&Q_A"gSWc )S=n夆KKBVDO6zϥp]WiZƃK,D.Z[ٶgZ'K37{h1D -Ha:@tULI19U!wT$ak.BTbC +_; Wbz+6GM᱑8i0rG+zƀ41Kj>1[p==B`UJE9$ &hBl{ٲeǛ>aL^jR~ђ%ók2wTr:ycJ<']mUBNyZ <;߈Mә.l6@25rP4_ueqG Ĩߡ%XHbu}Y v S]L0gVf)B{u< Cm%J> 7PMDzKL@?;k )y^L#L =,Y_h()">daX_寴q * ;P0|W^@Ӿa.8!Kj _n݉E04)Gdqt%K[BW0xǞ$B53'&; u%uW@3,YR"aݍ8- ;+[%: /]n|Bt8XcBj $O m=~^# 3Ŵ[I$A9G@̵t"U" 8I ] H.2vx0$5$OņF9Z~C{\kP0%vxlWFj+s ,5 #R^I/0.kJw6OW<B*?&dmɧb+#[ѵ~3b/~vٹW&C)HcY*Zl7zZ1]q X %62.4HXΧ`"DOP m@_<ϸ[^e~ Ag"BMY**AgH[L+`` e:0B>^ROrܝƏ7.)7Nd{I#[؝$?V8˶@+>8k(6~ FIQbfԳ[d'y0L=;ϸa.I.H߸T- R" מݐq/qrN%K6Kn=߻gCPVC :MRUM4J18A4P ٘L¹Ge8`ܻbdpBQp5mD23MF$_3o^1]%Mї q\K_!oڦ튀c\N <ŋ+3}4N Ex@nQZWbFD%WITGIa`Frz"80@&x^/7D7zΦf)@U萠K睺"J o*_.I<"%v*dq⎖0ٵn ;\pE@pL@j1GM͌B<<~CŠq쑹8I"i !sӊXf8MMarBɕDC5["q6?jSTtݪAսMC_"Ex4o7@GaJ[:M'orúWJ"ápK`ã-5#1ʭ ]!Uz;:#t̓_fPk*vT@;L!A1)UbH@ vD!F(z+] #wg!<6iPc׆M7wr1Z(McZ0uʷ7<@je*&X?{~r[h!":txlR{f(7l+ۥ<yf;y&6ЌQj 7\/,[Kk[QW m-! k@n~ bik,.d/B */aMk V6U.94 $CŵfqRq2~G0*YN 1\@{9і@ $E6S0M9Q %efʔ|-U\wLJ7-T2d2O'.6L@`k"f]ga" X#XQrsXv)0b4.30 ƵPƢ#[Wn26ui=G`CՋr_5r2 1Fh$:rkщ 7L z%Gdr4#k9V\ 7\4rqPH3iT0M/? J m@ 3i9:]j:BaኃI^ ,ATU1(̱j)=rw3~ L(\Hī_ IIt\3AA*ݮ9d">ʕ7'H٥]X9VWr%Yb'qLGU'Ә7 d+AJ͢\`p_.q4",9dMV&]]EWKdMNj.IeQ`]ƶ3xzDQвGԣ,ٟ`xobc5^DqfMx Sɂ!2Ay ~gez(rA67rXԍgzϥ9u%eË:GD歮\o. T` lpUq- E$ ,ڊ'œV d)o} 6`K@"\FFw?Po!BzĪn[3OΏVӒkZ {Y,ybN,ܬ2,faSI0hx}E{>#QGؙM ^PB\B ºY n("&D7fQ_W7f=#iDYn_g1}q}w=21& 7^Gɔb x) ;$R9/0=ddƂFa.rNˆ-FsYM=aK,dDYx\D>E^ ;ĊVҼE 뻅 FWxb:HewǧGBLS福s~XQçEx`BMVC 9G3Jo\̓PL8#&6rX ~JڜnPqCb[bM= 3 A[C-R>ЊΒ}cv1 gjmH GO]=:WF+rtWs]l[v&tNcUc N>e:0 t:Y`Ys[ <zZg"3‹3V1`ߦFmKcɓ/l:̐v:˗2&xȞ SEWfspkA)v+k}0vy[H> cY91LYc}:s5W#VKjz0?]eM\A凶_2P,2 FKӾr=+Lps?&U?p]*򘽫ޒ-y-,%ٹ/.Z,)KPr"ŧmjFHt@j4>a09~=4>ή.gss}}w f77F:  }}|u즷 VO=uZ98>6ڼ'x"Rܟt#,ii%̀X1-wnmxƛw_߾Lv?o޼߿ٸ̌߼y4uԴ a7\a\<_^~)jfEpxűu N:"ug)M'I[%!A ȷ7gc,}8t]L!s>Lcɸѝkm_6YRO;(8ݹ)j+2R"&?Qvk$O/K㟊VL 嵰^/Y"z=UC=Y|uwnN?qJL 2zk~}wz"`g t$gLg10fkcrֿ jM+ct4*gAm_}]7ӧ3öksz%la؏ٲ(Bh< +?-GyÒ&9h$O8_ScП‘1zc䛱N4XSh;mjk:s1mz$NW#7?w_ szGe&w#s5Kz\Zœ\i;Ǡp6Z1DAss"h"|#OkB]%IӬEM2i*d2n9f[a G# |9 ˎDMN:HW|njjcW238GQ n$xFޔi갨9sݥ: ;CgnL,hH:7Jr"SwIp=Vuڨ(_bj 6TBPUgrEbm澏fs"eQ%2:^J"~r;-EVWYV0ix8 z7|uտ==e[M%nxKWwz{ڻfNe@y"U-T7{B y<ۦ zZ1H˅QnGFQ4kCH?755)l 555S[c5lgRRU0u;gWB5.8#KsC }lXmsӜ}aS%Y%+] 3;"O f3c*˼{agU 3] 35_ibUxy$KaM&lo!`3qM10}pp{>Fd C?>bry*Q\]O "d9k:4(ۯ`8áS^ّ0?_&9u|U)i@yÛ @ӄm^*L f*(StmÜM+LP0mnbj"RfJ2`Mn*IZb˳l `on&7@MjX,#:<hq*"<7l4tRC2<_GG JISm˸>N_Jd.7}t;׷y1Ķ=Ӳ8Nf9{I'!3xe% KвWX|lٹMɢ59s^&}; 8ֹ+ikQ>l%#z2Cxif蔘j {:s?akjXL+޸ԊT+2%~TxQssLrT݆Ԝlv^/uUPOgV]3',pҨX"==Tul+A<۱V!aBWܓDtn~ P\0Lu@PWpC1(~q<6#`G+YQ 3?AǗDh0-O}>j٪mIis&Ե%dl/M_}_e9<>%Gu$,i2O IIOouA4bNu-$wS)bc ;,$]"P4KlQ]oc~`ϲ@XaU.k$n}Dû<&h.ݹ _sxKcG |$~ )2$#W 4:2 qV^bGZh @b!醴< E=˽#w}Vhw!$W7Z|V-ZTGEB+]ܴyF@AAvYVW )KΝ>*O FgMN,p̚ THtE:Q3Nu 3WY-6]bxn T($,":MDz+LRH?(v4(yVN.#3 ,y_N120r\o1WjK0NI3! ߇~;xB2 5teX0ijėbQ.ѐ"z$+qB?ZEbkvAdꠚad͕r"Y! NՓˌ^ r3Vǵ~VǶS1g_QV.D@q# Ƴ<"s(TwbUNeƕ;@vD+;cm")2`H=ow[ Tp1Q`V̟yA i;C~.xUCa_V8ۍi80qל0"~B͆> *#C9_UՋ8p0uWFd,$K#u;5}-:-O.9,Q$G^0)1D8Ƌ%b2Ò m倉{_D.lȝ`|.6Flހ@[g|C2F(4-&BdU y&=*Z!|8iQ3#jl= iә)k~)4Y?'tX;FHȳ+A1p. r>\ |SI S,y^7jN1,ygzYޘI]I*].C)*~#Y׊e Xs 2#"w w`a2qJ0!g1< y{iÊMⰇYt2~͵e^T"(byr<*y)&xpyO&o{^=Αq]WNڗtje[@K:5U ]ҹQa5Գ[dǹw]{vqqg?k]$]vq 2"Vݒ $/qsO%Ł˶]^ϳN| P YQK:OR`K:vwBlElK&\_ڣ^a3i{inuS&iڂ:VTstB 8ҁ4;f┘(+)C2ܪp8pB,GHaI@lYFY=@kڵ ؊p0"A'O&^LY׎&8ͮҺK9o.G&ZV6Ψ}вovhOSwY })׋>\V)IjAH6$?9>=GW*b[ap+`c-5he@VdD>emnb}evـ/B8ytdH-JE#ƀG\#l%_D|` ZIR@` & Mwtŭ1 }p_ıo4IL_VRVA]g6un -SFÎWdQz %|Fڽ]zPijm+Pd<7y Mp`꨿Ru@_5 0]e}!3h'}D迨+5m$XyGTo :Tx>TIx'0w$p5N$;O$;R$)RNDiɔtʅ)Q-3W{TiHrܡrJKo[td.N\lhu9F̺8`Eۛ-į+G#^ӱ2\qh#]gDaZkW xE+GޗelJ = qD  _ 8 t}bJ-ccQ:ɰF5C7-Mp$P 9`H|䐿aQ~D؏Xsnh %ũFӨi bP >_=a<3i;:]:BY `_\iz@qC|un X_\H n21bW5RZuhK^ R{4}t.=*^4{;X`W=#`9U\TI־I\/6בrծI:4&iClHš] ʿ WH.2R iE4-{Z! iE]l!җ ǁt!|ۣY6̄%# *H= -Gˢ W&YN$ϸ>N`8.ct[U@̍Lv! |p 4(O8 'Φs5ظRRBy6.d#JA!' 呪dXs=lSz״@Nk S8Tʿzo>-̬cD ?a5D{710/ө1FYf&ҟMfɕ191t!p͝ߪWy 6za)N+pC店aS灛?MBLZ0q6;n/gC1[VjБJU?p]*򘽫ޒ%y-$9ٹ/.X$)KPr"ŧLr65c$kx5f͵q{wq=N^ӟ凟o3ٔı F-}c~veg6SrۦoNO~EKl7߶OɀqZc6Kr21wlYgwN,hx:kQgaoe>w收gvO)Dg)-wbzpMq(k^^m뜗?Y'3G<6Mm8{b|o8;3N߽6)i?yL6͚./ӑԑ$LP$=XL;Xg48Iڒ + e%q2τʌXPFsM3 P7-Ot^#ou>V#Npխ|'@^[ֻ f%㯳x;9J=c%]Ϲ9X*~ѴN "+l)+%l,KiyDQA(jRq;[˔-C)QL?X+EYfpzbM]dXFJ"%T/{Ǭ3"v2a6[9.{Če.lUCzu E`Fu$ۃ#oY_$04Hx#.WTg-5 W {SYT+Z,U[(<kCaƤXy'9_^,NXŘ{vqmїY_ZhDzj=Q{?EqQZ۱q4ˌxHU©4h?P,xecl}P^a7 Y&]yN u cgnݫΊu=e1lķr=x> gFb[')X! !Р`d xk0g1V4~HֻNF;gc2>^+ #:?`CAg Zk[HP2&9T!}jȞ㔕T,tcy'l[?rHᓪox..I]Q™?ے_3i?z;ac//c`C"DBM =>W e$is)́>*vS1XvjYtޔ }1]9`3aP|#3"rkVPCfӠΐ?)BC6ru(ۛKW`L!%"Nw=gcA@3өEl\5a7rlJQ,cnzh믰!gm 9ׁBblt-| Bۄ j6?1<'F[CO7&fI 3DZfS)Vu@["m}x݂xc*ɖ-ۖ83= :$Zsx1rWȓ?HTʲOx!<~-i~,5xn* X3G$5K6lm.# ҅ lg0Yk PU0 Bh%Fǀ&T-W5b}}C `1FV>h~*袆^бҾuJ 7)ir -ˣa0/Hg.l6@25rP<c % ='F x܈LI~ CH")">YcQE j` +άSh.xP1k J|n~W6=껡xCJ bS+lLֆ L,/N42mb,ǯW8Bi i}hg=ƫ / Hh0M1{5I />E0R4% # YBW0x.FszPA!ɚ{ r簁zDw$Mze1KjX3A;QUR3X`,¯7hšX Td8!ymE,v^`56 SLktN; as: ZK'r=!`RzrQײ؀A zVЫ zV{6zٗ9E7 %ས8cY^9|c:2RY[{;"5핤B s𝱦Dplxk Ԟ7y<-6Xcov/[ 7!;8yR!p(+QRD4B+f+NAu?uvfC@i1Ep8E+~4 +˝ >-<ͻO.,A$F^÷zRcp O/hLP 0g 7(c)xʏrը cŃ(㍶mVi ׺RIy|Z&B`Ֆ/>Q{Bp,$f@z-(؈UEEkk~)4Y| kϹwc$pipyJK)) Oyݰ;FO Þ饹gz#&v.c tIMx^ʏ]_K\`i)iaSH||!c2ZPW! K6:ᑻ77jQXs('e >NW{I8G?td;I*_ypdm U|dqtAlGWP  o~`RuŁ~ŝ{u9LwAƥhIiv ~CsXv -YYYtu]k~EY_5$ˠq<^I^4F)#'(jbI8L\)v XS$MC[ kkg &8@p ͣd3QJH!nYU87V!E VGAq@lYFYvi'@g{:hկ["b'dr`K! 8q2֡ujCӈI  ,-Z (xQF5ZnnCM/x x9[RFcZ0! fnaH]&N[hFkg+ߙ^"T[BN6 oyĶ_@Dk? fD`8rO&O +^xU(,3G,́$J:+<_i)Y2xd3]d˜ikr5'EV44O)I}NXY_^6Y#Ͱh֋|u8Zî(d ְ ]b1 j))g28ٱ>[AQ bmnYQ" (˹Uu.;ꍧuFg!IGTl j'QK%W{țvli@9ɴD)U P$yU<29R R䓖 :ĞaZB(Đa] O/RJ+rR#oZaP5iX?l˛?F o{[gpDQHAs`#/ƙ7/.wƁzMї[17s-}sc!XǸx9=b`}#eBhXe@r?aS fy;t3N uHjykt&;]9-yp_o-hI Zۛ {;h 5*&XHZ$.[北a^J , hrhA!ϦC1l!/Z= B-FQk~ y-w+1ꪁ%$\}mwAl=mt͗ՅEH48SC5]2i-:j!ơzE^Pq'YUðߑ`*̪J5D (9D,i_%ٓIp͔'LSN,kT.H"n2%kKd$*SgmM Ӆ4 S5.'YFusu99t\`ī;]+MD (Lqrsvyyۇ9M]}\uy0G`U\^G/xhdmu}dL-Ca*I5?sMp$P!Zrd1J!!^6ZᢁBM-A5hixTZjZaNR (jh+&Z`!Ru S+IcÓ@7B}G6R˵IТx $? <LzPwn9 {;X`W #+g:\dIVY\ӑb. *<& 4l%HɡY ,l%Yd<%G,i U)zZ" hEf;>YtpI T/B<'T4̄ *H =-G=d-~ݫ}D,Uz3zt6?uGMY}ǻh{>i2vcγi Ygo-"Dg@})O1D?4k4rqܧOL*`v5'b׳u!GW9 ‘h_t.Veo*"`;O 6$^#LQ>'-rx?XK-2k*/|$XȈ@:쟳p09~bgwF}c|iөκFGYw2/Ƴu\t'F,}xp|Y6bl}@޽`jxE{O}b d)" ؏?R9/YȄ(Gnw~?zPhVIY1Q.%NPʷq e`Vj-ҟn*;{ɣEbbflTo "+@:EWrOYSUtW1J?Jq(Gn&iDL.Z=aer퐑4 mT C[C~^ e|*~|9fa̅Z)RB]֨d{0|zֺu~1{BT1rE5yb/^cz6y':Q56E A5:eCfNeu?Cqf83Xnּ d, ͓|^ y:;c'ߦmStb[Kp7-ڬv:32&LCrTj4$lLcP jޏx3Z u ֡E,JuY-5*@BZ9?- LHJhP0 dj8-k ܠ,DVqwYK8D8g/~1kG%2޿}>"8Vh<76kWHs'vPK ^BǶ$a/com/vldocking/swing/docking/FloatingDialog.html]ms6>U\Mխ*f&ٻd-Y3ږd6"x%FH Tb/xh4 O`ir}~>8^w^o8w߾s&! t"S.z"Zz< 캑9?;7<@ao9N:, pw> A]gq~ks!;}{7y;p޽|xs;8߾Nȃx9jgs%|]mӿ|'(F+'b83GЏN:}.G'IDQlj6ר7#,B8?t.|ۜq/)v77(T֬)o^9;Gj]Vp.:cJCښ'Q~㜜88_B*hj`o^zEz*.ZL q\Dԣz@[zW3 acX 7qFdt9OfPZ Xʋ)DI5ѐ# )5z0 Ηq?G!pEџ+/Jirn"T%ô|:&.끝ӑa(qEfn, y ]ě"U(YgBgj=0ٖcV&wxdU iotJ[yTmE;jʵPv8sE'3a@mY=x_g](- .gԕWTI+enކpgO.9-NMA[xo=,+Fp|ՐKHa]%eX vy C߆>g M)}0wx`CL`(Ƴ#*} J69_?kj9{ii?wp#)FI=$ګV)߬ƀ\ }ͯwv% ㆼ]u$$t{kD0䝍"$:C7bW(qSipawNJ'°=hMU0 ؆ndZ'Ǣwd.;%Tw!?[NNr-꒕eiyK-3_Mo4 ΄g׼pH*xfZƤsr ~xP[7п C"vnOК_~xi|ܻ̓*= U8!\K7١bQ](xޙ $e.  /L2LZrpL5 !dMB҆9g(e[~gAK:])fYʱ)kڲ^M!<;k3MM/Ͱөg#ayM`Hs9uvɍ"1W3izh&̙SBdF軤Y6&)7Plyt~6Bb>~:Y@g.i\J7'%,Iי,aRpV^$ bx?.VoJƳB#:HJ|Xs6ヘծB/c=UmB:_PILjE`p 2Л|(_P{ap0NMDˑ:=%3!t+.bk^߉kڜ3~MK'^̷ Y3%Kw׀ŀP0 rGK9iark-҉wV.(f;zEsD 5t[W O'dfDԽi{0f<:Gӏ3RΟe(SwE'AA:G?0-DOm' qQGK"naz7P.y렌i, >?TSkEۓ}R̲R#(`x~|5 W_ɿX64eL$Ul4iCts}~3 6O耖q~Wh4ЫI Y2 .Te4 mkMe*eG湶Jh_/Ƿ~pEЁ?pt3|mrk~9:Ch a=- ثޒ#T`4ֶ_]]Nƺ =ww;MċyLAtΜ/Mۻ\BSB{`ǣZmr8Yq`2kwuall~zꪍµ -fJ+؛0&B{Gޛ3JDDKdHo.خjXM_$Y>W4UZήf|irs>9E-Y̛l9y &V5^׳\sbl٥y8]c ; !`zZ√x 'fpʙ ja(Y^^c""VyF;Bu"LAZ*Dθ#;Uu)r ID(("T >3r5Q1Y&uqkr~%`TGEh F!.!Zn!0G Ə,*: T&ǩ(ITmR|K~+F)1Bvv0d؃)A"]6}GQ^)c>x7BT{|W5?X)+մ9rȶG6ETUFx6[0iqcբ~x7faBRz)eO_4JI'1k\LuxMIRF0Ͼq)tFґ xbp!Op1W`4$gr[&>t搖5b\JIi`hO /R )0R ~_8F-CZjI4E ⫨`JZIc4ba6zh |ٓwD-eef|z.y;{=aFs tY]okE}X8̙$Ӂ=eS1?KGwbcG3 JփSHϸ=k]N^) m%qؑG!?s^~S3EE,K-cmt/b (6m9J@]IElNeb04)*AS.i~T#q nd2lC>EPkMZ 5B[(ku,pvÁ!HOe6j7}\orvm-:|C3ͳGE, gAcBܪ$dw.%Sl/^&^x I텗< o)gկ iH#+kV ZLdOPyй]ۑÝ >7ކx\F Dj*;zVF[zrBކ8 !XjNPe9BeuPixZҞ6(s<%aot]~K6=zpʖ BZaSYrɏmini- d}O'm}BcUʒL FDY[rTVV3qi!dI=m ZIɬ6^x04ћ7!~$Ug[!Ӱk4 3]Rs/<\!44sO&5ܸԊucqx ET7UUس![K>2OvS'T:8%]Tm#t~xKBi[Hz]Йdխ,i;mRP3ou8),CKIc#ܰ:[S7-W2sއgA$.)YJuK*I롘iKxSf4y<h 5gfWGMyY}Ͳ,@u rtץO/u ip|vt͔حd݃59ZբqPqPZ ւNtJfVQܒDzJ>і$%$En[p<;d**¶tF)Psm ,7XF}m9bBKB '26(Ȣ)߯X.PT)iW!X߄:>Pl򖁜%%DvwgiE5;\ZՎ&p(XX2V\7'7t+rx3=9kC2TLTCn*DBzAjVjL~ȍ*r4`a hd^/gDᑒKI=.H { R)9Y\>KOwRBZ'-&i"BJKlf",u*jz">xr(70  `ڍ,+ yN V?8ް3̌_6qdzGm8j*%VIb׺_ |уBz?>+dU07,UiO(*ʘtNQ"GuZ |nDSShlR (Yٖ \1Yd,.C,1lb@YYLc#46Pݓn܏ {oQXuTctYh#+o+^]䑎`,sqy~5tD9{/p-gߊȘX궄O lOUDmddd[s~:n. /A ,ېd.$KuK&*n/uG{#u{Pp"T)n tU4ˁ $8e:xry0嵵ΰOhߞE8ܫ`a2#uͮߴق2zh&=D0iF tOHDUEHkhndV +Z;:GOQ}KLJZaZwQ2RwDjx9S5&p-Jc^E-<;dosդ^*/R#sO}18}$g_+0 u5u [OմViyeuV{9zW1vNS^خ8/zkca礍\Mpm+\Y$UT9S' uPDd'S.ħTF̺rmXvZ7: B;T/G)"k0ЮwэN?qYԟLȟ{׾y8]}mXޜ hg:_JGȤK?>;|1l}V3*cmk>=ߡ!uf/eK1f&&@H w~gimL!-: Msqeja?j9惊$/.45> jع'TSZ<(~Ƭ ߷m m#o P2Gnh3WγC[-+D$/}> \CQiԯ"w>0Bw,i9̲*SMKmRbdU'cF/EЍm_bv+pOo wnn̠iJ-H?v[BGUVٵ3pW'}'zUwƓ݄6LFMy_(|6~JL)ţ"۞4kqݎ#pDC#'O{J9+ ^p1Y- ]8ۢ%Eè,@n, y Zb7xE`/l L>TQG}>RZ.ʌUYLI=LV|~=S9I}ɮ.n%>K|]\M 5aW;$ԄRxhPIa6kG6]JvMhԵ~JnmR\OD([C.)?rҹ |)U`7Q*ܓo~mX&rJty9Sa @/9'lm< Vf>i5 ͭlՀ |A=*͏ 8`7$y+AK/zV^Oy!cgGU(^nf!aJ^Rięi?wpVR3 1 Xݩە$MwQvKNMcŤ*Ld"Gȣ")2=6b.j~DEgZvi8߾w9WCԮ`Iw[ġot@3PK ^BKFLU(:com/vldocking/swing/docking/FloatingDockableContainer.htmlZ[o8~pF8@%E 7N:$nmqBHËd90bD\;] ~\~?=aoг>;0I*b"%< =0|?8\!B Vyu9_1-pMMOҜ( 3Z3K4߃ۀ7Di {awv?eo{;Ζb Dt-rz$REځngp `ۇU&THKۋ="TBS9oG3[)o{Rq*J.CIE0҃$ao;0=wⰘ_,SUzlѳn F"":64?.F_Qضʧmh݆ZYH 0Ӊp=yVOV)^T,c6|1]ۑ2 1V'9 s14CY*ЈjtpqK8~ܽ*:8'TddX=%!o68n6?[e$UD4P$m܌X.~Oy(T҄·*s_N'z]z l Q`ԥm]8G+3ztTҰ[7IrP唺l^f94gIMtΝD0UqN%mFyC.|S"0Ι_b|0668XLxgYD{uHYT/ ~zAڍi ^g &{obHDAf6jv!z%P8 ؘVAM}{lIDW*)N2du}EhDA)Sff/`@d!g-6 lZ[ Zn0F0%I.%329LDN50l)jTdd* }HW;7D u~L24noWEmmUQAHO4"=K\І\;;^^yRG/>n#}GwR.}s1*{ǃȑb.}3Lo=B)2o{vxJe?9bm|.˱*Qq{ y=4fT ~7[k$t1 DF wڡJVdESKLUx^  r*^svfaF2#^lp}bkՖ?ǹڷWz,Z:sn펅KvSxlĭ~mEG0dv%-(Ɔq-@b=MB.:< *jѰ pav060;2:$p9Qn\^),9 á|/u[%4y&^>>khRq8 a4.Tgd&5U9vK$_Y9A/[{,jBs/g7J&WUn1tϿd\}xr+LRhuA#\@^6}lU"7l#˯t^IOY[`aΐe4y_qN~ǹ2a 62\H(ャ-oWo5>_ g˯V RbR{hm~?J8888 gCG7sǷsMT uLQU'Ey#i p:K @7l(geG }^SW+*1ϛ3+̌PK ^B>6 f2com/vldocking/swing/docking/MaximizedDockView.html]sH>?hw1{ffp}qT6V%p%Qza{:f0HYzee}`_u:4>-no;/`1/~jyk,|!8cڝp2Z >t:OOOm,fuخKP V>s2lyh!Y# 3-weOhܽk1xc:X޼}/ p`o?5pW1z2>_y0|s\x~~g;rؠ4eQX-c:rΣ#Ee{RkY2>h۝C6Oshcθҵ/Y T֬V7lwekرS: -qqa}mSвSA۴E".ς翿hW=|+e.$İ016Z{wK}"oČʀiEϘ/z121}·R?(ceЂtVcGGlHɒ|Ew$j>v׀P8=I@ʌ~n($GYH=<`S̥mhGkl7߷Y;lu'1ա zm7A5OD K#~;CDqo|KP'S2[ 5/Z|bFܦ%)"GX#ndI^1v4\ l]Lj%lcsǽgIٶ(h5/mľ^GY׼wg",>86۴OlsOj-i(dTqftW0ͅy_Βx?g+j"=ݍx| l"NM٬1i#}CU8ˌhݮ׿lb nZhH.x.gUJ4WP‘GrԒ5 i⣪x=FUj ݛύAo3.rGalV[0Q]g b+ 9]N_,'Qo蕥 죜9&[ͺc?߰tL6MLC+1Jsr\߈u<ƤՍD ~)ݍGMSAF @#"ZD !D*V 7IB"ixT$gY)^2jNT161ޫ4K1pn{n8%|9xb4,c@ͻX{d-#V? |כ»jxT>%重j+v poɒ Wη9V7Ʊ*lbngN͉i) vN@}+ڮ ^bNOk;ƒN_#rlq"77k/OG]oJ(#s!UcH3ex?D[e1L[,-Rhi64={LChqf)2z6q?Dk.,eY&R[uN3p9_iueP(.Ú,$'g%$i\N]zX`MDziY I¦^%`ɚ9 ]0i 1&;ߎm뚨HO XazYQ% Qs0Wb RPf&HNjֻ(ˈ!38l2n'>$e4X|Diʬt7_ntTG)H\1<2L2o!em{eavM^a}p\}pASU$p}8Ul#˗[l[l,*09߉D? l/g4 g]QKӗßuq@~גbӶ峃Mw (8m-pt4#4?ҡk#ӡBz(SpNjV>;^ Su/:  'ԦT4 gqcԷ#mqyonFN!l#ej>8޷9H 5(ӭbVwHu:T`@GxYVϡ&ps)$hMF"4۱Gd@?ǵtԎbu^Aig* g̻36?ɜh#?cC0#cYP  :_`OOcXeK=r tGS:?C~-[-H ~2Ӑ%Ëk6}"Q)r:y}J<'"VQF;mYɒ嚤5BoFDs`S!݅%oB2 -tWYzP0"_<̺:z)IWynL|iKJ3TPyH7͐i+w&+֟Xw]!Mzce1 jX A;C^TR3X`lژXa]*-ZlE? 2 Ϯƶ#!/8HhAGp%N"CT 強N"_yF=ۮ/eGFCGNG&JUzp\Sl怂,/se;h*;2RY[{5mLB smDR}yTRr5}K8J֖xhQev/[o 65 ;8ʄ&P)ᐂ(8bvc%$QP|9P(wyAZf|J# O8p2UVxi@ U%;[!Jq:u# WT]2XH9PSlH,zM XjAfH<@MC v~cߪ c(mVIakU_ǺRIyVY&z\n_cq%c4) 1^ĴU;ik~)4_GtXF@ӇKIΖpF_$y;%@GIpl#eIl aВI*ʝH*].I*~iؒe"XqPBԕ!IS;;ma\B,$N{D'J[:G\Pc "e`^T!G<[Ӌ]R*ly?đ]SHY`c" ̔VXx8~qǰw:(IyJ%A@Ƴ"@xT,׫Zd8ty>ϼjvjHA( >SFåi+w("'(j!ӒIWU&vͽ-vV“$MCǎ\/ /&8@pLȓVËe)e3[VN UHBbt w?nZbf"@bV]Iz~Zk({xUIl0"M]¯Y5842. r]  M+YYQy{Wv8!8)8bSᢗPŀ0:DI0uD2v<*<ќ_06P)%Beӓ8a6 lZ ~*y@`8r_7侄YPA\2PL&#VG @%}YY4,j`Hd,n.jA45ߚCӂ"+R]v'Ɉ> sru'*/dͬJˉfX$ZʊE1u8Z ;,/pְ ]b1 j))g2٩>[QQ Fe{6㾭f" qsū[ ꍧuʹFg!FIGTl j'RK%0MދI%ZH!`"ܨ Dϑ2M o(WZ(t=<b/QB!&D_8=`_G劥+F޴TKnP5iX5Z=6t\K~*NO'KNa28(8o 6"+X`e̛OHiA@}D MRev/~vm3vE1.4Goz8HcBY_fp;WizfZWޓ1j5 \ RuTu#$Q,I-͋p?߼0"<^ $},P%  ]K u 8ƵEdb.ch @H³%Nx@/P`cGt;>rz`"8(&z]?lf6MO&R!A3y)T\pHܴ:NSs~rG"?b% N鏚$U]ysi{u/e`*t̓TnP-8)Cx m1.$n|;cPJ}fǾq `$-hF*YQk+`*#rg!<:t8xlR{a(7l+%E<ayHG`@Cm)/C.Ԝ 8^X旐7bRQW M-! k@n cik,$;/"q*/aMk  VU.84G'z^daVe1\Ur -YhKr "d)OLYY@Kר\)n2%kKd$*SkmM E4R5.'YFuGsu99t\`ī;]+MD (Lqrsvyy9M]}Zu0GB`U\^G/xdxu}`L-C#Q*IF5?CMp$j(|[-9@H%| ^˱ڇZᢁçRC!͌Q$yʿ z$:*ynl-0GrtT7uZY ࿰p^ ,AT"Uc}!Rz p>ipXrH&Qw즬7ldǭL_?9W 3I ^8:V*Wތ#`dvbeLZ]Ed۷jeS)V'cBߚz^ÓUEyS iEE2$:BfME1 d!M7{\U{U`d ` Ă*>@CQBmez3|1/&3c0\FKWCh׿h{!1i2O"RKk hN1z:ٴ霯MIv%2yX,3$6)O'Q.m4HNH EZ)YL@3(+,) ӅdTJ"F娆t g:)ػeYRUXOӑ 4yZs%e1\NL u\qDt=(bxAPP [s(St{t?R;@mkwǔrcG>&:͊f ᝼U=*YHK?jI*XE9^-"u 3' eXx&^t#eNؼDasM\V(}^'5FC c\z5|GF7ɸ^a<@Tbfu{hJQfGSi.^lGiLFÿp<0&WF7ޢg$' Jzc,d̈Wflc'^eYب_GӇ8(~[G:9cӳFqf5r>[\vv1v.vQMQYx&q"m!Zr0͛?Ioe>=,vYͼjQX+3@9 !"\h{wo޾7Y 퐰6TĘ!IjV"xun8,˫Kcv}~9^A7\otڞk:h1:0?z]/-Mu~9Q />ĘǙy2ӽ; ӊ\!`ZxL7u^aa/;x'ݻopi+C]d =\u3՗KvܢG/7>tvgH8oQh.Irڱ܎ifN  紃ýc{P[[c16=t$u`9v5c܋mY{eִ-^}krI+K3ڮMo_'O`8=5N޽6i? ]R1-C k;?Ë^cKAto~8ȸذll=D?.0VQԣ)+ո蟱XKcza,3crޟG_>11&k2>V|CLK|o'Rf{c5cP?'qsk8$eF~(q3`#m mfv9 VgX ՌMI`EYFʺ&)aH$%B~X80~[kz'1}BABڠLeaKw+Jr(ǵ=8o=HFO%°EDz2lm7fe;M7J4zAU)Cx!MQ`<5xBh)bQ9j4FM5 #4;D-n=e[3K°i57ZVJ ʼnD;E3օ<KڹqWH9y[Jf}T=qfeÀ.|ܓ:+u.r0Jz.H zW^[ YIOEElw -}C hRZ!kfaaCy:ѭK5 JT?ܑ[^p#z6OƳ+|!K|HƜ/p&c%CDZ*BCѠ%;)E4h2,29}2~\ c_܆YNw\R9;`cQWڝQ@va$L ߗtbB*T+LJ4]:`xvi7d[,AzК|;dzQ/ )|kRY.I,evaom}b6BW7f(D !D&/ԯ a$XiXD14 $_&Nyv>?ωC[2a ࡦ2d-s sW`[c:?hòΙ̩o=sM+۱}/jM$g-,O6p6׷i~b8lᝓj#wx2xs+6Ŝ lt^H{h R7[g1W+B}{#h:-N1i外.ZJ(\jz7--߲; euiFƛ_W| |1 dBI)bCW7(L87e,@="^E)3(b+WA VM =6;mLn0c)QzybYʩ5lI.\Ӛɩ1,d6lg22U0u s#(a2>G+a w- !=`uoyss/o uuqI?6b<f$u'%lOkfz5|ޘ=FD\hTAvK,*`>Yo.MJkYbȡ9VQEe:_ffHpV&+t|SA#nBBS:[Ls9[4&fͯT!l;d8OFÛt2/Ӊ r_?&7`XN7ӋzP\ͦD> L&2zAsgyu<N*#qT+R|\Nn'WZ%ln_ t@5f z9XjL r> ]0әձF#*Q9AFU SfK7/F[4=ɲ0y9ǓU@ 8JLCa9 6 tQm ,ί# l>2^/TPF4PL #B^FN$T8UKBVf`b@a2/MDQU#_ bݔ7FS.wzЊQe/礋VDhy^//*=z $9ϧU&2HFb޿ieL Iɉ@#M.Zu:V(A.c0,r:oֻ0xDYw6Hgu.( $tX(8k8iY6?c\g]8df\t ٦fI0]oocI Y+,BFq"9\sN*)s 7IL炆"מϊ,'Hwnr/lrYX*08DAtx|Z9qGJB𼬜k%W;ھ^ 䢋1}z q5Z~62vX&7t>ٶVmfH c{UljB̆[dϭ9WRxU)e =8ݳD.c6%rtxPrnR&6yҡռSO}ԯΖZȩbo ;I¾kA30 doG)wWB[N*ޛJҴR)"bqEgd鞫!4+%E@Zqޖ,5d2zgN`q~noZjLÚx-tʊY=Rȡō|NsM~#E[ϵfm yAr10 DU5K[7l~q6$M^%NC9"B@ۅ3ϱ{2= 8f؈<։ .ŧ8)Rsx͗SeHAr@+k܀"50 J6p_kh/geA +z:2iYQ66e=D 7sˋUK @2~@u XUť dE9Fi +og:>έ`h=>ߕqz|x^?JTƈI;݅m|˻ [l+H?h=&6!^ dn(I6)wٶm ߹E;MGM:8>*0j<.Xn@umֵn XUEo!R]۴b[V]#zՅlөYz$[槦YaByWx+2uBs0w!b3s2Jɤf#90r0-7GA#֢G9-H!Z|E \ux=> m-`I,sx6r7fHeY'OO)IJ9e(KBRBAt.W'y(5Hߪfd te*2%RǾs/PcRhcf8@!߅^h`NhFW:%xWP*t7Y*cfd`XݙPh!y Qk7>ihQf󯐻Sw̱Zv;êB@b jwR力5w; :R! ܒKuB3}QHd@|0.ԙE8uZ MP\#j0ꆀb,~֐m2VeN;gO\""}*f2wg'PhmWmB vB\xuʋּjuLpGA,-IQ!;jHH)bBzE "E. 6@~o 3VN}+/I9;z4(܁bb>h3@ٰ~F_7e= eYRtGݦB:me F)(nh`XUA`M?,5 KJ<_)JRF+5HZ ]w a(LJ#!afhbY`NMR3EUҴ0h4"Z4 /cSW:mV-Big<) @;²ll zqq"&4 gE=EKhd6fckcm&cn^n':uv;z(N1s@HK/,>' H *:\ְ6^Gdä_ha<ӖHwvOd騔B@}_yf`qOlm:RdVTGř?ocq~_ |:>2%RCYW`O_՜ fkNDA@q^c n}A3r>&ֽG"8 y"0+kw飺ˈ ZJVL'] XH"[ոfAp*h`#TzAf_`_TmJPȓu1ث.,8.R%~zc8%|D|]h;]B]`_g@?7 x2tȈK[,療I#0QVy׏┍Ιx⋺$p.8 %o4N{@ϯ ⴟia=Oqdtr2JִKpǤq״ {b8?YG: m&b=Ǟ)d) W?&;V 8!j6"O?=pd^2 bjL(\(EHGA7^+'9{ClB8IAr&p"S0,/]q. ,Hq %YYY|<]^wNz/5諂de.Yr TF,KN:|^m3#P BMJ&sZYf:`ɦPInm7iPH4p\(XȔ(ᮩu@T 9ZH*=B_i7h^S=&G3M 5g,ɤ0:I0wTpȰuYE s8l~KsJª݌%1¶mÃslFgTFyGa:rfC*lx+DBWY Iu3ms?$UV,Mz'/ svWuyJGr8:z,JP 8Ŋm=LzbmXlZjYH%;9a~'s8Scp23AhDL.TH=GV eP ny qU& 5Hj$J@6 `K*I$Z H!`"q$f˄*Hv.O دOJHt=2RHQB&D]4=`_79JP+E޶T+~3}u7WޠxKOQjgv(xP)$#L5ktDvi¦vXHVĠu"SŌ&I2 |'P !11 7|:c$JW:rSs5:Ef{bn63:j4_VZLQK~v;GIPP!|m% NU=q^{S˶oXz$կ_a-M DϳUobZap"E>PU 2jƾc] ՗m5uDb* GW' #mhD  գ0pю:D}&|DL}ҕ?ř&Q"mjUY.6@ iQz(A}G%phO J]_u*dàUإc=w<3C^9n|=(6-t(3F<:0MxQMf``廕)ДVr]. ᦱJ(K9mpLUߑn {IxtD bC oYF=,*N3w$)jɁ$׺I|Q$!"sȶP8LEY@Kת\I2 e~W*H8TXReMbո0`T-D+F6bp*r܀Em!~]I0Ů4e #F 8 b\\k-]Y0%|/c[3WjU5/V 0T+`0= E.V^SpcFb# ܸhӢ n KCH|$rg5 a?p*Grn^ 7\48|25h/m ^:Aq*xBJa\:@P@c.s<B8bWga"Zz p=*phrH&(;x#U\KMK/P TN҃kݮ&)d3cʛ8ҮRIs%Yb'q\;DGU;Әw#P8dArɟm9ѴHTE4"ۘx3WsdM\/o*8*zPX#Oc{4hzDQU,&Bi;N4g r~=XNp/㏢מIC/h{AQgqcNZC=\u32-\M%r= B(ԣOCi=]lլ@>Z{hph!uڈGEFk+_Zv+^:sIPS68Als6nll`on ӰL'eE{#R0>ΌE[so=B8^{EfFqD4lj+61zp1t1Ǽd {M'\bI a"M,w+].WƤ?7ReꅡR+3៊:Xu^{?I4aA>v`Mtskz &q.s,Vn4u'xݚk.k5>^12 $VefmHxn8y'*D=8 0gErYk4)-**oaBhI`v%9@Fd-(U/P#"13䘖O6|s jBDSu "R"gO`hT i(͏ Aw3=5[>g_?u@{߾wK۱ḽ熶5Tؘ#okҕgԲ?PK ^B9%7com/vldocking/swing/docking/MaximizedDockViewAsTab.html]s8JNRK9f߫ڒ%{rYr(8H.Ak$K&x@̦flD7~ 4WOp):]^ۓuz/h6~}f+\ǰ{ӫꬂ=>>v?t]7魂Cv]f`v߽#t{ نsK† ;7lfl ]W[oۿF05A޽||]fwD^ظi|?9r-8 3c^}/,?}}ןzجq` wLA wh^Go_$< lLV< נ V>^w^_R;S1e4wM2kZXmOYKv.͸k9&:Y"G@}_ct5<AP 5C V9|5韎mZ ДidZĘ۠P;w㣹>w?hbJf@u8 MlrO7W)-l(M׻2Pa;vnw>Ri$zM+%y#)qTXm{V j 8Ie?7vh.,D\EYeBkBzm.mDfz@bh)k6I$<1!w7JtH_f6KdvKScz%ĞPz-Ã5#ö>!\a;%Q&mlKd3gZr\6y3G3|ʔ>*Yؿu7e< xM/}E~Q%z `3@4%XBDEUoDr='fuIQ*0rQW2;5&w)Y$LqKh%h @Cp12ϓ|U5볬+}<>Qdexz*6vUg]C`಴`4ÔBZmoʍ?;s/L1wS'rᰴm;Yaߢ 4nBA)r98 Zf~ y^c#kƴyg wCΖ-DM$CHZ(B.#=\ۄ4(0 kx1Nh0׊YNQ Ѥ}hYC8}ia'2G@E4Y1(jdti/{vgxKУsd^1T'祱cP&~gKu7]{`ל!ՍjAss":D*?ׯqICgIsm8nXƳeueT]#ɦXI}|L|lICL̇u= !F{3 yh:}_[1U3]~I-jougj}*w#g ?lX)KSq{cs2'ĺaX%v6M ^uYno ưrv%N5@} hĚ[zTn%L#b:`A037+Hfn[ nPJe)߽pTzJ4|6u( (pVB #`qf.^9T/hQYi~}z!9h`7WY4[&<> lޙ!6fپT6ur"m uzX&fWHu_] =Mr×ѐXY9'*i:h0? 2m0Mn}Ϡd N^neUu%# #Ճho08+{B r9uN?\" dCe& Zg4c& _t^qrMkia<0y*Cxa̔hBڞYv0tmfhF01+MP3\7 lQ4sxCapE5Ӡp'ZȦD(WlE Wzxj)U+Qܦ5%xЬJjB5ff\Q, .STPJ\>n^ïjM [\/!?ƴfrjkL3C ۙT6 }eA Jx OZn}ϾAvpY.? 9í>-%Y%?>FgӋQfɢ yz9K)jt!-ra|Gz4#/LYڮH I|n.eFU,IcsXdbu q8lvyHu,'MK_d\Ϩd|AqrydcNFFeÍ2$GWF\H܃pMņ{c3MO뎇P(?<+?PPugk#Xu9/l2<g@8_:[m䏺T~2:C\˽$bMO,^ 2n6}v*`3:o,K۫tt7\ƳJd_OWlrs79; o j"ܴ$rVF/GY}_&_g8p2&wOWZ&lny:84M6ЋӳYIAތ:2E6A sE&k%ֿ|8E>ty:;4R y[`2th˶;YbvfZNԈsnҺXr)xϾO۽%.}VD;HR|ZD$J$~GӑFPhs?u6 A7$Q7.4)}Rs%Q:6 !;5Vˑ4ƫt`"w dOkO)\R^R^J!M-?64J"'jا"u ukb _zLjxHhs 6Kh\!ax4F $m}"`#w^C"i("\F2m8H`xr=~s!%ӶL[D[>&8'KhF z .I$PZK5h4uӻ{g>'ƲM{T4Tq*Q#RsmCM-b`>6ž, GaFouml81 fM25|,NDɔ`K}'A F 2&EN]]7n-&L!"YkKU5C60S3x'mU P@O2Ѕ7pLd!E 5D ;C>|Q6Y\Ի>dXfRɨ4!TյͫgS7* t`7l@WTփ.b>xu+EIꑇKi+JXމgc8t! D|ߠ4OY hbkR]WE=-ʪ9^3Ku{-I Z{Eagö:W-@њxh+|le7\Yc !/}u;X+{UzN; Q%T: ~FW2vx6G_q4n7i}Ƒwl7W'F ˡpޠAEPR&k6^x _\t-$Z<]U&Rb})bXj ߠ:y=rⶃO* dJ}H(ؗQ p+NM3kND"fˁ@=qW|UF·ήOa ֨ ~n|_8e@Ml[P2)̤us7 xmhK1J9݀/ j@ԉ2$h[UzH U#$tIiYFRNkGQj]Z;Rs\yh]]7jAMphU>8h ]ktrHxPleeeFfu[C0ڡfӟ=]ݭUFcZ2> 4m.?0,l]mX+/(PН)9Ba֊ plFJL~xGb:r_5侀ِPIxE,7LF,95IdeV (|a&g ։ SEV/H6[ rh[0RfEJ Ej2<ϰЅ9Wuy4/dͬ*ˁfX$Zʊ?* Z ;,+0V چ]a1IRRUQC5 3|pƽ nbcn}[TL/=Wsū[썧tʹA'!FIGTl)j "1Y$N⣒( J b[7jǯ/ h@?XvM ..5Gahxܲ VʴXafh_sVP{R Fm,<+ӃRˤz`JS2^Gۨgrhw?U#? QLI-͋p_߼0<r %a<%k Z-R˔L.9џ3zH#WӜg6w0P-K^M]dXH[+XWKT$=#uIXCa 96L 9]Iޣ&5,ʢvu%86SB@i)ߟ2L7?49M*N49hhA\\uKH&VzUxaD'R& 4[[ D[l wLy-{cw/Ы#X{ZEv|-Z0?7P:ar@%AD/bp2 2 -۫[[]Z @dV߇2n7.zxKdkQOPn~ʐۄv3٤ Zd>9VTWth}g8O1F3/}V5R_D7:X[5O0BW,^i6€8lͤ0TҀ >`xGƂx>, ۦ!c 7 *TYa7ݐ Lҳ" L:ؼ6|GTnߑAzulGê2Mb0`6@\)=73d2M.%˽J{7 %yd n{nmy niT/5Y]E!d*M<"wYF5+Ff8Eu&$'?ĶC ,o w/ AdvKS ׃>-(\&yD Q 1#>!\a;$Q&+!9S\ؗ>K)*&!wz-/OT(Zk"\AG2U{UUN>w+ey ,^cr5EE9(ZƗC%h|UKe~-"`yN`|1,mִOmL<ٍW"2bL 5}%]_0-IHW"DWeLنdp !+ᔛpr!/6>S'r#^gB'A)r9|dWh^.wʖ-DMЭ !icKP'oLX =tkP'>oo}@m K%Z0zC:wPK ^B7 j9com/vldocking/swing/docking/RelativeDockablePosition.htmlkO;iVjA"v*%R v?I<];'3?;dQ?qVtEn?lJ4;iy\xgԎH;^pkR9x<6'it}?dŭJ7*f[gZ+؊+mlF-g汀rf΄Aw B5jSN~yrtt5r{&ǵ5ww̥yb~v\vKlWxC@lĨǤy{ypf0ЀqJWNȣy)8ư%zrظL JF]`yj!fT[y5){1h /g-WG!3DKM9dcu')bahy.T>.3P*u]ϗh3wX S>i9r?% 9 G!21oƮ?0\K*>D846e8NEONl6؆:ԋNj{"J2~cC1~eBy 2Jţb\#i6p"i Xhk̎(qz_\fỘAܣ=NiAu%3W9HW$fρ@8-lb$Ӄ“આ.TxG? ٲ}=c3al!)j~u f!X8ys9̵ISd.-qq ܟ\%9Dq;4h2 鮹iva: Nttnznd PVm•kk-T䙮Jɱ緆@8ǙL<9Sf ʇ3Кq ̑QCCt&&?M֕aOqWpG =4CC7e? F>9mtFJ1 &2lG 1u\+ےLoȞ_mIf!niIhېp%$38"F|џ@lC9` & d{{܊Cc [|H&d|H3S\ # qm'L~{?` !|GD %P39u?$Gp8}u9X|6>yoQat;c3 ;Mf;ɛ- ],D:1H -"W@* K7`b4dcv2pqR2 D;]YB_S>45d|(%)a'ix8uR )I}:'?}j}Iݑo 2'2J!*v"| Sl_.abTwBf>y+ᾚ^IMCSeRHk.~ ѥȴJPIK^xV%e`"~g%h.@[xڐܞxEIyt_S! 2N HJ5Bª(U+]RVn "H8~x2>oO/3I2#(=A4#ol+PɺیGB>X\Z;iuZ"kv!;5/Q.># lm Rt~-1\mw^ǥj8΅os#8٬^;.ʊmiv7Rf)xTʍv;>ޜZBv룒.` ϢmɰM`mLus}߾jͼAYIfIKVxR2&~~*Q{r+$(7?X yCg!̾'uoS)QSְ/HMQ@܈YiV+k0Wx{ X*,Ѥҿ]^VW˾6 `$j7@B~_Zq0Ud_}Q$.&lI){ ?~s3y4@_c2]H釿)>>OìqllwG.ek#OdNQHz%=171m ` r W/(թ%JJ5[.؈X/U;6|.Kl1@TJ-90@i!d"1vT׀)+DJlCмn}{h{S>]"g4O%Z} : > aOef9먲4 4d[*Ҕp 2p+oKL5'sRy+sgmKUv.=wim^ۼt! Kf҄Z/U(0ma[ΉU*SeH:Hjb-8A 9m9opGV{W=+ul:1;5jo!D2@XP@8@#PK ^Bb^8 ?-com/vldocking/swing/docking/ShadowBorder.html[ko۸ PKyic,8^지h,jE9w˲c;kQpxf8~t?.Or|vFVqsvNnwP?! e!B$ѡLS{z`x?1Nl/O: K<"^- p8jX$}|=7'Co\T%1ўo{zN@{{NAQY74O1)oЁkΑd@xLBҰ<@d! %FAhxb4,}B %$r8.c2lX޶!GnX=,;2܍iU V) Q-`.kfmz;ByH kH e5d_c l CZG!˾{;L&G9(ǃ|Vy&1lIl9PW aPߺ'^֕t 7 YtotfC|;5E7o A;#i|$|~%\zHcI`I:E:v [[Ju>q<],a9 \RavlIRrq&AwEm\[O8q}ݻ_u[#QL\*;i*: ҧzAQv y1gc|O7+`و.;6ç\]斈+%S̮!T-U G8Lт˘"~s-C܃ 44cS`x] ą ]$_Nnn #AFqVȆ_04al&DIC6i_ojWi0t&m f{xvߑk`~0Yi+*e\!EPb hplB_\EyW)>>9c#.S`,A~b&,<.ݯ2&y칼^zs@E)n0 OhFt̪^N#SLXN.:JgMNB Il͇ N+SY(:VI)}= _tBrz)'1Mp9A6 oT]qpoUr\ |,F"GJfVJ|%涋F+:[8QAϽp8:\rQM}#߱f B̆`Vi0Gl9[rp`@K Ь̅ydO,:oD^W_}9?o]QqkOteSyt ;#yA0;%\f s},6 k##yTԻ50+u~0$GyęUf<+Afh9)G<'g5MB?F$bvЅqEҠi~ X,*9/F L+o#URMS&{AUz_ nlxM`X@pt>΀+y9]K|RA5:Dye NЀ+( ( 1vrUSHۙcBزY驠8NU @zI,ytHuCl6{ x4N qix8!'6N@( %j#*< 1"F$Q El:FS36^: Ɏn\͏a(WW9!"[6G+[F0e2tw˷ؿ8 FE{ #ymXP ȘRgҀr~ /Ļl|-%˕x F pg^PY$$zX+ۧ*!N x JӢRJZxFiAF ˶ 32Oo;<-%t8[xT X=-uE64Y 8G/NֆKn[dTO*c:={"yJQ=4ah+*5k]p $*)VkT 4+PW<GU[WV*Q]vc9hL\܅.<4G^D\Q_SdQiOK?nX ЧgHQx[;UZx,-(VarH%1WxLHd]=W'J%L b}[2˦`wgGu;+~Yǝ~{^A;o*`QVE=%*,_eɱ6 -/< -K$=UIb"cpfLyD?fe.>kx JCy%zqtE8ij.'H%uPK ^BƬφ'8com/vldocking/swing/docking/SingleDockableContainer.htmlZmo"94W!R&&Xn9tn 嗆@Nw+Ev^\UzlYsҽۯgՂGgA~I$SL$^Tzğ"ݻ VC!BHG**'jpM'd@V=zp M̘(Ќ(Ao 1D1$g~_8?x|XvGNbf%N"| =NDC)Pv;-|ȐNDG~?I`ɑϐ* ix*ALhVT;hY O)2Ty)R*PJhߌ0^GwAnWKUږ*և*!`%}W3YC:[*{h@`mi'%NG7!l;z,?U(:D̟#6n3y2 ZV}? zH'Yhjt[w] ݛ[n};mo] 9)k2F+NOȸG{58a֣ g~~d5fa"%^qgT82a=⹢Hsɤɹp8׭mӘIMCM}&6jH"%]DOIvF9?h3]ی$ DUҧSnt /$iFCvj۳0˪F8w˜}f,qbr3aZ$bydi ';oubLSE2%7kaL˔$3 1umF|7cZx=19e6Qae|6=( (L^,NV&a|n*: )jkq.[[[w22K]0+W8sN"ϔ%֯S0 UE)>)zX^laSQ.siiIM,E_ ?$=~*5lV~f}cyCޕyejumYFFsuyfs_ s!eӁvۂZ ͼՒYknH~3u%2QYYI2 ]^iB_XDE$|ZZFOh^na\aL#moEfǶn."0R+Ȇ_bk)i9mRv3"4gfoq;LG=BR 6)TI$ f S\^5[ > ڭb D8UQҰPDtI`Z tc:ZHMs4 S1D4v T5 `7_ 0$ PuH)ZEHA}>7Wɂ1i"ӧ)pnH3ffJ@1&cHP6zY+'h+W"c&_0Pk佪@( bSFEq jXO)p!K|ppV-(kyM:_Zw Eg0qGwꈒAvJ>?qc<6:0yJ#56wޢ0AnpCg($~]y'.&{D^3nל멙ԅdg}BӲ(aZ.N^:;MM՞Ɯ8p³;SE+:5mow͆6 Zhi +i' s5 MZsj&; 68rl` iۥM9.0a뢔,q{~&~C Z`'yڶ+c"lsn+a)nұtS_\k.K%hL|kڦjݼϻKxz5uGI+:| %+H?mÇPK ^B5x)/com/vldocking/swing/docking/SplitContainer.html}ms8wWQ:Udf>%[Fdg(H.AY=gE;)$rN*e[4hu7?`|1vHLtNzo?_z@~K2 Y: o: Sl؛g.]30;g?}rC7#%''JpO;e0òd%0 ӝg3^=# OÇO㧏`J>+M< .\'0,Μ'y$"?ww?瞤+EN;&!s΄:i8yN>IH`[}a֦lIi!uҧNۋǥ3ǂq/lkn7$YC#ɧ3hŸg-ȱ .Tܵ~/`NG}ޛxKNOɇ%- 孿^!2Y2OG쑞 :ni=H,FL3魻w7=( @wNd2MLǷ~4 s`ϼ¾v? E37N9gQ4?`$|p*?v\Y,깉PJcK*GϳE7'lZ #s6V'ΰ[4MxnԶ?Qޢ𸈷(fV(U=/ |JU)xLtͨ*< :1l[Qs%>1I[RvLhg&qz϶)gmgi.Leq[/9%-ߪq n]k6 'u( Ϫ4.Sc6f?giC=7(UBYCHD#0+0qIGP2O;\c2LޘqPm˖-_|ס8]{JK;)y%ߊ)Z.0)M|i]1;wDƖWՙINjf*:4AZ0&[ HDO̘"xPmCOТ[C){(+,,j/{t=\AD|^1kkƴao_Zv zBU-BRB Jj&I/7SJ[WɄ >9-]pD7#9a#ˏm`'ZIEecɜ1~(]79C1ﲵ|{gx(Ѓ]Po<eyIjRYgWolޅisH(_݈!ɩ"ۿr=l$2ܨIM-KՔfQf K()aL* /-'y)bY6Zyrwڣ'n_öbS":?̭8FsMx'˟},7$?S~g/p¦`/K lWj†&mm^XFQvW%UZe7B)Q1{^X(Un_ß djM[ܡo!?4֘vZ3l.mr ͕2l>i=[&Ao |&W,-ޫdЊZ!  dw_)?\ Qz`x%P5"7~:$@:>L_ WlNF&r3nEtQ0gі Cёѐ[֭PL߆|,怂jԂ |qYϸ)1NǷ:yq T_.rҔmkVW8DXw&*aDǐpjͿA#nC_B 1) IaWt_Z?Gxm@\[opp1`*Y@ۗCb8Ɨ@q}7Zenh2+:4ʇo6I%^ naCjj#OwOTrr%7P8̨3Mob[Ren0ʿA \uMT$[LI?zK27]U% Q 7t RRݍW%A ]6]ą, ETIS Ӵ 3̿W N;Q;'ߐɸm8q֓!"dCR(C20tYlB&  q,=v'4ݖ Q?ckr5gj5zS@I?;~@MU5UJ[N +knV'9Lớ6//!$q7T2yD=ZI#%wK'Kpz82n.?xȤz&Cj-$ %drJk״Cډ֣H^9:)fs"15Y̋4i $)u=Y4># +6)w`% Yp7K>Q K6! br,3b6wwG"n4P}rȔ[&[82Ӥ6}TN/tXZAZJĔG ڿ挷&X!߆ǭ!8{tShdBnO V+µehNx+J> 6 ;ϥbR'mh8p&Nyxh Vq=|w.~F׫ W ע2z*bH|ϵ  \µA+TrSWSn'|ǽ匸Y&x#3 Z1ކ-k-! X w5/` $uuk=We"oԌ'鮹hߥ[j2 sXZcݒ~x=.hWQip*<q;Rl}UKđGM Z ]C7Jh*1`Nb|Ɇ[)--"}n<ζb<;)t<}Π\ &Z|$?{ ġFCycK؊ԆiBB9$a[H~։X l$nqgPgb [9yW@m<'cqcG:jjldVd(d$8%>ƍ51(whMcM#FB;׫8I~~bz@8ǹb]y8ȿs]NbSt?> oݱ҈%gZ- a۶^GdY~PM 3׵?D[@]f@V @A6W{!`QSa]U AX*CbUsup̆ [0&`~6݈~+lr_wRBYrB7LkW4Μ> GJ W M#zZ!aJW8j/ 瑦;? peWKzy'^%N#⒚F2FASn|8<=Ob`UdC0QG@|z냋q#[-q.В%_ëk4|D,I)OBmIubH*6`Cz[.DS詾3H/@׆쐤Bj['oP#RlNJ*,ə>,,esߵcZ$_ U.+od!5\܀ #N(b†pk9vX2E WE,EufV< 4igYUIC5 T4❿pyR#!tGr$C] FH# |v Gğ79hȽuPg/b㬱=ԯ7!MNv 3I12oo㵪H֢)ˍp־uk6p*VA "_XheA=1-ҝTO bjͫev׌,!z2bh )j$w4O8ELjǬp t{` ]5ff18: mQ8j;@b7m1 =j;يʷ%uĄ>5|d)rMҟJ`IoFkfRBBߋuͫs31x5d-6֐ijWp:sőpG^dq=k@\A0V|n|hO[Kp c[=Wʺ%5.⩥\A{'S^S X``$2C|CdD{~i9G5-#6{ݚwNso=X\T-m)Ծv싏k_o$yo8Q>n^/|)N1sDx)vJ$ N &:*qmm1sK9\pݰ/Q[w0&WTH>s ߔ%ޒOówĬ*+bC~|^\ |uBГxHQwU#|)&-knM3L 7űrq\w}AZg|H#_Mr8M+Az<$KãM*n t(e,L#SW4] XH gO.YPcY*}av3@w to1ckfTDīQV-n`zK#,x8kX06)ȯcTe%13h 4a:|/r*ԙv|ixM̈ʵ7 XU¶Xg&T[LѤI4>meŠ!!tlnp8F_] ~SK P^A0 a- d Te1T n>x4wX lB"{f%F|dVrR|- ~VIP+lVsH6EWo.ReFKMdpQ_HVM_F jl2䫻s ]9×Gn UA27+_@gco}W*^KFIŬ$@ۺS2?|Y"ur"w$_|^P![8Aox+۪_Jәj#Jΰ;r_71ْME5ܼ*͊*Vd",̑$6 $mVI U94yRdڛ ,E˃|4PRm/Z#Yd $PΆ*1337 XG a=SցdrSfNc;4O942T9񹞣SSjNZ1-1*RP#$f8/DIQ"Ţϗ[2JiVSk&H2N2 hU@ _ii/%$A S*!)J,1dJʝ¤苔ےR{\b-LT%$7ΟF+J>&\-,g:Wp@QQ?PaS6ikY.!]E[;V%+dw>[Ō&%w\K_bЁ~um#솀S\ <1g, ,qqLK+3IR5ܒ@=#/Y5G]OLly2%&yi: g 㬞e*D1E/r~z#=mr JEdKԯ,c*aso+)+݂G4DkפH2s_7ŀꠓQ`62*M=*h xx0Cv#z?}:# |́ yiȟiv0fu`QrMMx-Ҭ 2޼pkBK.=5\LB=zt~ީhMb@LlzzHX@PʙXwvZoʞ#4G8"B8v&sҚ@Cj)GMLbMԁdPs5):MfXi-@vkTw"i0QZE0&09 "f@,ѥ0IO꽐aͽC)epK?\V]!:Ӓ3! L{GX!fw9[ ;<_&HQQbmlA[Xg*݉vETHN"A1Ք b NG` oD!&(z\ ?`&2~*L"@hCMjG`;YF-fBط4ALF Z7TDh Z*&XHN= ;KXH]:kG)Ӯ2X6σ"K2c9#^8}5М !h `=/Wx.k@ )jҭҡeEDop§oۍ^r{'fCg٠V#UT`H0S+F$9DEhK"Iq-'*SO*۫\%2 e~-U\;TX[(6E4ysqF30Xvֆ,וԀ#ؾؕւ#^۹r\qGFΈ1]i--]Y8̻9z1a֍qBB`M\^A<2BkEzm h^ƀǢ#M4aeF=G7-:y0FER<r,#k:f7~/HzyXH i4i bR 5؟E҂:|'t%BkM3X!IL WfZ`1Q kpc8a}!Zzpn4v8P@:N)PABu QA{^a2+_%xko Iŭ]YILr-[/z3TvO4͗1 ;*AJE $:B"[lyV bB"sZlupI Tට 6F\G@T$UrZi=o+^M:ړTOb|3_Lwd0GWїj7] іqY2e26l+:nS,9Ks_x>=3ۚE=( ÈAXsö XdkTUؓ|&pIXKJg_׷CIyҟR |=~zP2E}HУAڜ[֗ ,mg$%WGGwvD$r4kX"bkzbM點wVp{DAwc[Dt%_;W3p{G)q]]f5$dO}{՜G+x Ϣ]ѹlٶ\)o6_tvFNȴt8evHjp̧`&Nò3-mBe9蘔 J 86>>kb'}3׫}Zr׫aɹLԷ|4܄s.fsiץu8X, shWeP<6@?֏\'C> Ӵ.8 ,h?$.F:ZYNwH_ȩ3ο_R@iilGtlӖQ6;uKԥ}Lcx>`ꦒ߲6O +xyyF(.=] (/dvW ＀󽕪p'2vɱ[6TbeX'-vhNU _6uY#8G1zNsUhn~{LW /+l׾k  +^W`j-ER< ͡x#{8-W!J]p^!O>8)]~4Ξx />GMl=;C<IWz~ 5IN+`&ʹ80ȓ爓R0ӇAifE!fI%ZNGZR|&Wt|(&4kdp:ӛ~:#r,U pW℩hc;8%O&dПIֽ+QL)?Okrz޿#I]oߗc< A~Ud=YI|8&+ْKĶ'9S5=,,pd„UD(k[|+q8 4ӭxL𖙃@:rE=Va9&~bض*Kj{'*/c3]}bAvCbg4@ԗih틫Vg*{gR*= EN;;`@v]y E,Õ\m#,cxn+X;q6?Ϸ#\FwnNOy#%-Ii]l͔o㵩u/AmF:|~OzK3& 9$n"-')Ќ70}[42Om@SVQV?;YXWhO(t:@tGy{`ȷt7DOй !iE;bhqS aEpU >mH8l?3||gre7KccTRLMTz@:sͭ PK ^B\ C+com/vldocking/swing/docking/TabFactory.html\o۶[Rh{pd͐AvاH -j"nzZrNhPsΏyT~:?N9p|~AVq88Nw_w !DBLB/Dt8Ԟ,u׎/Cg^lhK2·5EBMO$Ƃxh8C=IA<ڳkA> [w.ށ%AIk,]-:LY|]{vMc"0 K\ %7v C1M%'DXH"p\-dԴlIemCInZ}٬;ɼ 7s7"g-'HZ-9}/#MRmБV) e5iOc 3?hy8z% S~ Y [ zhG^ $FØM9#Gv 4w+txܾN5USfp௉2nFA J(М\r.SF3lyc`56d<̖gzYr"XkJrq!]юl7&828y 1{~<ĕAa u7m]2Pe}BX{y2gBFs'CZH=i:|*'O0CI1%D '7Sb`'Pd0+br̂[ aEP}`BǷjx=@|<}`P5-PLMɹԍ3hl$iSRѡ"0ejhO(ggv ރ6LǦ&4VQQ<Q"ӝ_r,mB#-9c*.6;9]> qLA$d(fc|blil2u u$6F@gZs(NB/3%N$E3h/B.$K)V+!!BI0.򪨟nu&Y^9oQ61y0j-PveQ(mVhn!ܯK&Nչ}%s> |҉ڇD`~cJ#7D\-b]DF1%E2ZG[+/eL~xkOxa..7X)g)1)3X*|guO\M4pu_T<Ŗ4Ѓ_"/ryBF>T1%%,G_CB T %-r`tlPx&~qpFd a c ) E'|vZzFh ` X"zGcDTpP?q@zu破=3N|G!fgHaALjSX0BDLb"w)LTCSBۣ#OT0M=}!ty}{>O6WLUc,g/O?ˁQ= ItL q`=כ>0#Iu#Iẇ!t 21_]bE$Wƛ㪡kЋR@:Cgл^}T!u:CQ',BCgoZJ#Iִ38#W= -!s7J'*g2ab;!IpzV+ZLȑ!#Mi[] M ]fiő#|5Ottr.QsWEʛy{H4Rw&!tGb8u[tVWעj*><;E `̑zj@x0SkEW؜-zBmmװ+j1Ye1b2Y«Eì%r |AcX9ܮB }%cJ?VNGeKa4&P\i-# (>K㞙&*( 5$4I&(; jS\*!|.SS$KC(ޣB~ 6;.+BMtxdrqi/ zKk5!cpq^Eb%"W.dO3a(+fZCM닟O`b^P)&k)./#@jE9 #xfcM Kh6:?YBYd!?xTmJ 6M!4<ZBYdSǠ8ۯ+ bh?x/'k'3 ?IO7+TԻ__6p*$yssiz׳ܚi;y\bzU ]S֬7w#I6sG! uSrqa_΢409oD6rqo$w*4b>MJBWz9H_I$VMx7^`yΔ1 `IKӻ@io[GM[ ,_-WjUþ ]x;d.gd8&8l{ˉB?PK ^B( 0W7com/vldocking/swing/docking/TabbedContainerActions.html\sڸ=3t)6IiB|@goƀ!@B.`ZbdjʒuC}moOO){l7͍ne &Ybyr)C }{<u$N2:K|CQJT-qxSuhhH,)A!0|Tўor]G KK?DtlށmK2i;JQ(1u_uEүȿe D-:p+>_y(*Ul eQm+*=,E UG!"T:Hc^z ڭ:eF]]C\uZX3Ru"2TXY+eRTfuQG>V]vU. ~b t4QʤOE**? 80 Raכ3#e jn2.`Q?A$GX([jׯ j_\W]k) ڌs|JLQ! (ˀ.K~ɼ>T;J -b^~810@}Z1g2S).b!81p513UeB|ufiDfG']Մ>8Sh;.i^;W $qrC!o%GhN"F.zAF]՜:FӅ[_,AөUE.1fȿC`HH4V0 ]]L1Ch@5A/E҆QHs1ƇŸ>1S6ΩfQ>&@cQd)ȵ NLkWhBO)!m0Ux'{Q2Ҍ#?GJjf]GՙJ iLLJNm S'K yu!eݟlQL14a>r'vޡ~*?}=[Q.Tx8f&E;MPy2㝈mQbnE1qj٥kM܇3,GL#84QSAgZp曺0.ΒW7;J!ڿ{z67k%gh'#jCh9=z &ynB.HGq Y=MJBr&J jya]jCns`Oљn*Ğm+8*Sq9Qj~.m98fXr=ϼ:Qa־rN1[ >  n(.0 ⶡ).mᮃŬ:aG!>z`4лAz5@H}':0Q"[t"׍/j v^:.\fӾZG`8~e>ǚ0.9vz ߳s@o `ό04.>kJu7zךzr)I)6ai #[|@n]ko}EirpX]஖Q^J^n[7,YdAyRJFue(C: DMF-@hXFf 0H?D8o^T+s63=Of yܮn(|` ۘdz,oJEˤP:̘5m2BMk|;Xu1sݓ=shQR[bHF:D $!wH? C NRA G ӣB1gTu.Fh9k/+Shੇ\2!V뚗N׃ر%Mm~^vZB'x:)Xi!^ {S>Wï|h]"ubwSQ: ABBOǺ%KOmP o6_8ƵNwIndI|>gl*YS/m*J')0}]8]MGՌzP Y|dL>=^&Bjn݃^+\{DIGKN|n_F1}D'2en-~ ™Xr{,XXc6XԓlcmZp9AQ0E9Iĩ:8Cz`8#VчOH'&hRy_25ijE SW@WT@t;ˋ1L[?PK ^Bv;o (_/com/vldocking/swing/docking/TabbedDockView.html]s㸑U?0j,csW;%Kvm%3DBL AɣK^|G˓Lnh4@`<2n.s}0wC6%>qldzY{~~>:co>SrovNO|qzʟRdzEFfPlc4;ohLgilGYƻt޿k}!ucl{Oq;߾o9Z,9tO_~6N\h\zh}}ooǯ?$#_c6+r1tlYqOYH`u֡t1(}-)+?u^_T+J:3X0mpMq8kHi7?y0N,gxuy]b䏄2:< k8}\1A7kBה%C'{'?m'$_ 3)I(ZXLXOg,ɉ_(.Kk;6́96v lL+s=oojpzlla@- T)6P2o^ClV1`1#kyȶ6DOS$C@Z(BKvO|&>nS>G?o[ܣ^';͹9Q}`3ְzvc^Y/qΊWi>8cղ.]>=ssu}˭?!=MK%혧f83S3震v%Ԭ~eFή!c`uC"ĽFDP !D_$!4bbjXeԴG㢖>5c6ɤO1kbkHofd 7svMcl[0uc#K #ށoJNm= 7JRM;YG޶ lX57MA ^u7cYxTEֻ1N5@}%ה,E]>Հ`V!OIf剝XYXd) 6b8Lۤլ@%9pI,}#W7L6Ғc `(snsdѷ1r%4U[ _"c/[N-֎2f4j4OO*6c8nZC*Їfw8PÖ+bmpֲ\:3o]:&n/T`3%zhUE W/UY\vZ)M1ֿϭXJ\7@R u&-y YcZ395ͶL [K\",(N1eN^-q+~ ·f>y5<͹9Зq[Be]l\G"A.⨩g^l>G\ J(^>6G;Sf\_e @qg"9yherqTHOj}7btW+$+9d|,+6Ns>\Ƿ_~!@!:7pt9 x>!@3r2 ׷\GdR5kWt`8a_7WmГ^ٵr ?ba|r}߿rs]nIic@Ѵ4a@F 0dm\emm &qPM뚨P XiiY% P 8W| RRM&HArڿUhː78%v4G M*}@x8RT%6"n6 :{E *1aPQp/P 3wy1ز\d_ ?S-gqɩ1+o7MˋK$AeP\fV<0ypkBL"J_EAfS*]:ha O=%U>Ho7Sd+cˋv6Nm<ڬPTw v_1toZ'Ɍq=42:T4}GZ hˎ/ɫuɯ0'׵cˑ5m~9W(C'Ŭ?%&5"][a tl~w-_q f#:9E 3Qj"7Q^ y}p:st_8X8O0CF%^ G L~.zxL7NBq . 5r`=aU>6^\@b|lX e ${($m#p؄.zh?®2`9\AWzZE 5@c^ݥ ߙ#;D(& #i@wcmwqCpjk>[=tX 5hӍӞvw@uH=It÷l}='G["gt~½ئ,^\*YɓSr䉞U'ڒ&널TaťwL6 '*/Tk9;)ZI5${u !”KN!9@!fAqcJ(dz`}mf y A_<2 m9,Eu܍˳i+}v$U1Prџ@˿rHwٛB|5f+HuA-.T`;Ǖ!$8;)pCn*kg/P䡊5CLo$,/r|Uz{^SalP_odYؚO[cPh]mD Ynͪkg$Z-O *MO[(Qwyج> j Sȍ4\O8yL;Z1+B B!B5[uQj:m~`Ê3x=ڦT c -d6 =j:ىń>,yISS()bMa#X_鯴q * PǼ0Z / H0M[5M ob>hN#MIslVЕ1 މt*(>YW =iF"O[ p4ѱޭGt'aZYE<'kIZSE: /" _낎Buy֌C< Å݈+bu@j;D+kUzN; a'T: ^j- fkm&neƅox'v}sMq ƪ 6υ(TMU..e;BE LdB scDqls(}LRyꀙA)/{K> fE׫̯er7ⶓ'_qJ8 U#܁5܊KS wͅ((b. T8a: 9ʼuzn @㵵;9`mDV*p@Rގ ֜]rXHOswç@sDAzM DzAfh2@MS P~~k0sG`)mvie u2( ZLue~+ |}Y7NUBq ""fho={YcU"am2&׾8p#VyRyE]?rї&7M|SI +4y96ծQ4y]hiژI]H*].I*~و؊mXs0v+MCRi !ٱ^ PKq"n=KfPdႾAM"ww}{V[.ќ=!ٜ6kj t3IZ8/_.E13Q0WjkjI8k KhɒeG.ZP'TMVC ZٍU/MDp8E6P[L*tg:` M۬ "iͰV{4p,vE:@G 4~|m+^/ Q$ۆ$R3yDݞR)o aht|$A>PyT 2jPB;1F>Hmvh_HplWI4$Ȁ G"2F  p>e@] c/%m$)(=6iP&nlwhT4¯}kAֵ~z)pOx d֏Zήbέ-Kᠳ$%st2 Ce^Ym|?(65?t(2F<Cf@@8P f0~auB^xzI Wt\[rSn[O]mica"ižִTqAȡuvTMxG'2w$Jp[!kH""hOjR= l>'Sc8Wj6/[w/胨1e26G6/?>n-uOlץZ7 !>qЁ&[tDĿp=|nYJ#3Tn0{PP*Gy@e̠9>8 ף05uC:B:zA{uAFQ:nҋGB#q%~>8kAU7a-jX!-3t^#o' DІȎpqV>M^ o-U,oQt7J(>wΣg̞,aOaE= Al;EsS6>g1NVBi&q:ث@~.C 3MP?/L@_"Lo%,Ęٶ,BA-q@u}_zVТF+1< 2ya-czE"GDkTJ޷,ٸӥG\w.JK]L^)5fP=5 ֐5Ә# ?/vcX?sFutSHF<&N/pB)#ϛL&x\P7|sStrMu5V#X ) јDz2&6awiH}'?ף=t`o%#hKz=tOzy,I@|IɐNxz{cπ#!b\p$X6Y}O(,!)ȇ!%!=_”zjW;7[5{zJŹqQ(5q׏R!pUe"y$de)mEmhONb4U64&C Ai Ե-v9j:cZ曫pqz|GiEӵ~hy*$IÎqEÊE\%yd QpP0w3qvV[^Wo{XL*7 \xSFǓ]~ Iy<,#wuv1,%Ju{ Vي iNs 2ym'>ɳ$Q]D0FOqԨLUFZAc@0QF8BLuzU|GOcl|01L%֯<@F~$2c_+&VdcS^UJUā'BuIJ6P0=%CKJSC+[YѣqC)w9_sS Joޖ\J]*'Q$*ss^=_(畒۬ߖf*PܪV"Z\_ǝ_W`vL2rF͵&+,F?lX],DUq'U{uQw5ǥ[fjvw o׿߮?Zo#]%%AU e0UI$;ɃPCTqǁϠhJ8X?x9com/vldocking/swing/docking/animation/AnimationEvent.html[moI)w"b`;S }ː40N7~w0`u$[iv}\/W-dU'-iv#0i`q.:ƜOOgX؋;FNÐxjuVň| 1/s# ]T]}<@p6 Gtttq ݶvt  /$4O"Љ]QQT@>!-dX-FG("~b'lL%'߹2fqDu˶u'%oǨgzFt܅ԨZ|rXۦGw_(u/^Gգ_E+8`D\h6ӦI1QFq2kFzj{!2<؏,B(\0g,X?7{[i~=oޙos1b89(Ϙ;a(S3hǣkTž\5iğV!4gMS:3_guNk[ؽn~{Iq=u F-p%"Sa>CBgZ[>I=1> ~RHyf.&Jq y ~% BqD.EWH am"ٯd L&RD)>m,Z\xd[]=Mehz߼q[<]UWOM6 ]R&?{_nXṇ**-}mlǏt^cF*yBj,ҬWfխݛU76j&xk[ȺfWGuM/llxIa4z)-1Wt2-\6YG3/I+uw.<I<#2A,ri MhE09E\+İ,x6rגnZߨI8y2QQ[R ĵl۩[+JH9wVb<\"4ZKG-O.x 5y[$&cB=ឺy67uuք?IIsq3D j6zu8zk0^x?\Fz0d0!pW|8KA3Haij@&[>p{v>oM C+vXQj}O|k5Bf4hb藣GQ5"7H݈eTcUә3dz%Y|61q`.XG,gDMXoB־ 8pfle.JS"%I:&y2L^ޑkv\=>Kyy0!BQ餂7jn 'ٔbpY[l 9;OC²PTM}t]#0uPv95&lBSx] uqlmmd)#+te+?LcujMChШ&H#wXo+1s/{<v6[E<|4Mnڝ@ Zvǁ/6!c&aJIXk~tG#w.{ 4v;/12لv`*ɕvq@ifgH7nnD;/:aTU~<Vt>fqݡkf`.xϏj&^|P9d c>GTC "Gvr|T1f<!r &a>NꝀŢ)v)LՉ JMdf$A%y&%1py}Q\&e~R2 2z;F;%} ʥڴX 9g?6΅k]FnoVIKn&G`8s. 0_c!nV 4) X_\gL@={ߵ6rpY։VĊ'#\@z11ZCh: -hb }95jyRN41րKxOb"̩юiJ e8 !3<wb2YqXj8lGȗ:loKQUgo[*mS֜6@Ji6`OæT/Y' ˈ&Cmt++"ɴ̦pTus߽A>JT2n]VxjBK^uڬcgY ރz@ʖQy'r *1;A$ umLR( <+j 5n7"1s>;կ>5q5_.Q_.Q_.Q_.Q/Q+G5xJ}J=*c=#1I`tJX+R3L{IwpO-ňef<3 * P-'UV PK ^B/i<com/vldocking/swing/docking/animation/ComponentAnimator.html]oFn ÖHIRՅ_dPJچ"UJ;Kd2vggp}}{>}"8:eR~>=C (a$ \q,dMwri/a4v΄MwoMtf᭐㖅f]Op23]^8D( ڧO#sy{~.v75~ I0F#waOsy>pdG0E4iYea0 ղ04ϿIEoY=N0fb3RjIG-˶_-o ڎ t3sQɻV 2B ?\w6&5ڄ~8X4oQg?/̧Bq@$Ϳ^9T#A\{dғ3$y T#4%ő}ƜIQK^GQu~y*h軔 ٝibFOp?e9.o&~&8 R 2@F(ЗccKwj 뙄طJ R'矝'm=A}鮥:苲'\]!q"bOMC~JG>j] c'ⅳYq$ɗ4$x$T -`#`sxVwl:l俟Cpfgr ;#×wvK}#m#18gejV3`[Q^$6k:+,W evNg&/8sWIvDt=.\س\SꝻI4.3̔8"v:<^xN%k|W /N=sOz:uhd2_wz I'a81|!B&& 2YTҿ۫OeE%8TPr[5 rkOM潽EHXasn>X+W_ t<*dGzvzj˫W+:P_l EbƅIF\2>?I:kfǘ]l|@ʏͣ@J9޻ Gie{!txUX]֤.?8Pd+ٍOs/2ї,3fP^-Mzy}AGKv)蓪( OStp&Oȁ$N ZvP?сwR+X2nU&}v$xxtr6q gn9ϛ%{\u|sƠnycaEk6aM-gKM8 gb LfE9hZ@_^;75@Zʲ Y+_ѡ;)ęֲŔ'T*\R/Xc"n iS2dr%TMĻJq]*jk6뒴Q<๲J< eV%FTb_ % WNbv 誓56/nW>WDKfyg&2Vݹ.85!j r'{IcP ۲R+9($B<1*Jqm[d:yFT2M #V<6tN¬k>]et‹$XJjF-ԫĮƃ `Jp.W~noēD/@cx lxm+KM*Ss{-uԥKgUeq&ϻ}2pO hEΎC%kJi89 Zҩa #NL7'(:sٲ9@<O =NOє+ym}$R -|$}n e/cT:Whlg~.yᮓndxz]e*A벍TEiI5I**J9|KWس^F2R=P&n{C6cc0p [O=N_CqIVT]mNqUmhm/3@*:hRmt ιFW]&|1qcU@20:GM[F[7!S]#BJ6~JEX-L.愄=_Jɋn"-s{+[[PLv5AeLz'{̕Ҭ<ӂQQ?TGBi'[.{w?~8pfq8p"I(ft2Sdw3)mwM7nO^w6[Q)x̟)ZLpfLp?PK ^BuΡCcom/vldocking/swing/docking/animation/class-use/AnimationEvent.htmlYmo9^aD i6)*!(=ݧʰثSBHJsxͼxfό'ݳ@q?:t]Ë J W Bz1kBE؋T>!sxAREIGOzlѧahg,*'qIMJ?d95,s4,רvߢ jLB~uZݽBF41tFjr,Sj ќI']Oos:e _^ԌZp?'^2CA"I$hGAq`6 [ՂKșm1YfigCFZlQDW7q"g1;絯huljʾ7~_?"ǟxPqhw אpMQZY\-4ˣ}bԸ||goapևÃ(Fpzt/Q"|HO8_m(dO%qrGQs>q+=OckmR3Q.yN6^ڮS᎝sl:2>hnqE\%&5ƾo#)*Uy] vX ث &9^&g0}NXM2ܮc={D wXg&3ᾊU z6td# kaVZ|#,v};8 LD KY&n!ຌFM3i-+PUZ@7vuNl%h`vxt!VK_0&4ۖW*jjM2MyY--G²؊rRnP.+1Xmy.B?iݐ*`D,,B]mKo7P8h~3$v{Ycu{Qpq?BmQeLgD#q{%ʲZi0)AUHXuWѦ#M/r7%)-.gZN@_8Q+&F~Bשo#TQrBOȚ@(<@LrmiKlE=fkZ9kh Vt4!* , &э[U&Ӗ/{U>xyo@ 뾓8SlN=C,8fiûLڊDR;m=Aa7&rڑNﵝ ck~>~^;γvtń&dJ[TnTrpA46{Kt:Mۉ9#C;Pʰ$izdY18v-*͈IghZIe)tgT6aڠzJ~O77DZzFN;Шom,>f@PZǠFDK.J>d::h?tTKNIvO7vHPGRإN*QșoKL4#cg!c6;pe_-P~3J7~^3:w^<)U]TZ'އP >2e_O8iC1{&[o>讋x.r~Y.woO@Ru'n vbQ6Sc ]dNԢfYNCwOsT j &@etq/"Kan %eEMG  u\6RcQc\K=ǥsVQpN8f<Q=KDGPĪ.:-!H11FcdcA]2/!zZmv.Dt6b!pf|'V3G뻟LcXku}Ib*D.ݯ?|Dcvq0 Oyb]?O*1=l`1rԒk~cokdž]' +A垼u1\OƱU1: ӼݺR]1@ͨ %g4M[n{y^|Gn%S*S+bC efeQ !.f3>8Tzei@]у>`k=,S{lXv.gazb^ Tض*@Ŧ+v,,֌ZBlջ@-8wFҊD,,DaRzL<0*hfl*  6z15a>uuS}SL#&-+ORKvi`XҐ`?iR֚( y^۞  Tn3ą~? \Jk\lD*q9&UQXB`.~u9Ils2?il)gnT=5:{(63^o\藎Ӎww]b3TtPs}*? + |, ٸžxZub9tV*/£/8#O1O1O1O1ad<гj@qFqQU{l@E[e3`~vxg5k>ZhbAมhHI%R|z8cuBE2oiYQ*?PK ^BC6Ey8Fcom/vldocking/swing/docking/animation/class-use/ComponentAnimator.htmlXmoH^)aꓮ䃽@;%Ŝm* =ݧh ev(:&E*BzS_@veNjeE3 rmAL@<ziMyBmA[&LYjZN$Tv;W4aK,uh nN$Qf(z1aԠгS =(&BO`zƘ24!c=)6 [wk=) ;^XlΥ^'PrW†xoI >1P7NUem'.`ᣳ} QǛϘ|,Sao7\K6ً"@4z؛4Qn kvKTM2@]҇jx]73}oǃʉ Z,fKEDZ(~/}ēlJE[f+,N0f7Xәzz"].8M= R(OK%} a:!s-Í`YQWx#l%swvT:ip}2jὢkjq UBd6k i!)*-UE- &Et &\b"El ]HÞ )FP1Ek=Oу;Iڬ. ANь*%|bkٙA +Z,m*5͒jάL_Ǜ^fnBhfGg7Q.K4QnBI[O#-F~mpۮkF.8oA³J ?PK ^BWGa:com/vldocking/swing/docking/animation/package-summary.htmlnGRd+% ew' N&d [;ۙB{\6Qؙ9Nڏo3x;z=0Q<M X Bq}\,:k6o؝ѣ5(gH&`K}jA%ꃤ\Q-]b|qdL1G\ĝS-.˘ᒙȓ˱J/)&h'hh4VE=t>&tV;U);j@1Xmj%Qp'rG#lSySfQ@>O=ay8Ju tsPnj}D'hb﶑Cݣiz2>Kpv&vaFIk*0{}S3VL;C [޲ JdCo1n==I::ǟ~W͖8(-&!= i3e4GJH&!*nLh d̗XnT8)Tp % b !2E^JF+O;(4jvǶ,ߕ(/%[f9͎3=kma0' \Gnk.qVo.=ĀTbyHpOZxdZZ׹P"TMA tڙ^˔Nڞ8V}aATRu`^Ũ}VL*J,c*; _Б7:0ͮ@hC0,oORq "9SJ ۱,Hn— nNiӥwpȲDM2CA}+ht~{u\)EG_8ܥX)߯S_SJQqZ|*{Zd&茰O7hh@=k" p0ɂ'v񕆒pE%la3tE>DPK ^BΤI7com/vldocking/swing/docking/animation/package-tree.htmlXmo9^a']ki4K@zMJhO)2ܘ6P~}c!"E6?̄~g ?^ychByQZAn +y;T3FbXX̘ɌplƗJi i̸e*<7~[)P)\+͔s]%(iWKCcqq7Lֽs|{o2ߞ?4 1X#h@WH6XhvFZ- 䘺NUUKƠxrw0w6O5CVI-EVl1b˚\2w, /F$~peGU 1ɼȠLxXhc\1|(s!-Jyﶕ +r!7ٌqUvz3[Z lI -45*OWLwK.j o]?档_{tݻ&-I+8we\&>D.UI:G2Q]|(%-EIU.,bG8i :=dVTQN]2=HYcJ;{ nk(0mnk!?Vcg1쉔^!O:5]@Lrx:ra," ,Ȧrv9LHBS;M*WDkFQ]noY2׭uujѧY6 Ge+|4;5SiXd} [vZzOnTi7N/L*.Tv5dOJgRąSZECBner(tҙQ(5cKp$IQ,DiYx=31xTLu;B)O3GU".rMܕaw,Amv=[6jUZyYz|&~j"F/Tعǫi{=ԟMM#eNW3ɧi_G<(wŨ_3|dG%+f},ڿܶVOR`L 'bp!t \r#2]4IoZPK ^B3b,6com/vldocking/swing/docking/animation/package-use.htmlXmo6mTF;YS)-BI5+]CD(=wG?ڃgfO//z&3d/G& 4[$u֦Y.(RzBWdjg9J%6 Z!tٲO' Э] ~ϔѤ LSwi5n/s /|ū#wph,f@OGNE oDf|FᲓ-¹3TFt'c1G)3f)H iqT ?/[Lā+̔1]HiGKF0lQDko-{ޤP%+mFݹ3[ Zُ?| BёqSnBc[=gO !lT΁5G~zGHbYnZ'|z^g^nP`bkj4LGmv \2'WàׇɇӓmjFVi.EVHR}%& '#mBiX\FבՂO2/<2?#˸sm,I^Pi.n)"O׵ntTgg3WCu^35.i 53\h_EE.x+郶zeFCO%I êU&m*`m88efnj}5Q(Iv"7Tö[F9K@b(k-|&=]]$[L8U1Z1.%.ke* EC Y.L+TUH7"*VeAsBu; z%фӱ;&A}8N|7:&E^P׭}0T펃4I v=DynO \-t9yT&#\;LjueQ )lX؆ϫwȎnv ѣ394b)p:]GE>)_\2;wwXXFAr9gu L9bToN-Ubтk jbI2me{Цs2fNAݣ3$Nc*tgH2Rx ~ W7[7DÇq 7뷵:P즲4Ӝ6>*@ɉR`‘5n? lXiIXT>C8dDB^nP j~:(kD5Խ PPiQȯXs9AR^qj,AJM?밧CIu/ߜ wi-0eWD3z%8Սz O?.zD90GY)׵ӗ[P;ZID[##sj]sҿ<}.ܡ\b~IZ}|DL.G!fb,+TQfaUd`Y>pٿtΡ`"{y@X.IL6b2y,$f su095# XABxYUIt 1Et.HA;m Wѩƣpq[B%!kL Knt ]1 -Dk9x.2٤\P 2+jIijf/71=}1J S~C!剏>IIm2sP]`KK:)tx%Z[Ce]"[6U>یG[M6+=j)qȏEHLϹKȥ*!ܬpӉju |ȩ<G&l$J$:uey`_;d.kW/ݔ61-T YR]Ne;Y,Vy(+S|{JdXy^W6n ڊn;87ah-צ.CWHtBݫ]E4^a:<G`$I6YWm#3?WIuc9YQZbRVtJoeմQ%[qW%afХI\c Zfj[XF:K~PE@?|o|Cm]Nl$cy7360`6Lk.D;g{Y괹9u8e#;3Al\Aʺ~%5ʩS9=+wQ4cMeWcMΣL4"®aӚPħ_Jp1o !eV9>XґoJ"ee 7nYS,!qŨϼ?]'E>9%b}MbھRY9m6>ki9 tmZ}6K bSNtqgXWh-FG));8333J! Wn3w6>]o~$A˄ Bn:xc+Be<O&f&.R 6W?=}e@dz,qk&X5, !LiTP<>^BrU Vr"GNH}I.o7%\Ks6_ZbÆgEPu8P:j̰qg;5 \/ߑYǡrL?? YyBd x y# ԑ#-n`vxKϸp70\!NydL߱PJ)Ǟ%=CU׊_MOm <[v"(W R4pPAuojLzEj VT Rj&'W] ߷ M&fh\%LQbOAiɔFP ~ 35a@*7oU#+.Í`Oich 5"pkGNH}IzmNo=C[rˆ.6ϲ"qBf˅ n[׎sa;ZLWSIz <=̜#3}HOjS"k{My\R"\0@6.=™|\rH`c{x*UyCY_ ͎Md¶X@IQEwx99,3@A%+{|< U{④̦wTƒ}qU~}@f/ziD9 ٫9_@9|\~3.ous/~Pt>tФH`*Z2]cxށ%+>[ tȓlvÏ%3ERgi%a7PK ^BeI_&%9com/vldocking/swing/docking/class-use/AutoHideButton.htmlZo8}Lڨ$nwV8:t2Ā&lEl'iѭ۵P>k6wC:GM0kn=xT+If"&< x#wa8͂N 0입#=C.A#3߇6uȐ3 8uvΈ('$FЛ?dJ"чʔJa;=^Vnޜ '17ojiuVIei9m\(@ ɉR`ʑno($c: vjPn1bR"C){F_{km,IySzΩQ=)5a_)F^ſN޹̑=ͯK"wQ75>TXA%S>Qk9/^{ u/N"{{D~$ ]CguĦhsS1Ezbb"'LQfaUd` Y>p;!tO;w=M$%EpOt WE)RIژhJVaEo CۭUmۀA[*[-=r)m1ȏHLöǹK¥*۬Xӱduȓ>|ܟE[Lز *Huk"3vEy=,RW.6_+)m,bZ -)\˒vFX'ڭ*QV'LѦ5B5[ݞll ۉ- &69ũ7Pq*,qm 1D^Unj(b7q SiK Lb4}Bi+ q^c2'n"84 HLTeHYy0I ~ESlFd|)(,h(W=Z~Lg[((TN`jq \7 :Zѣ߬uȚ;:Z`U_KBY39>H$ gVV ˬ΍Ů &lkL84fkt@Y W"ӢSZ<=jHFGw]HD7 3Y ܅{҆Vo],=hc*n=ܴ]_ĔC7|s\-il66VW)Z:%%=NH:Sz78 3k2}pR5>-崯Gqpn-09`I]DR D98kwg=~!ٻ {'{ ^'H]m,VpoW݊# 6M[w77a7=*Kܣ_q4(:u:#> Kxgdkrx1YvJVV;dtHxS$sDю.kNg̰dÑZڷqFsD">733KUid: +LyE4PK ^B@")>com/vldocking/swing/docking/class-use/AutoHideButtonPanel.htmlZmo6^T;YS$8a(hТ@v}GRRdGq,M.FjKwϽQqGgws{x߷a܃WAuĊi&bp7:y,mBI8c*B(D:Ol?}hY )1xXhl(јJi9M$}LT(6_ S$|Z :.Ԫ[,43E49Q bL9=g0P3Lx";ZS-%әTt6C'&㔺 5u3K?7Vas=眪=OR:+HA wAIVx;5ÖwY'U}]nF1'6 }bp|<`G:*bu77Gk> 1dl.ҕ}S{/OGR|tM66}S34#m"e8'BIφ@B;N khcYb|%J]b]#?Qt9]dں\.3RW`QC0U 3\);\ H9V{ATB ٠DbV`^_N(a:w\uiciI9Ki,g4ec*/eer*]T(^^ 3o15aQ"ob DXqBkS'$UqeE̴[^aZ<"N`_IHz $E}\7c z&&RslIo/wٌ0SXUQE@ r(`=4,nQ/("S9Y#eƁp\8ѥuZVYYGG$إ/9KBY9>H$ gQVn ˴Ε &l&*@ AU9 4{-?O+]mŬɪ密QF;U"Iu[&#1GZlر-Jy_DHi߼Թh,rE\l Nα 2/7F%F.p͚q_I)(DJv31lRc}ؽA+GֆpwM 0R*:_\Y4e5foxl\꼰էxenJO G޻ o)=v?NQ>??tS-1^v$ odn:1f-3lPV_2ΰ/iX` >1PF#qĮ4/+_PK ^B`N#>com/vldocking/swing/docking/class-use/AutoHideExpandPanel.htmlZmo6^Dt'Y[xsą ;-;fYm5R[xwb83pt A?w<{W,p1'18fl?:_Ʃ籐Rc$<}rE9z! 툝e37'Es 3`)KST^m||ts dz{{/e>{,Í5trMug;'x!gYc hxvébcIuQ3jaA셐1Mi `fځ]R&lp ݀B ) s4CHAտ%A&9;qíLWM5 :O}BsdeGDBffJ`Pcg u@;;&}j$ nDkgw  "$&C#նhԭ|ZHqٶޠr}("UX!Hҿy=&lig5bav6ZMfwyR~~pSI j̲SN~=#=sڒRtqerE߿x.$ƵG00{xg1b>gb*p/>)lCL$//𚉮vG2&=:%WW`N _(g\pj)ˌ:/, 1+JF]PK ^BqJ$Dcom/vldocking/swing/docking/class-use/AutoHidePolicy.ExpandMode.htmlZmo6^S*q mc-H0D\hQ iư;ReGv 뚵FjKQwGgoc ׽.G#I%}R#P)$Y=t6EHK?#;OT(Iy`0$|c!,"Yzx8KkfyBs'DŤ1ڀx5?4`>yEzG}j岬wndƐXW" UD{JxXU ''G~y٘ϔ"{Q3j}E10$`HSSPcz̖""v`\r331i>lQD Mr;޴@%s5rGѠG ICa#4φ k@A a$!yZdL/r>C^>ԇz2UDL;o aH" Hj& }U]|EO^Y?<8/0$F*;eSxMLr2\,L.cj*.]O*Phc:a=@s"-圖"r.t[:|x<ta\2_AX! t?-Ehq[^Ra*O'c"M0 ::U\wtK{! :tp 41YB38*GdxȤ-iG\f!$'}UJ:'_Du`&j1 i>p gZҍ:e4~3dvyɬݧ:U:vJZQ!J̃y ׵*!ݮ 6)|,9^_'5&. Rf6 egyjc=lԳ+_/. ߖ6U)E]uIY#ǧGU`}ڷO-rwU6(  {܊+#5.tILM UvMJSA웱$g{8G`"1,>pLdAG I׵iC}Nk{l68Na>E1vaS%XڇJkO#((h.h[.80iJ*\ӣ*m͆;6&[U:'u}Pi%l.PB@XA,Lrii6utW2?i9jj^ hp#min'vRdũϖIGQq|[tC?E3iY1pPK ^BE̒'9com/vldocking/swing/docking/class-use/AutoHidePolicy.htmlYmo6^TF;YS$-BI5IIunk,QwGQ3{|~_:at݋gAsi&R灗h b,!'*L? |zt' oF,$DM휄 M$0\dNb1ƜJa?)ho|&Rhϟl@Ls~1'JHL9G7,jaL,}h w]N%҅7p4CM&ȋQ{:6~GYzSzɩJ(e~H)IǑa"$+<Ͱxi~HLWQmňFvҘ~70#H}Qh'#m5^MMw0tQ6ok f 9 3 C)04 *ɨj0CU61- `d>$=+ri. 28lbJ ;ML* "9S+E]鶁HrWe`ֶ׾̇f!撑 ¾BW"PTX<ʱ/fK!k[ЮkRq1#?a6vGcI:2Aݑ]>|©=^ō;LسX,Z</qDQԍͅrEwMEJ+5@qK7p].hI[_%)TFtze1|p(ۻvu?ȺMai 6NZ?M!h~5Qųcfz0g| O$F'V=F>]}9EQ"1Se6]n ej$Óҡ^3$KiI!OMGY8P:5lR6PDArS˂#pH-=*Vly鼣[u=H(5c!)xHa,ZTtrЂm%Q&m撃r-86$ѥ3$,_:.GvKR=% 1҆dʎR}61m+}EZmɕk1D(ϒؕ)GdB)M~1167VN|c/Z^mVcZŨ(_لez/ pEP 2L Skq'ݡVi`pyުӇBk1=qv?`Q~?~lsSNn7z³%g7M|B~lҊZك\HDseB!w1 !2X^RI'3WDHYث^>tزG |U h2=5Fb{0E arSC%9(?/oPܼysSBA\unLASPa(gB '@/kH3 n SPneO3j A9mF2|T4cBKB/F=ԒгUd f%0f<0% jPk&B/I p{xezxj6mDYn}~xRxQ5>1W.L)U諍|feUܽogd&SvȧqC!J \j-&-ɰ8!G}Q/~4/8Āu-]`Hb@#ίwbeYS׉yZKR҈ xq :O0e\ZE^OT}llF*{۫wigA()N%#r?,(.( w9'*ҫݶd#` LJaM}px1Kf LPZϞO&Rc~MI2o+)ذfQ_+5;P(Tl=fM368$'rd5i"k{MȓwYm,uG>.pn>*a>b C\s6x/ BUIjuoĄf&2a{⢗}M扻Nk?K KLe/BUxۯ>]/9'z/yx'mti;7^ζ@ p 8w|Ǵ{2| yESє gG?q-irw*4ΐxMq߮g`1~IX$u_ PK ^Brj/dr';com/vldocking/swing/docking/class-use/CompoundDockable.htmlZo8}/VjbJ;m-L-tMZTb#i=I2ڵıy5OZC>}l ϝv?xUQ[aRI1['I4ى!F'{I) C;bg!NDP (PA14F)J$]1J{U.*o6ܜ>Ao_~[V흔agM5=Dkԕh́%HOwvאDD܄{m|9jg"C:D[7$`J-ACV[X}L\"Ey-fʩPjd 4]4PW f "71vƙ);2_U,1E֦~4[?}zh.N,~;md:uTkFMTp{OBj8ڋT|clղBήc6Ͻ)F1ӖElh*G uh=l'[RE6,k=jit@u`q1: A.`<.N~/Y&箆q 5f}*dI}xE)m@2f=♠i9Y1;m!&%IG!QwP?Md/SIOu?)v!Ő 2 ∉UQ]R0Q C@Qh*D kDѮĐR|tM2.CyJࣽ_s$K?mq%q&O!4R-ENl_tNw G^*D) WC*EDe*WjX\ cnXa٢PȞ嘺nsƥ"\hґh5?(|ȩ<~7Pa!8mOb9`0)#W"턓) :P.} n(tݵB ZXZR>Huˠ;[3_-O嵢ZMoKhW!K)o:~bZTHr&R f|UHq~G*0A- cf;J=a>̯94Pik7!Ų]ty{Xᶡy,~G1EH݌d2f=FsK:5!;ȭetʘ߾^s3vH h<)?lN*L͠^Mc3L*E3Sk060Ӹž*p ˄A6%LC+.v2 2c&wv %lln/躄:[l@D#{2TŘaT:(;1/&Ecx&@ӿΪtk(J g[[t :Ll OIy.uT9’^zSA;omIw eO,e4:UsZ0t4rHqoS3[ىi}z<|-yG#Ǫ'竏竏G) $/;hY*HVB odj7ECУ/";X`PRyJv[2YYQ @Lcsp$뢍 PK ^BAr?com/vldocking/swing/docking/class-use/CompoundDockingPanel.htmlXo6Rw?$ajDs7^MI(qMPb}~ƫv޿?]unZv"gQp˕n삐r-O#'$3"2,Jm4l٧a(n*'q_3e4-$Բ+.hFPY0mP=Ԣ]prK-|KCvEvje0j -AE b﹜Df嬥f˴T2ϝb4pU:\oN$ׂfR$R!@]2iV c=h&ؕ`fʘ 2%#cj6("/֑lRsҕ{ݔSPjD]#;2e_zknBc z^@CX;?s^weT.|=>"$O:]sC)_4?y8:XjXL+50ji-v6 nAwн|u9(Ň2`ƨK<$] Cz@F[sϳpc:HGQ >WP:\R( E7vVQm[up.8[f>Q>-#TJFG9uˊˊ"lWYJJ/ ۳+[LڀaY+{`gJ-6lb,^_+/4\0<t<8y23w[dO BNcK!ӄ"($uŰtZ07Zݤg\8ݜ+T-ky,<@a]`uWwc°Cylu]vμ<ލÁ91 kTr҂ǣP7U 9lz@-<Q.'Xs㎃5=_qPFtUp:s\~\?FG;E=]}@ MJ8 6Џf7!-8擩zz%:\p*53DD.#p)U ?>,Bɼ嗼PK ^B\pJcom/vldocking/swing/docking/class-use/DefaultDockableContainerFactory.htmlYmo6^kT;YS)-BI5IIQnXLQs'w֍) >t! mKH//Ċ.S*9L\.~$Մdjf%Rj%& :O!r@' U h:i,uk&_Y5, ,(e.5~B5yM ^ ~.p#Xfj #9^t饽w=6sazxKuej(GHO=TW5& Nv[ D3f($hNbSRza㧰/xzvJ0=e`VRِL("5A9N;ޤP&+GgݺO?| ;BydeGq~ bGFl}S Rb*k0C`Oq[CA u^TTfv'8Y9QC }P!;=vu'C])MV_ ]zvtZ#+`L 47)0y ]iDm`5yiZQ8 PK ^BZ1V-p;com/vldocking/swing/docking/class-use/DetachedDockView.htmlXo62iGH =Bo:&l$4MF(_?Cu׊~S;-|B~;kҎًZHDseB!7]1%!*XRMH4 S3DHYkj}UNU h2 =5SFb,ap %*K4ZsP}^NP]}{YCAZ;unk~LCKPa$RO&^{1k3CGSq~ *v+:g+fpT:\oO$Ӏ . PObXbBW[(&BO`zʘS4!#=*6 #C9wgN6)B9>HԔۘfTi#~ c96Ɂ$f_z}c `oN! ŸRWr{2_O^%dna"1_6?wY(k:XbXDkP0Tr .lYw {z}^__ yѡ Y12%(.T= }; g#./-ޤ(j'.U`Iy[Ø+mй]lt7*}m&%%&׋u`dgARR:a[bg|ٔq%EvIe CU5]>kZLڀaQ˽px1Kٖ LQ.)g #yL>$g2'Y7ObgJ-K6tl zWg/ -& ;x_]BvRz <=̘#3<OjSw%D֌w'8@E6׷qe qsU"q)O۩kT f|7&4;7 +ݍw)ZtۻbZXf*;_CA!+{z j U[Ѣg o၇zuȇM(>"u/zy9 ٫7_7|}w ) 什]R@HZ_ -1z~4 L ԫsZS:GI6JÀm"Bw/PK ^B:,;com/vldocking/swing/docking/class-use/DockDropReceiver.htmlZmo8^aV :ZKwmc;M7$SAK͋, $mw3$˶N{5hmpޞJ<}~\^g-AV;mw㝿- o`L!&?9`` Rs?2|z94B fIps WSHPsQ<w?q {{~>ܴ;w2ļdUB91IdzC.P0>]=8Ul'RÁaठ!7 "C9(21 Tj6Ә3MZ{0P|?(vhrsve4o*2wdoDj 9'پH"pݫ(th5?@)ԕ8Ek}[oszTDή#1nwBC$4jLS9RUrL (<un;p} :t|t͂y@32bc4v wE@F0|i4p7#[wFxQPڠrUs E M!lm q)Yc'u=^:+ ~K{7C*(B*!C 5EXdUdzh~=%3qwO(k癦\S͈ݔ1hky]gq18kx&oLb%P)ks227KkBY`(J]b*H,HGÅ>G$w9kH?fX\IX \^#ZN2W75vv2Y}A>ziJϨ@c*)*4w,ntJxz4EZ C"X[6j*ŷ4K-7^ $} z7^iР7DF0]0i瓦1r5,\p`{$KW% ~"3 g k̨!Hv, XAꍟNMRmV)&@f_ Tq;C\&$x;Î7l8~H[cѠcM?6F5.#bڵC&b?tP Q5|f/Ro=w/K!1[t>Li2T6+9WhRSa;ٲ*2bа?@ǿ_dO0(erN`,&Y ~@)&vw%0l|li&Ү $V 6kqAINx;]9K@bZE^dMdo|Ź dkHDєFWv)grƙi rCq4HWm"jTͩ}RḨXfӃ0տ~8qcbq (WW6P& e]O$1c!Y ]Jٺs7^ ;Ytxʧ:O'uN\GsRN#=ˎd'vʒE-Nde9bZEvXԠVN1ΠNL Cd]|agitA5`.mgyI@p_PK ^B/dr[+2com/vldocking/swing/docking/class-use/DockKey.htmlZs83zgd&؄w6p@zm7Mݛ#m}$P6v^lY=Y:{wo.Ż(q'4Gǩ, 4 GDki8q;t / (2 n8lM8;8o5ՂOBjo6f{ൗ'Q]yk쥐?LC4p ( )(T'lY le^ zpyu4 1Ck'L.7A>b{> %eI90#9;!=qYSڠqU{3Ei˹EҭgE]ϦSA*mvEHKB%žoBWHH\$E]IofAۅ :#C9?Zgq}Ѳ&-9z&e[wdfop2xgwPqLRҷx[fsz6pa_bО-%I׶pL3MBԘ"L@Gomo X ?%b.JLuʹJRwPFfsj/ϖLQ =EyXg"8',QT0Dt7E )h"Gdqfr9YO PlbW9Moz c@wEBsv?ȳ a"w3)YnlThp+hΈ cfKc&=>O3pԇ`)C "b$(4L(_8lƩF @'Qf='O$c9PI ti&w_r."2(Fe7ɥQ(WĖ~tL|GS p$K+!$BV*;/,:͎\r_?4 rp:@8_ھ^]}6}&25>_lPԇRdF*>V;•w3r eLbmov q#0gۦ[kXݥ./vڑ܁ o}P,=*L_gnX"}d lWoHi"g"޿cpޗ J7#!vx9|8oR:UOgFŨ?#Zyu?M,}UU[`XK$Į Ul6 /YP1;Jd0-BP |kCܽ d9ȂQ]i_PRT'RĮ2ͩpt3.Q ^Q-P.3J;(i眹d񃯛*UzC@TY9g(lh5t $gOJR}&tEvuY&{ssOi %+X/UZSnSdaBg.;&41'DDhUitVKjZ!q`DՈ uxfLj­3ݗpu}PJƕ[ȅm9~mشy=\xS.O]|. PHJ^l鋪4$s?c;2YڅhX._mVl<1l4ݙ ϝ b.f"kK5Ո4 J+JyQPK ^B:?]o|9com/vldocking/swing/docking/class-use/DockTabbedPane.htmlX]oF}pו VbYw>Ec:|yhev\yƊkTruh\.套1 dg⊈$Q̋t4\l٧ckf*4 Q=EwQ2ʂIU7Ty kn޼ס^]4ׂ5?+ AKP`̼@)ǞZsqk@ÐE}3|鴳'N[&r ^իmA2|T4cBK|'Bkk1ָ՟Ux Qz%0Ы%5P)&|H"wʹ&E $ZJ2h64M>HԤ3=GkoTy͕rLb}-> #5GJ%j8Anwm!YIfE#+Z%s LIAbU0%<z {vP< 1`hx'i.0EatRfYԔni:8P >SJ 3]O#.F)\L+]+vcNE&/-]5ͨ\yfo;^>m-#(%)~6{DÂ""Hq]P|ux|"-mKJń f/ԒF4`RɆ׳'ؽR!rs섉Ř,I^S~5mﭴ\i_EɆ.6G}r<,;W@P9fػj[: <8!w0[vq'#1OۭYkBuHd>>:|/ޭ.l #Jk.,yرSAW YfNL(vlĬ$8*.zn״ m>0d"TIΚ} et(|-|ɡ<6cϕyCeGmXO!|0:lIp psK;܋y}[p>(#-/ؘV0j~4'ނ|)hdl=ǽnп? c8شq.` "Ȁ#4s10b٨*+00l^Wpq: u@h EOL9$2ۋX@L7-KEUMȆ w«c|24W5~Ox>Q9cJ\CdX]mPȹoֳ׹̚_גk WC( ?ˡY%Pu,PPr]5"?cfpK"JLAhR] yԜo)S6'oxZ &d{5XWb,Jii\V)V;_6*mL]#ڭOv](z!`]NEm#d$6j$bhFBuȹKS]Q12MgbHh1h~0n350XԌe-l>甓9 ݺ\\meВhEȑgլ[sp|ѫ UUg*i%+-ӚlBElPi aI6|mlJ˲]R !IcLI1ݹTizVGJ 2z $'v(T!Iq5&y-Qc䆸# 7I٩#O@oAnqOLUGG,\l(UMu?#{ԭ"qr¨ep\hm%ֲ.:hm;X(PHxw.7fHr*<7Xnua,r0֟]L~ Y2L s0(%eV^Ѝ$~4w~hC'G$]Y2=gzy\DlȨ#2#o87"ۜf[6'r`n7^T0ѽб# \6)gDe<0LM26gV5fQ&Ap58=P>*Y"NYh9WӒ9A~3*1lc sٿ5%_\"k՚ \b0fNHG ]A]2o L($T,AWX6x.nQnCg-v¾Ww4_׎E-=wn܋i*mͳ'aWBn*S-Re7.?-|t*5%JΗA]:mսf-K-7objyz,؇l& 5/nH6&c牗p$<^7 [U*2,[\0 xDYܺEσefتTmu:ۇ#8wt?wZa݃WAu:$i&p/:}$By!r! "yͧO|N (1dhbĔD?hB%4&cTT*oAf h0J߾~VvjLfGE>8Q zb9b Pߵ]!Ҩʧ D+ A vTHpJËP %&e_4gHSNUL@OSZ=<%7 ˿3Nޅܢ]MͷI2wcZ75>a}p#ׁ$ק |c刾؂F-њH՘s44ʾwn > Cig.1ظupa "HcaHMHBW2faUf`Eg9=O{,hx1;D^x+LsX&qd5f101#^qgRiTn0|HsĔ."Нm!4fpH405OaorII Ab̍+bdEd6nEd99V`ɺ6T-9EWcߢfvrCM#J38sTƠ]nfO8 icSm2e8+ˡRQצҐ˄I:.gJҵ.N,SmC"쵠VYK8lT]. s̈D̑;^̝q:2ծEa@95{èB- _AEbh`Qo()'Su]|P覴HhtIM:E^9| ?i// JHluM50zW6 _(aI,J)|\ ]!QXë)"fZwf=>*X`4@^c,$#n֑c%:&璴 & ?~ /IWaq3Lf 8P*:1,nS?("39ye΁p\эuڣYYGG7$إ/f' p ua$x@Ҕ3HR'eZڡ G{Q%INk w xmhﲺ歁6oV(+{EA蚒k@{:lu{Fh3BӞyKb'Jgk&0iuLِCy_O3Ϝmp+kchh=kj@D 1C?d (e|\;g.60MVvrHe_]1$fzj.0шyqw(3:̱}qn$#y7?/8w=͗͊~g ==I-L9 lkSfNb;U{uᚽ|&|{һaisz<:Z (G*ep(~K?x_vƔ1-++y]Iss: %ҩCԣYg__3, PV_mgX[1F%Y ΩBtWڕD^PK ^BCǤ8com/vldocking/swing/docking/class-use/DockViewAsTab.htmlYmo6^mTZ;iS$)-BI(oغpdCڏzg!NO` Oo{]BzQ/{,h4!R4pPAaojLr,&$:'S3ψR 6yϖ:avAI2{_)jX A4#Y0Q<4_e.5v@4/?jAenLCWPa$gB +L⩇9[aI/{GR+ A ǻmG93f($%bTC!a =op \b"Y *EJî iTq~o  xC)*wlXw?|crDm+;I̮;O)|hԜ=م0 eRZ'g&{I!YIfM}hE!&J \j6-*ah<#^ yZi.E^$t1s9v[O2θ|64ψe\׹(EM)_Fx*5_g3V=^,_v%+5A|"e>OxOz뀪.y0(r#Ҿ,3蕫[q'٧B S&R}*% J%mB-*:fKV쯛1 UT@>}/.{-3}L!9 p y+(#tbX%ۃqs xebYGn3\ SAW(bʠ0ٶLXj9\:!vAsH{%H؂TʦWVƻ5'l$ZlP$R֯(z 4qmS=kO:|)XP-B)$?`䦂hj;mEFb HYsM'S$&F?N:}U A֓]e|8]60B't}weE$S4F0])d&G /3Zf0щ ȱT +g􀙰jRM\깻vҁ(Agj^yYl)>GIm8%/][EI ÷CS1gʅ"dK j%h6142ƒgM3,D1W03UaV0;ၑ.9 "#:2S'jJu3E>n5Y0~HQL?T^x0ϭNg ^7y](*GZ_ ]zvtڼ+ˊOZ3 PwJg8$sK9ӈ,ƺ"Ӵ,6+oPK ^Ba(5;com/vldocking/swing/docking/class-use/DockViewTitleBar.html[sڸ{;2SlBzmM54a7SGt1G!7J@JzI [j]OVct룳8U~ݶ}ƭAWH2xDB;>w*dN].^Q 9 T4_T9tȀB[t/I4h842}Y?hDQ4$cp*c*$=_nK.Q1ۻz:.k{,THגJ}hDJEWNwvόN|>kgp"ȈN}s{Y (jD4HH5=jj6d 6!CJj#t`(hḮW\o8W`/XVgC%>FvlEW~etTJ$]h4 /&uE:Ǜy׫ϳZ2뀍Q+;LB$bDS >TYhldp= t/:p~2{:_+3s2Ɖ\#"_=H;ۂOr1*шi^fd/s@ر+t)/w)ϸ-ihJiw~,)C-{m~JPj5U h,!RuM6&$ S~M! *IJo^4x /R_Kvp`Nҕ{D;]Ej`H5ek8N- -f+&`FTx_KLMwKp2RNg:5 T8hzTPa 8W&4ؘyI|.v)rznlKPui#iI<9CE4.f>[sEYɛ [Sg!̗A=܄; @WZ$Cf bY( L\Y|} u+3 3W| o9Įtu#SVMW:?¶h '7U~#I1Ft2[} іmƂ+ݚe309g"B.r3+Y.W@b?eI%emǛȽhQ5k'ƻUx)ޭ-I}c!_br_*/(Q4S02T;Z&H,ɐF@Lg ŊcWpۨv}>B$ 7p{=ǰQlifr8[?ndK[;'{ΏXW&`=ŇAD4ܞߔ1߶XBiCM坃Y7kf(c/UE3n7r 4gj]c BQa~#aYQ Ax$+)9u>[Y_\{V!wn@*H5%zw![6b(G#(#T\Pgn7zu2`׋[?!,`@򂄏dzoRtzLYnp9<tm,=AX8C5;o{t^|?F|FnݦpR}9}}^N~/o (Z<3+nv ,d)$ [<h/XL߃nl0TPT4:c!"5$#a6%JbS،4ϋ+oPK ^Bj@ 3com/vldocking/swing/docking/class-use/Dockable.html=io8xh}쾇!WoL.$}K[۲$b˒"ٲ-9["G,ܿ&_ϯ\VLJ^)_{o:6zi}[7ϻ]?ܳ>[6#F:|EI٢̘QC;G}fΨ I{<͓w{z|虮)Nq8"c> )"mwM`wOMށzğޔ|LNNH1?.`8 ~P=̬~ 燣^O"'m'l_arLN c™zd9sμFPQH'<ݓ۳[El -9̶L&  Zb1wD hjfroO}\Zc{jBkA;A^þ%lɄz.uN==Ae(.TX|S/HROROӤ$둙v%N/pjL9.e{`_{Lu `dž(;G #C-K 3kfoj?q"ϧAt,҇[2 Us*:?y!v- F $Q!zxTVurQ8icƿ%E΀Jy,\7)]P+ 5 < b|hg XHk 80 < tGxW(.hע h5]/fqV,R5EUh3)yĴ Wz!M3f4{ޓTe+6l|xE>| 5m"}x0[8HPVR bf D@IVPۀ=Pi O?D[N1؋d:%j$#1ѽtpe'{_t Ρ'~8'0YCD?^*~M/hBv{ r$R?"VLT伔K-'HS4ȯ`M-u]˔F.|1=``;U0.,"' ~Td 'XL|JZcgn 2Ιq$ eF:PѥԾXHY@wiR45A}LfT!BHu QOr03u 3HpҞ"z4 }-kyoěJM?v ndl)K{t\G7DPD#DU';Bd|} !"<1 h\-ҏ=ԭc4Tc|7-ϱDtJբa=hqN>Ub& y3';_q\@ܙz8@^xGYʙQ>#d#rPKrwZ'W8_ciO]Բ^r?g[~IGn7W"BUH䳩|6 v / \[ӀUQTNM݆ mw@g~7<(&>wQwv+Zbz^Oآ-vk1?MtLm,c =u*\A8\ea2lAIǑk9& ^)-i9NN1=yچ8 }6'Ru+i P4kbڗ;7[d($ > i? ?'Mۥo~߲:5-[H~]CqǚU"ŷR D۱`f +C꧖P"cH/ f,Qhz0*GU7YTw9 sHl`*-Di=](GflqV y +^߬K«0*$}tt8r]Ek͐A#k-YW,)tp Wb 2^SSt!`4L_h` &^bba1n#4yqQmvnZvVSG5˲Am:o[i ,&LjcUdh[{՟]j!Ke rq,F퀕3f^җaG1s\ <өp|3#RmI QY-!8vblY)e0 7TӴɢЪ!4ԌtчCy=w6[E8w?97Uq#[lLrO-K_s\̨t23X%y>^0 S>T c;ͮR3\x82#~P)JHM\MD=O31ED~k ,$t^[ndlH.ɗ(l^0G+X]|,BL\KYPb/ԙ_nPma a+ lc4}{Ǧ]e:w,omj%T[4FF`בqHUgĉ"g&-RJTǼp {\Ȧh~9@M,8A[76[X+e>0OU= U- RG&K՜Qo8fLݬcb -2v>!S9G*e*"L/qˍJ _$. "K/o K,SBJ;RKGmM)X{(ʐ|D=/ Ӛa12; $%:^qmp,ð$\P@cx UZ\նdkjQ]`D^kS1W4vU]_K&o!XOhHKݚL^|crǢĵ2H wWo/Woo_n~t}wrZ\Z2/2qc3әU9^FHKaL![q ~vDlȒ%9S\XSe&|Bx!.ޗJsXg"O4DL0p.ԋ.cƊec"@wisso0Hqo/UpCp ShÇ?G&0mF jkDE [F\rDiTmT8AV߶n9D%4`A WPUDa APgP``tdR brd`L^H bM35H20) ˔,u{ql/jWmu0yic 6/*0%gنZPYrd8Jh~mqgV}OK¹ "7Q{)zQGj֣C C kI@*y >y5&eb2 m)/ TPަ;e('ϡK! mՑ[Q~ ΍בr Mmx l[KZX6O ĩkOk{Bb0oKrITn,|ʅ`UspS59SaүY A_h)*P}Rӕ1A8z׿{{ y6##9s"U['0*EӔRPgBໆGO{]A0f)bb70@Iz+Q2)1Jeʀ1|#::mR Hn>*4 ˬ6xj+uv$@}sZe HTw1%N8?2ƂD>!x_d $}j#poqWE(# S92`g#ZUIJȣ6U9-QQh-Ͻ[,MbkNÙ.V%nSGD> [px2K̶Ai5j5a+|@^kv>둔GISZ ߨ&f?L!LEpTα%(tA-ӷWuCY1*KX<ܱ#$5魈2 =zE'n7/@o;/TFPVV$j֙rij)غE/v,6cV_V\xp_%ܻ Gqi+$jcHu"w ].*j p:p ɞ-0spnDGl6&{͎-bgLD\;N|S^yu+0hx`ԽgTۨ{g/t4FBpmӦExAZU+D:~oHݫHHQ,/3DB r$Bix~ijnuԾbуQ(}802ހ,%m!ydʙq=Q#qȆ`8UD (^1%Ԅb}O!Uڂ27{ [YaWx4uo=-|%X+jaVX@[!g1bw3ygJ8&;jF.0SjgJِنNSҙPϞřHEsdȁ*|97@:h Y0 tǶujr4w,XOq. yNZo[d,˅OZw`t2 O<*h>6e}olXfQXpYrE bbCテIQ]x>)bM HAg|Ო?Q|e`TSGߝ ȇVtr`a3LW&>QA }RH %`!^ dOG/N~\ vZvz纘M,Ws( Hz_}ӖuԼ*ɯziN wtnr+E^ 1iʚ2 2acw6gE&esM]cx!mأYߓVcxʖӲ5/3Q<]64LfԊnt\z\KΝsҬEZ/bn|V Z4s2eƄ)Pe41+|;^:ӯ iU^yﶜI)0 U;FQ,)I1,޼sB̵/7Ac@ Az i~ozrK/v׉["OBʪnXK 1b9 JA}kwk6xB ݑgٴ͓C B|2='sqܞE$O\ ;eewQulOV TGB%hS FCYJ+]K;%nf8nDfB}Hsk _i} ?; E{Ym+o\FHm<)TfdY8䒃m`N=㿵do7ޣq]gD4j,6{KN 9^㩛`^Ҥy,gJe-sRkDm,IH:Gi`yCdٜh4w7Û IqKē?&eQDMXV1W`H-WjeQZ+p_9qըe,ɕ^",)҇t1Dy y[(*ʝbA=ƒ)fʶRl]*͔ͩ-]Ի`aAS9ǂ31 ftp<-ƴ ܡ|뎙v`NT5Z37>Ӂ`T:S{l-̪cK<@;SX%Ʉz#柴:xTVurQ@,1r6ufYBI™<$N?09Xʧ ]@l(6k;O'hØ,_v(A@S0a8co(_KFO8+Z׆hjc~MiR;E],mՅo.w('0ӏ韆=s4oyrmZ&ŘN7.A?`)N <[)a\@"UPK ^BGL]Ccom/vldocking/swing/docking/class-use/DockableActionCustomizer.htmlYo8}L@Z۝N-ZZTbWGql'h`ݺ[ 'f랝BI hdlnRxo? CЙgncشt.a "$\L$)*L6 Lֳ\v.p~ >\do$D7E&Stx"1j,$fSu?7yrGVS6!T ;uW&F㊄u3E)^HswZn \SFgD޽y:l5 &`tF忘Z"BZa)R`,6Wuʹ&zA1֘_0XKJSkxM$9*eZƮop281;Ҏ(O|IJ۟tց:(̹ThGiN6㍤[m-Q,SS!Edw’[j mT],X 4;.T! nEeNMūâ8GIT`B";0F89[9zX̮]ml.++m,b#-(+YfgHEѬVvUSܩtS ZUpVۦl܅)" `PH$Ԣezu6R'$UDބD3{Vߧz , 0j: q@?a6'o#8M {Q uisLYPQٌ03Wh5M q WS>EBEV-3en뒶fKݐ`U_K[)BQK:^H$ gV Kf6!z_Z& –pۆ._L׆7D+$y7;0܏0u\,WF7mSq3DlP3y1qolah{纮(N3-Sk k…]@,/O0p3{1'HvMPc˙xyGCåSp52"/D ˕ V]v6V>;n6|#MfbjF(a^wg{Шdɫ{k:篎G9͡w| ZnA(d%H榓}xM-aɆ# Jo+}8~9"cc 񅙥*h ^PK ^BB3"/<com/vldocking/swing/docking/class-use/DockableContainer.htmlZmo8aV &ZKwmc/;Tmq#I )ɲ-;vn֖( 9Z.}.?4Aj܃K0B&,sȘmF#KWAd Rs?4xC|tj5j^_xbDy+fx1nY(y˕Fo~xs |&vv]law{g/eydNUu9tQHg~o։yS&  l~:mp؀=߅˓A{n$إ8  =Tm;X$7x\\G8EILڃH^o"Nxݻf;ّᘾuWԔc] =،eQ}$w͟WQCPق9YK¹#Fs#Fnntu(npBC(4 Nc9TQrL Wm8%|:<ʟfCЍv[vv:L,`G}#ZsolGUo(=UaeN6Df)q >`ا5.f;絤 c3u\b*(0XL|Hak4G*퐩&+F3[8ϦT.1d-8e ZEjʮ8$}e`ۯlv"\fRΑvf/]:W;?* 5_ܭZKFzVq.a^y6syC`"TKd,f;ch'CBZASnu(N(ty8> 7LambTB9ױ/}}4fc4u0qݸT}XUehEɱ,)W1x.34[)*iP"H4+2拣j  ~i`ۨpu!sБ QqȲ) CAE䞻Hgy /@dI%Dƾ`I!I범1ɓa4U8fj\Du,J::}ɑWXt_WBdžR6\S6ۻݚADɋQr ,6MK ΍T-ɒ;&`>VG!vġIqtM<`i W,ReijrZ b??DCFU]H S :V|Q^; ]RdXجpKOw]F|u 9}%폮#O겐ftӪdX mn"Hn{isr* ?ŢK=iڬEm6Y]Af߀Dé <`0Sd0.Ei Z#>)g=v|Ut~ayn#86=f8^ҺhM 5kpxbב!:q:T8A>ewaq'|=c G"[qmUL!KP&/Q-NY@|˧4)6r &3{#?9"c.[dž9s*ȥ* fr΁Fh=ƻV.nGXPOxof벬pH,n8PAÈD3DKi)Pp;acP>d Z +y|kᅂ|7F{5\=q*xz[6*;f]#~`li )Gk:ӁQ d{:P=?oCvtŽR[N*hD,􋆋ؓ6Si?p17U~wS<64B f>@!^F>!7NWڑPPK ^B>j-Ncom/vldocking/swing/docking/class-use/DockableContainerFactory.ParentType.htmlZ{o8?@ìuZrmc;m&Fp(hEol-Qē׭:k%t~;|݂ECtS L/xw><Yq_+Z-9R^JL`љQ6V(|HL 1~q F;4ɇqv_@Njws!g{]ή뷋"WCjvË|^<Ηǝ/;_wRm)vU^oaoͫWoUh7;P4Ӝ?(@R`‘5쮉iCĚ03(}$9@Sj^vx(/45W~񫯭՜ )yJ8UCJz uSʃaoNIVxͻ2Öw+U=]n|FGև=b#_zΔtTbԴe+ߎ|"V\}xo_? CЙg.c1ؤr.a "$L%t**L6 Lֲ\u/;pq6?^fO$D3E"tx"1tj,$fSu099# ؐI*O}&FV 1E3t.HswRn \FFD޽E:l5 &`tF70$%}EpO @v̹Th[IA㵤m)Q,S)C"kaIsWj mT}Z i(9w`R4r:3yq@95GӨƄEv/a"1p09[X̮]mb(Wt[XĴ@d!2JfkȪ*b;uX/R6te}؊T׀A!9qmBWHtIͫ "f:}wj=>OˋX`t)"@ _$~6)CE0࿮K`R*mUCM1vJf3L_iy?1]:'ǁB&ukEda*'kX8 :GK wttCU})m;C ZҾߥHpjUh(07; iŴeFl 96Ļ跺5U+w =oK r"b}F P۞-dCt4;Ɂy F>s}ɳeTegJLN%t/Ÿ<4Zנ<|!ozkB?݌O=؏n{t\ Vp]*<\]a{t;B5)w#"p2OMv]*/{[a0YY lr}w HU*oªKdX] f=XlNy޶t₻IBD]jwVBXPk`>KFj IХfXZ$;l*d+ íN|qodWh-F+Oܣ;s9ʇ娫.?iWjzWyeG^*KVZ,odfQ?`goނl0PT^1ΰR:dq&ėfKidZ+Ly4YPK ^B<# E=com/vldocking/swing/docking/class-use/DockableDragSource.html\oR=.n6@rMoJhNʰ|Y+@{wY`C % QRXgkܽ/C.>vAh6܍640B, 31ɻ Fhח4/GHJЄ^勽*8 PP ݪcۧY\1Ch_lBن!Wö/M/WA ;oa{ݛ7vvфݔ&Ok8 WЖ}!kw}=[?Y+ źWr瓆 GHkؿ8 dA]^Rx ƦѬ*[UvZ#_Q&ǹ$8&hkAON7NyջfK;ڒ })R'ͺVFz%:6#Sqȿw6~B5nB MK)49E:ֿM/>pe,ס>WN!BC(41 ɡni:"rjeΏy~g/" hGLkԻL՝9H̆-`{) usY_RۑPt\J#}7xǗPڠpe}e1'BY"ܦ8]i\t6.UؘIM>"xd0y]l7HE2慡%$ [q ij1yQ5%s\+J^7["Tm9XvYԱb"N[! T" &, ՒFh~L~TG_C+zBj8x$hօ1ˤ΅ l|@:Wd>@ L*n6ȍذWdp/9u2c:F0 ϼ;j`Ms*pO\5~H~*C\Y 5[ӭ{[f3lrCh=wiAxecGт+I͗N͉R 8l[JMQlRgrHA7Hu$@Ud2TZ<`10(h"}?⻫s r]qH4MOEAkԅ>}PB|OQI&)}2K8̫l 2`T04h^ .cRמ _سd}nz2\&;uoMfA4aX94=g ghV ܢF;2qVF&~m.YPcQ7{xc'wc=yY8B |egD_%TE"EC @r%j'F"2VRO RK dT6،Fu]LOtBmMHyR;R2؞{^%sS?,NNtAd--C4T+ĵ9߇3/n譿o.o2IDegov~]+ 1Zxd;? n atu\[=Rn=q|fWʜ \׫Jh~1K}Na7u k ]n _'& ;Q$s>WQ_Yn/KND$pqWﱾ} _R/ \#$F:ZAbggH PK ^B:^/lq8com/vldocking/swing/docking/class-use/DockablePanel.htmlX_oF0J=`/\br8@wUb[ wvm pU,dwoV޻6>]ovdgAF t<&d-`qj̢>q:&P ~7a@j7o.u"Wk.#'4%4K q^Z=v+"UpT:\nO.Y.LpHhIdGJ =k_ɯ;WH@ =mx`qbPk& GlENyY8xizDf֥ۀTa}|tTd:6Á$/Q>̇F !3Wj8AavmcyY&8. mĶ|L@ *dv.dX^p]#较ۃ~(7C-;:|NQ."WD_ (D-^$j..O`+Iy[H(mȹ]>ڬtV*}m Sڕs _ϦS^[eJ8{[oGV\=rQO=5d_=z W뚫&JY#%^X@bm'%ZQveƭ;A=M9LGs֊_wZpfC̖gYe_u8L:jԸ~.^TijCrȨz$YEҮNԶ(ª7zyWq5n1P6tD\Ȧ]@:|ICJ&ik;PᲑn7]Nk7D ب3Plz+bC@5D3=Hr7\$v𙶧;7T< #^wq3~O7HI;A6u8/h/h?A۵nw{.-Qwpȑ8沙fK KqH`J'Ih )x $]8ǘ> Y,sOPK ^Bjl;com/vldocking/swing/docking/class-use/DockableResolver.htmlYmo6^ TF;YS$)-BI1IIQlunm,Q;sGfYw'xprwaw܋WAc$i&7:}"XBy8S*B(:ZO=}E)1dy4s&hB%4$s!T*;/ApA4|%|;;o_~lBӇfcg7QQbljrDb9b8P s͟:KS%8 ڧ{GLB+ A{IAqS $8%bC9(2ёg7~oƜ%W )< LRk`"( ,o; 3ly9"^_5,eƮnk?}a#q1$с$g | rF_!ߩ_|R"QWcd+gs I:N5s[P g fʈM0-L@2 dêgࢿއ#`<!'JE%s4v "K # |\]/M.܍j]`J!G*rĤҨ\0xP9aJr,noֶ5gttJ20yβa׹]>+=7Ő mHjH9KlL6&lSw)c jIiioT3C>G7e :ll^yޒvByM2X gd T5LhOyi ]wn.MAb3E "嬅"uɶbN-őT]9{Śq:1-‡ۃq\CEq6Ob",jm-bwEy,ZW|6ݖ6 -V+o6` $""lJ☙q=+Tb-%4C%$?Mqܷcz}&|ڳnzfvvk0dw0WTG;@ Ir(U_=Y~BVgwS 2@n .\DxmgI6tPuO(T#!.HrdUjLP;AhV{ۡ~(h*[n[<bx%6o"mWvh&ɇIQTlp?i\nfKhsNT_"t?Sw̦2g>>OSKHfZgмX5?U"yIss:&-ҥidGk~k̰d㉆fʷD>aaQlO$K0.>7`8";WڕD PK ^B[N Acom/vldocking/swing/docking/class-use/DockableState.Location.html]{o8~uZʣ{>vzM7MĻPs+KI5oHdˊH"6ؒ!ሶN^wz9Gz../:j:οN:u71p*h`qί,d ~utjOO;[g(FCNlOxVW7Lo=Aͦ<#[!-͐`ϴ' Âx?C B5&q?r q_ѯ?1I<'9(9Gn8'>B{O_sԅwɝ)ؗ%רeW@iȾ>Fg7QMZ$,-$-KΪy/g_#~b>$DXH")WḜ[hȠeٶ7`Fju'O+ڎh?f򝻌F"M]JVR߽Bcm9M|4~ h 6&?V 5t_0^4#!czwG+ɏA8I#~B9(zҠfᘡ> 0ԑ%4i-Bw~z7wgjl@m{] H'}>SP Ɖ<{-%iR΋c|P07frs [|n N(6x4lfK_i53/S0(,tg a9a9ʰsoXz' #D"ʆJfG fڃ%HĈ+1郞blI2ʵcd!&$=bJ9\< #wZȫ?Dm9y^0'u"U[UiQei?/I0杚A8#j<}ѹSY.1KZ( Ow txՂIU<#`(1 ?l HkN<1Vm vɆn~ 2cj%Iҳi' Wo0Dr"Li+9c~@-XčQRczSID5 ̣#} 8CH>(гUf e7ʩcf;RPŲ Zl !$|R q$;\[}2Q簫'ߖW1_[2<NXԊo_Gu(AϼdKW `=Oj{`y]X4Ԛ yK3w=bG1T@ܓ40M^qXC+ϋ:^.XZiY@ђ7%=0< 9\vp#%H]'טR5|I.*s'63iYf~su!#7V3JjhT4#A5*]w1GCnTxqx{ @#)ʳ*e(~e߰)"dWe )Y>^!prgIg"° ĶV]˜Pe6[[5!^JrD2@vYi0YNcYf#~e [0p]ak B!y2}.#>#>ҽH^g-u槛;Z'H6_F֕M^ \f+h[k%jvãmW i"mT>ȚW*^/r=iT`jr7,f"TZWmYYvP47jR]ȶ)za( ?uw) C!Q#lOo [s,۝MGh,l+,q15}m=<6/0_Sхo9Eբު Ԓ+Ea#@A_cFp ًZQ__wB0qP}Kdt{˦B ^% N$$F1q,:4$Rz5a뀣hgwwYvwR]jFQHtQaPG\Cb/)jd>Yq ]@N:D{vΎ7#'\* (p] Lg)~2/$(=fD ZjCGԗ[ 06m%\b+;|J7JWh`)ɏf2#<_r@nJw6][` A\g4'WQ9!_ 7T*'6Dm)Fp?2ȊCjV 5~|ppcIa=.8yf6՜_K3'~r5='d@k<{J0`mrwqUcĉ1x@b 3 Bj`M"* 35^5$u\{3rlUP=O'WY(L)yF69ë/S[ SYc&79|g,ϖM<ݧ7}zi? jMSIGsmcXRQvBc.yxvy}UJ@D $h}뚜BCd?d򽾦Ur,z~Uٯ1 `I" >Š蒋D1igR*@mize%7]7]]ֆL]ݐI׼{< W=cQ'Յe'*@!;]`=Oj5Og|m}q#x}k~ăW3oXAb% !Ԋ{D^#gYM$c(;LFX'QX@q%8,Bd\|nj)tN/͊ɊI84PK ^B➷{q>com/vldocking/swing/docking/class-use/DockableStoreButton.htmlXoF~aΕz^ Var8@wUb[ &UU|cijZkx}@Uo-Q;pTk)haDpuojLvr A&,3&Tck5^>tq߷; $O&3Es7pT4ZsPr ϡVx^~;zvZ2Hl~Ҩ!CKra΂${LMW>xkRWscLs?wp{8 A.7' !k34z1`bB.ɯϝR$P6+zh<04 ~1lS {P$g0vȸ"_m(3;(V{z|Xr{fI0Ţͣ!4B[k-U:W0TR NP8rAD>t/?_]ʧE4ź/\ݑ|GPcNS1ymBL\֓&\yX(mȹ]t[`gF kR~Vun5&H<ߵv(J7@ "=ʛ"{'Z,x)eޘw.HaB6 eD@_KëM\yƅŸBep/G5LD\9|'M7TwHYekn˻zx6ݤ6,ߐoЩf$ =~1j Uĕwo+}{ YfCOW(}|ѧ4Iù8|aF~a-#o /S^wQs̻䒬L 4[Qh6D ނ+1Wg/# |Fl(lv7c,XVZ~UhPK ^BrªNq>com/vldocking/swing/docking/class-use/DockingBorderLayout.htmlXoF~aΕz^ Va^N ⻪OтزxUwvmUU|cix}S{'6!=5M47\&Tr^^y ՔDC23 qAICtAi͙1se S԰Fh,PY1<Ԃ} L~ ՛7W: :ԫܖF'4 ry2 ڞNvmI3ե4PN[K5zp{ `BSB/F<4гK?KF0=cx`6)jŐ^A!pлbMhdW=V<5etL5mOO>cjXOb?G=0QK # }\. _|mf !YI&aU}Ek#\k-TgXp]#迃?xbAi0Eu$t5=vZ~i6(Gl' Wڠsy)Nkۚam;e)q8[zXP .\VFP)JJsl;Lz@ê"۪"Hq2wɡ|/Um&Dm0XQF8<˘mof)lG¸]S!r[{ǘI]Sz9r[`oFJka~Vn/5;T-TMl׺fڱ(= Oxz7'f~Ãȉ'Z1]BmH]n!l[۸ gI3up/G6T FH\ ȄTHQEkmzx6nz6,3!ߠSoH{b7F .W VR@͆[(|ѧIcb/g|?L_\j'1)^||悙QI%i~Te@lc+V|:3PV/|_D Nhِ', Cߜ+ggERPK ^B>DA@com/vldocking/swing/docking/class-use/DockingConstants.Hide.html[s8Z.nnH6饁Iܧ1Of{OtK[tSYouJ۟/IE8%yv>xH[PqEH;r3:yĝB7kߩ;T"WlҢ}FJ%,Z$a0'uc!T3tO:˜IݓnHji{rpݻ i5ڤR>8\E1ED銡;@grװu*MCs3R2~@$w-rܺ(yo4%!T:>@gf:TR19,:JOii-5^W) $Uf \St^unߪ+yq`mSaGH!]vo>o rUvLZدERA϶ſJs4ċX~7{gY2kk;\+ lIґbt<ܴۤyF::yd.Z .+:Nq[(O yYxTTN j_@mmKs$BKtUE ܙn 0KǜMJj4R9uq;f\l4v lv+/ŕgp%w$f Wө+*,8Pkd6\i"ɺȐ hk13D pk *M6+AIF3 rwڒl hgAMWj*bBeۙkI=4n˹dYԃW)fvKV ŬQ)=1vqXU!vz%]b4 ˓_x!t+w|1V03] ](S@!/`b E2MsI`9ɓ6:t&mT! NP3$ud!<0 4al k_1V0U F9&^{x3VĴ'HJ, }O= E.v$)vIopͨkN=L;!㿄}Ljx8|R ®K/bHZxq?Ibe".aq%=2 qYЎz0/H=`$/ I>{pYerGYbuj,a0֝󯘜aNM/gfZLvqʝ+Sɇ-Y~U,xl{xf*g# +6/E iؚ\l "b2;jG dPӏ%4oK%8$3i"L/3S+ˋiDTPK ^B@ps _pAcom/vldocking/swing/docking/class-use/DockingConstants.Split.html]s8wfKfn ܤ$٦&ݗhc,$dbi-y=e|rnxyBVq9[/[gLۓ|s^GWd|{DB>z N`/; ǒx#1F Epr%< {tpݻ洍$>i!@Z>l`|=[w|vjX $BJTz]AȘ{tdۇb1"1 J F $ dRTQ?|yip8>}BC-%.W 96,v& l]IްTۉaރ+\NC]I֔ZM%W;>j>sRƶi*Ўp0Cf5~gڪO99u͐1w s0`c;#*G`n`PlQ >vTeUe'mt}7Ǔjdr w^;6:SP/➆TDP]hO+ )пi<=Ʒ.BsyЏ 6Tddr'MY&?Q2`|j^GŚ2bBTS:] ˉ G4gVSq>b"pK@`O+9!m8,ȨGBN\$>(*4)-؍: u^mad5"JyvZ\4 ' Wx:~\^5g&P' n|W$芡پQat1ߦaLU#Fj<}sIY L`Kt 0|u«=®[xlh@a5m 6D07" E, 9[ucs^0d4=C:&a:D%AʦJ\KH?q~ fbZo)w/ QqG )̹z*ZZHC*p|"b|K&pP7 F$dOǢc*P& d'JƝ_k81J\1\ D).LK<]߁!N4NJ}b>3!:Ry\̹h#4S&kBI'(/ 2>N`!M-R),:a\Me?S 4BܖZ{,:O[L'EGG}4eBq+AV\`.C[~DƁ.%WugeyaEe`yĵڐ|D+ݨdrG I +DS9'ftr;fz3ʙ+vhxn_Ȫ 78uVt)J}=m_N.P2Ѯ͊ɸO8рq wPxK%KՔl5gfO׷jb4b& 4n2JlFTh4)@SQi_6&l4Xf4"p~ޤyL!;KPjݲQ(nmQo8TK~u =jZk5S[?EDvi..)dXe g׫Ay5ؐp ^nĜ!'GqƉxd*Hm %n[Vnj9Tq5-*݊t-"2(Vu(s`! I1w+]L(&1OV3gbgK'P%itf(\%AI:8aH:umAeMU?XpU" Q$㧺ט75졞_ v Y|iP.[G} Sk],d9x8QheiTXox 39rUXD:"xDe$y*IrOjvqGN6ʽ:pOED !_6s@ʤ= 5\`Uj wPD2R Qۇ Fa%!LdO`OMKpts4'jL8{sBf33N > jRbGeCi"ɌI*  랅E`GDr\ז"PYh^iJ ^injR1̮6-8|ҵl Ty7+0rooξ&|Zp,lh'&S5K2~k(ZA=6!`'Bx<ʨc"F= =. -r_vzD?"ٟ0) -1RDxWi}]L9Rپ.Iŕ ~cLņ4fNl{oLژT1DoyԧtxHVS 5 R*PK ^Bž?l;com/vldocking/swing/docking/class-use/DockingConstants.htmlXoFaΕz^ Var8@wU/eٵv8TYZX^{fgx>؁] <[v" TnTrZ\ZyD2sqARICtqrzLڀa&Pˣpyd1K4 ,Q&>"Wp2\=ޖ%B|,ih_eɇ.-{Eƚ:ˡI <ۯ2RvZF <=XJfakxH/YKw-D6w8@C6-owqeOg $V0DS*R pn'є7De՝0XY$+=wB)ZvۻbZ8f:{%ÿPoBN51oQ=4mVgqozQ4ϳ8T֪N9?L_o["1Q|(|`w!H!IQ~&TTD9l#$G|2PV/JhM\m"IikPK ^Bb:9com/vldocking/swing/docking/class-use/DockingContext.html[ms;L mgww$liG`jJ2661,$&&Cw/ȯSrMΡڭ⚋wtgu&;ux+oGk/B1׾z]Fհ{BgȨLR|ҝ?G*c&';nSm5C[͛wiT)#w\5E٭&Nr,M!nm˓gӔХ \DJSTk5G.vyۋ~Gj0Ip}S˘X%&Tv,EThxd_{W[gY0c[@kk^@SKҕbt<쌤0$_u1\\ҫI Cu":c0s!w 0b7 jΙH8`()oRiP|A*(9Jg|3IdHr٤шʩsi]$F2ߥ @Kۺd\e噀ҳb@Y~FmeL%6 +8Z2؁Y$YYd\ Hc,j`dpŁIN.U5_i K9Ss]Ŋ-* UAjV p.] 5$o:-ԧ9XlP-}䘸m?,8od<Jɚ$}P(`xx0=+ T f\R$bG+ IƢ?V冖$4S,2Nay(P<0u:YA:Nꤠh,HcODY(?kyDLBMF9ֆ\s$ cbFoFUۄ>v giG#Fm:X=P`帧\ڹ!/E"dE\|ŃA`? <0i1д lT.h7h({=c2!;}FI.JgC1o}Q@шXˬ`ao ͉ A٧=:4!de^eY)KU6!_:DEЃ#(6%YRIk1hE#~ײUlmUZKh^cװ:nZxVGqZ,/so!^~lͨ8< X- FZe[DlݬD_ dx}ʿ=1ք yS0>le!]VPQdG46149A6pC?Xk~']#7,Oy_6̶s z|fS^E!>F$5 `]g#St+cPH ( [9B}+)FdN]ɨiJANZp$ 395G$)o-`DuNMQiq/sC E.vRXHwI@"֛xY 41Xzʳc5 R"A,||>L"|~X)ֽzbo7se&k/sY{=0vڹVg6\t:gV> Ϩ{iWx|ya~^^tx*/:hL_wXeo!-A]ԱŲqc቞zr|^'wl@{xKfLQ;,e& 7Q됃''7|H oCLNN~_NOU|4m7ﻱh?+e~߮L|pI:}ۉWAԅ&V8u^tn@ڞ8QF=Ӊۤ+FTL2ƕWfbJZDhf8%sUс6ۂ&9..6vN@^vжZÀ;ֹtr>6nHH >_-;bv,1n|7nfLk2s$49WK@N ՆیۜpP!A&}UAMwG/B8ZŤk옉0xj 6| WQw2϶~f3S_]1K\*|jHAǁ6WXj^i֝pRߥmC*o["S-$;U•_u: GC7Œ+kwdmM89izQv{vqm;ό㼽Ӕahj>Uk1+2m( d"T4>?PO3Y˟Yu"-GgfDf-gdr/ۍ/n3Q+ŋ 4#Ksr모UӉ S|cԓfJ^xn{7Pzz#>j[ޖtv,Q% W fzR΅MET`of-(i[K9*acUY'߂m'lKg'Ǔw UMӛbf%BeqeՆ~KRs\,/!lK!1YCk2TISSEo}uܝqqhnQDT|ӷҎG|~=Y>#ӧ9}Њҷ.ߌNiNy Z!3ý7bbx渔{sYǚXsV.T'1]Pq䑁6 ^kNm ^:c\EWs^q /;g>s:T~kxN䰭 Lb}S5LάW="Ydh}ÛtCQ{暵o괿Q'{EGk>)htb.2;׽WNLJ9t&Dc6kA)Z< 1Гb Bٰ*20^vh;:̟fɆ s_M'"kq-[B%%1aǭn+a:t m:]1:k4d[6z zuDdr^_O%]Ѽ Ó1h-Wwdc'!/8ZJ푊<,~gBƄ3 s5]1$o Jcva&XuV34 xٖ45T{ʆ#*Kyү܇DtVmtQ@:mSLcD! ioʰ'sXz >6_Jc cˣn|kiOh-&gǗ/8t?1b̬A2wif~Y5tHxS 3LЎkeiZԫg32pi[ K0!ༀKc38^aj5]Bx/PK ^B.<$p=com/vldocking/swing/docking/class-use/DockingPreferences.htmlXoF~aΕz^ Var8@wUb[ &UU|cijZkx}@Uo-Q;pTk)haDpuojLvr A&,3&Tck5^>tq߷; $O&3Es7pT4ZsPr ϡVx^~;zvZ2Hl~Ҩ!CKra΂${L_ Ǩ0^s;gL=ՠm M b,O8$}b@nbPRQ!ҹJU`vFz {rP>- 0`d]Y/(eq$|1vZdb46BiC2F,J:NwmڇmUeJs!pl*{k [#(SkR=z?**.*把wO*7Q\Lj6vU L7X@'clc%%h¸=s) {eSL t]|vj+RkR~Vun+5)&H}<߳v H78z "=ʚj!{'Z,w)eޔw.HaA6 e$@_KëM\yƅŸByep-GuLDZ9|'M7TwHYe_ɻx3݌3,_/Pf#=~%j U5fwoj} V;OcW(}|ΧƤ?:s.~.rF/;e=|)GJ"KpJZȏfC4-Xzz? :B @kgĄ" x`gi }j.0enW/PK ^Bfr@com/vldocking/swing/docking/class-use/DockingSelectorDialog.htmlXoGarpVv8*/d-[/14jRvvgGU׊~_c:7-|~;m1֎ZH+T%c]c2XJOX4`S;gL*e0m5| ;['$[3Ek5p* ԆC-9UO&‡ys.޼סߎ^ PchIn ,XH{/I`^%m@sx4R{8 A.7' !}3Zz19ᑲbbCWR$Q+fh=8-~ldS {`EлuL6+9T=HnJwͩ^ӅcH5.Ӂ$/q0> Ck'g뮔ks>s²8܂Gigonq,ma %J5 ZANԦWaymt9^.ۢHvv]GC'P1܋X7IBL|(Csmwc%v)\OG]( TKf\ӽf g1*%{j[oGuuŲblg]ZJ73A$kf%ؠ]qB)kDSV#F4<S#!}Iy*d;Rn@)ԧi2{;hc0; P׸ذKmgK{}͌e_dB;7kH湸.੨g.#%{B'j4I2o;M(RyBRǡ\k@ %&$5%E!. UܸS!UOW(}|קA*kl'(b7@s/sth*1@^|wJ(i~.[*]Q͌h6Dނ#k1ZWg~EGHhMPQ$*!ZbifiMBPK ^BDn;com/vldocking/swing/docking/class-use/DockingUtilities.htmlXQoF~?)aΕz^ Var8@ĹOтزxU;CrpU,d;3;3gx7!ԁuOog-BQ;{pTk)hnL 75&$dZ@ dj)5 b{͓W׾] ߷; M&7gh\%LQbAeɔFP ~ՋS;j"jo^oGPr_ich 5Q֏{E7Ok>)(Qljg꽷ǏЙ;tra"n1ޣWNLApt2tIHPTlPnj\/pqt?^櫙!r\]2GM羑k/2mO K8llmƛw4GL*碊>g'D\sBqTBa 7j—O@ dkglX4p^’L[*l6B"cVMI3(wiԾzV3BMe[HOh䶚 IjƭĘG`KYYSq-ˢe('^?K*}s6}N  ~bTPƉRՓgd}wA9DɛM-s 7(5:[eiG,kNRF?PU'x2< iʙkU't2BкwNH@[TMpxx7M⽎:iOxUUl$30_;11<.k19Xن"R|ݩr.洸 @'0_.jHt()iVk[61=$&Be6Vqey~1)]KM~<[~|#lGBk1pK^dp aq?(%#;ؒī.3򻌪W47?c"]brX^˷`%O44_ LX1٥*46Ӣ$_PK ^BD ?com/vldocking/swing/docking/class-use/DragControlerFactory.htmlYo8>ióLQi)pjuj)jN2Ā&lCNҔN6Ay=/vuN?zr GmBB~iwWQ}&.*9LIX,N$՘L+",M>}e3Cbwɸ0{c S԰Ki,P3Q4;,Í`i#h 5 4 d{ɓq;(:n():C#j;9*:e .a'G m/Mf J KL3:g%(&6K1YHigCZ0Ql " ov&;2^_=T<5e֯~5hY?}# 96Б$fOG\HiԌ؂f-OJj}9ڋL;OA'4{ȫ[s!B 3%h͖Ug3y?AwY45..sx$t>׋,PiX\ב՜]J#O*bĕF.L"1צ-Ddmst"Գ锪edcgW5>^nhfRņ<Ô1qyR!2G~C i>Hm̄z6p9PLhOyI.Ʒ):8Lpj̰uH涍t%tfsL_5" 9 s Y 7k"(#tl;\ff/Gq\5&fsya5<t6K/&4۔6 +Vyu]Ue<9Q9l3gʏI ]r Gպ+C9$A$ .f4^7M@*tE3XiSN;^ciuN68(Gun(c2|pe9ocq}{CQLJVfWJ,8DJm#4La(F׊1<~dKzh}[F?D`zL;לҋizr]@#o8?+W8?W*#>̬xkzչe~lYMvlLE[K;nLю.oezU CI{BAD`C|fwi8c21-Z`/O \ bgu׹ _ ORu̗mn 6J-4 J A8fjSkѰ<6D{QOWiрF.̻Jt.D;w b:O u| \Kԟ o۸sm0.cx^QpcvkEՙ 钳7U3$t4%ϩ{6XdX$k,RnLg>pCf=H-&DmjV8ьpy`1K4! ,T&>Pp2BnJ.f1vΎ+5[nIѽfM2°o4 3=߻H2O%;u`}b!XPyb<t!,GĄaJ%ن@)y0/eu=vu:K*5*.h Q.]4 ^z{TEQ>PY;9t8:?й3F?c3F1zc0]D"پ Kޅ)%$ePR mGYBZ=?+:\p*5sB.p%8.Ki$} .PK ^B_ouAcom/vldocking/swing/docking/class-use/FloatingDialog.Resizer.htmlX_oH0IW`/NI16Dܞ)Z{,^kwr~]ۄX^ϦkE]x>!iGiPAh2ԘjN&$S",M5^4^>t٪O' |R,LB%gh\e S԰k.i,GPY2<Ԃ_]xH~:ԫܖFG41Fr,d=wBR6BN/8Z9[I5s 48gB,cZK KLY/~,x2DiLO3u}6dSơdw/8&gt/>]^ yٰ12%h.T!}S #ԲeIxo1o tTW0-Q&kn̕6\1tq(~RtoS/4JP5a8ӳF~*qߠ+ᱮ'#Vϑ'{q/'rl-e"ҥ.< LFc. (`W&<±|\rH`C'y*MyCY _ Md¶DKba^<ďn=Â:S S%h6dy_CvQb hK前{~![zʗ(}xyJcGsI>c3F?c y?(Re`]`ulBEKkLcou'!ͨ=8 M47\&Tr^X,i ՈD=26SqFQC-t-r(Xxƌ0E ?r9SC%x'7wYsT.޼VیZ 7տhA!0`.P'@/칸\49rDVK&̘F)[H5ӠT{{R#)9eB,c L KLY[zjXOb3,G9 Bf !+GJj:EP}#B,>L:'. sMj)g J.4SAXfj]m԰8.EйӅ׫^4oC9^m:nj=y{ bZ~k̫#U lWiԟ oڸr gpeZ\D޼m4:ltJ2;ޫwrS-)LpPlv3YqEY*BuSZSkXncYNK_`r@5nTieL>$d&%EkAn#lmhWm?w9۾NqJf?F {`һrt% WN#{ -~i7 AH3jf.r"E ܶ=ƤW,`qH5"QT\!fAlb~zR{f.1};cW(X֌X5,~sLiT]P~,_0rdHB_mgS;-T?=!$K4ɜD>c>B@p 1״/rB3Ԉ]llIu/D.\y! o\FB}q~3 #.˲_[J4#Ԝ\FLx[+mй]<(ڬW*}m"%9g _ϦS^O;?GI`-aK[aAUAWP, Ϲ <9T^%kf/4G:Tm0n/T);f"1&G]$3.Y~=YiҮb5hˡpL=BՈakAz_hKxCqa4ӏ[mOB~"Vck!&ӄi2%IJ7(| 1rjGdzmn&¹/¹]?0^{"߂{wqGAi~FT4d@)QxvZ@\ݟ -.8M1Sd>`Sܳ4~FY_9I׸PK ^BGu ADcom/vldocking/swing/docking/class-use/FloatingDockableContainer.htmlms8{gޙd&؄{6p@L0 },@^㋳:JAA=/ˈ 87&~Ru7&Rj&j_T*K6n#,"hԫz,sY5,$ JG43bJy/)%prC 9F}BZj4DvYd#9GP1~gBR 8m22WdEM"X[r 9j0CIS^x@hG!so;+-QLT=m&>c#faw&h푾bݪAo Ixջa;HږuG䱣ݨWC~EûdGEHQ;r]8F ٯZ%]?*:A8 pn80㐏j码I5 ѽ&rH[ɱf? p2#@r:nSҺjˣG5_ƗtZO$6U_`<9'Y򸔛ՈzxƗ.WڀpP&sHxۜJgTM||v [%`lp? V--G)gʣUꨫYr;΄ؿf`p6D)ob:9K hdk^B$|M>q ty`(OI`ö m*6p ihRЕZf[,P$&'Lw߆RMxXv/seJ@Hvbb#!H]YBb H0]`P',Y"®MV Z"m!ǂN׆vJ_ńfF2b9%4'E=-&'ťdQ1Bϔ*d*7SmU+ʒ`ҔYGV̅qH[*PN+$cw!s;b&Sl5BGE4q0FiMA~B芖u+@fu>%jC:#HE-+l')6ΎDm_ b HAB'mfJ1PaRH#&GyZvLxe}y],TRSXl 85:g:bA&v`wM% Z){8BrqCÀn6zfJٓ2ĮoW|ϼQaՊjAcf@΅NE#+9b{zS!{6ַŐ-a 4wP56Aaߔ{7f2\7?V U1/:VҰ6PP}ӧu>jcvJL02l y,ӋDPj ֥Ca B (O('/ښPcf&>ڊj[7I>d;>mmGRR+CL(?o:>,'ae4zTih;4aw/owSM@\]k)MFp-szj/ {̤\uZP}d]؞$7K)"zsY--,1.^311rA48奠\sVѨhK)MB! >dIu__sAOQq^d`koo}ZshអvV6{(9X']Z[^2<9es\y[EoE_K/ݤ&N/"' @!ҁ oJ?0nzx45i,& biV6+oPK ^B/Nt<com/vldocking/swing/docking/class-use/MaximizedDockView.htmlXmoF)aΕz䃽@rT r"/U?E ^`E V;CrX^wyyloڽV[>ܴq EH;hgμj Ic5Ob*:LN/Y.K2Ց8#"IB:ׅ.[鄁a3e4,~d1T+.h`Ryy?{Շ yCjw.uWk-͵`/)HT)%;SKs.n#,l%T;!|4bDԫzuߜ4HfmELSq考bb;fAn'~n ׼ܳaN])g5h91ءq)jh y[.tu.!p&:{uLd/Cl~`wlt{APʼo42O{ X 0:op 4_Y_Y¥Fqw{6:.x,lBE+IWho8B{0b'S j̵:t4֔FȂ :|-^-oNm1f1LUz.ܳ DU 4+'_̍ Ŏ卓mDy`U ]vvN֏U+Ϊ6ꞃ>Pk0c32*ԿLȺAyN^&dhD;@kWv]ޮ`@܋o78PvEw(-/ؘf.1*B?5^~`Ȓ'k4FXeyIq߬RgyB"6a?$OPK ^B|wAcom/vldocking/swing/docking/class-use/MaximizedDockViewAsTab.htmlXoHaꓮ^ 青bN6Dܜ)Z{?@S]ۄX^{fgx鷃?1E K'mB:A'{pUkH+ySAeguzNjV'^"$)Iijv]ՀN.4-όѰb&f!']0CeɤBP~wճc"joߞ0PNr[kSL-R0N"o)PSO̹<[V-TnKU"pU:W AbdpZY}xVqg6f9H&|G`jƘv@S^R$߃gq߹1d %\XTok7ͨN'PɘR{ƶ'7\($傽9v gHXM6Ywe.|9zEHVxgq C\ёvÆZ' #^fj[iQ8&h 过?^5, :`lƼ'i.1Et9雝-OjSwySp%ڂi)3]w.ʌy! GQ˕mLNg&OX5W-ʵgdAZR:d=r?l,i,bw单)uӴMأ]PfBԆ +}pd,5偁,ll+PΆz]*D(;c"u1'Gݖ$ a/j1rɖ[>p(~VtoU.JP9e8ӳkGz.qߠS]F <%3u3N$Aȍ%D6K]ȋy\S P/3ˋUXy&c; #q5{=䩠k4*|1'&;T6Nb%Z(EW3vw> B1~\:Qԙ^/AA'y淫׏3^D_(M4 e^zTAqjuhDМ=:sL_05W~`ΣAzl/0(`S*IDh6x1ށ!K>iW1g4BdCå`stB"uzZ|]pPK ^B(0T UCcom/vldocking/swing/docking/class-use/RelativeDockablePosition.html\mo^i'+RiP:sfpաNgQvWSeoCKBB)6mA8>yΉe)@߿4q}úOjs *)prRƟ|2xCn9 !cx ڛ.Ȥ:jGC"]g@pDcIԙJctz}+,ѷQ*>U*yFKRzb!P qbohD}& cre IqSq<$oСW*y䛞!EP0$dQzz!n'ar1 D:HNch)wpЀ^nj_6_[ɯ uaY|0 D"<`~ SoAU5c LpDi_ )P oqݣ\Hܢs&B2"bw6ꘒ+F!SOSf>-%`>k4gh)| -?)-Q2R=FP4:e u-3` mC HIWQb8 sU^퀄 sb~b? uQGBN3:\ ұje (Z;^`'5-n-Q ݖv XP&zTLȬњ8 Y/Tt}XI ( 0Ӑ/t5^ lI 'Ә!BWNٍ  jۈE$tAXI0^,! ԩ ND'6ux!B!A :CidG4]ƭ7aa12CS@ g "PYXF@C4 |]H$@. ^:.m=V=55FuD9'T  TeD&J <_Ҋ'IX%O$PY :dpKLtjhfGzЪPJ= hQJc};k+Ճp$"PΒQܬzt=CNSOkGO;Gqa:8Lj]P5~~S{ R4C( ULW~A8\aPxJ6 JmHVem/ݨ`ԄnQK1g/u-LH5Ջve}ݩo.ۙeјDD]bZCYygZPNژ$C3~z>m% b@ e38=kQnׯm\fˡMbE6,;^yaB)I]HLiSgG(/ v7&8e롑JRvv؁|өG)P)̎Llb%OrT5`w'ێŦrowDʷ{oQ?-=6ǃ(u|KX;}"}KN-S̱Oi_(8Aq*&!ÎDb&*dd1&H3;f d`c;,3< fAX:|~1һ=o L(4!LNfe~Ө9Gd;{.VLUa+= X0ہg~$WeMoR:ˍ[&A_b;T_jL2>uG?$-vklJE[ ^o^~%"lhX(F3K7@Oc:V^ڕM[wl"VZW_;*Lwcfi:TLL jl2zyBbߕ[Ѕdw ?ì B]#;A@ߔ!rs+[sgY荘ѯ(*W&!';DRM@46M $]w='(jX(?b9 h(k-t?p#+^th["?t0RR3+~39ǵDTզ}!珰Dis[\ReieR؁qIs5_]:%  w̰Y@/,>Y W-ajND֧hBk"a 쉐5Mʹ@5;dV+xsx֌& /t [b2pH *T(FLS % ?Zt ꆥTwiڋX帅i@n`.buoBPL%}z?Lo6Qڇ;zћcL9CwѮ!;W%̀nK+IS2a$%ٻ #Xcuw"7SbaG WS bDC>ҞP >Rgx'RMj4q.# S(hթk/72pݵƉXkHGv\BÚ[iql_2D߶4"%%lUvD1 e ke͏rڋX/?t=Ҽܸ3|;8Ac ovtjww}vPUIXq*)7`l˻ If f5[#(}seՒ().v ]hZm=) seҼ/?r[pk,xx7c>GdC1^3/1*wOYaOW9=Vw"|H`ՇNdwBk1<]eZUgcVǬY=cV%xy'2)a_uJ-.1и%),C7j`HusV Pش":OK 톴fyDPK ^BsWS9com/vldocking/swing/docking/class-use/SplitContainer.htmlYo7=R׫ԂԻ#60%i?E3'@}BYmTDs/[ߺ'wqg-8^?x0)Nؘuh~I5{WLKi$h>;|С.QC;cW'bpkƔ$ڷTPE MɌ$rU~sT\`˗u{Pd 36?hAʼn0hƑ-H5N93-) aT>8UdBRATp=ƞ? PC@FJ 6aʙEy#fSj0) d6(A9N;qȾLWKM ߏ?l.Ć8#&rXyttTaFM*4WOk?)Qhtbf߃7^G{q{P8a{4;iH&}B-TA_ɹ*:b˪BwtՃS]vs*yi90΀,&v}ҰxhGV36r %=񦌛!Sڠqe:幢HsδY,Ed]鶁Hr<ɄEdvм̦f1咒- ®BW"%b8[g&!2h:ЮkRp1Q-#ο`Qf6p Mdr PƠݑ!!˴9Oy*cq9h0c"1Se6]n!tj.I'駢787Rx!OmG 8Qf|g9\ݦ~o" Q9 .=LrGB![zD}hʚɡTxH .^Xfu4;vs`iK,V6sNVplIKygEXvJwLv(~j^z-]Ȅ !ڐS182Mmo(N-r-8-2ʲÐ!68yn~كpf>%V%oM&L5h 3y*Ur_=JjH&IĝKŰKvŪx]m{ ]h cmS#LT!>nbM?N-3xJ_ XBXhW'Ǘzg|-Kc?%[sO(QʏQJ!|ǧ)ʖ^vՎxy9ޒ6:yȚO\;hl^α-v5&_UL y^q4]VD  PK ^B#]mP5com/vldocking/swing/docking/class-use/TabFactory.htmlXo8~_lNv.B{ ftO!|8 ,:~c'R*5B3|o۽Vg>F;rݹkYvD&.*zMI/ YV,jB8'BJ͂^MCtAI͙2sg S԰k.i,GPY2<Ԃ_CH~:ԫܖF41Fr,x2 ʞoHN;­sjgA5UA2l42gBSB/ƕ{h!1,1gWWO(&BO`zʘS4!#=*6 V!pлbM eW=R<5etL5mO| !GԦ7[o\yǵzLaC)!S;ӵGJj#A#އ7d &Cv8't> sM g- J4SA `K1,n!{jP< 1`d]X˴K(R͎\P;-OzS4yd#ԒO\FLyØ+mй}BQõnLպ]N5J܏KV^Tf/ [b?+Ȧ+&Rm).|s.OUtx`]SbB b,/,Uld/099@{#=a #uL>$WeMoRU*ˍ[A_b;T_hH0uG?(w%<3qa針Vq魒ȱJ]BmH\!l<:|#^3.~C,Wa w<إSAh")ͲݞXD&,-nר pmg}`I쥧* X +NckC.—j텶/rhX1۲u/zĭ9K٣Y5/5|Wn}֗ͭ52쁾d aEPђG?PX@Z=.8M5sd:`S<4 ~".Y_9IJlPK ^BJGpAcom/vldocking/swing/docking/class-use/TabbedContainerActions.htmlX_oH0IW`/NI1'5Dܞ)Z{,^kwSͮmBCiuS,dfgx鷣?.ЅǫM'W\(@hԒ:0v gHXm6 =\r򂐬$ .yC5\ӑvÆȥkT ٪U`[4,Zo!tOD0aceڣ+Lw ]Cv@.Fe˪ajŧ``[JLx݄+m02cx^Qrmvz[yי銳Uu3򏵤t<'8ȨvXdX5)+3SPG;̈́ V+Xk#YI_`r-H5noT\?RvDcNrwx+I]- rvAiFv|SXj_jjpg{׍$TAQOc]OF <=#3}7N$^OZ"ҥ.<LFk.-(`ׂ&<©|RrHbC'y*My#y _ ͎MdvDKba^<ď^=Â:S S%hdy_#vQb ؊_jrFޣU?q^G(@g蝹tf{XX])ERіG?,Y@Z=ݟ].8M= A`K<\ ?GW,/\I׽PK ^Bcp|9com/vldocking/swing/docking/class-use/TabbedDockView.htmlX]oH}p땶 iUi"nV 53@Ѫ}mbX94^{-| ts%!=5$< 3:"d\zs/c DIi4^.tٲO \̘U h<5FbG3I5 \tAd C{Ug7Ty Kծ޼ס^4ׂ5* AKP`̼@)ǞZsq0dQ8[BΞIgl){UQьi 1.wPKY}XVߺK$J05aL;W)JjMRL$Ir߹7 hej(y&٬4>=<*"RbxoQ5W.1gL)諉|feUܝ'd&Sf'O/,\A *KeTLz b2)I8>A뇛A4/8Āq㝤]0EH#ίwbeYRSDQv|ZFP9JJSl [l\EElAn2?6PE:M[vCe Q00_%ct0bdC ] #a^v9?RvDbLrOx[$sa/)UwVZ/٢dC^уZc9Tԝ+P3^-H cx;-;V8'#1O۵YiBuHd>>:|+ެl #Jk.,yرSAW YnNL(vlĬ$8*.zvմ Mw.0d"TIΚ} ex(|-|ɡ<6cϕyCeG=M/z_6C<~au2I٣6_7|}L?(ȷ]QGZ_1$]a h6x!N3-x^^OК2=0)U  ?#,/k??PK ^B:3.Bcom/vldocking/swing/docking/class-use/TabbedDockableContainer.htmlZmo8^aV PIӽC؋Nv{O-67%iv]7mc$D3ό$мn:_/9lat^hK(H+00o¾!B ֱW߇+:n7-pjMl>%qPI43Ɉ" Afh&P}om fLfE.'.(Db8cI/Pc󝟵IC& hpNeu3It, ǭ)C $إhPsk__}c ,IySz©S=ГGjIR%ּ g*ysvD<1*,ճҍ{]W7 úEDL;`IL?]w^28*5->j_nDƝÁ9f A޹yY:BsqF y)2bJH1VTGlD 0`mߴ -:&Ae@ĉR|^<pn7ۧ<'_tvd8'[G3KA ;v),]%hfWHA KNUXBPCd"lIys$] /f`qf>. wLY 9d Y87K,#ti^ rjO&^ Yw#qEޙ LPvrE7 ]Wr\TH8=3FN˓Ȳ4b<.ӬWd*#Ի_@ud} XTKAn#8k:Bcj^@MI3Snstkze~DMz$'D2Iq%&yRX"i#HO0Ӷ/M: ?&{~ ~f te$ `L{/b&uk U#LO^jK \7:7rigV\t= v uRo),MBZ 4jt2B-VRJ- O |k~{ĔJ sLvT[U 7(;+wJ'mPb^MJ'W/wbtfȧ-KO[,}7[fk)qi/ۻo]ZZܒGxCS Ў7w`%5T+׾}8J'K0!1P McS8YajgZ$L <PK ^BTMN<com/vldocking/swing/docking/doc-files/attach16v2rollover.png sb``p  $?ORlI. Ap品" 0kPו*'3$ӛGB=]C*n j6}Y};u X?\HjcH{ %3&)^s/|!Ov A滪/W{ʜvJ7L|}t)jv22x|w&y1;$e&24w۾2CþvjA0ۗbl5(v*z0S~h!@o2xsJhPK ^B%c]P1com/vldocking/swing/docking/doc-files/close16.gifstL``---? F?Yt@9'8t9d<6,8!aΩ7APpnF]2PK ^BGh ;com/vldocking/swing/docking/doc-files/close16v2rollover.png sb``p  $?ORlI. Ap品" 0kPו*' ÁEB=]C*n] >)xXAL+tn׍T_2b?#'nT@ #[\vO  ,͢ ˺(NpeQ!v^qʜ?ߞdꤲBݳw&ZӜyƳ#"KL\?_ظrpn t&:&PK ^BHFaS0com/vldocking/swing/docking/doc-files/dock16.gifstL``---? F?Yt@9'8 9d<6,8!a3eńG I6+6>:cb1q*L PK ^B_:com/vldocking/swing/docking/doc-files/dock16v2rollover.png sb``p  $?ORlI. Ap品" 0kPו*'>p_PcHŭ?o:pAq ~k-]?kF xwq`ώ^ut۝& 5x2냏yx8p@aaoɻ·>?g?M̗u1n zTy' eSBPK ^BAD9ו1com/vldocking/swing/docking/doc-files/docking.gif$XDQ]T@PAEidn^@T^^;{̽s=s3J*b6((@CML%.oaki,jg@䝫wwo"\D4_y\ROn79 CnDc] ]RwyeayEEEMyuUuue YIe}em'ښ[;{{{`]m6w B[9 n@P]TUϿt-@>.' Ku Kw eK 93wO$T~./Rvl2rBrw#s~WQG5mOk'=$wf\=-oz —z[ɇ6^Ӝ֞=5;E[0{DzVuyRn"-ci",K* +ږzu~`Ͱo>lρ"wC-c -9{:=]Þ OK| g %9/ lk/9li [:oװk?{`z/=mm-!_1/m]o!?ΟKK"[[O[9׈ ]5_5}:>~>?=]?=7 >ESエgͽi,O q#*Mf*ay^l^\5R#ěEeΣN!݃A.˙c ׶9fz8Fvibnco"O~plW(u%+CGjnhh*ZzW$TukP.VxM䱴-EŖ&V-Uv{}hmt(Jd^*/?i2%CЈ6xnXՂhƼ6ލe.ݍgi,NcKrb9K;"*KȌm.|Q[ C Ӱ}G-wǁ!p,hj"UW,C4.C8oHI9'};TX]JnQ{ʢxx֒d5,E2sEIy) {qEyIuuI yIG]SlG8%#jcn-3wk6Y2d6T6< ~ˍUΓRYc[Ϥꖢ;ĸaSTF1$\JQ^uhkF~oIʘ|7-:i^U,inJ|9󊌫uV{NOQjA׈jQ?b%@:24 JN j {G OC_!i)H0 ! =EPhۘ,gvbQ6ex9 :֭X (ZȣKdDkO {*ƒJL8e!+yE+o+䅪Nak4ȝv 2\,ą8  C'VR -7 {t! C7uǰ2|ӝu/RhW'xbG}WSdACbޙU0|h u0Ua~NHT { AM(A̔JR3RJݏqťfpCIDts{K™ӥzֺ(+7&׷lҨB1|2.+c@ @8=0a$Wv|X9DŽ!M9t%uR@tyc*ڈz!Qcx(΁el!BkJ͡dZXQ7\(o=/YOG7+_ KEoXK%wjKb4*+%o혤L}fqSj~pnIsd3+2 orI~2|FTN% /_ؐ-" ."JrR`Y5@tRǪfwsI_)u U*Y|P V7{!߻,=fyUTPGEE\0zshZ$ Ȝ|)Ė?*(Dqrxt;ѽ|6k;&~/o]bHjwoE< x^.7 [B'SӾ[" 4<]} y,goD3)5/' 5߁n8QCȕPDbC)WX9;ù™oBXD#D:ɠcGRN2Jp0ȚaPE0#%pm'H(0uhk$qL"2W7*̐m@ʀ wc7NJHұaDPԄ]!  ' 4ܡ0` иd'V? 0/vǍoJaM e7k@$b%&~ ʚ%?8q3N9RNG }Y l)pK>83hNe2ogJ2 y1~-k2Q.kVoMS8s'P|Pm*ss4R4MOI:j1~ސvwp:#cv>'f"{S>Y n'lBBBqQƚߤԾ+:0;SI֔(462ꓯXrh'/!iHhUe"svE*ItTU5D)]hRxB\z0b13,2,cR$l'qdʏgR^I&8)T/QrU `+D,t98ҵ+`';`,o\<[-;[z *Q  ƖCK>}& S]W0}K$OHSW1c:IwL[fu K@IwGBej7Vmerrm4[:r1. "pq7;wﳔ/+5`5S9JUfOT>=܅ew5rp*&w ]e0h\׺@RʛntՒ.Gձ 'q4 "Ug>xrXIZQhi[76Yp[vxhkp+ ;:qk:B;jڃ8]p~&#Ѭ+l3AKOLYsNW6UZ}NWzWLM{HN{zM/m QfTݶTaz&{9z|:|`]f] _:k:fq]_8zL\; $'\9zwV4&uVIM)׬&.K?rxG@ëa^Хg|*/ &+Rc̚ 8JZ wBJ˜Q5{mK\NrZOh)yGMW'ϩ}ojGp. .oBqāPMQzeR QaBTܪgnŽ}թȓҐ֕OUb4$zꊸTIR;s jwD}dJnBՍQ< O_]:rQV}3mP/"q1QAր[DB@ȍuUGp tM+!JC"T%c_W2t{:*Mjp+1 :o?G M<<#Z֪ݾuVX5״4*3Hi]$pC20 WWxxmVw 0bpFoNϥֻ>Y@Uc[,eBQ*"r"2<1ڒx̢s_~V ^R}ns& 7,a l7[b̋a~XĩCAۨ}+j5St*69k>ccmp }q Q7y}xB'UQ) JEM+l=pFۓk>q@-zrn, y7Y^3){MCħJ%w/PB9=9ןPyTx]=VqjAh4t#? Έ UqX(p5|7{I=ؒ3G/3āxa?YY0UJB}Q2TTV!Eb؅9[ck`PЖx{56H;t6{:^1}2K;~d^9vc6{PPݸ/+ʠՈVɴZbD~kmM}ʾKٸIt]al'ER'eQӍNE2XCR5?^Oz}/,YǜRY7O4e(hPui}՝GUy^XE { }0x5ַ'kzSԳ4]7y|2*QhƉR(?c|ɽ}7o5C{Ah -Pֶ4C67GTmܕK=3euk# mSgPI^!HÒ)(͞UkRH ?ѼJIvVڐWBem~ J EETA{[ ?ۊEK5MFjy8}Fإnk"I+Šg¦sn+ 7:|nGaHodyݷW۞ *V^q_Wp3b rYj ߋ{L#Rz9C[^Cƕ uv2v0"=d9J/dqzqgv:gqOwr(+۾(Ix͹Hs8 Oч OY۩0: *3&83⇍{j'{c=%G1Q~4q MsZ޶bڋS=iJM:XU4]Ut_yL;Dn!EjYGOG 1dG ĹGv4h;dݵߔƏ^M7&u^u"" !8:-Vx!0q7; \vQSh"W7V1|' t: g `ǖeIU?߶+.`ti8ơP`DtL:IP8]|@B1At S7jSAwb/{O1ڠ谖:5* p7`u{w{o? (QlϯNڅdxXj +& 0?Kؙ&"nv(Ԇ[q l5o\?vy5,yvKY~</h Eљң~d/E0=DhJDlJңރ?=ATxW:+Q\ul^gLI7JF 4(5X1S*ODJ^?+CXݖ5FRԍ([NtQ_o1dLRe?' 1`X}-|%{Xs$._(3]bs<y)SݎS:ݸÔx'[n XWIESTTUKT' 'TKT*TДUU"+9'jUZÄUTkUk9U#UkZ' 8'k'c'Jڽ' czN4RUMUTo#PhVo6h2W*PT-Wh6F=UW`_j AY~Ƃwe76675ycVXcN vmg5<4sjeo5w5NhJ˞kZjazoקo^|Cg]&k?LdPik~5GS53ʗ ߗj;C4538 ,E;I@(1a+a:>:>deA:y:ԽAT::`]YYF9<Ȫ䣌#um\Ы;w_=1Ӿϲ"л krϋ͟n>f`iz rIg>xgG3\>@֓wI= }dp2 xCџbk9/-"" \S 3 BFyFI/ WP"OjpB~RQsڇS##mEjEM9T!= Ç1}o%teYn5L/mx죯v}УM(W&K;eė;d.d$xLMkdj,Dʺ*w͙(jZcZrd0s65Vs^&&AK%Q{NsBsGz\^+꺙Ԡʙ5ggo% r-w#$ΦQFʌMjzIVL†6h3 zh31`cg_ EEA(.PT$enl`d`OVo`Z9gm(W7Kߕ.xQeFmвn1˲&_qEn%"hJF3g_W9뗙Ek'f\Wf|`͑Fu٤j.33+ȍ!9?mik‘-MuܺͼV 2J;(ÊmIŦvN|jbb`+4zi. 5b80'z|flg!: 8 Н€F#Һveӹf]|y y|Eyna#j-s nfnV$V( l{Vh/b=ݨ33 R]5. ;4&{@gt5W 5SᮝaɢE¶Џ` A ÿvܘۖ~--U9V7vE4FJy V|6O۲ܘ >{pL%w0ָ^)GVm~*m;dZgG~蓅]UƥŲ7L[Ϟ66 {7; Mz\H yM- яu0$#nqye m4iejL4#Z·}3gSWqY4%[FRRR[RRI ][Rۥϥjťr>% !3RЕo.1gKglO?4p4-jp֣7dym~kFf{Яk5#|Cj" &uÝ0 %&R{qAV޾JQ&y Fc)z߈ (ߨh߸7Qoo"cnBn:V" ioR}E+= 4ylL2l~9HNmdl=dlJuqT牰?<~^Ӂuoc'Us\~yu&QeGwUX/Jٵm^AYGdAǹHNAL!^WB^ĵ(&,Y xHmxiм~NJSk-”d>iၸaJ 0Htk =|ýِ {ߖfJ>{-k')Ezt6zFflc;,㸰w`?8vv2SO%E P5WeRe9Ɯ8:pUIg3'̌w; wXSQnȦ! F(~\oOߟ-S $L%mam)j\wW9ז@o[L}){C%}blx'k 2d !6ݤqd[ʌi 3-y ˙_#~ݨ 97QsXfáAG,?ח8ƏHN id,-p/ { |NYww?}#s $B_* K6tZɘ/.)H۽BpZ}ʅ8F:@9ޝD™.X-Z;-j\}9hi7G2+z6f]XC}| 7w V1?}nI> i'@rCj|wd'Ȧ!04`~exW9(_[K[9:0fw e#qS/'̧10]d\7V!9 pr&x;;tXGY¥=C;eCCŘ̙Qm868d/Q9/P&І2%ja;m @^ P:BQtPm52Ig(NqU{#u8*CO'28GkJ1F2toz;i};y҆7sͰN31׷.2\緖 ̩^5^sTfp,!?#Tiq@#e/&bbY\yaE}V|;]">,-oor#ٲX 0 ;;3MEF~=c戮0$:=0`?^͓.qbz" S11K n W :>Zni#CGUł45ޡ\U nM[*v *셟rb(_+$J4?g@(ê 2BkCƇHH7quM3P4\[Q]gN:6TpK5?OF8:wM(^"(`ԭ:y0qR!5(-4gU`fS̀äO^v.¿Rsu\cI/)0<"mᯔS;Q7U=ؘ&Pr;QzƠRZOݔw tQbeKápܻO|?8Ӕ;4$gMj8d\ΔZWv4_2XU6˥7Nͫ Wr7AfAfU]Fz̾:3ET%.uaur?Jj)_r6<د$EVmBvt=@lB,$mٝ0Ū'h/|PV<#nMW:ZA@w.C0swvh|r^͵1NSO?vamO^?7jQd"(o g͆u!ѷR#vmZU2ܥS#%`S9ޭH3o}{ygwrm! g#+WO)YHװ=_RwQ7Z%)~_32h(~ht 4?g:|B)O [ RUQlN"ة ~; *"nF* i,"鰑U3QPmP5WQE#M -S 3,~u:I1w@31y2ȢρtC{@! TQ)4fI*ݰHϣX3.~M9*E-"&'R:E(eqNeכ3n/GJ۝P`>=8spF=m2=\61Fq"MaY!4j3|](U\A78q{sVe/}#/϶UOPG;+/S'uY2$h#lu0-=RԸb{pSEuNoͤȤYD(+8Dms,Io`qlZFқօ}kQ94 3I:q;ZW|6 M w!_3~.QQ.922 ^{X:rm0sPd,ּ w#s6õw-ߜo}-Yj1g++/FxkJWx‹լ@"re6 2x , 7E_ &dZ>CkIc*dRXGqB/Dۃw`[ U[bv`kjBJd U1) I̖f ̉3;=2A8UX͊sXA, -P6>۔6N qy~xNQPTs-iWV'U2Ʊ4TA#o@[k>'ܪΠ^$ٓxwa.U~L(y'WDջ<hKHm: u#xCgR Ȑtk& `]eѱO2 ]d c vpm@34隉ռҷ:")J'<2c4BvTήݲݗP*HjQ-X)99mլXANϛ^껼4ςM:Y<q#5)m'F(_[.d\8|"35T+.K~E$}{)|2lQ Yپ/3 %wk-r+-/0،c9)t#_fO8 QF{Z`d !ļT/N݊|O!qP7)z{X?˹O깏u~ꔽ;%j3l zxUverY]eL.fhgO,mr_p1Y;){T@`ud<9zzJ sd6k ^'HuV~ / 0a!G/>Uح64}o;3Q>B3Zr, ާ:^wb FuU}"jJ KxGHDHGDDugAƗ̼nϟ\Y6 1_UW#GDt'K}za[@3χmj_%O`qw3厏P 1 Aә0z2jSJM6XqT~Ȧ3Uϋg`ϒp7ss}rtm&둂 x+?ifB>533Sh3ɋWZ l|LD0 s&t3\r[o#Z@LAZ Fs/×^lg,Mb,e)8$"׊["B b'"*aQĄ Q.ٙh#ɯYӴsݾCr GPq7.}6,TǏJOBH_MGJ '׬І^k*;e HnYf6(H,82D_ȸu`SiMGŜsi%,[’GBDI}U"U'=zQ}ˋ!Bt v֜C萟f&&FFtkꢭUKD5m -'Ɔ0w{MkB_ԖguGDM.Bᡊm>&Fgc]~ӦFmr0w~sCGZ HSGfgؤHo"JZQF|/T zB>cTQ4Wa%M9^ķ٥+j'J{5gB*`7e4~ҎO%5BD>ciwV]Vu<Br:ros,}q6+gG @RncO_ ya׆CO؋Dr3Ks+ޭ"{)*1fwOD4z-:خ@zr8=FH+0C7(C2xCrZw;;;;{sO)+;;f&d/?3&& 2ldl7?{)s)[Qw+]l+L^ku1` ljujm@'p&}c&l&>'>?G~O>SW>_[>g~>ȓrO|*y}mD՗%v^*'oby][CG{lpZ4 ``Rm7D 7R H ۽ч#}<< ^bJ9L,!-~o{.j]#r8'AG?|wӇ$8N,="aI< ش)eK6 0&J,ˢD*5ڔMI2*եGVU*جXlX8 @'Ydh\Ǐ^'b` 6|qbŋ DE֬=#IƣGD:">?wsG#GŢ- Xֹ'|Rqw 'Cq^](v׫s߮:ཇ'/xG-. r2.2Yg?‘69f=И8a/١L8 @}DE p".aN9[+zGqH :$qR$:I'jCd#>2<1$K2!0[y 4pz'rp LOo&}dF*I69Rn.}iSSBMRQ,UOSuUQ[r 5ܣC/2X@ Bt G<41Z5k e+?b̐ xx@z|ݗ~({'~gL+N_bҌl.ˬ"ef%eăh  (eHN&V(eH rfZOVȡTfyh hȥ+sN<꬯֚뭯j6{lzZ+чa]gů;am3VHaX`diHr* iG8!̃r'tn=tTƏ?+7mQ|YXQK̿r?̋[8KVaSpi^({:!u h޾|02ߞѿu ]E$?ކ4DbSb&uA&R ,Zw(nuMGVf]~|^zBb.8Ƹ Lbxm8B2ސ17>[X aGFHþY[)1[ 6X20.Fir˹FOyG? YHCrX]>Ѱ#boaq!Y _1hI21Hx䏄$jZ` Ze,i9K[e.yK_f0Kt+`P;t^fpzΆ6?$V"Юh Tg:ٹNwD=;<9x5| ) @AdV =y'q vCOYWZT(-2эvGIҒԤ)EJOR/F;1*^h Y,N!YB>lne">QC%*Rt9e Zp^XZְh5kZٺVm[ZWupE:yuiOsd. ^ i%բ2~4D}~~kVӮvzwޯ\\z-ֺzd$k};ZtԸ2w"FD*A+(5߸qok,Uz`W?>;8ws^}")?uIo6[}Y9˖.7cnQ|4wR{7*A{i;m\C^n&F%rLA;|'yA|9y[ bP eZײ\l/[X}޴{˪ѵ! ]xG%t>hN'"A}3??~󗟈q*5Q"лG9c ӊb%~\ͬJ/j/ pPw O(x(8I A0AJMWPY0OW0[PkmPqa326Bnލ+ z>K ;n n jfdMkƨA??adA+4QފĎ7Q&t?.:tL1qWV1/L3E@(Anq9AbNFFFIGUQg4 `G 5HHH:;3A@K1L2LDҤ@5$6I$0Mw.I`\1'OI- 2bP R R2QРQk\Fw]{HTHSuI4:AF>!>Nu>3TK" #l ^*hab4xl6j@Km*069&V3T8Jj0V-c`fdh֜iZ+dh*PрB!,!\F UjeQuT |tRH/^sISsw@a3K0ВbL plȲMbj̬,&hApclq ̋r f켨n̕mvȖ,0׼rSLh dLښ l .`gsm2[hyUFVI aI@ Qvk5S^e|o;<UaaU[U066%qѤ>M(o-@jrCpwox!mof@hL`Y1x Bf'roV@ \! j\5R{^t:@T;e@<<4`}rTfU0isKXѢm vǀlfxvlƪWRL mq]e wtSƠmsl"mXf ܤw Ei8@O x6Fwj˵`HIQWH{V|`:ϗζ<ն_V>ssnKtDL2EY R.͖ٖHjp9E i+Cǹ&8'ˈ r8`Pyiϵ j ]Q@R)uHw^5ysDu<_TUKM~MӖ,ndaWG^B|nAQvnA,_arf80/ 2\VFwyQ@Uy=;lS=Km?`a 8m Pk Z.K,+ Ѯ$/TX{:7?:;6_T8UY05Ynv @ oFVjjx,luS^:LS o@0ޭ5W0tz*0L-k:k O^ȠT?遞n |e 7\{ \e`d |n`o-\n u@v}C|^d;`O@#H eqߖ,M-2?ֳ,siux s\L*[E#QpazOOEj+3D5N 96|)<\cb9=c+h!' 2YrCo9&]#6̼x"o=!%V&=m oLqM&ї\Ʉo]/0Jg5#_!\!؝./Β]P~ 6rˏ˅e,>NaM4.e-M !ѐ!N) e}k_+8gq=O)3N!z`z{*3+9;5/KC>O^W^=Xܜ"=ڝ#р(axD@x >-ߕl"=sص1Ы~1yנv;#APؾ3~>$3? ?W7y}6xuaQXt-/uq=%Kv}Vp/ثX9 \M1;M@ LtkxO5ghԯjp+Mzݹ[sO>ZPpvW)Ƶpg aFPBX!euYV e.ƚ)cRxj&jY^;>neWow\>XKĄsO:)C Uw . UZ jEUw=erVV}UPe o Ua#tG`j jbH(a*jhqh::t֙A]((' (Cn6@Jk!%rG@4;3obQF ـ5Z{QUyNY XfBpf5 ȹb_Ge\I\x:ڊP *oj"b"zkj"(d-z$NT$rI}*@Zixf1uURQAWQL} Ђ.@nZZKÃW 拷۷ $x7-Xߴ=߇Է+xvN~:/>o@|ƞN @rA|_ pa@|b q=2Qؑ?o=JT\LQUXSgMYMmTNVJ >DQuMSILja. h :LtW_*g r4 f Kb0)=<CVvY =w7!`OxhY>$b#78HA0vRѐ.3f,4n!81d4#H;jpJ9n)ݘ6*n O%Ԩj0r WšJb; ;FPshd1~ܥK>2`3ɔrZWҘrpן0fv1`հL5E[ҚPNM%%X{0N gsc*&z*r`W:jPz`jSFfŝe:5l-m - H8("v s]|Wז쉌}ï3>èYS7s ;FS1?^rJ֍8)"Y0_s8_,) ̡*f5 ˨zɞnÛ}38V HHEs :uZ)qSu8WW&7'xҝ[^4S_z50%]5r-]e7j24?5RC[}Qsc_u@;H:,k:ay{|:Lү0|Myһ^W}Oa^`۹^E+n0#]~{/I: oh~Ń|i[V90:zP|N\f.7%cs tbUq%{wܷ ɐ  3M&~ E+\EW9#*8+ 0:v>Oa6awcsolg/ auXwlfsD|4o0{t83TXu֖u?,=6 &, #~&8|,-"~j0x肇x`_/&f|XtX|7'^oWpoWf7QzbJ7XrPt%x@_fHm"h9h4*h*( ('8(-(}؇  h=%va39/0%P~إ/X0QXҎp13b1яK 0"F t%P} 1pѶhX>V>eNf8ਇ&~Ȃ(量(7~vh .y7Bjs1 B#938 c9/39y#8 S9:X98I!9r9(/7R7e:#9:d9:cLi2/4/_H%|qȑVT4+$_K5=#ɍIjՆ3WKd9@BB ym9y)9@!T9 A8x{`z9YBC8ySK d.$BAw~}EheYʑ19~}H@I947@DK78Q82`)K !KdA JC8w! J i8I TId8٠ x9TxI+]g Sw7@*DzyGjJzLjH`PNQMJ\41!#ij  sJujvJ @uyztsz ʧPʧ꧄s{ʨ : {: wP<J av4j=h2b;>Ӟr٧ ܠ  }Z ʬ/ 1ڬ 0ڬ @01ڇ1 0 X҃ S+=گj k:%`m=S<8E"&s-HXBi+9qf4 ܐ t ~ ؐ ͐ ͠ > ?K@ D;F? дB[AkQKO`ɐɰ^ ɠT C˵KQ {z҃pS1t;r+t#Xs۷C ˀd>੪+_*>XѸB1Lrh;8#5hhhY P EX+S[؅[K>{~ol+Ӌ { KB>Y+!='㨂{}{?B7)& X{ Z۴R۴00봸[, l<~ ̴[Ȁ,"{м3*+3.* 3l47LO}0 A@qx!Z+ZZ(}Ƙ:`*+9= $= 7pP Lhuwl9 |zǀ rLȋ|~}[$+y[^5jp"+4iI+M_ܐɝp ڹLl׌Ҍi|` Lڬl{PS# ,wp JT*W߄>6艹c5h+{py}0|'}!=$'}"]/%{` ?C-EMGAK$ Cx}V$TI%F%^ _-aMcme],sQ ðzOp Pwmy{}~-؅=؇P k n*2RٌMَٙ]p pm ;qسV}EcKh}ֵM%,%Wc* ;< =ƍͭ }ϝ}M-ؽM-Mm='ڬmXc;T7!xӡm㎻Gs᰺HZKB>[z.>ޤ蕞*.7颮n뫾뽎댾SZ MjN+}Nn4JBI%H3\K2h>1G~` _}Ḏ̾.=)N9@LXĻl>> H-!/#O%o')+?#'^b.ʂАV; eo^>gH=o_JKPOVRU/\Xa_S[0X=r"SW?GUuw4un.K^䏿?%O7:䓨/0[c45Oa}cC}o=6`\d\mA>??J `~@Ro\^e?9*kگaN8iNZ9 ;ذ@/NN"A'(i)pbhc&/6Ps4 ZY+J/q&K]QigO ChQ!>4q͜tY>>/a$p M06.[jy[үE+OAoG赲 4u L!>+l;UЂd8t̜W vREf)h'`g-yhRas67 !^t|z&t5bh<}Oz;TVOV#ש_\yuw/4$GG3lhzs}fK.ڊbnֽeV[K@8包ȳ|L?/5f A(FRkQ]([eZ.A/Aܤz-=%.|㚂ȁRh;"qSFDSI5ԝPTS !BO\#{$i*˓ߔcQҝc"qS ;GM"Ǚ1$-.=Tb,R=f5nֳ,@Yv-fEԢumkIKZʶ)Y[tS3^A~G"٬'ASu[/V- D>0`+׼ /zջ0|{׾/x֕ꖷ=L<7x.Kl&WQ4l2Sz =.E\A=%F;G,bVR9=Ohf2LMSK( eg\۹ 8aKnYOH1DP9 b.K|ob΋t^;O*xWDezʚG0 y X4!#. a"ov4 M#+ȉe8@?B}O[c(fTZHfSd4hׂ!xϼl!Ђ^` i h@ijN!hGJ?F >DMr+wX;sM|i-df<7‘!!\J7/"[16+qf@B+)qn8`U4sכv+Ulsw3I+NAgeeqTf ]#~ lHw^bdUF;|}h;@yw=x;wG<w|x "7u8N#C ,󙩚aT5<Ùţ%u< N^#:HRɞ}րh X3jg $b <uf2l5y7n6sߒ#趒hgs߮?3C:K2Jiz;&K='^*r4DTda;1Ԩ : ,.lB5%ӗ+J$a>&2)[0012$34C3|8x) nJ3YBREÜV4TdW\EWIld)=X ij$ePL؋ھS.?~ɰR\d˵\˴i[p˺˵$ 5!Z4+bɿ>5)˜:DGlFZ+9)(2FB2 k[% R١md3ux}twHxZuHHH8uTCc#hi[4c;2kdSۙC@1`3pJd3p(02!<'Ky\'Mшte]P]ug[g#]MkXTktXQXWskpމW#c4iô6A2 L d55):Q#OqЂ5_t_HM "a"!.xxbhz$ s1L"" H0gTЗ_dԚ8i>XxA;<=> (ADTZ@F~dGndFvS k*3f tN@IRP#'pZ(Qv!;XF:~4D^_`abYMff]i<XM"zFK^|LȬzw2X-RyNԪz-ΚcEZE&[LfFh^h ]Cdh j x h`krn(¢F Hʔ0,C>aN.i!3j:C5X@Jj6"Vej.jj˹fb*F܏"o'+Dt2j;!ڪ ܥzŹ#k@'XEEJ~ɌlǾ3^0;1NllĖeY "@B9FL64!cJ.x~k=!ԗ^*ီFy$vn> ^UEnWU+AY]OƜJ ^[1%ʙjȮ  ԩj.:_ ONX.p , S['7Gq:i?m }aծ1nR)ΪjinV^LS*硻jК8kl.ncctBKa,gDRω.+78V]7W{X7s9_:w:s?)I0`XCOtE?t8D_tDwtIJgtC_tXtHWFotHKtPS/uJHKuRwxȇ<.u]/]^]'0b?vc'v])]pFFSSiSlvjvnTXdj_dD4wFwؓIuNmvwxo;ss||HL8w|x~Osu7UI4ixxxxx'yMyxyRmN}}z/O/ׇ^?w?x?s>O7'\BvZVl'mkHٵ!ɈD܃{gr1S@xwuLLuLxLwhG|sgpu'}7WOM|P߇~P~~޷}ܟ|[p|W>'{>7uh+U937>k6bE@ #x,FkA~!|g<w Zt3.4p&i)p^߿}8zOƑGI*7ɏKI~1gN+I3WDZJ |y ց^q֫kK4h[]A| TZ⼋gYXQdi^5ժ}~a9Uq|gV-o9ӜQFM:maj4fij6=8]ٴV-zt~˄iAu2۾4[N0ކ%;|U2#;So~Ɣ8'RFB`'X '2H J*a>h6U]`fY>bh9ԈO,ࢋ, ePa|}GwH2]6dw\g: b|ҙtVjazyt4a&ܙe& v)ny'|s >1xew%NIוe re"dDTPQL*S/arM:*:Ϋkܺ뭭 5p"r!ZqWh  8P; -h D6ؔڱKTx:LeWo]tmskV0k t[lN 0l?p"q֜raW2^,],ܘaү4[r5#8BXL$R;>NSC-uVSY?_[ȸ#!GW&pƕԊa6XN | c:4ݵ ə-//:,:'/y5߾ n5Ŧ}TBLCLmڪlзt0n@71V`:̅.+oeZBSoR9HeU* 2S0Xl oDcqB1XD)`=a:ۏV.1F#YJo\T̊ʁ2-laR"8X#\%+[WFc'84lQ/ r:ԱyR3eO}t)&e2twRĺILB!&i7Fd7Y}rV4z*!F:E ,.), @!k@Q@50dᨵ4X @ICk餁,5aE+ Lӟ4@PJTW-lQ:5ШEyjժbժe6RlaI!LCd:rH~%K|nťUh,  `$c=A3yA>O4&Vh> QQc-X#ѳFhztRPE2jKխ^XlipyF]:QuXؽnvknuCWŽOzU/ uSO2S[ݲ{'󦓽3kM6Mi"2&7*=[ ģJTg-Y֏/D#&!% nB#(Gm-puܠ[5z[|FA`=dL82=-+a4$r1Zd3Ye5fe 뛚,m jȰ`bŎ8!drf2izć>X[1땪? N d_ _n:ժ^5Um|ղ;fU2iC?x?5_L:l_1V~C8]k6,pIge~l>XǠRZ:풘H8"Y% ׉e/<6qx]2\\&('Ʃ&+9&Z@)_[<0N>\:[>T/o[McՏ8#D o#?򋯈[`t>{ϞM?fk?o?DŽ?o_`" *`eEM$D_^ ]f .`b 8|VHC *'` *@ ` `҅ G JB:Р @ b "a F`2BaJ!:ZVjZ2 r!YN[7Eaap@U@@h;Hh@ 71U,fE5m[%b%j"Dḽ[&Zb(b&.n۝Wy]JPȸ8\ɉ0X EDqLj,@+ (Ict,!jH#ph#CH>E)%;`o(a 6^(@ |>4j>Y?=ƕ>c@@#AccB"A:4#U.6Na-yUøI 5aMT$p{9/B0#,E5:F@#4O66^#8D5$Rn`B9RB%C)<|F4@0@OcRC@$Pe47۸MN6ϺbU[]N+%``Wa~afS`B7-f0!1&RJ~O\5FXM%ZFe\M/E(@U,4%6%R.W4ZC4Cl2nV#gL"g8c%P;lDlnGfRJRenfesfs2l&jL"Đf eb5Ef G~_KJ~4 !#FL_e՗oPS}zEu[߹Ug|GbIK3NhL*KJoMJji%4P5Ge:.%QhO^ $9Z%V:r4P6c )Sڨ[>S*19ہd"x{fFVY}ݧ4IN-'Pq (f9)6}}[ed5Нhh)n11I`,,@`I*]vJbp28) B' .E`ߗG }Ys_MFZ$d \ Yբ&r̡oV+z#rpS Vzq&]9kej)K>(3dFn8C XUpNۈqPrkqHjq@vꙪS雀'@`"]bE)Yi~ ea\R~9+b& >u[P╲$E\yyP$Ă,L)̂,̂,)m)-ΞB:CVB,H-*m,&-,Dm>mf-v֦c} YMekjd}f5L-7r"}" !(J.k|[Gi6߆U e(ip Ť+Ik~e+Ynnn7"ۜf/RB&3ĒV6!b:f, Y8.ʎ(Z R or`& /oo6`ov"pگ0 * ;0c0[0 V/I ;$$*%a 𩲮Ȯ ێNU(N,^Gv'ȪWpGޕ֮ ?oPpfz6x & {: ŏ'qTf})~FXxY#fY9'_"M:q*W2"y񱹖[[D$LwFV U :$z + !ikaU)1ppo%+,. /Sټ2.׉ѧy (~!'/'gl5grc#&f|.î,ڧ茮biz1Lf[^٫=w;/f(t}:I}rF5KWȂ)|e{ven)\ڪL ^/ XC]4!j 2Y238/n>rT5k |0+sDǶPBiin=C=#2h4zM{.49"NE]汰}.i0kC&gP疪EC?lH/4ژ1 rA ̀J'sYXc-. %2N[ef1r8흽Λu j"+M`tBvYY٩tn봲fY[IT$BLaOxgy/aǠ܃./yc|Ly~.7|7F{}7~u^8y8.Qwc7.w|_xPxOx73]p~N7{G9yO~x/wP8xw)<`Z;`pk9g`909wy9y99yy ?L*/((Sz[czksz{zzz[zD@z@:z:z {;{3;C{GK{SO{[c{{s{w{;PK ^B/0$;&2com/vldocking/swing/docking/doc-files/dockview.gifu[ qDAݠttDBiP$F.ݍļ?p;7pi?wҽO%#RHC%-qas?IHȇw','oaO0T08]Oo ʛFco?G{1333v?'wGwvfvN,OvfNNOݿ /2itb c\T]df1~ҾO'S |7 e7b$Y{j,9jT7C11&^@7Ax, 6_b95;mG_.!COGW1 &`7A݉%ˀAj Zj^UN?Y%fwG`E%0\#50p}j%>5~kNb$" ~ h͍*ǓZ⬻^:EuGR2K"V@zyR_]nKg_y/X&@݄P,^KСLzߊ/ݥI'|I'2ݮ^~J2J{)Ynw|Θ*⢯5|&R5uճ^iKz./u}OYހʠvK%KDaU+w?|bzuOQ Yge>O8uhc[ E+ȏ; 5$>+^*}?We}Ӑ"rZ=7}YlTV]ipp>[WX(jxOI(dNxNp╝r(iJ=˩AA<|43 AI{!T.|# eoSd! ]!^m >|p"ňJw1_a熅F=0e>H*0 [Wۼs8(d@%ޱ{7s=ALa=: TϸFn[A jꥃs K,)]~%뚿>rȡ{DQq4ݜ(I 9 'S }OL;v KV\95V=;{]6E~rD`_f\8'g .3{߬$f9!uSz++nXU;fuRbۣ@yP dIh#RgI6 U\o*E{!LPdPcQ5Й֓H j#iXN\W|jog_5l5(z9 rC+L h8:v`_6%dfk_DN0Q59W^at758l=4,%)K=.gLG-s%Od5kΐk*j‚sZ[tUKSŖђMcޥQ]Tz| Ix>{oMoxTuG;olTWUJi%Ck6͚i%=>is"6/ur\0#i:կ~iQ̦rZR4 U̟ '{10/)[|ݷ6M˅ JP71&Y`4ϒ¾9ߗ< ^:WGU?@ gTǸ$m*{L[ufި; ʥyĶ,0$Tf!꾊SC00ۡNDq>,~U5a}!W&[*%_^gks=Ioe!>R+ZKYMM5CIc ^#K!'!}-ĤSkAsŔ+RohuЃwK&&fW^7J_'sV~ [ic Rc뫍q4/Ӊ`9O\o F)[d! йd陧%1584~s:zL㌱#[NZ:3j*|jt@r;iz .,}V:>{Xe<ucN/2ah&XT{cLr-,XMEz`)t!;JA rV7H Hd^^pi1Wq# `vx4ZaiOV~֔[?קn dvXqJ7K@|f?VWp*/`|tI3y8ظ#ɸoͨX '~}16BeŕU-A+>D[/:IׁfL>r!sLZ̳r1| C| inBB,x3}ͦ%=\=/i8&޿^%jß iUi otͺ`4R#;Dψ&yD4Sht/54}k)_W; 'ox ț&ټ :rnoGyEmg7\ 69-y%7U!PVh 6.T Bz!ЄՁJ *++Ƒ ýU]G9YME”AUE `]9jB;B}cȐØwA l5v P<r-1ީlfPz `ir1Vof٪OTBаڂ6_h;b6r: 523͚xl,m `EA߅-hTaq5Mg1!uXOǚ&6:x}K~PcVs0w6𚽶MVV_o%();tػapJ"I ́PmjBV0OUh.Z45v7<ӺTycl{(ڈ m}E?V>M ͐~Q|CgˑG?Ұ, ;]ӊ= zaGD{ MhۓM[ZPNޠ( n_wR9)DPq%Vbx> ;ԇOi*0Hi?b}*TbxLA'gE~9`/Ni`jDUu3.}.O# ba:t 'f`AlPNF y\y^~0 *n>>Tx `EE733(&oԋE`d,!w8 <}?O1Ft 9z*PLDΩE}-ˈZ@[}46\DmGH/xF kG_x#>rLby|F:7[791RǷn{3ÈF7PG=X^ܫimQ۾Fc'.Lt=7I*./J( N(ڷƳ ] }f?X޺~ج>2g#^8=ؓ.D ɑ )icr' ^_me򸸍93i ?[%7^G*Ԭ½z 4)Ie4 4nT~X`Ѐ:e 9XM4ɽz?q%{`6&8 6Um"=cub66RNA z"|~BA 81o#-9ax~[o8s_ah`?qjA3Wi_C{Q 8^Qֺ ߇p۫hIkaյ jkw @ e}n}dvJ>/un-{a4h>7jf &K^"bЗc{ h@,N{5CG:C޺HMv_I n\~9tYsJr}|M?!{>Wf {!hqq|y1D-E7oբ&92ݡ5W(1fzr;33cqt$[b Zտ`=ɯ4C~_7pD@rk_?pxq}'[댍ї=3,tJdiq]]ocVv߮-toql;XNh!E_+݅ۚԆD?Rh~3D/P,fn=pl׾POg!_3ƥenKw:hs W.lH8iChW28bT:Q:75< JWv( G V@rVTqvޢ! s qY~~MY 3m`G_rxDJsuQGMb FJ|hQMEXh<>MrLvqfx6=(R e_F~7mRnGX)&,B6 %0*j=m^~ZZy(]t/zm B{h؛be$vWEI emL¨X}wܘV_w‚[rŦ''$fa9tiI#Su`ŁEO@vuvg"f38mN5h6B݄Ⓝe4kf%1hsn߹C+L軶A&'篹Ǿj J7r_)J,Se,|e{?LϣCFђi'6m^$Kا58rL϶$Ul]9Wa_8 Uxn)_Uj~^꼜C(.\;j5ӲWaOzWA#g\hƫOFr!F>y+wCXPڲv~iٶzZa§N [Cyb5n=_|7~31ȅ2{{.)$ -z{3+Ic;+i6;44z-'brGeN󛪷gD3c`K521߇qPel bq""~LSu] Yld kSmW(E8,ZQFC>7+f` mʭ0^7ǘZu\P)vss]Gˤ> |Γ᧽N ,,~*>|\Hm0t LoM!9Λ#L ;A$D됬q2O({ *Ouko쪥lI0G7 " RUAv iMݺS{)&q&S*J b׹6u87C^ KVm#걣S3SC=?GˍGûQ@!G,;zx4oLSe*ym:sJ`j xAD&zȒȬFo6?;L)ksib}!:o?6k| 798;ABcmm7 po{'=*7}Uvtz,@1xsJhPK ^B!TbT0com/vldocking/swing/docking/doc-files/hide16.gifstL``---? F?Yt@9'8 9d<6,8!s cΊYՓd6\|pOҴIBhl, PK ^BJL:com/vldocking/swing/docking/doc-files/hide16v2rollover.png sb``p  $?ORlI. Ap品" 0kPו*'0Kz@ZOǐ[(tDsmV[1/7U>fon_J0s0ݓ^me O^ZǂQ_̇媰)mûڳICfiY/r0>)xa/ k^:eSBPK ^BHiZ4com/vldocking/swing/docking/doc-files/maximize16.gifstL``---? F?Yt@9'89d<6,8!,s`anEF}#+6,>'dveᢓ"ش`5PK ^B^3(+>com/vldocking/swing/docking/doc-files/maximize16v2rollover.png sb``p  $?ORlI. Ap品" 0kPו*'nv.!o=lWfֽO#_ο; 'ಚ%eaƏGAKբvp(q{d[[gs,._7G^keۚ]onLzd*:&wb;.4tW*hb{ؼNeVk$'Uo~*?s`Pk[(d ~.PK ^B8 iZ3com/vldocking/swing/docking/doc-files/restore16.gifstL``---? F?Yt@9'89d<6,8!,0!F>I+ GGZEYذxiZNB^M?'6j``PK ^Bx+56=com/vldocking/swing/docking/doc-files/restore16v2rollover.png sb``p  $?ORlI. Ap品" 0kPו*'eY@Þ.!m6(4MpO[42L9Mˏiv[W>2!w7zL?կMF:7sT,fԞJ9e#Y,ABL7--ifnplϻ^|exݔ+={ď}_y-}f駲oE=4/;Y{7^E _̎ɳLG>Vm|tTh[PzeSBPK ^Be9x]x]1com/vldocking/swing/docking/doc-files/sample1.gifLLwiqNq ^ݥCŝŋ;w9>y&;;&Ɏ9 Z#=O KK @Z+Ht@: =t0@ 2AAW!U/F,D i2@i A:H #&yBЕ |%&T ---#cP& S] ЁGu@(C ,K% `n8a0 og0Rg:W# yxc xxDa"0HڛL:&S i"`0`$ff+cE։`b.yӟ(EЗI閕 |4HHHGJtGGtPit?𡚤K XuZuYM#%֣dYDxJ˚Mޣy\R(}d)}ϕ摣摇&%4Rq{@@GhZ@DDCG]Ձ`=euuu:0 G@= v S|ze=iU-C`9yQQ_MOAގ6_AQInVDǠ\X$%?0FjqXbG#iTzQi֝dVj2YDUږey֘^՚5SD5+5fuO^N+Vs M{2;Am\].|zC0)zýA}G-l!ErkֻWiPJ|PU\g :g+]mgvV8Zwi> +C7=Fqo\ɡg<&zvPbv7X'p )B3s@$;uYp\0|]p'h(&>S {fab43\O7Éȫ(ğJdWJSJӔR udeDf)y+V2ڕ+~YgTE-F|(|fWڮ8w8A4Z4C".HS]dJ;ү̼tp/f2Le _|eL~5~Ukc9o<;och]sjZĝ {kߴu^q| uwX=beEAT*][(&y35Gryc+ wdmE{5I.OP ݜsݼ݂wOG%\ceo2*fWKVmYj`sH$}ld>k!a6|"1@3UkݗUNx<1-fK $?}($L9 M@"5a_w4#ޏJ< I<)\O5WϷ4!_B$-M;/ ._  QD"3(6vbش_b+ ϹqjD. ܥ*¶ -"͊YGjˋц{ np|Z7'EjAFYhPHAC$(w?=6F*xKKy$Y@Ƣ'ENZIhe`īRqJ!dd~Eu\Mbw.qjx Mϯ}FȚט|lF?7.!.دTHe9"~z8άf]7yZo]a1K޲j=J+~i|kM/+ lM&qfKK+:WWOɹ+eڑ=c1qVZl3\}֪9 ] 3Y#|)M6_d9YcBZ %F1"e]LZλPx]>UkL/ yevCkCk>qcő4"~:Y(SjlرVG-Zr89VauZ5km ^pg' ' pF4CVN(@,IʏS߬&@4vQYlv7$k5j}6x~,CjPr"wv |5dkW'?π[kި΍a1+ߦlqDcaX601a*{{5ŮUme_>imZ1h?v/Tn)߱eU$ox޾m3W]|ۥYvBGzC0ek"7: &Mkf3s*)zѡ/j$ ^s/HRMSD"J'O9|G ?UYb`! ;ܴaTҿluFmO˃koNVAGkflKN|fV6w;/d3z!ligq] EO +d"{yގھ CyGbKR1=Fr#da :lgd}roy7?D B@sVjv2X-{b̪bLY:H:ɭg2̻=QJgkÀ}s8ا9o_#"ܺY짥L0DӢeG[J_wlN2#4~1$xP2{}w}"zP1T!,v1_|y~%gDyaO$*tC#CH+tٛ@1;!wjd!DY|B%KzdW5F%>2^'=>a@:fNp߈7Z@ZmPUATK|T@CMte-HoZ4=}7@C7ZYB^K$l3$ fDwn)f:B(p/{d^b>wIv?R du{##=GolAVlBlzJyݻЦʸ6,م\ufĄ̒+oAg&ω.[ vq 'P&<5*/ Fٚ$E(R5i&|} mlQf#TdS1+0r0:hx||P '=[y ;x*H*Ajy;TTw⊩i٩_S *)> )J!?ISLJcM'Kjg0K"P;IiJӮ"{L9yg+)/̛'3q,C#6 WjZInڃ]G~e~\փ]7mv_[Dg}(V7OXe#FVRrl25"662~Lח|8hh$41 zfEF ³ʛAEW'Oe4dU nU NY <)\ڃ? // vu}hg-P Oآf{4Y^Y\!("\i`u5bm 4A1rB1rޮCxP5r*RTWZlj(ZJee9e:e%ee&9eeJ2krSdr_Zz@oNhaZEi?yA(y%<\22"̿2Ŀxe$[̪ (š*5*ǿ ɿ*XTY[9[6ڂȃj1[\ȩ*"D5Ciza+iU]lk hi"Wr+1$FXV^z3zkz]zS[ÉhþC)y w s"E#X#a#z@#fn#vW#z#s#3>W(ZMu UmRq\'Z Ka[ Y(Y_Mk,#} Y:H*x( a(ʧF(R(`mC&-X7`3CXa E#Q~ݱ-DE @*ej;!E W ۯlT3p(Λ&V>NF<>-+D. y6rzVfy$J2[Hnx\Dz2z{yge]/EXaa@qniM&{-weww{[{~StEwOA5şKS5 _T-FMsΪ̫X.ivGmD^765qnէhgƀfДhzAaCcC1C,JCk,C6ĆKC·#MGGkG #6w128?  ] ``%~`wŜ3!F|Js~=MB)GDbNcZOOz?rN/+x Lr*3 BtN/톀wIEz< (r_,nۭ/}bSFSSs )_5a!JE< te?ɍ'Y x-ogy?R7K@5Gipsue.bP|>hc8~\==4}62?79'$R$Z`V @UnDV2CnH [CG? Q s[*LLlDOF9o6a"{5%>(@Y.5('ͨ18]ӳ⿹5rG7bVUω1b8:b7qy>x bܩQI a󙒺)ʠMjιOs-u55õ΋ZB\3~ B a6\.3d&9bf.-f(-q8 = =_N&tYr},E' Ejx&HzF3EOEh겎f#ۻ.0awd/x..}+dC..ZlWOyOzO OȤOw_eWmi_z_)_ezOw_ lxs(ڏ'~=EV?03 Fn㠔>8,;^ۮ[}?[4,:֋= P?/ f >K86> ?N>>*Khs+qOk.!}ge}\g=YOiGYi7igop~u,LBٜłdp=VM=j\|YKY)K6C_ȼ<݇wjP !4'$÷K^(i9U·++ٟ(45*7K5 5z Rd暾/ cV4VPFzV띐*"ϬwoDg{{{C{{+Dm#$]{{3{k{{s D[!!8! m#n"K?"=[q[<2"ګ>h@͠Y lcac#౤4)7Ydi)oe@ee$eeere2K:^zkވ651o{a,sá478jpT 6nE#0ɔJdIX6 QgQ-7z0)ˡp;@5q2<-Â=b>zmDkZpT23u6d4pܠ~LP'}q/>1jrm{ D|4*dz/{\iz`>b{~V>ilrIEFgpv|TrHOr_g3!`3ht ~7-z_9nw  a_QAfiJ'ا%~Ld>L`επd FN@APdI9 -M}ѭvf%0LYbQ?3AgwNWh{b;ߋ[Τ'ݺy*(eIL㿍ϓiS6r#]F_yE"4ۡV`FbC!=ﰠ^LJM47y u/"Y4%I^x 53JgqI BsJmQ-ytuoKK,}6VT*6`G-¿8z:ezzkъ!1«o &="_ʷe֔W=S>okiM]ꑹtK1{….8w=UE4 W2HlqI49Iu|uo9aN(^#{q_)f!o9lD3Y~sVzŸ>v`U[rL_?o'zhS`@Wkrߐ}Z܌^Wyl񒧫 ][nҧb??i<ב{l!ğ6tM+[OAqn]4\ (p>7b'zms3pvFP:푽@nD>zZ+)V ItISB!hnE >~;J `aqؼ [΢asz֔hGGۿW[h?*D S$K5kt9g4to}o0Hm<7NweB*Œ>Rx4.zIL?#y^ 0b^'~2Nw %*ƺ3 QZ(-#o%Д:+a11yhw3K9ng*r"şmn._:zqZS9NKE [gIX.sIR,t0|s'`;Z\uUzHT-~UZzD'hl;ArƩ!bnfJEN5set>NQζwM ܏ha&UR>!jgsM6Lg$FUD22v,p>Kn#_ЋD;d ԭjlmhwXZ$.tAM8,3\JkQ Ybdw1Z3bOX0 x$P]Wrm%i{*`K79W E}҈=sPbd^ifZA䝧:ɠ'.SuXu~3[jtqӠ5'EæsjEC9HZhG(FmivAhmu+./T5e?2rj:츻[#L{cME[XcxX[JMWJ'6겙y,$]B1Xv_mwYtDM|Xqf^47)7}Ɇw=)è+O7rn(p/oqGo"Mqc_ >Bn9 @ pfzL]|S]:{hPbxI$kk=&e 9PɞFڰK(r"m_V3G˛=^Ͼ}I HiT ΢n[v|?#JN'?ILt":f1h{Я=Ğ*j9YQP|aϕE)~lej}8*)-6_oi@h=,ʒP$UV`ɸy|\,9'{cJgׄH$[jέgщχϒX"i?إTj kJI~&V?TB=F;(%a!i#,fD(?"kP;"`!kr.k"k-gN)g!g).gE g4b.ުf sssjs9#/!!."e$$(/1Lk1 $!|." VN9]+' %/dj5R(P{u,s,>B!\B‹B2RXt?I3Z3s+/*QDr|Y:SbT1)6*^)] س"\J DDӝRRRiRb% uϏΗޮ ։^B4_i__&@*CRʬ2C*d"+^x1nը~omqIa"UJ,ڝAKLVGDoqi)h|ꞌD” ty4fޢ!ԚT*8vbjQyPu4}r|44~2cr?Э~;9s~?:ut3s=Z&<$W<xԸP{ݕQǽWGPTJԸ@{hUGŹJohEHYu2N5GLG$qjHXgZUH6h8k8|xHS4ϯ,/ؚI% :ZjSS:Fl^ _66AFl` nMNc-* bM兦"́R{M ʜmIUOsAJK:SZ88KօH:KóR:@Y>%Ly Y͏:e:%˟:&D)]sÚn?A GZ+ =::Vusp8,[#uV6 ͖P{{BVrQ͔/G /x[/D ,өGmԋBщ0v_I2j6ȸN;[)4/y}*i%o>OV?9~2\K~u7^ ut ~⬵Y{roywt7զG/6c>nu5pn'l1.~ymd4*iOK_7J?0`X;j4T1e "[Gњ3&2191߈4,[./֑-Smn67c6ϭ76.6?m/wğ bvWey!e+]}lc|ǹ}Z9Z*h ok4Ϭu9൮ª 0;z?42A1!`2]opw̬!c1-BG2q$_RPw#w~<lc1YeleXĖiXS,C,QUi xĻժ{t=,{B\휦\&\b95Z$w$63vʷD rΖ;_$-d$QlTM(QE۶>/ih-y[xXq[ '$XsQpYAt%Έ,%%,F l,å̅prF$Qt3F,Dm&mV&.6G]{][eV+{#S N"[ipcO]; jKKs5mҔ]bq]:=`]dJ}!}B5bKben5Byr!8nǃ_kpX|Rpoi?}bbb:IlR|ZKleWB`5>LFX>ek]~Pq֎z=Zk|FPuJzy$Bp|PG¶=l6{:彣CBͰ1MD6.-1]WB福zO:N_Ϻ{/*LJ $!G{\6\(s bRþSSKiNA%©u><\vԱ5dhpeqS*庮r q3\3O@Q/NP %.ATk Q-& mgBf7"7|o\j&hnv}FF$gרh7sKk[9wëolxNkħ67['P(YbUM;5+- ɭ(Gܙϝ6E͙,́^Zey Ilc⦄[]]‘ݝН!͕b-=g'LLKC'KCNٕQXǃR6.9W%30^wJK >utUFSXo4IpE%qsq@{ Tܶmcwha5{Yhy]`0/D{)4C.Z7ě)/mn_++~'ڮ&Ҷkl"X;_1w cdsߍH.j1/&ޣ(~Qx~\K[-*ݷ (G6o }O)ljo{ >jHd (hzj~lm hV#x o]ǔu&M޲Cۧ=&L6Uz-,*\,el{`B'].!wr_gC鑢 B_J rhr;1"9cËO~_YS>c //je޼<|ƿ5isCsUU@ >>ŗj羼 Iv)qpEY7Řa  ?vyJ9F),Zzm٪蘨(I_eyº%Ziߛe:#J~<{h6%¦lI"xb%$ִ;s*_nw0!O b:IuRmjO5qntҲ.R{QJ~Dz˺IrtH!! /'}u!I˃%fhZ" |7w^"cH^)C2Eݜ .v?#R4s@·4->7Ywd&Ͽ#umw)bGw"0=b .+R*-4X^$d[-QfE1 Z[$wgG@0#t4X]0*ۇj`.VU촫i2JWNeuTՆǮX؞rL* u䄫F;f7@2aܮEx#m h޺A.ݢƾmٰWS5wc6KoR'\C^Xcߏgݝ5 <`<l:,矗7t ]Cl{ߪ n.NFEpLpV :fcfCx;q=;jőbEڧ51$KiD6jr;'A䖢q4/g݆+lg7 k3V{j9dXgBʵÿ=A%H-7^$c%+[7)({Ա׿PCD н޴BSz^o&lN㹎+l}&~YAz3pg*[b۫핝.[& T>MC c[PW+BߑZ7MMiɍxUnwÈP+1`cǯQ؏G_&. Sf4fF,M7Il0ezKO83ȘM,Ymj@-#cpן!puSoXVn:Ųe3.)A\xDeG%_:ƪbKa,l?yDqtPM_}MOl8qVyNVT')7sڥfΌ6Z¿r&lDW[=o2<1f<5~XL}^+Hzh+".ELBγ#]ROULD;$N}aZ,.FfUSV^+橫P~ϨL+\d-&fV=oP!*.zTrI ĎeOJVy'l*MP6aq6gVF> ZL:-qpk nNepzRh#׈5w*7XSC&Z\=WCAg'@[SqԶV r0'{pU^0>A8bqm44.jb3\_[5t2y;]$0I!Q#nߒuCR6%:.Z6?t9_umBH\W Q%"w0pm:EM\ˌil(4FxPioS$EƵo[BD&-n[I_v6D&`-|"F_DžES{NBDKzNuD˦E^E"޵Z&9m`z. h[^.ws7^?>ޛ>C)7cIw?R3v#W&sjB?'z1iB ~\ȇ>]~oxѮ/,/?1<ů9WZ~Q^?htYúYAOFtp%ɘ*;n̓N֚EDK"\.K+[J^W{ul6 ZBZ Zt8T >ޞ2llZCyCGsYIdw[YGLOn_j xj=_N~m??b"XSbS)eě_N2 zps)iӜz\[Fܜiu& { a]:bzj  "RjvEev?3#1{3"%v%5eW {.;i LKJNu@ae2! n K8-5w8[ ?W1A. + AbfozA]b]uitA ,Lmq\+њEԗEKxvE> 3H[~203X E Y0XY .{mJq*kh z-/Xs+7A[ 2st)s8w#gCAem콋R;i+] fPP8X#̗XSXZOQ}1- Ge L^Xm%͊Q1Qʩ.Ά 0 PHA|2C -l;՟H3cA>[E|adڙa2 锑1pmQOGD#.m+qCOGZRǡ|7J4-3큥lH,>J6crK_bsHG:ɶ eQي~(6L R]nED%t7w'&hy0/rlMtbdڋi0jF[1V'iBts9rP}uE3knku[|e5ʝ6kVnU1syf3Smyn5_۶ohxVWճOWT'GX*O5^,kӒWJ{&B=6eퟪ呢UeMbvS]&KLS0LSu9kk-&!aEenRSrNy{q$"|}/ө9]к  \~B6`SX*9]i_9u˧Ӱy!°CoJVxz([i]+4ߙ% ܩsyý] ^;X][ny܁N9kZ&㫮I]a9G$GښlE!9dj8!J${s<~$qx%8va)S:<9^:Tem֮͂/1<.#WY<,Zpr˵tXfR]\^{"_jY]x;kYne9q{S[Ww^)Bȿ"X49*$趗pu>Yܵbhe.TF2rz2QC؂ߢТujÏg冋hX/U=.M_8zcƊhU#Yt~fm\|֏'=Jp ٭|fSn2v%; wyϮP::mVˆ`BƄ2@w>~>!lc?&sjb׫6Ȥ_Q|䙥* >Εff.,~‘TZ&!=\ N//Q:^GqG+JWoSJ|ep=8pT)P_|E`]wvWs^U\~ɚH}ݲ6s;Z?3IsJ }V()Wg?*Jt]niќG1NCISszFdj -g[]OOʅNM(wŽZޝXc$k"pغ[=d(\R.dF.^'>rs%}5Xp5PM txl ipOn>з* YxE KҘphEwZNj۬l]5X%vT2[ ZL^VR빩튷`%SfG[+ [[ $6{\{߁=s[[5So||'BZdS| `Vo*Z0߉6& 7+\yHDS[X{ @O]f  ybS9v$B ;Tgtd>ӡ.u-`oIƳ_ H07YD{`ۛpmWFѭr3 S0tCΖScHw93x~9ۄ9L^th^Ec]8[7߉6W x?:7O%:y ngCMy7w9w:]SVx# {nzc'8+;SPlɩFlk\*y 4G}v|KRi}$F~zj:a{R9nKXB,)цrEn(czI{0 Y2lįhBʭ~6,{8+VRGXSYXe4N5d}SN`S:)OHAVpeTY5Yޖ 2D=vwoDksJ$^Ww]6$ ۉ9Z;u[ OQOvXnY%ZhU\Ehq;"Cg~yiSFڡdQ/^Eex>ޛfN:옹WpVWQ P9*/<6QjsIkoZuArXe!;Ϟvħnzu);C/e7']Ez-m;_ךgn?wQ^ wM߱'7՘xo:rǕ7u`:#= ~ٛ_紛{eWM"(}D迪o[JˠyL(9+! f@I3\ ɧ:_LӌG"ml cG8E#DxS!'i/r߻C2e=suhF22p2D]Ę K"HEZ}}r Cjb)B;:{|!fCWᰐ$!==!qI3I,FIed,c?iqw`## FzQ,.6 TLA3ZG\u-3O+Y~3{t"K=#624*L$;IOZz$bN$R(@@8rF9%K{H\>QvP C~2èGͤr,Mh8ӑU]EK:SRJiGWJT3Oܧ?9J=T?lX0²15*:n4)*Ӭ)V:UX4#ESX25gի߉4Tejst)TUzm`Է-ծMk5kRJVU&[J6=,NyҝYxn5-Th>ë\W#.cA1 bN׹=l{yVMeEx'[P ]mxZú ESlk\/{˚7츬Y7%%;Crj^t'J[EY!WŇ!ou^?GD0>}_֊0^quޫ˫ Pg+*9TMCǘ%/d{xf&gb$ɔr\c.sr3>+G3=#&_nXjF3hCkqLZ$m: &IV);t/gF{z<5g0Z֟je#on1+dI_{{mf|ۭ w^ݐre {S6v]9ƹAo$wkZյN/pۈ.-o8k07{'lx_;/2W;o4Gy󛛄)7cM梏zkN2ǹ57GIǡ>yONhS.wwY]$K]_8kN<#߹ܫ%L~1Jڪ1Anso=u9YNaVyooOws~ƏݍDo_m+i+w}{nw{!؍:V;ϳݻi=E4Bw=J.A~wŽڙ{?<{yǶ [yE/*&ҲKЏOᬍO{|.#oSRh.n, F;,͖(f\0fӸt~0l譬`SPEu +GtpN8pXiPpoo^ cPO߰pP0 /ެ MHn4f|K /. ѐѮƲ)Kw.,Os /wK[+K m pkfpjqQqP )p~1ps ]ggPg {c 5Q A _J!,ӱ9ѭOXJ3)PLeQ,}1 3! 6.d2"}v@RqVmQ !c_j sRmLRr arQ2!"oP [q eHrr'/#r%e1-{R i{ M"1r,+;1(!L-' rϰ,? 5/?+G2/g*C*,'y+3 w" 3/O M&(O4p2D+󒁊r1)W1y8#22 9J3'3Y2c0-s-U;lQ221w#rssTJwTJIe>ӯ2BHB?TKmr0CUM/T(tLEHHe2LJӇOJm4NcdM7=2PKHS!W1O )F75MFSG-C9TR1|IWuKA:'*7ųP?BUTT Ws}X)REE/X)YSsMMR$MUNYOd1VOUZ\WHYutC^R]?R\R["RU\fECSEͲW\UPm_4T1;X^G?buT\a5*+sV9U_2xUb3d9/YdU7f-DmN+fuZ];Ld{Zu;N?uc}eKXqPUY\Vd6l]6ieY4+)J-lg/6RVn["YhGXKveOLuj""mg3mou ?VLWVO2g#$Fml5m >qi .6smgArs3UorLp[wb=ptHvUkk J_7xGvUvW6kyWC7FBy/nնxMSlc%c#s)t6h5[;w[Kvjt 3yVjrw{ojdO7֖wW8y{uksw|C͖vN7wtjpδkpxw8qdwfy5!V^K}^_{AE`wRqwqプvpd $Zel18rm8o8]s]Bc5h븍}~g7}4Wi߳v5WfS8c8M'(<޸#oi9~\8e#YaXQWroxYfAQbxH[h,Y>R?yeE pMmys]8eg9E9KYcG9{ٛ#CO! @Yٟ9٠ zZ#z%):5:yUחٍZڥ_cZgkڦosZw{ڧi5ؚswkVv!A&ZڪZګzVD`W~Mx=ﶨ}VaZ皮ڮZگ[zc}8w/[%AA.3[7;۳?C[GK۴O9646Gu*v{۷[۸[ׂM,Jgׂۻ[Ǜۼ[׻;ř5-^n{yF[d\E4[|WHֺmc +e-Q~7\Nh5;1yyý68c?ڣ-g|q\+^}QZU%ɛɟʣ\ʧʫ!A˷˻˿\ǜ̵6bMBPXBiX;Z`/#|"|`!*[W]=%)}+}¹o'jBO¯DOSIb-\}a= =<ҽvݾA{_I^ѽO"R~# =_]JzH?^C"l6TÉBThq"CRh`ۤ줴'Y\ Jf.cʔ͓)a&|dOf:z ѤOJ.ziUXZ ֩حdj+ڱiמeVۮs֍ 6ۀ(M "bTNn|| C'[֨d,Sɜ6Iԉt̟O :J$ڕ;,ARoㅻxu_kwrś\wJ70 '& Xq|d;<v$I*ՋߒجQ:K %MmgUUMt!(u ZuUFFءo\`fbVŘQUb^utg}6l㎢37d=h 8Ђ"N$KJ9B9RX~y ]1*iq}|8sYdBH'C%o9٠U&r (G{ag`ݩb | jJj*(dFH${y;&Y)I,;, ,+6l.+m^[m^vkm̊K~{n[,WڕS!eaMտ oؿr +7,qP*JidO r"Lr&r*r. s2v(o< ; bt }>3t*R_uZou^ vbMva 'GWkсO^&ڝkZ]#2{|O||/|?|Jܛ_&Q2z%k\5՜~~OߏϿ\=={ٓ=G%{;nJp/ jp?p$,61F0B ZBA k(І;au ސBXD H$bD%PL*^qS|b !qcHF41l\XF8Qm9汎{G@1" (p*PA HGBR(`A%/iL'%)iILdA'5iJQf(KIT(cZR%(U P%.[LZ2̴/IiJaR֗an#Pi=a^hY]fא$aெ$Kڃ=]%zd'R{3%Q)jM%)zBz<AM\s;Hmzԗ9t:ѠWVX ?ŝ}G߹H.24L EˆUFa.W|w HGY{h YYgWz-CWr8NDyhV&%F+kuc=+wkfgd L ko& .}}8: 4g#$-;c}4i"-zO~#P[X[Ѧh"`*dH `TNu lZ}dnL~U-ZI2X\p]@B).Q5W(]X9;UHn7MWoΞFG7nͿ"8L)sb I"‹8ft^wKH3 {TL̄JUeU6&0sjFUĽVk% ^盕i F88L \|7ui$u\V̙? zx!";¥; Syc.ITؓcyk)AuSdWtcg!:CI>}@aKyqU@8I??E{;_UKζ,U"~ܦ%=Tw{RaLyi=fb Apf&(\A:zIç^|?3lQ]~ģ)r;؈ٻZo yDZAiF 閈_;C0zM=)~ Kd77̩ H?KVx0_M+%${9 WЪsh ߯$hO$o+n[o'N1w*v;:ClQο|s UZkҮ{5 /g`Q_>@:2Q Ҽwޜav ywOǞSN?0ze-2h59Ra3s#,zYz}yy^ !oxV_tnhvc$7G4B}^}QK֨?柜)xs"_a:{wةj{M⽜>QͶA>2>`H hX%ݳù͐T_䂰y'KyNڴk̔O=6Nx8>x@ ^/7gdK5liڝR!y ΈrWDkf]P!AW*AXPZ6z@&?1΢fڐ|N^H*U J;PR_ cob8ڣ;i dp-M~Nv]jrMAғ lZuѵf! J0ջrF~s+pŇrY(6ss: \bH4}]m<\{aDzeiFդjt[: Mb#-+==#4o(~(E"ՕGe20kocY x^*|3,UxۅE hR /[XջQԚ [v1@k_BtvR@>M1|nqw:&O|q.n,b$z8̞<:{gN`xV7a;:dE e/ N]RXzrl>z8NK$$'ߓw}uzTJ$`w;1^LY/WC!c6#9Ҿ9j4-H@4-D8G{9Î%yĈ"< 8lдlflI"oZ]lÝ>_%y&jR Kqlm>jo|рq,l&񄽩f4j,D4/4e[1AՁ%qx󧭟a]5;_ R$&3;#<!^Gn?i}oj D)άvH}?@{*Ds(vSKZW8~,\2; 0I&E0$f4hYCLcmBu%e/A[uZr49 {L=*زc"S)`Jbt\.^ǢhaR褭ԠA\cG,WzOpLOKyNPŤ/R( uؙRVGcx q# QV2`v ۖms'a싈<@!R̦D >om҉y)C9T߀\J^Gʓ$MgWPx5)%Xo8Ytnlfd?WL;1jhq% Z56sCCB?$K _ //ڒ)ԥ5X ϚMhL=e-ݹ + PY}p X ئcC ŕQ"/x]e}ECN*n跧4svx}0A{XJ6܅Ru=N@&n@7^6ZޯEu Eɉl7 OzХS0`"rtRʘ1S;Sl_]iڤ4x֢k}Zke)%ztblT#R0kV)] >YiuL5h%,Nbh?0>BK.ysXKnǤy%bK[+}~l9 DR+r1eM Q$ΖTbɿI?]՗T %e%'`\J|R.ACRwIO &q5rHo٢PDł$iE\PW]~` .M f:Y_!95sǥD{,x:Ty)xq./:}[[O >\YNUtDt wz F4I"Pz,_UV#^+Kis3?\ QŎk.1áҾZ-__C!|>?ntYZ=-SsYit&$>\l:AD=ĕ\"2",ʡ/c(}8*.A䧐f`=er-]1@p2ϓ-D< MS7E;ɂ3'Ij8CH%҈+LwϮz^ʔ:~GiJaԩ*{xQZ_WQIdkOmͦ"(f Dy ")#XٝniAYi* V+.2A8Az/>j;Hj6V4J>:Ĭ`r/z?>l*bUٿ .)_EWڝ;bE{=@es{c[xEƩi>R+rKBgI>l&{nm$g%a,-$,|Թ6]H$1CsoFLJH3w@jD@9DRldW! "ţQuv_̿gXG)cIF]s1`4vGZáG,qD`uN`*"ןuɇ,%o$Ej|UktyhYy lh!-[16|Iz6/omdrKe,,HB K,?`а+hTbw|,1˗jp@k^ʨ,~NbF_y+VTk^ oX=o˲Ao4ON=a>q-,Ȋ.Kefn-iS)Y^܃wϾr ayۘ>9$;1x "R9s+1 L< ef~)Q1:qކ23fAХFT`{`~iKx7sېf엲mE`8_&UHHdr1uQW8{[ޓ3bWW,ӷ]ci.}8e1F@5/{#eGVle}%óuVGoMUbʿNEjׅEuS&f(l^֙TcByeP*BrU;7fiԭxcg3=af(lr]HA8M.Pha 7!qOe|p7K +_xumu %c$/GCL'lrbǤssqpA0z$%!tiYd@,D<[5Ĥ%"`b̘\D0Rq8fÖeN_6Vu pgnG2٤[62U?$FܶzsoXMbXϖj?a6:CN̴ix9^GS!Ϟ= qg Xd`}`gJ~]s'߻!םwnF4q*0GtKV;=ab9|-뜮?R'(eC?&W ~OPs NQ1h+ lɄ jĹ%(u@sKntkqP4>cAptˀg\[oNs "ep|lQ2f%Nx,/ nں%KMo9v̂ ze~Hg?Fs*%B',:b77@GeHM"~pbPlNr0:lF(ڎ,JJjn #H&er*Vn2s#ײ@U3%+f٠fȇш~'4+I0 %zIL<`~qWL@*XՂiࠢ.5G_m;6! 9KP\mw Á 0nK_36Y{?؇ØOdpQ7㄰ nJO~C5n1W}P/ ў,sNMdIx ԣ ]9D8T,ɘbt~ݭ)? .;wwwHkeLQ+eGl7RJ8JHYi Vtx?5<,0=4f2b.[p&BKdih9#g-phf;No'ss!u0XJk~8 DRkr1mp;H-n*S!lGA໺/AJD0U %'`\J|. AL$'-s (`gDxUtF!#ԀUhnX AK(S0U]AI&¿K2aK1@NB)r]K)b3qa 2W@cJ$^y1LϼjP$`MAyvʚFԧb IWhUL&0%ЛQ!g.e}QNS< D;qb#'Oĸi-A"?l-k{loVi"k'V<K8GЂOctff:WzwOg풮>IQ+U*pu.+Ģ`()k>|A:AD=J~wnrQX+DhHsċ,`gH¬RrB~ i!yY$%05TE rEARE"\)f1ʩ#NJNDѮJFUu rRT_gJLQ5`_\.])o舙ΥWzU3"MMP!K4y,E,)-BʨFg%;%LrF{|)pXDGyco!Nh"nk%5R4W!fXb /8=ͧ[UM3{SBVxN l` a9XSIu2x좠Cb>85

W]~IS}[|D8L|M9bĭ(۞3[wTʟ ˷=4M"BSLPfvڒO2gFS8w:U_^QO (ib@ R9NKPڷQ=:]wM-:*N\g7gEݒ̗Kj&6ju.SUM*2VS5qm)Hؐ$~ ]A dXH穣= Zj4ը K Z$w UV| G|]Y,@ 6_nSx :_.RqdZ>:S!Y + iu|>PHsSOA@5v 6Jbsd͟3`e?ej+ ,L`ìRhR:-CsPЙQK$ͬ%vF}:0/Y_AcJ fԃf cYw;T+r:&SF.@%yWLeֱp (cz A($lUCxD5 ׸irՉ-Rw*W Ȯu.%T^ԟui?rrik˗j-޽̙ ̗ 5KUYUqS8E 6h5' S 6h,ᛦ/P.!Yz6Hz&K[& P' ,'R&͈\PK ^Bnd U0com/vldocking/swing/docking/event/DockEvent.html\o8WKywh{5{y!vZm5eo(YDn\ A573$_:ޟ7gK|tqFVquvN#oP/!c8p+ Y8|p|nOl ޭ3['ۋ=jz] T+)pذH(gABxj31h#8> {ttݻLJCLJG'؏PlF'~8D#<&sݣ>FSGH@ 4E~x"4,?-?L2&ceB m;濔V_>_F$6sɫV+ju1۶#߯7>87@}_I&8ڠ(J+(yjq))%? izЇϐ3t~DDLiu{z7ǧ֭\x 7 @o!qtE1iޟԍu`5B8X +j ~O-(\,NڹJP.ʖs1 #gyMc=|YkuYH}0bsT7jȐ$n (/ק8;)_Y'PsZ$".GzzT :Ւl P yI &uO 4Nʦ}ᤅQYɁ9W0A' DSv\l}& !KDfH,rRYCyc6zqhlFxr GCH─_Li(Z$_'{ _\&.+C:-a B`( GJt, ùW[҅}A ,yenmCle"#eiC ^?W[ON>x?YO (o@5Fۗ|k.*y,?CO<jGO.6FQjiU8J!4yj_]iZ4{)pk5n"X((-+$mȏDMy@١3?ȏqR MCcHWw!f/px\W"o:hnKxTp&V39%mCoY˃n#t/v=0nv|HbϐΡl~"{r O 6\Ӫ 5=BH7ɴ.}$ m53wcWY}d  RDBC7MA) F4c( ^$(Ġ3` ).QOUT{8ʀ:@~l#Az#IE’tt"&Ry gٷfkN4HѰϡ>`ω<s9W7L3H?@xapmr0],0KR$y7p= =cJ59Z( +g^.(\HN=D<=HSOx@xt"uTۑfg,Dj h ÇxOòB/EޜJzbxHM_)nCT7=I}"&4N#;CHA{&p,3^9H#`)H,ADwe4p{877~bvYMIg S@G;Ӕ㑜Sc{ R%b)gr*%yB20y,jW$)d(e(rHL۾n{׷ Փ‰eU;}xIVAcTlep.I6y2ez o˵ڪt)0VVc vhbW] #HO"w't eŸ,W9BO@X˳ޗK2pSl;yHҖESk'W͊ ]AgKRvgY^9o avjK(Z&69{8%fUidKi{aunŞn0qQUYH-у۴9y.&8iTeۼhAv|B7Q;|yH,:0@+d6ެr.3|$5ZYS$NUn񝠸/vٹJȆR^;t)'Z^ y()- -nW,7BJەrái+De4v%a6j;o"ٮd!&rI!U+6 +[Lqa4v%c?D*sRMUx+6"73*}-^m-z]-rK4UHiGo%.8|m5A5estGҥ%/UE,W֪'Q"j]V j}vq)We*\V۫73U?EZVD{s@.rUi`]2C/AWrbt/KϱĽQJp{APn#oX%ʟo2:cjjzfN(".gD'f:2脿6/p4CIil`/=5;X_HX_ju&Jr V,YI~(nXQ!pF"> }q(g7K a%Y+e*t%׸E^Jx4cPPVpL-lhO4!ogb+2V@+)FY6%a|0|I^KL]w Q"4f{8|tc(hܡJ͞m 2GjucRT2UtUsWYW-oPA م~P3+_/x;umO׽e iqDR?HHH/Fz0a$6o#^|HyJQJ3 IH̀ qЦcpՅ QH/l9?ѷ)n Dx$*^DH)> PK ^B  K/=com/vldocking/swing/docking/event/DockableSelectionEvent.htmlZmo8aVvCSNY$v{O-ZҊ]&;q^u$3 92k?WgyWO/[=?-k[rDIG{Y'29lΎ8yk/cq,i:T.CήȈBF,$9!%oєH`_Ȕ)M#nG$:N޽;V݇j8%ю[2G9gSI(vhS28cVyu~X 5SI )u'@lq$EQʕ&ER^ws*BJr _ @aq]o߂ՓSÚgisW)K2w^fi|uaC('JsWvYЯa&HGSغL'Cס|tZIHȐ=lU߯5etVsWfk\>kTWfth )I[kREDPض2a L)fr% hR_2E{U&g =iCʓ2zZF o) 2s_X1h-LUJuא؛'fQdm[d*!)͹k4W (W 9) ]=oVwnhd I:LqOl=ubU[`AATܬŬ *GPIɹYB/ӅJu *|Ʃ<-*%ܛ 8UΥ.9rnM[}Q.}i8KYkWw8)L<9Òyt(N`xQ"`Y3edíTw7,t8X^ַc%7U|f ,VY--:"/-/*E׃v߄RDU}4u6}_WqgDAUCq r5k|Uȸq QjXҔIt#8e "D_X܊ # ֜C\pEKq)BNR70# cbg - )(XgY [ &ip4$` ʙbIT%`dFftN)Z C> @%9Z4nuRhr+e^,A K,{>IWE?k}l^(⟧: ܫ'CV`?֯WflCq`NS 6 םcs{|̴) 7Z22K Q)\Ot4&B?,.J8ap-Vyz], Aq4/R v5OzQ3>C8H(5֌o=-zJȒni2إ| \фz3.mJW˳n{9e64{媜u4h닆ӹGl/ 5^ǶԺ ٠3j>w &,"&AD8G?&7 ώkw65xt3ͷoK5MBjsʷ[;K|H[p{k뙽e\35ﲜ7*6-SZCaPl ?ƞɎ{2{G?^Uⷫn߽\kǫA,e<.wE2;o.G !KStޝ~aַdƠ^W#jp9#4[wd$+BEK$3neLReA]E}s++ S:}< gcY2UrPM $d"ys6{{u `)9ymG7Ro~0z# grX@2eS/ҁy¦mu-img5o/۩WIEj̨QNE@eoBYG:oid?B SU$hX.ԃ|6wyUZ=FbLUil, %P*TF,$b-Y0w>|F_/w٬ 'R↊xDV#K̸|zaqIGVp=*V$72a"S4L~/y(Ҩr6$템Zl]ł$WeӹZ3?c{Tft%Iz;SeR22o=`0fWX|oW((si'9V'[Ws:%EJo񅠕ˉyDh ފS\썭0]2PF,L#ȅs5;7{0eL\u hqP'3Oэ9!0`ZiuݳI+i7u %Ɍa2X!ZVxBv0C0{{d;DHLD*]ޗ`ieXNCUې@4xz\Z ̅zuy]ebq9٠(g=6+rzG1 /~&2\8f_B+'{"dVRl:t:4[M qDló:#5n3;)߶ƌg+mO_}&] 1X{TehMAQy k?A[_[%^;ۆoݻ 3d>\7?UlE;׷:,f80 "wi )+%˹y<;[mgWh4V~Q;\ &y[LK;ʨɌ^4oQ_5G,"r!)|Z^:? :co?#$A8.LHN6W"y`îmdzMoN5%yDkAUIl Jk qu%*JN=apd\nӹSSi+{5}LAVbx>r`X$qvu*M hʁmB4hJ(%'owA'HS(5SO˵_pk(ntntntntot P'ԵV>^HQe}PY_56qxkiл j8 gǺA0!BBDxwAԝZ%Iltkgyy4m>PK ^B ' 7?com/vldocking/swing/docking/event/DockableStateChangeEvent.html[ms8ZO v^fj2lHfSk#$%`ػz1$٫P)eu[z[Vj?{ઃ|\S_Z̓ $>D|y]9sw~d nHN[r.i:P._cUբz!qL}N|C4\Uf80<:q?Dp%i{trr1nəKIq̓;Hq_VCfU~gѧğ9OЙ{잢a3ht;!0qPuGV=GօvL뎐 Et\@)WB8(J\I^wY҉p~EX湫3NC2B_UckoTyCDpdzUO ~`D]X:Wg %uHf@Q ,4AÄNܚ:+Vyʥ͛}B56ؼIZ(0<3̟ ڗ,nƪKCB;6R"!^vD!A{JSAC\]a=2m8N&~pt=۬%~Kxڴr2~äTsoݿ:]v/'L0pʤ8Np JaZ-uG6zU}J-Ku#mi\fI?mқRc>b:>[ 7Y,)) @d89q\]M4WX"Rpy6oJ Y/Q;NZd~zt]7a oia }sI?cc4\Ms.G6jHXw`f,nWvddDUGjDl/.B(a9uT|e(/(Vae :Qy[d48SC9Cw&f0xWZΑ-c$}??akO?L7>&dThɭ,'t2 Gx^޷c=BU|f Rҍ*VK՜,AIi9E]-s|,ju>j7MTߘC'z(uR4eh9͌7ԧBMx` f<'D,ke#$2WaoҜcc;xz D_ȗHx I8k}k w4shAClp'MM3q4ay{GC:ֈCJ`@M5 6^dJ̙h2-dBc@䏀QC|b {Pn @PHfObLWӀeCX~$G2x#T4W#b4U 8~,0. RrO (ᓲ!&W2!)gt_͈ hmD9=PtV~~aZ.>\hfZ*; y0D9с[p_Ɏ`I!Iϸ&# FCo 3,!mBYn1FMP|maXńr^ƻ.jE!]¿C}N0DJ9@[np5ݠͯz/˄4[+ݨl;#DB=;t@~XԨ;11Qg\< `HrT=!'8B>` I3M_**,+.X4ήT-e ArDc=TȮjgHO哤|| I &A {5[6gzʶeT :ں ]uԬh[?egOQ6[]<',E=Ra=aPfsBߊCE&2ӣOqU19'\+m0S ktFo(#SRQ۸yA\= SXvn(Ҋ!r0MXΦ&PUNٻ`<[#h4HՙlJz ;@s_71>g˂ξ5-Q ^ ;8UEڭ]¸Е{X6l *fUqo"Oq<\fvOJd¿Oήx! rD4O+ Gi%|,yZdG.C=jR`@Iޗ Ă}DKiVO>RA"H іӖ={7 ,XŠyy u.WaSn{TҒ0W*o›Wmy- жUW_vXVܷB~@(+vuw*wd/, 3f~W10c6;Zp-s%4Jud:>U(!OJǚGpHPݶ rN{mrNPo|TjrZw;-%_)KҼ,OJ80>mx@oרƏ4|@9!HUOkB @# Ƅ3I¼Q Bnyy4o0wp?PK ^Bxz $Bcom/vldocking/swing/docking/event/DockableStateChangeListener.htmlZ[o8~pFf nN3p.S@ - "m׻3}/Xvnv<7§φݜen>_AЌ_Ϣ7칉7a9I\DDUAuvE"\2D(S&R*RMΫMb2alCvRK0B ڟXrIs+T]>ˀhy[8<<Ǔp:<4ׂuz2'#%F4~iNCNl!{8[to.O#'eM&"I;('X(C[]=L1^fȩgJl0BKdbF.OFr\k1/޲`kwNW6_SN3jPVj`)g9rP,O#ClDUj C{[zA n̮w8G$ҿEĐ}y֬g(j',xB1ϕ)L"RU;ʶN'1-j6| :~Z!)\7ntb{1!onm3Ţ5~R1uΘm,gEM*^9D16ΚD/¼?7a"kby֏Zf>_q[5YuGruyol_w(f™Yx e Wz&a!sY&kmTڕM[ ;݃lcKVLTF4]!ךCieuxI}SPC\`mlY¾-y|Srn`Yeׅ X2A*awE`B2e֚z[!'2I).|T#W 7f?p&Nf쪪"K$5'\"9.6N ձbË/ԁgϜ_Lg+sފ dyY^&?GbitrT v$D`Nѓm1KCVd?Ina}"Bd1Vs-\i붺TP>\q}O=lRZˆA*5s{@@[8#ԛi[ ɄȼHX2f_ROA&yŴݙ̈́SSF, B6H0i-ӂ54r6EKai)̧_T,`dc!0c0'[$F?+7S1 %O4~[+=ssvڤ)ۂ]? lϹ55zm#NKWzLlr\vrSt 8LofNVUP|07 hk, )[O#l0[gyy!,BҫMW5 vxSf73&ضNJƷTWs{X`n6`$ƦT6WB H;tb+{ l? ՟~ sT!5T nBhdE9 ~PK ^B10 =Ccom/vldocking/swing/docking/event/DockableStateWillChangeEvent.htmlio6{ K94vI2{ZS@Kņ"Oe+>24]d0p,ݗï/]g#ⵃ׃ 8{dDqeBE\xċNl6g:D ïmrfWtH+;K̞(/j=Hu2Ǔ=.T wx@wYk2Cʅ8xvrMZ<nɁa`q Ӕ$E#L4xxb{ ?'$c)}/)@jIR36xTdx}\6\XC_fJzF^. >ȋS 3fȠz9,Z+*daUqsTTIeQutqo#*,cY-Z2Dyx6N#()! *I3$f4 Br_McPU@Sn6+YhzDf)_}o.R墬|AyZd]'G n: ڽ1%/$7[($ Cҳ9KY 5ɌJB#LVqsK ׊@W,AH9I!o${E?uk6h-UbBs{Koe;# P AS`%CAh é2AC!qC+cV"2 '두A9(mExL!59ޓ(c,o RH (U|AFY H1P+['ma% sbʠC!jn!\$"B-C @@5$P'.[w\ R$IR78:Ú C7:2G6/Ht#\#=8]Q(z\\[ EX޸CL}!rV@~4NUֵ?x4&KEPc8N\Uf6WBp`֛A\xPf0!RKc{ k5aĜCpB<@ $LnU.pIyݼtN#ANMqYKh ejZv$L܇P,CLBbIGs蝡8m}ٓ~lGkKwz_m:1z 5xaX1G^ٕ@ѯ7{Idz9ѻЖ*w[ tfCO?]/ύLCA{̇"KQz't.#>Ɵ}S< pϏZ&$,jc\͛hA1&ᚍ ZvRsRl#5^LU.jpniUJ}41 I4veβkNqT(3xee#E*VI+dkGMz2_J)M^d!K5PUDWՍ7f~(@Cwh,àt^ԘV+uZLm֦ؾhbRZ ހHyqHx9R9)لy)7,y^3 ܄. % 9aiه'oBZ(כPE8/$ʒ;T+Ǡ֬1h}z|2蝞=4x5R [c.Iv46j)/?ڹ>+tsn4SU>Jӯkͫ,ya6l/I Xr/y53(i BպjXL|@j ps!x~B&0diɢWh-vL17 ])]cbo#Q=2/޲r{Noع-v\}|Ww9PԄR \LEQU&n?nuY>(AUf7dY?%!Q8^9x2ܷ# qOGQs>19wOu<5.N>g0yΗznJ>0W= cB8?Ԛf^:+PD\`6,<>j\8XuvL% ]<پLYV Ⱥg\gUa} 8n9['emvVM$}M'\gCks=s\l--V3^4]=tGwͥQ撢@N@ X>&tP;IazmعBu{]Yl fÔ/C'xnJj C| (j!$$Ir-ΔL ޙ@+>3e:Rɴ Pj"/f>1%"iJuzhə6͸;2p`*H$Ck 0 3eZ&BbSFJNTL>dԿDd¨Y 6LKSt.p$$Mh\87_f֤5/6 diQ]8AWCI?V#N;AC!v[CO C.~}%*n$ ZnmUfU-''X%OuP'8z'U;hb5ƣ[Ľc%vLV8k)/Sa5!(6(("Ah> ~4[dUGsF[i`Be  lzxE62 Wo6 +W "Z6ȟKNXti[.An ӿD/Ow50׷v9_;>'XEg6Qe˭ʥ Wͪ9hr*hA m9+0j|Qʋ?*dw\ĕqiR|=qGS \@m[џ;="گ͎1MpdU6 QY )PVs[n)n(OkoَٞJJJJJRwķ~ۯ\l?6PQ@Nrb;q.^S Nwa T 5}*SLNYXQz^VYK__PK ^B%p "LDcom/vldocking/swing/docking/event/DockingActionAddDockableEvent.htmlksH{f]\e$?c@6a@٫D 4Bi z^z!8{v:hg3j{>M|lTV4_W fć%2˥$$k9QoiHc\_^06̮1 [G20bk#nB;z$c |18?" aryQ˜&abӖ;4yΦS+XLKr[6s [1ΌwVPŎsŰU֜/(6֊MDƲ gV~"X[ n Zr ޷;_C?kr1s?RKg.BЛ-ޠs[a- (hq:N!CFԂc?"){yeڎHS[~ɬWZVgjw2ȕsG.i~ƾYxPF T Ue; 8$&%@pnѰ +pƝS7/1i:w:6߱J~n/ ;o;\a6#a9&Gw@ )ia fP45v#;QM_) 2nFlzA_:+p=q;M<;{J $6 kj)(PH6ɋyԘtUo(JjZŬʰ8Ж} V(Tѓ+e>NBf!_p26S\9XX/B1ә3 K~\5,K  s6?/G3gȱ0 Z9zؚ{m&lO>4Q-kKmP+ 'R^PF9CG4l6RPgڇ$.fs?T-#@L^1!q)Cb(7!׾~HumD} HHҀ0 F<B(x"Ba}(1WH`ݰ S0Lԃ07ߛb˃3^i!ngrG@o)BLRK.J2!eijpf >W(.U"RoGC/l]@~Ƿl=kt$edc9GV}xz,׆CT/ON! &<`VVt )Id:mBI:|Q@ȪNJ8c9:HRC;,͸Besˍov)GrdMfk}]^hXo-xޚzT83]k^g+b~Mܟ}Tnd,IbOHmiڱ;nMvP< ⒐XN$P\\.wN 8()7T' vcM.57L3ɛ*j;go|_7?ek|(<=d=v[,`deGlp6qb;qAS9=Q!)}Ak Co{^|*mx1Bʗ /_..' w|'^Z˵kkBXMjy|`[N̼NA˷> $DWoO_5CW'R*)~)D0com/vldocking/swing/docking/event/DockingActionCloseEvent.html\s[egމc` -(OP,$Upo߳//ӱu9{^{n㮉>mtݪ#dFl2#'.u ѐ644|/ fϘЩ`ݡV}R ucT* y?h}&rT_#b `9NpD=:nE|t]y^Fw .$/RW}D{}N~oG&xDB/v:2p3B>thӐHT4ƬTWs{a0`L5D!+5lB44麑/NyEfNP4 ؑ4u6aU| ;B'^`[L|]_\Rq8h:E *'"UMمDi> ~eb ]Ar_A%q5@9`,B(WH 07k=uoٽC׵z*h ۳ ŽݷV4XfXX7 K:B;zp|<ȍኘ˜Kḩ `)\Vy̦S+Z2jW6sdQ -97Nf0^[Q{YäYsm޿4#X\g7Ʋ amJ̪$Ј[$dy$b[`/,ɡ6=Ҙy)%!WBƃI7ȜVwM|vAj-E g\TꜪ8UZ~,h?eJžWGԴǐ~u rw^&Wϻʚ3!Dh! 5Y5ͻPhJyT4ތ eLE2#QLļBf]R C 0^"PN`u`^@cYuupg-6}/v85 ΦGveI+c_8! ? D$$\9d0b0l4/=|Maq7"[!S42dAo8[~V -O!d7!NQ2+EPZ|2S1diZqfvGYCKq-?9oQbГs=NB`mgHWhmH |/?bnJ'3_g9dJg{\?1 2/N|sA,ǹ0"Z5\~z/m=PZ; #d}w)rij 3傋A5 EL fKCQgk}x_ I_D>ÖΆk Qarmx;0Y&egEdSZ6t$h taD@u0Bd+oUNf}619Rb3'ӍG(u&Ci5 |{[y""N܀gu42Bd8H/xno 7Ϋf=OH՜e r [,y8.{5t!!KU[f8mYN'o;?_CHڸmQq.Cwf 0IyE'n;ƻvj$ A'|R%Hѱ<1z-R'G*ݸHBVVެxx.1 = ·kJէz[:]23sʰ{ I IƑӒg<nɈf(8 EtkYB |wkyH:)3Yo6O:*W+wY>y+n[ùv4XoDž "ʝfqB}T%ջ 4bg@PdB3tt6 S d \`VlbϨ(%QGT}h?ajVGS ٪eTmQ?n %y}A߂s}s]f/ģŒ9E֚Y/_d|O"+n㏲/e|]֚D(cS [Q2PMǖWsS[ц5GxByB\p5 |:bcay vtwA9R PK ^BpQ8 LBcom/vldocking/swing/docking/event/DockingActionCreateTabEvent.htmlksH{f]\$l'wǰle5HZHZpw߯ή]Gt] }6o;M@Z0y0sdأNv Ր600$ )j_]P..Y{ez!{Uxτ`[x$hsl*IH=:Wg^8BK_] ֔DyХACE1t\{@!q.B" EFFkdXjhqUu#_2@86`x5%ZDiiU1~[@gudz޸C0 jOgZE3o18 ٔ=H`Q@+2gۙ~Y \l Jjg!P6Xg* )VUY ;ԭvS﫯Rm\L)xT|!0nBoScYB;;\i b* iCg"tx1 m+Ju(tå,Td3̀+Pl=UA)op {'k΃g[LbB.ۄMWb $Ee8+4ւ`Jm^p세AlN HO-?5-ocP\)(Hた1<OŴ{J!#"{ 0gr)tn y_QpxO =5}u}p㼑cW50LpnaI2cQZLusIvS, |ű&r {Y҆)xK %_T,p:DK@ v?E\J|۔JFRcJGOYűC\oBBF ǡ?r|Ýfg%,Ȥ9l`3+á[xc1N|;{߷j:I:: DA=jj)(PYjF1ٌm[qƕ$hN}0@ͺYGՍˈI@9qSb's{B[_lղ@<9D`"knPa]t,qiӹ^P@ 8j.7XY=?",r, Vuo%^}`~6=R3XVm% &"'Ҕ;ogi ;Tme Yԧ! G5Ķ7|"/PԂu,1une_bz6xVjK"Z<4bAIKc 3ӌd8'*. 4B?2S+Pڝ T?[&||v/qSaɥH{L,!N^VFJLak778!˷zlz9ltZ`~덌r/ ANߪYIM'=aw{붺fLJP&lSv@MtL_RI5 F-ʔS@i?ȿVӛf##"-hhPU \ul<I-%P#C[ĖrY0OO"?"_ȥUs Rt -jA^a3 X4IJ?AG-? KyA;#dF4LpBP>(#{|Mqmw}͖mH>D~vkR]^h;rtc޲lǦW )dٴ̏ɓ"[r>y,qq)avjIh?K9fDg%Sp<'rk;JOx3ttѕ3mK5xH}!޶ϽWWKћX=}Y ڢV:^vѳaַ(E5Q53ƉiMǗXǴ8 !r{݀ lT&',(&@fsLF@2 ̉|dqrU4K]hhD\@gɩ'RE);, xN13Ϗd5w@`o͍`_pD!W[gf;/b"U" IY,nb!0N8 Ut8Hf\hoߏ&KbNP X(-#i8!VY+cLkgKTwR"O7=v8ĆXGFi7viig VTxtl0]ji) ৌL9-eL' P}(ScNKGx]bSPUw AmhX'ϓ*7iEvg8g@2͖YowGN"gdU`Rж'KXx"ɻ{U=sVL/hE7VBqvRE}.o;!x[z7$2) GܞI lyEK 2m!azЫ]aCUxٽwNJvd ɱZW-k]ɭin7֯u(wŧeG#_.o_.\>{/Ou ?s{r/W__%KT֖4,P s=v~du ]vj?ZйDRyWu8Olr<1^ TXsbpJ߲@  PK ^B_' GAcom/vldocking/swing/docking/event/DockingActionDockableEvent.htmlks{fLkɏމc` -Qz-"Zه^ @I{imiG\~5nZ}A7:2*e5z<9Ev]NC깘YVk ce-KsynzIJoi8co,yN/.TP,oJEYawR5+L v?8$ޣxo$@6O'q~:=x4mtvrzi4dFwԝGBq ѯ},'ߴ/-PH Sh!^_wRF;V5xx(2$_BkĹW Ӵ%$WHUCϹ(~.tF~1oLAۤCG?P^8V`N~8F*)Xd5a13q9{f /_XZ,K-.]/v3WRG70%& Ti¬[> w_Sm44]EFKi0 ij]_;WR㥄q@H  x`LpyEL0ӍIhLx[9|kAɲMF%g`1,@ݨ,P+4cyʜk}i8agpiZd$Qb5f `9X SI`V^a*HU(OGz F"ʑR&`V/R+=?zuK3Q XO}FmQLOϢ/ mvF\*C~!G, ,IG vGd-꽗V&ϠZ:5ߚ'" p TNF ? ?+9 1%Ĩŗ·, UCb͞Ibb.eLQA=*dIqG! el|`ՎL_Kl0JBcHGˈӤP[?+㬲8e5*vg/a|؂T~TxP?)k:G^.>f>x:9?# ;@vo? 5>dtJ4 aHQ.nKr򅈓RUI)DȝMj SuB1#~o) HJ1>W} "zhg\h 4St)nu~[*ork5H)m9LIVQjJHPRnr߶èey)@~Uo^wPo6^U>Xj^ aywhl+sQ"uiH1 o+ ;BRz+}rSC',g+HI-c꫒MJ8|YMOۢI*/)}wdҵP^$:JF^Sb>>)jߒ"LxQ'˹ Onig&e/<|;:)I'IO_۲`<}LD|vPG⥒poyq](Ďzu0IHU׭QJkgK5Mwe KOmW_?Ƈ\_yY._sѪ230]\)\ .WsX7+p)>E0B:߇/\۟1:,o%>\OTo+ݗۛ"^է^3fˮ;+tէQʌJѹnY雭=bxBL[H~n$7';Es{+8;!tMW4 9v_~62#?߿Wfu*ڟ*뷡T밀:[M䜂96v:{b Co{U=*~UV|u{t֯އ>zӭ`7>થx>|?2(^ʵ+HaL0kx3%}?H t2 ɛWl:Q)ynH] ǿ8%` KNFg( εigg?<2w.m@grnv<둸-MUV>0gxR;.PW%D.tiTl, EƩ~CG`Q᳃㰂g(C)-J+hIiz@ʈ5s޺Rس?Lrg&?dgl[#? '0j@e?\50|>HɊk`כ]хşm&3S$لc\4ŁvΌUsA#ug{d oѠۻ֝V: @cR  T&wͧC{H&&-}$~=92!'MP/cOH@C\`{(AOh3˖5bEg33xX7G խhM%d|gm8wfyyb}ٯ@)$Y`,{qU:lb B%NԺ%Uuq${ޒv&I?cR;JcaP˛O-0S|`&gZR,5YSt#p?!z+8'̃i}f0Dr~-] Sd+xf%%"v1d5 7a#i9v2N[!a ɩϖV:p]]1_Ȥ 6EfU^wg2Q,_ءx[Zsq4gMM$eDHH$cpE }/p3LD o>zoZ\V@@q矝 3ZL-0Z@ \pF@ luDX)Ӥ'a2<?F)c:cER"dsUhISY)oVA09=cxPv'cMj4YR *ڥK9v[%a!K.I{~>ܴ~O}#T!̠#H ]S꒹:3}*h3Xq|Ӷ ;нϠ]?rF%5 ۳3fR.*=WrEԹyer l*I3׮kW OK3+r6/!|"gn 屭"4l"\ZK}3K'Ȉ:1Q;P,L PK"5-M/`!l ^"Hkex6z}ӹ ۿtEVbsX:_@N:gbK f?jOx4ΔUr}m{._Դ 9=ptp.3{*T0B}K2\RML+|s`z lğG1n{b[ZcFGz6Xmh ~NuqkmҚ^mԖOdF8%6Kw]le@:wn sOWvhqIHL'?k=Efں! ovE=daXqKMŧfw!]:39͒]0˃>WaeҋPfUe5,@)QbX{ZQ^c:J5r? M`oԡw{ke2eU? Jy=S2&-Nla 5f@9Rpxu˳t'ҀxG&$xKA p"tT-).V")J0IXD*3H;Jl-#k[7 mZF*tV_r0_bR^-C!CѩOf "MRk:K Qhe`eCTQ]$w1',;T]ki%_$旵e.)ٌbL3bl%8[P Ō. !YfDIAl( 򝬽%;aC;Ys OI>]aʜ'y6-ae#D fAؖ,Vkf(# 8[.SE^C>Ex. ;nHlXS퐪mK+m۴uLlo _T}TQWے *G9*:WX0 V"uX2DFs,?_K9tYFܦD{/"o¶yUD$Uΐis^ƗhKiʴz>W"2cDD#&KMz1Px++Q Y&& /:XAy`" ͺb>!  6rbRA'Sj߲.(Qm; YE| H`l-.Qb?GuZ :\0ʒT[4ג2s-Y|+ٻa o7-_K6Л*W`%'e^z Ww l"{`,^} ]f`B]y(J(_)g!gk ?"i.'<ڞ3WC,X/00m+I^%U&PK ^BUaOA&<com/vldocking/swing/docking/event/DockingActionListener.htmlZ[o6~0TZK3d"IbO>H[jhQ e{=Hm9v)乐7s4g=Aq/þx緎`(I<)Ap~yv_BN]S.B(Ӝz74pd -zpNBfL-LQ=odN1gRx8[_$f)?[pButdIY/$t#=DZ4~tQ)[~oC4er) =yy䡧E5[hߛ$}x33{?fH/y)A,8|?- |3n6bF>*IW岭^G/O2ѓl?I)r3n|&1v s9cBBmi'#fS4E>X9kjS|ɼg`g("#3 #)I4Ѓ5*La{70gݻ׹ p1EvM渆S2yO# fMzHfepiElGVdbO2ljT9NN~x(/\";.u[s75Oآf)Js㚍fүqH􀑼Fuk[W*:c1\Ԟnm7gd}Vlrd̍k+BY&Y3OHǠ_Vp\=icƳ&ƙ#U`?UqZ!4`Ω]@-w8MVT㚡Pޏ [;{" ֻ,bA]:WIڜ@![7I ł%~af_K _hw v! w4d۬)CTX*Zt@:|Tsp9,B#&T80yHjFI !I`rOKPMyn줜iN?wm(0.ܿF+MwVz 2zR-6]:BuNT] vc< !z- Dwlq}#N~# mJzklc_P˽ADLLX:KR5=Oq/_Cg^OG/C;5bfIA_J0n KAgX.'\<\9Щs :#!8#Ƽ!1ި↟Z)$%QIJ|e@cg7QשaeӿlZZ3CajE:d@Ҝ>+Ȥb%VI2"m\W͵eJLrj[21hzˆ}ߛ)Vn 9ek}v 狉Bd)d ld⸫TZܩ^T.e|ؽ-@Q)-V/ eS=bNoEcLjj09Sҁ抢cw8X̸S$ʖ/KX[*myy鸺 Yoq[Op+t~yq~ӄ󕒩LfbU+1\y#S~6W\dah!3}c /+acce eOIau3; Hbk$BMD|7[ϭ=*'(5"5'(jee$\LklFnWYˣˣˣˣˣJ Y^!^!s@4ɊlBxOd:SMq:I>n$Ρjk[]&<|q*,51ܲf9;3β8xo-/15j.~TPnA oὐA|gLB|ᘸh>:| y<<~fcGwi3+Gj]SIA <c@AZďo ]ExBfAtcoG$4'$ȇ.U"r?U3r^Lˣ=W5X6&$6PȘ|-1#r[5L0E'j xmi˜q:l5j\[t09o.һ= #r5#TB\MX_(d;ArՁe$~~KjrΔ!2<@i@-iFQ0c$2/,ޙV?h`6]!w.}T@a?Da!'0 nr_{V25v @Ě 5 <4b1Lz(P'| )9 (Ut2ѣ-֨T@f9*!vF K5 h)#V ES?1jzp|\F>⁄fZ 8$wVC 2A91h;A쀅OЃwTy@JYZIm8AѸLgғH҉Uxb ?o:br ΖTZ$TU H46s+D-,yr= !({*k@%1&|lKp$!=UsY I(7E`B ={Q俈Hٱ>{fhA08HUҁ?#~J{peqeCIDa6 &Co̜"%^q|u3LuA4Tq h,GqcJ^a2N-PLdIԓ标. gddiԬuT]̙Db`S7jk*=>Ձ@*$JtILWXRX _M-'e9wȂ[T8L6M/>Bub3y``=}&t?ob\\8\\)eD:7|qpZf3yT.c\.aOR"ftq+ "hshEylBZrXӣ?Ol6>ߐ.KA֋wπIiyBTOc=}:Tx*%f'3/Znpثc|uzYX%G<`&іcB?x~ ]0NNs'160qma˺ޤ0 q< "·/mZ+6M{h3v_ĺRv,ùLFX]kc|b_{0a\U母1_[:T|ZȿIDlӳ966C"-?Sya,))ݎQRp.K/2&"c6nlL/2?&@ÚbaoDMTo8'@+S_{p,VcN-`A[W\A /F @bmo_K )/}i]n=|wS^yUfPi }C^ (DG]ߏE;oǽ2 Uz*q4LueUS͓i_j~fe϶{_qL b?+K9C˒'+/Z|hCˌOTxsW-WdKEiꊲ4Z`^#v.hG> ѻqNV_bPC4 &qMwI RwMPK ^B? dGcom/vldocking/swing/docking/event/DockingActionSplitComponentEvent.htmlksF?LتWɏ]w!:eJR3k!4_K/p%ts}M0~o]i6Pjzho dKIH;Ž_C?H}?RK'.rc t~O1>2d;K#88J"9`=Z[5uFpAqG8 0? qT8-%-DCJ:B/K7!ȳwRaN̳OdIFsPCNAI _O^ƤCVEY5^5FUr,~AiI̜j+*"zt\'䕢hR`*6 "]sx3k9(s8f4:q5#>_Bu}3@u'6;-a& _д0s REqηo7;DUNa]skUY*)Y6NM1ܳ&s~-4`[ &QE380!>Pw]?0yii += u%\bv]U [ yJr?ܶMtwW%F8GaI:GFW"XB2z%ƝKf2+1!..V; e<޵7n_o6n_v tr+4bӾ1>FoobQӞq۷FѽvZ#" "ṰzEiwmþ2$4>;?&8h)rYJ€atLV=7_d0q笭 WfSB/Z:$ ;o6aTW3xR! Mb3d6>\e@S -.T.fpNׅHZmY8}#T 'PpL8ifhgפANwasv_U^`SgK={Z[m6,ԢnH5Ύ34t<3<-3}Vd\?Lh)[.Q|gS)8!ZL^%-%8-2i;< (qIHL'ʯ|:.e|TV4kt0,s`9aނlH$xb{6L 2%7 3޹C;6wttGGwttGGwut ezͭ}Y<]]fo<}>8@O6MX`:l2$XƳU6ƉinQ hev|D[^BStspelc:~Y8.E#lDA&ÒRu46p1"ZN-37N܌|δ\Ce} }\R.M$R5hj:X Px]`6+ݍj@q"KF7R4Rmԛ-%zaerKz6$ym³LgO8U9N's0"{K@MSvK#_cט}"6=I͈Un*e6/&fZȒȓM/٢mt8b'+Tst-gyZ`!#t;rHt0]j~) X25fL:jC_ I$u#^O /m3E3F[Y-E/N5[F="{Ko1)hxtued:tJ}/D:+x~<?=l׽VՙщmZUԗ-?;?;?c=ٚ.QZ;AƈP.J~ɡ:(L `,2>G+؎G-p*ڵLʵU)~Aʢ|wa)7˯ /QBWHxp }v8eCEf%k#_

ߖJ2P瘮JZ7yW7;k?Xz[l9׹t {n>8v^wkzW=^{wN/M^9ez_].]6w* T+9ťԾbyMSm0`ۉ!E)!tSm PK ^Bm; NOcom/vldocking/swing/docking/event/DockingActionSplitDockableContainerEvent.htmloH{HΣSݲG wO xoPn/ W[Ug~N-լ!dFݬ+d mj{.v ֐6Կ5|ot/fטЩpGC5o{.KhF%ǎlBT8`nx; 3W JoF6|H]n-n^П7ϵ@Gp2AU0 FXFYU%AW, 8$+(ʦp!i`'I{ty QNy%CjTHℤZ84'C'MZ3"$͵'R ?% MBbKwd:c}۝QM_)kl 2nFE8lH/.>X ϊ>ֽ,:Ԣ,BvLXN<+YPVJlW352ѮiQWuVCYEeI-'JwѨ"'*%pBECUv+^e}C)=p,q UؕAd#4o k2alSɕ^nɱ0 Z% xRRY~8%[Xk?i]s0-𯚊Xj*)ϰͩ/qMe-h}@blk ,uIr }@ş {(XGE_qFkWa 1QzT(dL"+*jv:.v-h3,)OG AزP \lpۨ憆3k+W@O%ns>7:}}xvOyk+Q5S?IFHVhVnx*m-j%&0 D (ggw՚z_Qo5U)= ňձ1vU71hȸ{ٯu;FیȌKZO( z۬6ۍ j ǦdPRmLbPpuS/{fktB^=-]0kl" Dj/X Q*kЯePF\C&k/FhX.;e C![o>]RS$ іY2ki$0NyF'qt\ásF=UK;NP%@t[':-jeWdEQ's6}.KI 'h/f4G1%zK<xNh+95&  . u. 4rʎEwB j%sjs7龪2;/xh)$` 2HAeC?/ sU:_G4a)HS7&BT7kxQ#宱Ro~l!b,ݖZI]}W,$U$I$+[+XK|Σ4Rc[+.I/,3iy!;Ec¿kLQzEf;ǰ#!\t#a'< 8BLȆoK9.em(SkK65ǥ=ZlCXTUg{`qi^!M9.eslmb_"6Ư F9x3faVngNmdUTNgarE9|-`r9QV(tw:;>wM'qOJea6%oy^WmMWRU|~Zz/lzOHuiote mir?ҌX a#EfI!k>tLbȊVk󃴜_?`f!_ g!;ӪF1gF8}r У31:.?|h 1VQG?W4 Eَ>I }cRm_:n|mч@K(x,nG#]2WA%p?h`& w?[e>m#a,, k:nBfL[\JϱsOj=5,(3`}ASYu'GӋ4^cAlO@ >[̯,1 LaHOmXɘǥ UhI0*ض6\r^|O- +-(O.[Iұ;7lK `K;D7(S V)@ԁ:#@p a'b})2RB8C)RZBg_wFJ؟H2zYS v] t-ZU lR 6D Uw1*۶~. D˥- uxN(-Ƕuc^ejԫCRl{⿈HٵҜܖմf&s ΈyRv | %ņԙŠwCoXz[-o8DbP%.ƁU/kZ[yuʰ WE(َ Kzҵ,V"פ V_DNr~\5:5fUD%kLZQEDì D<-*$Rh>_U eLT1Y jÖsV)O  1zd,ٚ;]#|=c3hR24%Sa47n%JJ8Ed 1"&Bs%h=a݂]C˭W6l՜]3%c`d= ۆt,YG5nD 'ֱȋ2"c2HjuHӈ"`ĸ,_#^Cmf)< HQ2A[B[ӹ~&j.K&OTچd{nuh3L[ Qt#.d9T ybG{-:7-SaB(&Y{Yq]Γj~Wo^wXo6^N pur0 bӡ1[u541hw9lnzV׌Ȍ? +ZO?+ z׬j \LbPtMEQj믄{.{]lē> 4D 9>)Èm{ز(\ϐI3|}*2$ ~ʓzxvcDyPWŇc,I˓,D$Z=J!Ω(ƂY{{lzB_jŪP?mNڮJV|MqY5a6$X\dc 5p@jFnM,+TB>'hb88.QsWj3Ha#.0A*cuQ'yxPŸvn|D6לGd'd{ٻM?U wU7Oxy\?!{}H"Q\E-"o_"ȫ") /Mn#s>aP;K{ OPNr.PK ^B-`T/>com/vldocking/swing/docking/event/class-use/DockDragEvent.htmlZmoH^aꓮTۄwj8%^[%T-x@S/&ܥ({,ѓeg޶Ϡ]53~@%zU fL&k=hLka0H{~<1AO>5cxؐOàTn(tBPڐ Nyࡨ G*_Kkp,P(~(٢YzԱܖ5.0-0^IzVG4/S}Yޭf*O!aJCAD5fW- x.[jq22NgTjPT4ty2}bwðDrR`Qt2ӘMQjv*z&23%%sosuYbikE\Ω ^Q70uT+aR]o`kDqk%\>nlCG*tDͫnSECw1{|'πR&uYπ%Hn^t]?BI^46!ҬV"s`_s|FGU}PKou@v%sf4-nrdPDNfrըMCDKz̴FwxŻ ;&Z`U_ CYړ ޿5Ii,\gH',:,-b1ZE>A}XDw=|āM7nm9L.k!pg!Aab\F'j L{.pj+#^K#yv1Gk/7[7Y )?Jv4Zl(z ,N L>t?S9D" .u BRC2g1Lcfbi1p~JYve@HPT*R H$h m?X:4niznWW9~znoH"ifWx%;T;<F*~22ƪY(-ߡiM4M}1ǜCg.AkmTPfa'_ vjZ%֊cB~r;ŏKI)?{QzcWL'˿Bw$a&hsMo8(wvv-aO7$Sfwz<_v)?TV_y N#Q T+=}&bmJcB$ p5hQxմ PK ^B 2>com/vldocking/swing/docking/event/class-use/DockDropEvent.html[oR=tMbҾSVOSlc~ ;fvmC $$"=zGޝuG?.ڧkzrɼJN=xWXGD #d 870&}ğRU00UKL5?;Ra0i>JFhyү{9Q>?"֝/|#1(فof57(a7ok5nuXzp2Ufǚ1ךrc${#'dzJwlY=fDvW;n? 6YS^*x*1HH*7VX$7LA\ƠcfJ_Mj^;[yݻaK> ڕєuDjeݨ ?G^,CN/^^]uuFbrpk' "Is|,]&rvq#}!4hʑb]%'d"5OYu.߳e]:9ʟfC,$2cu\}blYiFɅqIEz4w<>[ ?Gq.(9|. rg-"S> Th8j^ٰ.@R`(-l;֕~[Ab+,[rlrUHGװP-לOjB\Fdwr}u#H-+1:-*FקdyqFݯ|qZAe(_٦zԵb)3m91.0\zVޟG^iXQf*ݿBE+e"{7; s)mٺJ"{4sqhT̍eQ:WgEv@Oc˓ho6%zso3Q=Yy]f7.CIkXwm"[$xm9V/ ۹<,%Aʩ6c"M1vtU b/҈$ck뱹-|Pf]ucMy *+ݽjyW]QȤ" %I|E $GH1ɓff( dB\wOJ:}rȰ~ w=hP>ǁl xyv ܖA Fxl2&Zc4*]u1+z .4:`ОT{<9]4+\eZځE*WQģ; {+AM) ^E6o8Ѻ֚m:D,$(o'.2؝H(`ͰgWm82X EH[c)r{*&*4丽^c N཭}yke~A)֜}5#HD3deXL틚if(ޘ,yQ&.Xxx*дM. >?-AP+F*8c,wZ[WBCo! ]#~mTCRkA%5اj,$zĵaN`OjNkll8}Hܿ57v:mŋwZ? 98[[)4}MWșuZZQⓔ_j_%uSa'hˍ{%Bq@綧љIHoRQgn8V4S_Ĝ8@u1cD uGbs,#ϊ 3tf6 S{h !EyCxğ󞪥Vs%>œNvbwIWbm8\ڬ߯Dˢ[Zu-5v-q1S;]#/k_̻<9(wMNB#)āw U*qX`!S\|E41"*d YPPK ^B]C&:com/vldocking/swing/docking/event/class-use/DockEvent.htmlZmoH^aJ-bNmkt^k.Pt]pI^zޙٙye{:kv t>7q}ݦﷺ-W݁ Tc|3T*yԛz\ ?T#gK*tϟp]hi (ѳxPwhl ) Ә hE&$T&TH;ޯ^n (4vv޿}VN n*KEgI%>4>& ^ES »C}/'-)WUw|+%"㔺+dQwr/nQET3FR倚%HWR:0_w<_xf_w.agpe DhQm'Ch7{Z!z֯tTJ-ق-$Dhۡ%#}l|=۾J_|~F'Z"Fb Q4c= oד5"zyΎ{ցi: Γ63pd#'zKy%nariGVh`<N[eHHʕ 14'Tv."E|mN]9y:ƝY:l#UF 05,v?ĕ7;+?Ǖi(N@xqMѤSt74նD@gHR|tsN&]XXoN>,qD)G-cf~Ҁ*ĄLL/tRXFkIoجccIWCĀbfQlniVɯU0Kds:7}-4u>c6;"ufUeNtC^ PCF8\ŖQ^,2L%0'Pue7E<Ғ8˱,g4*eCWs*lTﭩN^4#g1-xaQ&nb D8]S-WDC 4@ݩ1&$ #:{"u] $Яx^r$A v)]#ˬҬ5w)s{23AnHhƁBUÕ'dyvAP%2&gA+(?k,C W$/fFwHspWt%8@EAN ˴ΕŦ㔻(n$!NiNMh1olp7n*t5T+ hΦpdzjghaam)"7 y\xxT~èQaE7La{CHW4Яx&<\lw:軤ף6az,/;%/e@I6g[N#O]nWyTHh3OuR5J (xwGU$>P6Xapq/[ u T<@ (ǽΆ]EN<ϾWz gݘ#Qdp,Tҭ>9 E{:ž  DyHB2>P<lno~IՊkۧi@  fѸ'sGvQzRx!X1EKtttpT~TqMn/;ejJVT kd#ԣ5^a?8zXDZ5$b6!7hYΩļLCĬ4xPK ^B]wGcom/vldocking/swing/docking/event/class-use/DockableSelectionEvent.htmlYmo6^TF;]S$)-BI5IIq%q%@ G{=;1Ϻ'88>!!t먹 E3 Rcw,hI5!SxMEI'zlѧahg,Me&e4)ieS԰Ki"GИ3Q=lG?G-3j,[~ͻV ;.Í`Ϛic54 {IZޱ9L;: 6fih|9z:-`K6T;eB$q- Sz,<DhL2GNþ2:TqDY^D鏃3;ēҳC,)U~6h<}ch9Ȫx'KCc 5c/ !ނ?=TYG[gS;(V"xB<73y9N p5$\[R \h]bUqN>/{(Fx{tN/s6lZ2 qvGQs>qa-=1Wڠqu:BkSU* _:D%9gPϦSAv#(⺠b'lgo["H2@F;2R2ٹxv7frbaq?aQp D ^![n. Q8L!d&OV6 c|e=Lkodb_4HTM]79;$\u8HiR^ 39J 3z*nVyPG!V 6fäq[.qEdU \0.QU0Ċw7{aBMy3֚S"Li.㴝5N[Ȥ jܕ.k(&āӍ֛[໶L6Pm7Tᑠ [K_724K{ M<}x,'L39@l9}X'ёLX{.9X-9G;h6<,(*z~tYI ס((2>SKiL߮HVZT PK ^B*l#Jcom/vldocking/swing/docking/event/class-use/DockableSelectionListener.htmlZmo9^aD i6pJ JHОSeX6PtX}Iuxfό:ov8Sxxz҄ $Ͻ&!N?xUwh2vИ5!4ER H H BJ͢A'am6ah{(41CF|,aCw e*4跨jx7N vw_|VVjݽLF{4>$>1Q4'HO5cw+gU?عAicEGl*5Eը'; E#f($8ĨRbqvaװ@@`zȘ R4!=*֯QDsȍsvIn஌gWO͢ki4?>TQdG<٧~!15fv^pwReml#GGxTm&rގp5\[ELtj}b[V ,~:8?>\O3t" 5:Am:AIKG/dda O5OÅYMy,42>+ױ'4v!"C|nH'MC=E6M UF)E@Egwgd-μ\m^@'7h4nsT5 !#Xf6W?fb=]Cje|&4ۖ6 [ -IB9@Ns3[,ت)_.rsP7!FyԶ1ɓ3Bc X:M>h(/IWo$]pǶ<<U/B?,\p,C:¢'X_Q.Xb[cy^$u3-E6PK ^Bcn>eIcom/vldocking/swing/docking/event/class-use/DockableStateChangeEvent.htmlYmo9aZkB;rJ JJhO)2a}1@ѩB`^%RP ^xfό݃v1|쟝BI<ۄtu؃~F5 w=bw`lL$) "yg;}lޣcof C%&f4*he ˨f H6cB4oTçiͷ͛w&:}h6s]kZS GT)I0('@wf,A@K iǸTvl^@iQ‡N\fװ4&NC)$Hz PkQD[k5dL T̘@/R&C<36 kKYwixRv UÌzUqZ&v?|5!D=0D+Xhu6eOk>)͌+ѱӉ+BwKl4D.> .c+22[iL˂bUaE?@/G(|Ltn/ـfW8_n5d/5O28f|l] ;uW#)U)(<\ROTxMJܽ3澚N&4[&x|.MA)c0#%̈),m0s 3'kY\3hfB]0>{c}noyҌ M:/)gdwOec&R]sUf2'_+[DMvT1le]Nkoeb_OJ43,nԥnswJؔvhiݞYyXpryp@#tj*de%A3ãITŊ-|T`Er8Y[EL T ]|1ضL kE)P^$d^ ۩.5Ut,s W{eI3r- kha$\Q-n㸲ݫ {B`jNiqӣg>Y^M3l 4dY+45JLZ@bY=*kI:8N T ݙ J!ס49'V7O:u* )_m)6ֱgm{It͚hyZ r'c-JO4fnbjGm]ۦL^[xoDVw[b} ϩVg9<]" jdZDŽ2oɈ8l@-3 zd:k$Æޑ oxĜLq'M2DA''q0`0ޚ!G %U'bM,`jC!v!QĒ]ɢZy*]齗54׾߳S.8vbL Rp&q"]iYV *pPK ^BӉk;$Lcom/vldocking/swing/docking/event/class-use/DockableStateChangeListener.htmlZo8}LڨĔnwV8:l2Ā&lCl'Ҕ/[Q>i6w]:$m/6tM47\&Tr !d6EH!鞑DHY8h<~$ f:dvAa=`3b4a1X2eJx؎~[7Iװի7tZ]Uw2Y4 pϠ/T K #=D-= *kc㖟 LK؉Q :G[ċEcf($8'@CbU2^;\bh3L3y}2u# ߂&rzpn{'}S,ڏ Ǐ?|!?#BPԍ[PCzZIDN"G$x5!j/=q5\[E\Ni]b'[V ,λ{g]8=i{B 6s$tڣNjvS}pirGVS>t 2=񪌋Wڠqe{"rEz.DdX^vY'1U惠q ;(![!5t+4R 8!A vUM|OU }BnqQe>YXPYV19' B*DoN>b" E;]&&~eRVJ)*3ŦKj1W06܎#=h 2 ~$orkKF' 3}gA&r`fIY7J(#tlf6f/Gq+\5 ,zuy*k5 tVK_O>/&4۔6 ["-)E9켚@Ns[u)ߋnjtP9>ޔT$`S!a$u}եP>n`IΪUuJfvkg ))Y/&1 q,hi0#l{1ĭET-@~Cs͖5w\&yMf==4FKiOj_qX)kkkkn8YJG&3䞞ڬ e7MY5Q#@!Mm;5F;o+>U/Cbt!$3;KӘYl.ϋNӢZTPK ^BxoMcom/vldocking/swing/docking/event/class-use/DockableStateWillChangeEvent.htmlYmo9^aD i6)Jhր/f oln$"΋g!!ZmET߅˔ BScׄ,hI5!S253)5Ǐ!tٲO' X*4K͔ѤLQ/AmFvΨ`w˗ Ш 75?hA%0h!PO'^-Xj6>ѡ`g њrّ} R ؋Q;D3f(H PsjPD_+g(&@`zʘ 24!#*6("J4J~EPpmJ=RE˵]]llF* hi8" ("`6~?)FHFnZX<A2zHU {7Qp{)65\F^!"qlg2袜>3p?[&z>tۤ޾bet1Km.zDNz8l+8Q5aX^w)Lʯוp]nFM3}n%_ʱU@+Wy:rI[1c(+ |$ Vb5 Z"qe*<<Qg;Eߎ|R"Gѿ㑹4qZ}~( BBgL:f;ƥS3e$y31Еb C3ٰZd`\t:mh|8<ȟfHED) H[daI+/dd!1&k 8!)e\T+c+4V!"\U \FFDy6l * tF-!mE[YƳ,ٌd0>_lPw/(WWhIi^nL9hs9'gIYR(#tjhEA85r;2~Ci`Qn2l PxjgE&" %e)||YIinVVU!-P|eψV~j$Rؖd6׀BJ(F8tDE^8fs Y>KL 6Ks I~B$##$/} [b1-{dk ݣw$]gLa420=\~Jg7[("39ye΁p\8xEFmuXw]Vwʺ⾐|F$M9sMZi0;WuQ:+^p}F8v-Pۦ37{[S78 27~e<13fvU[Q`K3jOĴ> )rMr5$K5RAMrS\NBXNgǫo!X׀wJKAYK ¦IZ`3e(-sJ1>X5m*VsXUIGbB\s"ºƀv`R~k;7 oE͗uoBk1*=2r?5Q>===mqvQf==AZS!3ʔ4G"kvY3,`V9eacaĒL/,Tav0֠/PK ^B5Ncom/vldocking/swing/docking/event/class-use/DockingActionAddDockableEvent.htmlX_oH0IW`/NI1'i"{<^]~k w՝T)w;g7m]6>_~d5he/΂rZ\2v^0\.i I1LՏj|: []Ǔح"1F F0\|d*Mo'@n<9T*o\Tk Z溌05jHД\k%`!I읈'^{1&heȺ܈";CW-N.uA9Bw}RcR>C!%K =k_ůH߁Bzڬ$)R4հLC/'pлd'&>Hl*Ψ^c(dm>q_k}CE%5'WNௌ^)W6r|xo3{1U<8GbQHqɢ#4DB[=U2W0TR j.6 n`A/I2`dc@IH_P싂b-r6~w"7Ot=%I~Ƽv,6.etPi mz:ky%R K_g3V= z7';x,( n12|[?55j3WkZ`J䪉RVH%@ G`@ݏ0U8/)֚z$w\\Ƶ>EM7\G6>Yޞņ:e}cgoW5VO\MP!bux,ro @DGyudԷ[1dl nH;|*\Rۢfkt!$:*(mQ C"A!k@(J"Uސ.CoR㡼q0*8]@P<ĞNk7:*a 6d|p{ }Mj!dw+~{O38ĘdW7d/mK{ۀrG~f \.<*)-*@f(zF~koL T3}hi )x )Ċ8]oyaeYZ|pߌh7PK ^BQA{NHcom/vldocking/swing/docking/event/class-use/DockingActionCloseEvent.htmlXmo8^a6'v.D ft*C 0qdXt~c';R#όgxګVѻѧ6>_o~$A˄ Bn:xc+Be<O&f&.R 6W?=}eQ h2=1Fb{0E a?rSC%5(ߗ/;wyKT޼V׊Z 7?kA)0`!'@/KLz )0+җv ):cKp*4zg5C3f($8$b CAg'.t)(&BO`z˜R4!C=(6 [sCΊyRv }t`sI]$ }}JQ)ChԜ>0reJļgZ m6o'dH Yȇv,/\C5"l% J.5SAԦٰ.j#较ۃNu_6`h˴C* ] Gz@F'=婿1x(GS >v\g>G\is(&:mOg"v1*q.8[z>Q \&GĮX6{ QFHs(#P9,vg7<Tm-S!rL=C|v^4~{-6ڴes<~usHj̐ >b#aǡkLoU'rd"{g/q>rKmˎ!Yc6Wq@gQ *0D᚜XSAW M3foLhvn"z x+c>V[.tfz[e/~lLES+LaU&lCI(n&5Bcx?!ԁU <ߏ[v$ R<ˆ4ᒱˮԘ쌱r,TMX4`S3'L 6<ScN_O P P(E?6'a<b'\lE3͟G4zzO*!O53V`x`gi 7^`L ],s_!j PK ^BiD#Kcom/vldocking/swing/docking/event/class-use/DockingActionDockableEvent.htmlko9{Ԃ%S)!5U@{Oa bm~c{wymzե Jk{}ΠA{^D=*"43L <`dL:gY4ۏxdE̥4JL4?:xpNgm2vB'bp0#J*"&ЛdJهʔ*a/-]^U:+{z]3^N5 Dkq4Hag;S*LtVd@z%|:V"c:ZTi AAW$گa3q F͜S=`)b}):hQ-p"7v\=+eV~6hZ#<~ap'V e13Cģ aԄ>B^e ُ3FoGq!bڡq¦W Ӑ0m$rLSؒZ&`==[^e%ҀUZ@dϽEi+/2X0 kKqIMЙiy\ +coqΘ6EƋm2: d<&j,4/iIlJ |H~?tp9Z?9Gov43۩wsM.|1.ЀQfwq Mۤr`F㸘ݞ!.#~[ = )uȌo[61C.~ۅpDԐb1qҗI_I\&U,ihQ7MZ]; PȁesKwxJ<2JgR6(( vx4?M*7HQue *hD , *UY=׾|_k-.Ԡ󴼞ZrNΏ NYɱUrP6K9Xmz-ıߐ$2kaE$\xRؗ zRA $acs{09 ~6ڶ$K9?;ĢjIj(<vew:94މS"%*W{TR+A 8ThCSf"Lj3>y#lTNpӒ\z1>-Tt'הI691ּgSL 6̈BIԡzq!wԍ֛P)*4GEg^o|Ӗ{-봅VVHL\|_i0?Ȅ U΄]lLH;N}ЦEs3Br`ba|Z'Y8۽4 z#qـqW*w@#v2Qv%.P}-#*c (h*'=Tx2V,@ٽqz_ܩH֎W}%S(%v1+Dwfb RV0rꎠ՟+@:lr1ֈNfvd4=Y% }Gnܧ@餜n1Q \۩96)0d#f#ܛ|TԚ6΢(lAe&b h[WK/)GŇ[/z9.RKߪdbc>ܭ<ܭ<ܭ<ܭJ,} rOoXn)e,KYP{C[2h>N;pd^W9c b"kK cJ8u;-  PK ^B~8:Ccom/vldocking/swing/docking/event/class-use/DockingActionEvent.html[mo8vmҽE؇IoH >4yE7CJ{SgbDqg{EKi(EǝcM:FXR.<`]M&pr*ݏ:WH*e Ll^~hs\>FZ<7H]/HAs N'*f1hóp:Ûknٯe{{~><ݽ|,+o S=֖a8FL軸16j>7 i0#Cإ$(GY4WcNj)A6cN3F1h50f4oGV*ү^Hv~Dդ9 Hrѫ(L@4ul^'㚔* "!x'竝(xtu"ƭ_QkaX" J:ijb@u&V SŇ]w:#\\?]Os?D,&Q*;cTx%)we,ͻFdΥɱYEߙ_Xj0bHs&-9/w6UTc \OCu7EbQ%Kz:XT:X,*E*uj`"]A96Hwhw5[ eN x6$Z.q\nE|K8 (o牣t?ydu]pT:b>4JNb7wǽ12pq}m ܐɹb|n]3K0s6ftThܔGRzEn2 s:Lde@O$iRE{ѫ5i6LDC-CL)t1'}4)mR#5g U8_,RZ(%>Z Er갫[a- ~p6N\D3w vKuF4]!8I"<1<81GRCyx?_Y6yF׭C0;q=LUe >7o7ڼ{bC5GTHJ*{PNɏT].cE sV((|m+desYk&+91#L˩ذ\ 6v4Q)w]-B 4TY1JDx^N_5tCA=m\t]k?DhgIBDeU-\Z:OrH ɴeQ=y6]jmn|^J>b~-qV[c`qep X$@` bid!V: {Y-+Urmyc2Жl3[5zlzk-B[ m LfNq.kAC5vK -bHJM(@J(5qYsG>O)l0pmjj[ r#bf)1י?HS|Usr"zc RFu*kׄa7'T$eRMY=_07wmlȚj\Yeʿ}im1on R&n |tZאP$㾀 dZY@ƣ7ZGϧvqn&-:e &-DK}gDؑjȰ3)RMОDNa `jc{Sru4ھrM`-؁vazZn[Z.rbXUU @m P!qzhA=tXuӯRB+q&l /s"N Ey]uOӱ#S e0 5!b_mP@'2h@be)jL]%݉KHo0V"y?6Br_V8]Zbd 7UMfjG-yˣjoѕ**B:_UTq0ٹŧ/Z5<m~?#)^N?Ssx<ѳw~qU)MVx>mMC׭,}p!LHQ{*" zv!Ul9(s3-(y^PK ^B]Fl"Fcom/vldocking/swing/docking/event/class-use/DockingActionListener.htmlZQo9~0JW"uׄwj8%\S%%{ k/f ol. "|u9ݳS|<<=iB^VU4pPAQ;`hLtM"H H"BJ͢Agam6+ah{(4,qcX5, >T&Li/Qs%5a@ }mVjݽLFG4$3Q4'Wk~&,1Qڧ\;/|:#6jT>Q 1Hz`Vko'נCLf"a_ kPA="Dn_.mcOrdI̾*/)Cݨ1{:;𗧵*kGxd̾/w~._>!ģx-m3v'hKo!bQ6c=%h"zEΏ{ށÃiJ}AFȴM'h, 򁌌P;#Ṿi0<# r /=Aʄu,"|!]P<*J% gPG#fAx"<r֏xxpqI?ZJӅS4PrO a畿,}ٹbg~|px힟|b'3hclNc4k [ًӠ\F$1]vXlΨ^f%&Pɘh| t'WB$WWL^)W6rxo2`,Ckqr;IJ1b$4DB$\BH%+*1lUm+X Fݷ0|osHP*×61_&fKA.Ƹe0żIRL]MLxD(mhq}! GI-lLx>^K+_/sց=z7';(:Nv{!mX1sc .3^D4]ozU@;PaHÃapl[_R*s pML𹔹+;?\|2)D{n t|mݲݞ:v?(Ԋ<%_hTq5Ew~(߫}DzcGF}s2=[9?N&h솔YEê5m5 aSuh͗b}XűbRF* )fwTRdQjW{CP8qKtOy*_ػPܭFZٮU֧UΎަYݦ6Rb{&g\vʹ9v2?!Ew8~ %$B&!>!|n[VUVa|!?iH3-þ U@)$]SQc"KVb:3P-O}-1TzEMqri#^bDs],u_1W' PK ^BvvQcom/vldocking/swing/docking/event/class-use/DockingActionSplitComponentEvent.htmlXmo8^a6'v.DD{O!|8 ,:PJiA{/JPb;3CjZfG O4 IH+je/.r"E xSc+BVU:h@f..R 6W?=}UN]T h2 =8)qA%LQbOAiɔFP ~ w3-5q@*7oU"+.Í`Ϛich 5q23]wcS( EfQ޶`x|ϩZ6#x^#(ⱠfHv3|;?8bF-\9xr^[NɄ ?X{ fb#f}qe6KrB2nx).ʹ?t,{l[nl#IC;vvHNhHQ5aX3R~ʝ%+'<=[fn'!={>?c4sC,"q u:4`vxKO>.ab C\We,kT 2βޘXź*/nW Em/A*G۔<+{آՆU`S}"ylb3FybwbmFEQP5^y o.+>S:r˓lJÀ%t.;PK ^B Ycom/vldocking/swing/docking/event/class-use/DockingActionSplitDockableContainerEvent.htmlX_oH0IW`/NI16Dܞ)Z{YlkwSͮmBI^OJ;;۝^+:\X;j/j "-H.zMN[.(HՄE653ydj b{̓]\-r$0q@vivjeQC:Z( IjoD2 .01A;쒯2)V. ϝ*>en(u8_6XnKŴ:H =_ůXH܀Bzڬ$)24ŰLC/V&p|~]YSXxezDf6 ؠTiSrctmHk>I_z+}CECCkW.k+Z |fgWj7k_^0c勶$b@!%4B[*+tQ fMayUt6^gF64NC\P1nr`oDo0@tRHhӤ?޶q=JZ.ctQmvko}ڔvBٌU`O+9F*+8~[֏`ְcv9ر}a{PFD4w]9W-6@B'abG"L|:ks) veS 4fs~2z>t[f'< } 7tzm)~P;{PN?lg;CaW)`x@ġGvd[㑻tli?2 ;(_#!+B.8tC+8]!UD&LyC7yjo(5+ nV.(W(en{wiUl'*oso]nK3E=R=Zm-9=}EwSt??Ԙt_BEύs#H<7HlX?v/Q,m'):Uʊ8Ვf+ : yD7`JLt<֔" x`4 /0.9Oc PK ^B| pPcom/vldocking/swing/docking/event/class-use/DockingActionSplitDockableEvent.htmlXmoH)aꓮ䃽@;%Ŝm* ОSE]ۄPE ٻyۙgw^+0ԆuA}K\ y< =yT7p4JkP-MnP\ysQB5jr2H֨!CSrâ$w"zi #T c)|(ʾҗv2Qwp*4z'5%34bb ؐгN_ (J"*%I_ iT8meލ%;0VGJfӀuF6G@CI&#n#X#^ *Eh_@_92Y{\وR|3;=3 QQni|8[yRfN/TVFmg*Ckh*N\U.JaHuzwBavן]v MΪ6gc T88܃,6 "kM1׶;%ӏp\vyxabL2 dor2ɗ%xi ^Z=-ƱcwB~갫7(Z]U(Ki.I@^GDx djZ.K[HchNJ)[. } /tDPK ^BA銺4com/vldocking/swing/docking/event/package-frame.htmlQo0';\>`nj:m.Zت=Mc83NH&m&;{79:[E}'W AFeO$!@S+BE'لT✈$Tzo߸'w *w(TN<Ĥ2UdU,N,˵<=\^/s %ŕӱk-ŕ`0BD3.'8/jL*896cFcV$ ޞdHg u" L)_臧ɶ"2<ƹbkwi$#mܪcMW~ԧ4Vͳl+UnvqpD{c+> PK ^BQj/ :6com/vldocking/swing/docking/event/package-summary.html[mo8KIڽæqif/Tm":k,̐ԋl\ D/3#R:fpy2)a9uza˛0 `w sjiJy֙boOu85m(Esj^]lNRoђy"֝\z-6n؏Eg{{}wϮC2$(R`[NLEjX>|&*eo`_mVH Y MHD;4D,I2z*0̠Mia\ 5" ^&١Gl%Q.3S٫#9fDE}@|9D>Yz{W2Xbβ/VZׅz즠"}.[r ]JgU^ƨa|$i1qqt8IL0DYܽc ވբ߇ei (䳄/AUg &HxlTֵ%jnO3^ K[j.r[ &D?x ߦ#{0B XvVXlN13SZRx-Ǻэֶ* )iD˜\uLL՜!kQ"rxH XCxK,Ps 9QG91T0. i LLLq!hH$1:-IG)b"p9V%r#QFy)vᜯox&_K x+QS&^IFk |#5a|hQΝ|p{pkiⵑDg8~$4D*ǰIJZY4'#k˪XCNȠ .)0WE2usK91p(6,UF%>*pcCp4 )\.e4 bWpvس&)8 0Nr )aCJ`t̹#hCs&PLNT5KꞚ5Om_iɹZ^ËKsEir9-CTZڪ@/1mBe/I:d8b8W SZb1d$s/8+ 696E(jR-e+%y-"!6)PABk3q=ƬUs)u!IG ^seMx>m;>l<]pD`_Hhmg5*۪BOEº3Cm=M$*r (mژ墯KtNe`%|Ԝ_]#hq \\)pvXE\j+ @ɯVͱ'y} я68c8.>ZkVj-ȜPdzM}'/#8;wJ%::cdGJQoMT_Gf f@iƊ"OLcw_ߡA,p׽yI a#Fl‘hI¨jǢ 2:mc#R`TLb6#N#TEv9> Ӷ3]FhPϝ)I>aHl:`| v5 8ƨ3>L'rEZ r2JUVZ?v$3~ b;)GfTiuoH@ %_ \nQބDzeP=C=7o, +J_OR)^{)bh满/dYgEf׀(weل\z*xf̌16VއˋX6![N}I}#TrֱGQxD|>wN GED "sȳO?myضѣ@P԰oƌұ0I1 Lg \̘ThjNqM#x7 j/uP[kę Tt=m#h hZT>^p.y NթIĊ„E|Ұ<nGai+Rp$ KE ԘȂhdľDUʂdÆ8$p ca]nBWa׮]ZMO_|TѶ{KwXyΕrLbh];cY DڙӉ~Hfnm~}8$F`Yb=x\с”YS 1у>tϡAUib\:Cـ$baqQؓ4J:3 dƔ) `L87M0O< rĐjGm;;kpaa"nn q襐Cm11N!ɫhի#3«6V0^0o43S$PXncߘP졲~೜hIHXJE .TfDuDBdeuC0RAV  9ZտfBR? ,(cجr 8r5ǁƅ:X*K.K6I-mCi=*f!cIUՎԩH5늑ҩjP ZtW7ŽPV8 hq#e}\IeQU'qȊs)wc&.3f(LH-1mXˍj#@*U3{G2ݍ \xK-h[(3ʶ MtM#V{@P0*.E%pL-w)n=H+xPMSmK+^2 `XWN6̹PpN8 hY7a[dShFgGF&wQҹcS_׭|eKݎ R[B _wuk{]9c>8$c-a=~h<փ Ifo7pKyqǙ3AtCe]gYHF_ \:6AcŎנ%#W/lK.8V;,Ys+=JSȾsYf/̏PK ^By)v'2com/vldocking/swing/docking/event/package-use.htmlZko6>[-&@-ɴ^$v MmDТ@c v-Qٓo:npEZq܎N *Ԥ2c"ίh:PAԽf$DBJ$Aoj56PA33,)3 fo6a`•F oo BM GƱeR#x75>ܰ(T|fPO鳸8b#>zx7'SF0pJ3HgU4rVv.R=(.63s(igZ0T 0Z7$kѰd2o47 J7ׯ>3ېliR]C9pϛFwlBqq3k%#=;{gׯmmVC_'zH5$f=BXAOɩ*x "FvCߧymar8&4w«6>S .~E(\ڔvJsV(1')x4bjR4k?l=P~EK""& >1B4n9f(ν.^nrley )t= 1! SvE^d4Sw}zܳioFɂW+7n]uQ 󨸳a3~s05-]׻XIJº4iGvO+esZ&do֩vO*\[_nF^%&9|.8]. K83.$rl`'sfh*aMw9OB}e3ъt]p`ٯ*U2S3H\рVL X-NzSƆ CXywܵ6:Y3gIRu5F>-[8Jgl^-bu5fEN`؞a¦(?[,W=%XoO厱y]YOQ?pTD(8Ppm%[h[3nnMBϰ9tLfBGZ!/| wd!"uݤ^hbbSyܗ[9 2;`j(66*79qeV[-l5}E3}A4{}a|}rr)_X,-ϔ9VfXErEDzb<&n!۞6zV圔o}sH,=$$%Yt!˰=%=?hֱ.tFiW3FBC&MO dcHd!G@]7ʨ`+sTwR'XbI?x`*TcEO8XKbGa%AwOE4 N-Ep"3%y-*.rMċRhc\9-,XV5g=iU:G<8{v_?=~~B~'~_!Yu]CWe"e >`-GI_f8v۰S }C-Yng(zZVb^PK ^BFXR .com/vldocking/swing/docking/package-frame.html]s6;vfHiɖ vz ed ڮ< 6Hq=H#a|C\ ƛ\BՒ}LP^: 6#2hoL)u=H/$QC$ziy7? }3& sԾFͧO76 &l]U zXkA g~1ww`w 6B.Еvf-Auj WU3/m|$-h<+]SAyh.>>KUzc}GMEB#QDzɠCm<߭HӈȭoF9,ua2B;<"B&޷I|%D^x)mS.fYlhFLM'neZeZ4Gк<U $E,z(P Dk=@ @r/Ό̽Sv&ҤoNXrTMt arT΍ᘥҾqwqJs!RRQEj8gτ-HUAsc%> AVʙ vX);j#c\ܿkqq.s1[jv2O+Fry}\W*tع3JHgD&ߝ"<Qظ斅t9H%\W]Ϯ雂)>Vre!o_"R+Xk8dK\8 ι6W nyYr/&ރh Z(q8RK/ < =b@ 36'_S:Hwp k\Zrf6SĥZ4o#͵)Oqr+\GyJ> ˤf.5ij3y&4w~WvȦyyl}H'D̕<~n uNBIGWN&(IrZ=Klzy壑h;^=׳ݯ$A,Ώ+;H;0":Sʕ JC}#CwPK ^BĪ͠j}0com/vldocking/swing/docking/package-summary.html=o8vCl7Iw煉&L6hҙ[-Ѷ&%>H4l1H>H߯_o_hhty{\&:*4hMWtgE=py仾7D}'/ώ8zrxl*"VgA:.bt%ӡ^OI~4\-N ɈA*Hi7 vE&J.8xw8JDӮ.V3(V,bh\MNϵR {_E8 W[y>h=C|~/^p$TNzFzT[{Z/NO/~/9,qV3Mg4$u5iFZcUZbK#(Rթ'nn݊/kSC3CPfo0i7>?q m$(x"^$ &Q X\`DUj7"|KZt9|5D잽5_ӴFЙ@xc=w s-;nz3n:(A@Pﵪٸȕm} nk+TY"bz_V>q@Ʊ ??L>FeL zԦ1Q[Κsob~I4'Y4I 7o;* 7ƙBSBdM*6l].}5mŮ I'8y ~0u@Bs** }+U2>h҃M)|YI:!!,+;urBwb7Ium9H\Mo.}Gr6I(5LЭt~]I?'c}"}6 ީ@E;nKӹGAary X瀽7L+OPi 쉒EÇ\r#9$c.f| /lRUèg`qJ$Xi*@74ӗBp -Pd6(.' ;JO[9!~ /j2o z6$"q;!M]c `ڑc̡Aʬ`*6ًwbVG{2 z5ZW,-_i9aKU(rnjC? D4 D|GA*zwt>&b!nhDzعLs#Է6 f v#%HD)c(ab {|]Y%;Ց Nl,{׃Gkh}J4VVY ^IhlbXCqQJy G7*V_FlZN9ѡ&nr6l >S#ډ:+mc"IdF@1IxQ1mɾT tmkKV&?J%lbNJ"%4+$TZܭ.@ЁAg!*rY :V H[d; "^ j0;&11/vOk<װ pRHoT{Z҆o +À ? .`>Qy{.[gG|8cx|(Yuͼla,IV3u$PtV,$-3Sr2sQ+\kyiBbT0KDF| \LQ,"ͬL [#:5$8K2*>Ҏ´)>?̗%͐a'5+C>ˣI[sD m#7xvs>/ްh!pU9hXq8X,:Β*6d.9Y~)u8,5k`MQuD`Q^R'r(AhYP&-gQ03gYqLj \'*< :0Z=)㸪EB-٠:^6aP;VA!XTfɇz qzCuHS&J+jc M !5t~2rp25dvb7AWuN2v4*@;'|*Rn01F.]䆫?!TvM"sɞ[ha^,&g-oǛ%J6eLȻen+ѣtBeQ|U+uf Dʌ +c&OµieaN $;41cMwD'@kt!W֊}\82v{qXB%f_& hqHEyB? j# H3LW-M+4 ׅL(=-an^k.O)$TЍ W+tL)NIY8$- bbo"}vz=n60 w ;(ճ3U9^# 3Mn[IFSky ̰(0pcoh :7dlu:L͜ykю'x"["^WU7~)NhR&ƅ=>wL)U>Br s ٽqĥƛN@JJgOt 5ojYMwL%JOMbm<+gߌ_`5_z0#ʣa$x8wܣ~d)_GI@+Цt4(NeV>|E3ߘӴa}&_ )g_چe3ԡ9J7i\/tk0^90'-<^ӕ9Iyd9h%5[ ;ڴ,ۙXTn\CN`TQD=qt}Ԇvx,YhtH*=WelMba,O= {C^'7{7Qq D ,DI.f|5qE֋DT+Z|lCDh>4˟(gl? sNV\˱,ͣbA-,wr]!|3/$(F.|!&&Bd3xD7 UVa|&S瞦zJP8 dlFaՁt*Q҉k 2FKbv2 `}0lT( - x\5ckfŗSc|鄚fj9 oMMF Dg1Ih`!IR'9LF޽;j7tbYl "9&7Ͳqed{jǂcmP,K梧>S}7yt,&;HbIs*ZSFkwe@^@CXeGYueF Ei#VcюiUr %o]~{7.۰hC;z88CW n/HD7hGsCoYa[K]3G~toOu?Ouj[ٌ: DY #mu g(<*/yVj7P5L"n#W{&LC۩ 9Ꝃzu[G޾È1A&9pErcc@37(S-ؙj<B7(Yw gʄP<0H#:=!f'Ozwgvg{f=]*dUǀ_F w2n3ij}"Gw v҄a8ŗgT"xlD^W*g>WkidиV99;${.A[IRQ;f1l3\Y"Faࢰ1_MZbߓk{Es`cw o 6v :ra]ꂴ$͇R,ERqhz8PZ9+.(mt3#.uS8kVerdPh>ohoI?vњ:d἗QTM^<"׋ "X$&ouߝkkLIdpBhjhv}e,dSF( ` N7I}\SQc7a{&(>5BPF3QYɑN g/7d8@q^XMn>:kR|S)Gl/)煘vDڵg;.*zc0'waEf&[_b&6uET;MLQ@=h\&zƬJrsf3ƝJlXFVv>%4ptf_,Fag<. VxqڟB`Dn r\P~׆-=yص|n_[^v5%z]W!{fx# 2@gx3#h}..l;jz:%pɁ -.?#tbG_(hv?}xLߠ֞@ݏ1ypI6 א7:-?Mz#)<0Fƴ0IFVzNܲ$\gQ85>1tn+eN92eoEʤ?!f91ieLXʣ^wXk+'oC>|~҂-Y ]T%O}뭵'o Uز}AXInLA$ |5v|C|p4h@ QWJeҭC-CCEم8 z¹]`i*: GC8ǐK sRc Ot`Aҟ-ޭv-W#mRga\t;&НTΓ݄;;f ^ȭL,Q~@;$9hqe[BB0#ӄs_o9>!e[V2K8.)GWAIŝ{lM39j  vVnsCzd:K=a_fi8 ! BRHũ .q!Χ (Ie1]rd޹=Wj6g˭>S,۲I؇Q Z@yn&srR[oW0Nb2ѥ`giN-]6IRJb-HɍW٤CBg*I tɕ- N&1gd> ҂ OtY$/nQD6q? U@`TbfI'ětdB&ݦTOFV61-aeOT vB֗'MR+rr ra2 ~APrzqJ\7d\1ˬK>,g¬FN=p(³lG%sJ=>rp+[++';#20oB+UC=C>T$tL.mì>,sqtK4h~Ē/V>W}G_E$Fgrdf`9\( sGG"g) /pZ~KT=#Zbȸ+Y"=ڂ_ԣa O *GkmcP?#EXO0S))`U %??=JO &Ԑ;)2@ }Iץ(i*cxyxwZ+UБoc9rP]DŽ|2{;K@oyhkpU3^X&P>*2>coRU_e$kzC3gSkb%~WlŠ2bCj,mL.BZI_!K 2jXsqߋAWD<f!fSz+GhY{ x ;ł΢mleҙvGx:1&~Z\Î11}(|EXYUqӨb/L9yϋ0c' wl<@.•q\(Rg3 ,q|EE!>ss,MZ/W쒫6|r-'`dQd9|9BA-!ajbȢ9TyM}bTe@q1Kf9bgH67QZ`2+3܇.,-tje%/34bS@ěc>F+ѐOmGx~hwFa@'W?Nf=lQ^)JA 邭 ܞt-WgWUwu?}&nئma+=`6]y5u޹-iwnKbNX7o (S#ti}֎T$v[KwL ruMN @xS\#]w[-?|H}R6>_  rLTw;%şJ(b!Ŷ-DZsqP=>>|cx\с LE,@bs`aXu\!T5fnRGAVxOC.5c?(\pv.&}+2Pލ9UTN;ësUDvV `B5Wqf ,^bn3iN/4hb%t~S~2M/t~K2+ =~<{Kc,#ntp33γw=|:ZwֶX]P ZbSjʕTf ]2+^II澨sm͇ yX! ^x& ̵/'zuS馓ic,43f*4h~P{6qOdgѤD+3W̘i 6P#Vb1uBw$$x~ke6 2 #Rv *b.NHL50b͡653o sKl\ =+ňZ;UXz)#&uPW{%_="wf֣!a*c\>L;PPF! ("x(D>C*5* )*KTqc8Ma*셹v FbN iH1$x)/<l[k3L1D@Lhjr it|ܽ[#uNqB"KwИm˷"A;Ok+iOD uu*ză.$|_ڡ5Ҧ]yRK3 >gH Y-dr@;-R)y+-' ]n~(eDRWSS& ԘcMOFd2y |1paBQM~k.eAbhjjftYЖFD6)W-+=zH|vbR4{&O&殢ĸta)9s* inABU<+sh'cb/FKlRvO@./ItQ7(L x"Ks!<ߞvR(р"$!c!`:?J1yNɺjMcb\iR a \إ L*͊|e "`W4X!sml nаdՎƞh v:Ge?@4{ttt!kщYKPH>GQxC.oWL'!}2=tQOF!L: ?  EՑKUQ9~a4ª#Fx 1R/9wP/!ݪ^UU%nR' F'4YrSj}Xϕk4 ȗOW$ תHT1NW0/6Y՞iyb5\4ra Q4HP'$''KTYR6ڷwy^580簙Q|aC#: 4-3+ɩaP='%$~ ո]oE; w暿2" :vbdLәXR<hB'X'P]]t]:ܻK$bs yQX,*D+G@P]<>lNrL WKԑJ:Zb0^*' 4I{GIR3O .o:U{=\"|݆T1{,=Q.Vjr7b,[bM 0|8oŇ&HBɌ34V>2[xtrfwv `.[D=ԦyjV_+bT'E85[H$*oJv ;~ MGM$9@A(/__ff̤w$  @lQzr^U@Cr]Q|Sga\;6qI+ZuP/AeZ\ o.a~I'ܛ$ќ౛DG)4[ I̚ )-!xshHfɐ8X!o=OrNzFL+ߘ:;ظ&<ϧIq9Kx+f4lIfRwQ +;:d'/,SY )F`[s4k򖐰 BQ3/b.S6[Gd-vp+;X$ f(xw,ࢴ x(_ߠXS 쎟A,v&CzM뫷e6z327)M:_D=LgY@ư]*J]fTPfaKY^y,v) #AUviQK$V!l!bPۤjgX?tn|U=>1eZ|6[l3E QPJ nywP&.Eo&} ehǍt=%v:*Ҁ]b1U{fvi\l䷷$3Xz.힛ieS>"RbSl*ݪjCm Alan2ΨEoyjlė Be;5Zm*j;tcG^[9:L#?mo~_?V"!}iw kNHCQB/ozyPQ(㣾 .^+^WhNt/JClRUش"f(I_ڏ> z`^QF#BbՏBACIü8'3 \GˋꍞPK ^B  n4com/vldocking/swing/docking/ui/AutoHideButtonUI.htmlio6{h rLwi±N΁颟YcvhIe;}-i3DJkЗm=<]6nj(YֿkUoO)jHD|Ϧuug EghudQgt#ר|8TBwx``T* Q{)}vuߟC;.jv}p`xtj_:~g'Bg'jDWB\|ُ"{A6x/:{x_ѹybх%AG6Kp*9a/*|?Jg?(ӲŬqdhd_#a@wʆiZɿ1):F7 ܖPwG$عdQrpC;6W6wrwG\F#_ v~Q-+OG%cIbWϏdPXiJ C.av9G~?D2Q%p*?٪>5j?ꯗG}U@9=i{m>d,wȾ*R̹$(_Xl1h<W󯗣p Gb"CPehOi䦘Mj`( 3W9?0exQXp4gLfdhH^Szm0; M\'}V䪙 O߉0@cߊ3MsRuH?ˡ+̠_? :=n7dsEäsz~F4Ή֨6^mUQyjUUG`2;)-e1$^7M?U{؄!laL|x1Y3y S{Glf,̱ۿcG?e0=`>QQ82jJ| _4ac^aɋı /Jd)b&:{ =6Bu6#u?xsfr%Y"I'O%b,S1bFOL,DD4V7Z3$uW ,ml{zѨօ9zzXyFn?"Ժ'2*)djse`">aEW mJ1OZ?p =61u6ߕ]X\gitXV3Aƻ!FQwRC\om~`p釐fM&+LyW +6p'Z҇+$\`S 1FE4XN2 j H!nm̅"q8( |Y3hm J!dǨqu2ͣ8?6s DU)?޼g2|.W-Pʧ&"V8+.,>K:*-PQ &TUORWd޾#̭Uv 'dK.F>q=4]nRe\;7\W×0H?FǍNʎX=C`?DžR48I𸴓AzFE/jpΗfn׼ :>P@,|%CAOk +N6,DZjP),k/4;A2YpV,8rɗ{rȝEHIr!D1OGkxo$=MPfgcg@=':bKJ$#SGi[#UX d@%KLSkjljVϭM3Zy?g ~i 鐞}o2f[l5bqA^d+lYb7oq,]x%Lbg1e&3Na $1κGڍגk]W|[U2AM0="@kD :$bS r 'sWJU`VꝆ?Rɮb K@,63ۑ7sY:fyrS!XPS z5 %FϡtT fxo+`1*McTnBP'ʘ\˫qx ر)bНsJTa0钻3Z7|@m"M[`VHt+ iu4z/mob S)vG+c[k]{@pcz]p|k^2g3|'ow v7] SSfP]qWO7Ƽ+Gmݪˉ`03ԛc6yGFOㅪy{d\x-w6{IoK@>b'X۪Ԍl]bu[WGZpm(ӕM&Hٍ0}Eb$ȼ}wn`n;67MbwnbD>}{6 Bk sgVxcrB81JK;9ĿKBcO=62R|+>yTjUoAOC|#:,yO!:m9]np.Hur#Uv`uwHU]ԩ da #K%{]{B.yݧRWM1;ղ۫r6y^u;"Ftюono Q?)Zsw+Ԯq>S䙲^PDxz[x[uTn&Cto E=_^܉G<8~T}u~䳊 z|‹$w?%o7@b1#_Kt^'D)Y5?\ʷ4xsȟ$NN>ċx&-7#fn` J;PK ^B H9com/vldocking/swing/docking/ui/AutoHideExpandPanelUI.htmlko8{ &@-ޡmcI$N)%:bCZCR%[~ŏ{1G8yP$}Sh~u>/YYQqy?@JB/eq=8ytﴯ_[q.IϪ9RAdp TT t`/ H%Pg>v$0<:mCps%=:8݇tld,I%#z,g=C_ϛ}=!_;(.U,@@V-5Te_FV2"|B0HI a!?"ݪeNo`Nzu5n'R{C_ eijJv|h2b?[m#/TTDתbVQ`O#==uP$Z ޿^8Qc(V]{_.@0@CG } U2jA7u>v ]ֿԯӧ2,2L~GwО4J4:gZv@էZ Hىx|.922"1mc *"p4WZVҬ)s~ K1+ZxaP _qJM+VyɈw.uGˆ*T4AZD}Ka} YnNs+6R3{Nyi1P]L3]R UCjpz(D=;bk,vzS0un"G=4&k' D_K%D̩D'*ZZ j4.@G T:i"]%G2Wu3wcs F@wՈ3/%!Ų!`:W 2.Ogt]P*4fɲ݆2<dR_ (l-IPԌ y+1AGsqID:OGI#ؕF~Me,> Oz)TRUxQVn0 Y^dN jonPޮԊH՞$&N[T6;fi ƎJaPNII:  #O"*qmTE*";~g`,RQF\S2:^SA]( U.mo,to$@: !2O1ѾBhXʷع!^>m&V :'{o Ώ$˳=Ӌaw;҈dsݏd\F]VSEnWkJZ' yԅ1$HB&2 j0OJuz\H6D%.9tT\ uH0hc<$9 #އ {("*2&R]BXXR< Ѻi_6ڭkts{qQ}1[, mwޛ& +<"{p.j!H- ?hbPU3qD )Sbky&O"4x52!~wydnlڭsc("޺* K!(B6H>u.'M2dFz_:^,0x~|ռ?..> .@#Ty/AY*.U[fAH,,e>~yRRpIe2۠fiFF!-,eL2T[ji~_Py{yڮ@qf?fSlSWKQPlڦvj6<)l1M.Z\-p=,ǖ}J 'ъ㸼YMd$^ՙf,. ȭZ3W#t͚Y,:DA5@TW"|U¿!Uc~>m׶sϬz%?ևי k*O݋_i5ѷg)9Rrftn.g&OtWz<"{_;Q x i`#ת@D@@<rBMi6woPK ^BT8 J6com/vldocking/swing/docking/ui/DetachedDockViewUI.html\o8^W PKywh{6E~ h%H~Ç^i/AHg8yG/V)ҹ8GW7'g dU_ iv{{ou"s*hc8BG3LɡD}s ĐwXpb{³j_RK2}*Y"k!~"3 ؋N|aA<}@1Iġyo޻ࡍ:G>jviKPHIvk7J&7gh۹|~}L{_;X Pjy UKSG҂QEU-.BC Bm;)*ƫV[+NE{Pd˾ҥVMW~hxlۦG[WD`ԪF.VQeGʟG F 卑l>i~88WAzq+(*Ra-bS!CB +[g#DdG@n!BJ^/!aiiK(QRH9сF$T$"^WńNGO*~Г-03P Ahp:ct%(|ʈ=y8v樰.xZd3PnÈ2MY]~IYZ?I`detn_[g_.?e\pHt3o?SL@@E%#Wѭ# Bi g /PϏz߬ҹ)U JxՓtI[-Fj4ytsz,6 OPnfSGչhHNYNG&SxM$W9;@V4y *kAFU? wLF2s9l>m<4odȉI\~SCMh{%rQH&V-5ͨ4af x.V)[bgغzYԲ ŜΉSC[-ST4ay>[>)[]afP G]F]]B"d|JZ¬ͥtspgyF{ XR+QםbvՎ=Q\(ٞ;{^ރg9d.1!xOV&\~& Wٔ}jR^W7N3誡Kd阨^B;|#As\tu$RόI6W:1ѓ*?ϴF\Y;[ L[2<ӎTi{봄S bfN^ om"!3,7g?ؚoD@-¨O;>QLz}& V156$=FqGcސ٩^rzi8Kes@ͭ/ Ĭt?n([6XSV\2HU TNZN"k@U7"0ׯ27p\S59jrr,7گ.|B8@{{+6SF!6x6y-kqtM8*I?PK ^Bf6com/vldocking/swing/docking/ui/DockViewTitleBarUI.html]o6 Kylm"q顟Zm6Jtw/,˒-'zĢ 7Sߝ\;\ϝst}w|~FFò}жΉ⃹:BʨaײN/ d }'չl~\0hw].5h 7 <73 ?bǷ# B4wwFp2hoO?}C'wbuSO8;C[Tѧɓ<sGGgۇ, $aA_}5 ^Oc.P@ܦBJ2,; 4Hi0E&QyӸɂ;/ohtĒy[T[;?\\y&ۤCz[?ҰHJm`L~F&jmʲg%zHgYR9dC[_@[)" CCun?$0-J0jt9頫Osu.~?>* d8 %%~*cb٤>訑ҁ#  :{4WQ(sNCsUk/&GugPal8SZ %xhh6OΣ-7!&q* ,X@݁Ӳg!4\hPE$J-IFXU"pƟKw SE?c5vZqW53*:bOcj)S;%P2&Bg84#2 c1#E>& H*P%xѠKpSU._K p' I$\n8K$""4 @H&}UHjx~ר亲sYPP:s/7Qԅ._Μ)"l@!lBb362>o!)[=(Y&ץ@]?0iBD\w kg^U4R A>Y'X w3$XRh T3P=^f]%|AOwraP`)t`whDs-'eNKT݁&]\_~̙`I~ b-&͎; ez̙`_4Pޢ)Iz6Z,ŔMrq yT &m<5h_]vnڝ \(sGLg^T5e5A>H/n~r;UfgoJ Z%_!u˺ۋ%iU}evgE cJn˚si=O7gh#ư=83{[aͧrNyF?E>FK̚Nyںs3AP:}J uU-z50bXBdXg˯݈kJ~@cmqg;?!.lP !& ;4 }3_s&]?$N"y( o!"ιMZk">>fȺq7E|NN#ι".TTLLudF*"CH0j{AkXĎEm@`8ywi#Q'8#53C.Z]o7{vdsqbZYzW؅.Fh҃c fM7T؞kO7*>XKDya{q#6t%2YLȓy7JQuT҂VGEoeu<]GCu?f:;tJ'YG j'fр `QZPP1ZL :`r9:;ThZ!Orˋt׭)gsK%g D|Hc =+VTU7G!%vk;[=Kj^n;XE$UN8XU$N8:NŒ: aY 4-VwW[u\jX! u|䧘ui.o#nz j23&cm{S׀侢#?ij@I^j=.qR몳=7_t+OfW7kf{NbYa dL+T>4QC>f(}!Wj6YHϵ7U}5lnG_qh==o3h.܁=廲Em>`*>o՞#Z1Aç I쩐cn>K݂PJ)TjMPԻu[U fnb^PؙWԮ8UTt{yN.^Kqttt㹊}XL^VEI^7A+4}QnNTh~gR%Y](^zU-\vW͟=|AYـn59u,\΃z+Vvi1T]L+ev3 9y|\]:JϮqBtUws]f=w/7{3ʽ=3JoG~?zAOp*/g!{MxbΈ`Gx$q}mT'!сosf.k_/_><@>:?8RkE4rIw)|8Egzmdw7QtaI#4 1{U?|%wwB6 = =/e3fQHM4M ܖޚ<ie=F?tjoc.4mR!_zo f]l.?W6? EY4Hd<۱,) K/=?v}=0q-Y 9 *B~ BHh6,>"j?߾[]T)@ |Eo`<^,̧I9>gw4g&'q@uOo# K7C+[ ~Ǯ&`(u.%t۹Y<gzjXPf|K;ԥehq <~8uj3Xk ǟ408gIn"5mԜTƴh ţCeI#?lpFR/HSTjC i=L.U)pc3{||is,P1e|&пB`CMۄG) GbKS+EpECpE^Eə#,eG[g{k lͷ3yQ.c!E')e"|eh( ih+.\TOeԳ@sNVFAM@UCca fFB]2ıA D !7 ;@ \*/#92C;hCaw ۖb +[v6hӧO 9 X◁NT_SI>}w`*'g]t}gŸBSZ䎎dҀTaHuJMcTvƑݵ=|oex5E-He{{G (V6.e* N-(1kpΗ0hV-?Bm0ٌP )!UoXh $' kC]_ș"հ}"?@1뤊V4iwFVBzKVR2߳`89,q?\9>}JZT{"nh5shԬBni*2/H# "be&}7BJU*Bv-fq3ˢ{qoE\[6C8ҬiԜm!`m0FyhQיMLBu؋fKlc̈ 1}*(,]ұ|Sp+lIQkXenmVٹ5Hg oBt}&D!Ff{h]O~M2$WȝW[kjZ5 *j6?SUOh"ؕYcVK)1l!KKl2pQp4f)a6:/C,e2tImPv Q`4f)`-Cq>M*W<cܻ8 {'ٚ[t8|C0Tr jj֯6 A|8│Q'|Ꙉ[a%eRPBV?PK ^BM½ \[6com/vldocking/swing/docking/ui/DockingSplitPaneUI.html]ms3TvMfd{ۅNI6L 駌1e ߣ`6ӲFHG:::_uowW=\:T_wT;UN,J<♸ݵ'bMI;=tFkW>ʩr.zUQH̱! @myZ ƧyI'bՠt@ځ~Txj(/,Ly1dɜW6_Y]F7SoX~L! ZyveٟUFXك5AU q٣eY0CPdMP hpصWGef?4]܏wU* @Q 5i;}m 7-ǚ6#YLX6ўqAB:Z)oĔ}Q8qB\,f0}A ^ʖ5ҒU.s]+?6%S|OЇDjPDK`n4aZ-H F8q VUc CfؤhY˶phƠv!Ca?|mCj0sWf%,es*Yvs5Jt}Fu*mM,kF?ߠO/tvhcO,F<™meo}%"3 @N|}e~U~X4un.CԽ]Vc6㈙F{$c(m/(v{{ݫj#M$k^Է\zYeE"jEfASt[Z1YbEjeFWwcpe2Tc,]A3zVvM\m b-l_tKMi ւϑ*fMZlbr٘{W";s(|P\ GΙzyf0src|F~Ӑo[ұi:a9NMw)D q.'Ei# Unq#;DqBd{6~\ C0<Ûf2mWh&(dgbu7*>:iX5Ho˥;AR2z;GQ*Lw GR0նjt{54~:?"(sc!mQk!&A& km*'`Wy!S{-{ #1ۿuk≶0}>)2$#Y16k4>ǷY_A s cI+^fCeiυ>^eD ʃM*cAK3&F 코D ST><lj+m+h2$s|mXRLf5b@ƍ?eb=Ag58`3˜wm6NХm֠IM'.r'w_1'H 1OF~7ײ"dB-ױBTTiErWwe`\{j0.Nۼqo* ^ 2[DM)9~#B"YWrCU# l܁:;3b.SΉ<'WsfD9R S\ڃ IԌW%$V3*?8G1#5NY0K%;tB, $0jd]1Ԍەʕ4B6|0U3ԌzO j6R %VMlL]Hv]lG'cd*VZP77dBg:CwƓMNd4P=hhR'EQ6aS ɮJ"+f<'To=U^BgBgcgle|]?kUo E+q,=EC 72|DϊPqO EEN 7VߙH8TC}zQX?pTHVl}!M_BQ CH{Qlz8&ጫÛ/6~[qy- Ow$1G/TjO@pI<z,qqVS.Y.lOl,3}ᴣO0MB/5M/UYy&̓Ni(&behȢN?_fɦdݶ6(AI|7%?N?_;GdPCWҙ%I_.?Ks/:W+zX_ 73F=,d1MG&+3}wIГco <фc7ߒw|197Go5O6<>_ܱ$tԅCLl'9rސ}U YBI :!.&Oͷ>HV3ƒIVL !M*8#|йb o84 /؏/A\uJr4xĂSGX\[~[_+^m%1c1 E1spZ:գA\e 藮5@OKzNXb"R0 ux}Ŀi~?!PqȈ-;)GqA SAG=- ~h) # y% le-ѺwIz$#H(iyE;`\q|YC`nh{V)bpѕ$h=t4<`tuukp(G-څr0tx,wXt:wԸ a`uC\Պ!3g=B^~p"rq8Uߵ6Y=hR5k pgGx_3I>ou /Гߵnޢ}jmLwpTy'N!::vR(}?.O j(tSYYQ 7ޔc5I=63Ԍڋ·Lpb? q"ttܗcȗqӿ\]v'e8XI,3L: ^o3 %l *)dόisX]>Fk-&oIX\A_ gC}!lTejh@cEN4i%O2aXSѝFf䀌I, H9 +`^WB$vP b{&O׵ME#\ ! u?QN(uHH"X $b^v3 %$'0}Xc  J2'X|(=xtLx j9!0#e Ȟt*;~Ÿa]ohOG/TbO= ϊ ,g,M3~;K@!OP(8mC x ^ J61=%VYd z$EV,YYNlR*B؎F$M?loת<4ll (34 Fu/r  )9P414 vM=3@ۍ[qGbט")b|MߋTك(bT_H; "IvKd+G75s^%L\35]l gƊhY.VEᐋ)oƗ!aഭo\& DWĦ,`% j=~ ~r| ]j<4%/c3ߚJPYat>"2HMa#iRk+f"qcTQxriidF'MۦTJJPKʵ|V=5I5 /FBE@jYY(v^tEM] gð񨷈`j.8ҷ$4n鴤vT;-(}[Zn%)EЖMhIG@$g*ZQ4.n5s.dtS9?f~ pu-:f* }3^3tbGbХ.ISMصZaltkf WC [7& ]9Gt@Wa#fZ@|B\u gs@:203!a뢗Rٔ.h DS `jSoȄ%K {!7(Uكܛ'<[%9~x]7Žjb?[!SU<p%qN(OOYA9^ր&i]+9p3޴Є7MoiƧ05~+Q f Ov@#W+yt3>фGQ( viZci¦Hp klr-G:|9]ACY2_Vڴ:E+R17GWau=*ŮXP[ItK?/$/Ҟf:kG%]%TfVN,=0І `ϙZőe)VwI̟XEI#!..xzݲ'rd9ޅoF]ow!-Mؙ)Ի"JM\'Dž.KJk  S7⋰n/_bN| R pJ1s`1d"<4r.>6Z&>B(\b 2Fz /_VGIP[{$@,(ӆoA9 5F={sIE,jHwΥ(V;2ˡOB 2/3%4z;F>NEtZ"I,25QVu `[p,<}zAc1~qw[:I [ X 1./g>uiH&\d|0sY؇q оycc?X"0`t6iأiqgu͸M \kS6!I1w[ЮOxM(0RVdJz˻RTѡ{'"Yry#s~y5*5u6e@s&8ਖ਼ -4}~s)&\Z'Ufwht Ef)kUA'0X#)GFceY'뜽9A|8<#w>F5&ѕ+sgoU: YPh&^IsK: :[,"gx:4DM0+]yR&/s0Kw̿Rˊ4O9APC34:T%%β<Jm39E>h%36 2劗\O+eYcn_ $ML5]aDy,[)i߫K_<_' (TaErebTfɺ(iVqYٚZo49ޏ׷kZU&)(խYYr۪^:dE5Ӿ2!ՈaegNZ# 4:qV//ENWj=_z\9)Y1S9 ^*Y\FBt?s.o'"%}XniJgÿj=c_D$[X8LTb;Dg%dIU>.ME(iX_wm ΰo׉k[D 7^bؙt''R5XsXBSݧXZdiK'EuyleVI&t*DyߕV@W{c|Sp[F:xpɞY)Q8J%bIwkh)dq'9W mI 6.B1#_=ҕIb2]%XڳU(~YZ2]ysئWq X͖V!RgYe6[Xٰ*سԐM6dU&ՇAguӖ_X!aϼ dV-ܲ Į=3kɚU i֞Y,iU ơa?a;dh iGx}Bi۱LY!.zc"@̙HRK֬f˛A.[X-Ĉ+e꬇h;3/Ӷ\u@KpչnUUm}f^gQ.b2OV I/֨R,.69=uG}TF+h 8e* LuK{^s{K=0W8KK-ț{>[֝ yU?4K-H햒sW\K&fDKNKKIހPGڭ F폷]ܧ#KutD;`\q05L<[ B.Q'Ax]IVTNA/:B@BKxB.CJַ;O tHe1w :%_ z0Pm,b(㐗A}H6J lkhScEԖjv3@Buܲz3ݝnx;UJWe*'xIa&OxB8u;7GG_%~ {A rs@~$)po%PK ^B`{Ccom/vldocking/swing/docking/ui/class-use/AutoHideButtonPanelUI.htmlXoFaΕz^ Va*>rMN \էh lYUw'AQpj,d=3n:K `x]wq CH7fμj E# \pko}I5#R!f^hBy|xg!1p]K\ h4|°@Z;mnkjAN#0Ko%PG3OKJ!k'hH#&nxKj^իCkx} %4dB,bڋ X/n]a‹.jLҷr1B-[?mɑV| l_iԟ ۸r Wf ω(Efk5oS]qvu\Rw:GPcE1,pX 33r{?l0m06)NJ,UěxB:ʹz6U&Dmİ ^(\pb&vr˖nkJKu\L.']aoq3J0;TlFў'E_8&U&=ATNlSJ?%@PC>t1""ĄfF2b;%XS4w1~Gwٜ/dBe[,eb앪:[SjF)ԟtʼnFh f_gqva= ~ݱDR9+<|7/̛@~P(f엡yepSM\t`3*:2`h6x >%+>Wgntt#lGKÈ_ lĩŷ .PK ^BC>com/vldocking/swing/docking/ui/class-use/AutoHideButtonUI.htmlYo8}LZi)B{QԲ; ߳h˦NtC48{qNݿ;:Nń$m/t5[$#Fofl7QzHgdd%Jd6=chYıq@P9L#&YO&eЛ?tJ3Շ)N{R9O$_ΛWwB[Ȳ h5@_@\3sn“Ux&*>c8tfJ_nRK9#AJ3KA4ЄEIˤM#R\- ./A3F3#lv#eW` ,}iOs7ٓҡ=ݯkEγa6j8?~O]'>2cWH4B zžoCB ZɩFs7'c7(4?"$DPqƧhy7qC{hV3tGbjgZ~༻օ#v`|Zy@ٌNWyN%@$j@AF[\<^X\EՔ}A @,bh:axRQ9Vrڕ׺"S>r6dC|U. V( IOʳu,0yT4U>w%zv4x75,k/  ysD>e.gn3f0G^Ӫj:T?PK ^B5|Ccom/vldocking/swing/docking/ui/class-use/AutoHideExpandPanelUI.htmlX_oF?)aΕz^ Va*&'qSY]ۄ}85?3nџsvap}ֽlQND&.*9y͌IO Y.(jJ!8&BJ͂^]C-t-r4Xxf%,ah* 4ZkP\Q_'P~xZ?A'zvT2ּL@[Pa,B[L.A+3.I< חPg?,٩'eVG2^٫+M69k<*Bw`<]RrLaFe!!C;GJkS/)w;B<u%W6n&\i2LLk[(޷)q.8[:ϩZv{~AvTXQJǷ8,96Y7q Fʻ *uiЫ^uC6rxFU Q2,:n6"T::kvK{x)L2.Ŷ: npm)~R7Ni|Q5e8Mf~*IxɨǡEtdo 9Fj'N/4hԵH10sluWЍ{>`b C$eC>t"m Md6Dw`Mݻ|)Z{ Z,3R_]o ]Vu1R(s]H_(OlDhugQ0;N+<|7/ơNj@~P(fBwM7iMhts͟Htf^{G Nha'-!ÿ BIPK ^BOx@com/vldocking/swing/docking/ui/class-use/DetachedDockViewUI.htmlX_oF0J=`/\0U8@Iէh lx5wvm$X^ϦkE/SU <ߏ[v$ R4pPAeojLzFbǁT Rj&7] ߷&c2Y5,sTLi4נzW==>g OV;{~ vjey9ZH΂@<za]ƃ63t4eqI-nri A[HuA5yAr3ho Kz)_?u! ܃b"Y 2EIþ2ڃb { zזԓ2C/UOͺۜ5m>#jXOb7G9 B2# õfvQxW{{$.#5\ӡ~ÎZLPɅf*hlU+=\Gz {~{q>(:`dƴ˴KE:RuVBP˖'}SyUo9zm*sMwcvs&JGQõYLvoJܫsٌe`dAۊR:1!ϩmȪ.RelwWn xBzMˏZKU-&Dm/lcE.6fb#;0}5+tW5S! W~))?0Ʉ{jm[l,AIї"vB8~3CՄϷR+a[ϓCLmLS 'rlu<";(BSǢ_+/ˋU\y"#7Չ" T%j9N|'&4W6 [1e[SwsbcDw.D(TUk\Yu㗧P5F|?-5ƂMi6vR@E/ԡ4Fv"uh.sW~WAژQg..{ʔ0 ؄Lh=8 y`ɊOpi)!T$[0`:g1~H<-?3PK ^Bɶv@com/vldocking/swing/docking/ui/class-use/DockViewTitleBarUI.htmlX_oF0J=`/\0U8@Iէh lx5wvm$X^ϦkE/SU <ߏ[v$ R4pPAeojLzFbǁT Rj&7] ߷&c2Y5,sTLi4נzW==>g OV;{~ vjey9ZH΂@<za]ƃ6.o9[DV􂪛+v9|PtRqP p޿:j ڛ1C!AЋ1%%&S~~B<DiLO3e}5dSơd 8>g?-٩'eJ2^ګ)u69k| !G;ko\y˵rLaFe!#+GJk?>!yI]&ay3F~kC T ٪ZW`{4,>@C|P>-:uFii1e$t>髭-OHGUs>qT›6\i2LLk](zޔWX=_gUw+9*ttcbCSawUw]8P.@bB +BF1Vrhc*6XBG{E_>qe2Bޮ LKֶΆn[ln_]D})bo/4Sg=>TM|;)ޞJ</8|ty>r~"hQs!Ӌ (4u,B R0X^ŕ'8rS+XX.+yW'; tPɓlKÀZ"woPK ^B&q8com/vldocking/swing/docking/ui/class-use/DockViewUI.htmlXo62iGH =BoSeG$@)m٦pS#/~ߟǡkESu 䚿!$4}Dn1_4?7yk:X_XA+)*L b[QlM7 Gz}^]^ ʷEš Yo12F,.T#}5`#.Z3QԂO\F91Wڠs=ڬt*&%f|N*k 3ǂR:a[agv~XUd]UU)g'N:߁'/TtМ]RbB 3F1V8p/c*6BF{M=\>qm燳OH}O $Q쥭{KWleFώ'Y_ Df{ʆ Æo_וSQ{+1CLt][E.Ȼ^+Ա+ruWus>`6b C$!`=<t!,ǃoƄf&2a[{,㲻v}myW~؇řFuwXȊC,.xp ؄LWh=G? q`ɊOvpi)#$]a;sb,dYZ~PpPK ^Bw@com/vldocking/swing/docking/ui/class-use/DockingSplitPaneUI.htmlXQoH~0IW`/NI16D)Z{,^kw E]ۄIX^wfvfϦkEcu ++W!yI&~EF~kCxCDd`R34lMm nAнry1(D0Qceڥ v .Tݡ|UP#Nߘ7ԂO\J\yݘ+m0}rڬt. ޯmꂳU`b8&v t46ϥOm]d.Eʻ]t`]'Ϡk:,?\F/j1!jG?QG8<<ژl֬^K6O(l\էL>$R쩍m{!X+XFіGUحg@LfO Fogץc;HW®Gω.O^O:-x!D޵a> K~!Yc/Wq(] V'0D|CSAW"rfOLhvn"bJX]wckCF>F,TUk5]Ys×P5E|?=5Ƃϴ}[Dj7$}ًyMP#{:t8Y󿃯s~QFY%'>.{˔4lBEK+Lco}>it[aN+ ۽{:oCOD1DBxt@Q; z_\EX^g:73fp"&v͘8_'M$_?dFb1ڌJa;=_n> 47o5vALs!ԸX/'K|c rJ_nA:ZIDu93v:{60t~jf8f'T̙)"}цS })`74 2QiN>@ {, huv GHBf}"/pHBb9?W,K w<>G|,Sn*emVTF`&+鬴 kIo[bƲ^=D(KfQ:mƣ#`͵#gX 14B3/qr/7,(#td*_E@85a\F- lXCbE8Y[X.]j(WtSD$DZQ_!w=ZN:bRUNLҵO :pM}ټ+CCA-lK2Mm}Vymj7DSD^@MI3]g0k}V\RXdY$5.rLʤ@Et_*<`0$ؠH*}s i Іar'JYזmEa&'oT9[ :^GC,7w6J:,iBI=aޠ:H;S5,t mjq5f6pS gC[27 }#"pC9IT~G t"fCFuU !9R3 DLJc C&o+2dT+عu~|aM5KYt9LRDٚ7,cd6,+촱c(eP;Ԓ s1%dJ[̩&ϊV3G  w=!Ʀ]y{a`yS\ZEd1} qioH)'KҌSeT ?N}TW_fnQuz-ay7@}=o~[UbH]|=iFc zoq]SkL&" ԬRpJ4MxiQ8MT?PK ^B"9 1com/vldocking/swing/docking/ui/package-frame.htmlQo0'?}MB VC#$wa;N3VNtO5$_oa|߿ h&9m\iaDd0VU4/f,f)ϙs43= jgA*\b̑gMgTXpL7ypB[{Gպ<;p_J%aE0&Fb/͗t-BՕ;7R/ʋiFp5uYbh8([2HseP8Ϡ!.}GR(cF#f+ >jM`^P? /1^5qMl !\LyAz]MKX3+[ta7)rɋ udy1C۟7=qvYБebݠ ŅzۣAMzO>r|QxUFd/՘+^@(z-Z0G؏p*;^߂%cޮAI^Q+MVRG|X{0G4)ڻ \Z3Y<߇q綬bE|5PK ^BD龃 3com/vldocking/swing/docking/ui/package-summary.htmlYo99i7vftw6pJ &(SdfLŌGr  i.Z]Q c?z ܜ^ G8ق$b8> jr-"!u<3:B(: ?!\QC3cV']']3$-fTMSdARJ5ooC<hv#K3i7h="4hEߍ$3fԆq 2\ R1DdfaװjYvNS5TW9J:QW"2C3mi\c̯J$u]M e)|59QrN:N!5H 7/ 9jı;؉n3~N٢:u)2h*h +10bcؐ0)>0\=pyxi@‰R/,?#18_Z9m11Eݳ<,.Ԃc0 $Ϝ;ܹVKKD*,h]vۭMa&&s75"xc{\@҅m(*|Ʃy<]{T8qM(Rtp.##9'+d1mݻL\DF+[kLuEݎuسS..4N+ZELqlw'\Z[Йi۽9/"eWrͻCJ: mJ6^'z?eXq+~^x)􇱐z'h"Ęr̔Gnp{ڝx` & $Khy:&=FYwo' Kg_Tz~Oט<@ۂ ]]=Y|An{.EeAp<.tG' 's->εـdߜaW6ɔ% | RO4 ĄCLr[aΙ6'tv=P9M؄%;cp3 N&4ѪcPvlSro·TVuM)+% h3,<^H# |?H7 =HmҶ_ B(6Z?/?32enUPw%fl kѦmYmgQ{6moS_@U_[v=F=… h^=* sl+P,HuKjA be8d{/k51],K(| .(A r}ԫ4Q'@ W=D[cf/Z zPBOQ5%CMӘ{ /a{j>8:Uz))h)NjM;gte0s֋(}uO֨gr v/WҧWwc^ڽzմ_i ԕX'ZIu7Eu])M^I'fGuLpi 3goJfY9kJ5UiwehPK ^B2#0com/vldocking/swing/docking/ui/package-tree.htmlZo8>inCb۝ډjN2&lNBJ{ދ9~6NYK&l:lb귢or%S, c!kTx|>wN Fj`:ǯluGFٶ^ѻ'fQS%{?Q  ̈4BxTqtwn.B>C۷G*ZƲS`80aȑsMjr"%:c W*}m : :tNqO"ȇ-5-YZ]}gr Ay͒jS,!P*z+Ƃkߒ1u oox )]BZum/xXGvIהVCvWH`ՖNEnm~ȩ8/`yY33<&ɀC(A,@%1֛5,~.'}|m\$OhA!30n> 4 PL7yB;9u/ @GyC&pE}EͤJtRq.ua98ctndBylջ }KHU/Z_I hѤW.(/(-Sߣ.,6zUؘ 1s}!ІLI6K|ġ.9*B!qd#N 'R`=6\1@e)hduJLYH1P 5G>+;a%,ļdΕ5D ؤ'GuP86k #=O9՗ŹWZk6,`^b52wLksJ,@5vtUrI7fH EYIޢB Vqg( =S :a 5 m⪈wPhϐiҺWFvލq ?0qdXRQTx.jjOQMPn&\Ľ b W[QDZ'J'Eϧ扜ߪ) 1 ـ5)Q7 O. bG K !PncCdCt@7I᫫eUZ2#B&2N7.!GAJlF]AFy0▉hhqO!jCJQ3g᪇"j/6S $'S16J~~圕6EwOQmzwE0f6AyEd'-ۣx"zk0}H{k0D=yOː3K~'f:5'Zaq y;GM{%U .LdEy>y>O}25'>Qg?kvOrS/&tDx3MGwa=˂ U7Jq ICosv%Pv/?/p?PK ^Bdt/com/vldocking/swing/docking/ui/package-use.htmlXmo9^a']Cީ-)ME%ր/f of NTygfƳv5;п:휷  EH{_ju(jnL @05&{KrǑT2 S3R(1I|, ˖}:avǞAIԝ2g?)jXE4#8X0Q<ԣߢu!4O o_~{t jc/p#XJ3 r }:z,Zd|IX9|WtƖRqT~ 9Wd?cBG A8:_ã7BPLā6+1YeHiWCFZ0UlQDrn;ޤpP&+Gg1 O~Qʎx Cc 5g/!!9dTs}=woOTnh~BC/s󹆄k:J,+9W0Tr l.'轇Aݓ/'[\Fj^Y.йE:t1(OF=}ótx^GV >q@UcA (Ef-t[%%bp2ٌUdq4{~iF%˳BsBԲ:n%Oj1! v$bKy  tg^!(Bxv'픉,Ddxҏ,Sp?>uK٧C}[#[t"+wkSw8Yc8b5\Ȁj°Nq.ꮄ v< f{[>R'B@+E2:eİh`tu0ЕK>>$rǸ.ڷGDX$3AW(*b7 7ńfҦ2e%-Hܢ|UK߶:Y.g¼4T>gzT.:j{t}vS&k]HJ`ܾolThiP_,Mn|Gn}5vGlٳ]M&W ri#f9E)`8!Fa~,;CIpڬEg)ӡ'HurM{D7#i!>ewwhtَ" Q*0B7=JCٹLrG3y h^yn 8^?;\pyZS:{O#!4\0U%PK ^B\y-com/vldocking/swing/docking/ws/WSDesktop.htmlko8ڀ-%}HOmѶ6鸾>*Ep83R?tO{9#{NjSbwuՋCҋi="Xf3{ӻubaș 꼩j+6#FZ-,Zħm@3ꚺe`.Y̡{rh>?A i@~%!;ݗ:uaD膃/O1Y?w}DNnǎj-'LP@:`h[uѯy Hg|̘GRpnq̆m˶i[V;,C~_>Hd#TA Iyfc߶-hbe[SAm:l'1O'Cc1! GQX Lco0;524&8qVFPY(4mNn{]ߐ|<5oH 2)@0@7>i|̡XMGELsPovI7 ٖԗh ) ĚNy]5Q>ÿӌ;@Yvɂ`2P};cK0y| $:h! ;;g}zq)5[_J/ǔDx`QHWz^dm[ ޲:\1ִQ+أW-EAKf!]&>8?wKАk7pnCarea%|:>jU|6m4-Y3>5v4>>d$qd oӵk1߽׊ 5[f:a?jf+Es]0<q4witx$(ei7wήNbdNH{y':V #,!Ʋ;L+hɚmq P:8Bc{ F#/jeȓRllư!^I~ ^A5 VT )cLȴs2|KD VT'}o56\bԐ տ7oIT焸HpH(*tj X"Ä"!4B)R;Of&=l+ x}FhA>Xq a1x 1h,!'u Z6Ar҈inQ33‚ $=83r@D#ڟzXCGMM][Wo4 0zP,VO~N t$8!pu8r&U ]^0( z]|Uq|N}B'3O3K1G#3F^X9Zݧ6JPξRy4 XJXQ%r:3uY-%\J6LE:waR kyJ\u\1ozetW&P&^ { Q4ZDN75l/d@&jJ&)n\/>"` 8X2%XApడC>Sx7Á_Kx%*7 Oc1H]۶Z:N,R=j2<(ʹ F+ԸRc+#q%X&0@dX`M\w]Qy`XO<]]B]sdGPbqQFDΖ E}{}uI0(T*oJBio@媧NYFԳ:Uь6q\p' Fp(&tQbOcG^b;5FlMj}Ce wNd7{q*'uM:XjH7K`sY0]ivA?IF)ӴΊ9*:u:`yuJ?K=_ձiD|OcJ jryeC( qs _4@fI*$o&rHfɋtT!)e>@̀ U |UkTwe4c V{&t@1|aN(HiDRIB(^K]g^*}D:WJ-u߰|6Zf_zK|3s-lX˽F1.z %k5l @K@f\n<`t`إ[OWM$*rQeUeAuSj PU>$=:@o ^C^AnbU$^:Aԟy0~r!8\';dIĬdܛکPLtCS%[[i(A*5&9 r0U-a<1=;̮́/ ,('I`GWu/:ghAF=~s_a3Y[t&7;;P5IdeNO|[VzC-:m^_oS}Ugք~];71#J$u)! ´bҶpUFsx-jvbSsU,V| rEGCJ<6*g^\#ɫ3̅mMc )5O,sq8-9m#]5`TNJ0)JP;Ou-Wo dskJ}^/2x $rOX!i󼘁-qmi󼘍)8oimR-V'=byq׷Aʹy^f;mG5ґQK,^P'u>/ ݳŞ/ˬ pNF@ȧB(AM9'+? oYP^_wI'y[z2I+F}6)0ng3g{.zɾng䧳\VS< >혿8Kv{61;456& _n^/#{A^L4?vY :${rʲ,cՒhlu (`xpierQ2G6hywtTH;ܷNx|oY1BoHFE![$, r"K(iyJg9,hOl[BME~&*S73 <ţA#F劣rCEyjي [U}]4-si}.͏:v#+4ϖ'5\~DȰ%jg-»J.id{` Xg5@gMr-Jщљݘm{.E2SvO~7Boןp^bЧ ^xk"QbΠ,X] =qXT)Vy 4NރHrb5Fsy+PI/>9s0EI SN8bj8Ⱦ[-|[H5 SQ(<_J)5o88y{V3]LOyQEfi_l{ \\q{m.@ReCCC R!1/)xI"wן/<Ϙ3Re,뀏?θ$'bn*ƒU:M#םi %8} ~D䂎@o1uiz̣8͘I49k 7=JZ #+(Мqu.%2,dq13l\ia-3\BP]iiz¢hROp_J,*TX6h!`I|*1hk1TQ1k҆,JOG-SzH/aW;iCXo&P=9ƿn,QLނ'w5! ܜ䮽_˄ƹq$e#7gtهL9G;NCꍖ(r:Ev\N{!< 4=LYׂ9qmVze8aMk<ÆO#'ڂ-{5P ƍ UeK >rPnMHuiciE)մeLtڤLM9Ta;g‡E2Ho RV3\=Ko~-7<=6hVڃ%]k5[:gnU4ӰU rXP_k:B |`>uh.qovv''+c@ jGY68p ,>?BWA&N3t JvKJ٬iI"jU 0]L݈f.%u|mSnfZU&Cn遫IB->)ch Dș<5&}nmN qn[HG T!Q0 ==qbd YjxIqrv\XGIt8[xf MeNP,K=*WAeMjH[ 2HS&xn*Sz].38U U$ '_ k-~rzt$) s,z_hbH&O6X d45Q:ãL=ln yo;`sjU{DTB?i_\w>tWկ NTY+OsAV#d HQallC" pv+zP90V}3!/F*.%+mWT`U\.}-`8pg'ws!Q^67"}h`Ȏb,|P+5Z>4: ST0þy䋀:>T: ,Z*;SyepIܰ~h7\ BXaO;|N9?|l5 wUvX26F4H"=Luggљm> iaT1}tZ ( [I#[G3usdYW2b,(PO*dRR[DR5TߧA%:^WM֮cM/Mq3VA|tΌ A6fa#w 7{y+.ic_8\?$y\ ]$4+@ޛE.C-: D+ۘrup7«4zBCt-yqk^7t;7t u敪Ma% 0XuwS/Lm,$yBp܁^(-sctfZȪ^F\y Vm'gB B~U9a~</M%#i\<.#G~(4ށAAExY-7EyaX|;5;OJZ]~͕-ol& ?xkEzSm`VBn"̿٠f{+lZbͽ4fz#^RħA^a*3`ԳeS<ҙOtLKc h9w'J( ?ܜщiKroa "eY}AM9qcҼ Ps$%W~[u+et|G[Fm2٪|m$Qe ɘm8x bET`G#,5j}źG5O5[ꟉLQGii@Fob6&s ^Фݱ &"uʻ <<I8JcM0ADt.tU{fD>@]uB2[}n"u,kZ=lфSaKU0AZ6 lu$: y IܒG>BS$:Z^NhH+mcD,JWT"/pF4˒TQQeW{h_7Y`gh?.AROM!<"C%G3.`d$3Ɛz8eP10y}#t)vՈײqq*{Xo4y:12gYY&veLxi{NVWh2#,YMC$i@:R:Sd=Ets Iht/VܳyKx7B'C_8}ޭĈ"TUaeqLYN2zCR.//@RԌ$4%&jbd-DjDήhaFyYd>4( wkpv!}P~$k?vY|P!'XtpnQbs[xfض$T["#21dAD;t?QÌhx}q{`>QU::c0'AKe 7Uj.p)m\KF ؾΏol_ N혚Gf((RNf'fڍX婼+3$ÈrjJi5Q#]_D znlwݫ" pLzصm.S''XUiwOPkzt½Q[y?:ЄcכoC;1YݖV'_5LY 2I3CY`L3̖MW٩]nWE["}Ļv2:wKtB)a黪_We?UK^^ZҪVW*ӋWW곽jA.c`"k0 )bqu/Ǽ?MM,50PK ^B7f/'3com/vldocking/swing/docking/ws/WorkspaceButton.html][s㸱~ߪ*ZKsٜS;%Kvm%3ټ(SBP?NH6=əڵ-ht7nON߮Gեq}s~9^A7\ ?v߾3c1^o4o?zub[Ǟu-}ݧߝ6qrž tO;﬑i>hZxtvO=AF77 rڱ(r9irN`c}!Fd1ÖRkݝv^_⅟v1 gZp)[ >5%v/pr@ۉֺ#FJ"tV(c帉u.9]?e-/ 7] DtԞuG /1霅vh{wΩ e#uC"vOB'\R%Ai~^Aۨ q~ђ㸥fe4)f-$b` 㰘{n >?Ǜe %sVˁ7t%6af#k }cmȦNMTqIfU]!gWM 9-Q°9sg6TS7B K7g?yk:>ndjgPϭζW>3ǧat,RM,}º3R LK1eM0[#b>]?"ty5}HKFˈ&`i2S[sL=p[T`6}]CD}  J Y'wJ͓E]JyAhR99pMd4_r4~K &csqٙ95aã4 Dɰ6(yxC ,wZ2uͲEs)MKzZEMcqK]J5xBTC*IM1CUB"q iDOꜹHVfd#1cR|V ?u5)l1#uQ;-kLc&3_]IaK5i͐ W͉T gq9ZحߦysmU?ԇ<͹>66:˺ظ$?%b<fUG|1a._g|}J4:ΆuJrFHTYfRUn/r,J{ا SXE%؁KV_[eݫe',M}c+Jd Lu-s% p.Sڏע/:R3ib;q!0L`ɐ#9~Mnhn|NPyn`2ɒK:0ۯpUq+T_W-A-ӫ(^+ 6MXjp-bԁ z9XhL5 r6]0k UJVsTq ViV9!if9QmE+LzRP8/Gx HIBP&t m:[|V@ݪ בNFz62v8 F)M3(tZKDSDTP8i6kw l_* cQU '5 bD5N]"jNSu@xQƣ'@ *8lZfi ^W# ~ 8HZ<VhDv>j TGitNd Y90rGArtXtY;+d[Ӳ0K}A|fGgq)`%d, ӱzڦ^O?"΅\E]`h:>>wjHz+t -\EK^:!fuG)0ICb+%^84Z,!y:vds:L`IcȎ}HePn eVAmf*IfE :gIG~kC!9-TkK۴=w嶬ᾌTh6Yn%`ۦdX'_՜!/Z0=ewdwQ9d K0F>|wOߥJߏ*!lDerH?H}D?}yؠᆔd(&¹)Ib8sz&ZI8ܭ14F8HmPz2N8L$~62%.NfVU Wٌa>?.eεnD^u?DӚᴹŜb%УVM4o@&J*W6u3\욚3q7{Pq&O'wh!OjV]eֵE8.!T/ UX:w~!ib1" ӔcՄ:LBh$e5:l ӐM lJ"h~DFęU$5T:?]zB9CJHyt w곈n7,Q458M!= SGD>ĄgYl728q MǙʰq;zґ" %}Bg}%I;m|vgy"k`-ߔP [Yqz~6ZP%-$hF%Q_Kd+T(L )}:RIV ̚}̇ ZY][=c(õؘevcgmmZ-`11&uϗD?Gͪ8 `G?ph}x> 4gMR3|7N?HKkSOkQ VRpfK{ȼ;!ŒgTApZp@tT,5^ !'(bfcÊ䖬`kd/S5P$\ *GҫrB>*-7Ohn%f MZ 0HjͮR$JY#kxu)\Sr%5{p(HKLDݚۈIf U|;+$%UC[\L%hcԪrW5꼅%V,VV @/yywGCt{Q@ \z&Pm MWbIl%v6+z56W3/mϕC)5eU$m+rU:3[+-͇By6hc,%KKpZS'IjjT|8U5>M݌;nƪIһF;)X} CzJ>2BC'mY}gzGVү((Hבqd: ]B2 _*g宻tP* v/Q y'Fap|;v)?+OB`2aA9 :v|4y>g ?&Kx1r'?E"-ҞߠBriPwKVk#Z &A6v^cw:Gk9h @ *ck/j9;"UGB!# h#5y +XBrnw+ԳudXaw,LXH!Z5;fT0<52Uij _!:dP|B3_kd@bƟ 0[iI#$ƩŶ mMvS^`/ chd56ACQ:`0r ھv5]7͜4RʄPh6B;O~> < ܵfU[2_;ԓBB#C$=3bpPp@w]t+; "! l;f18zIh"]bl/)j;XШ$(ܞj?ek R@*_}az$;dۚ @Iߤv'-+2NNP}jW}ufQ3* 0b2twTwww,T0A MbTf4 uHQ<0] ]InͿTP}Ѻ5LF{ +t߼f,L>47"CzZBI^P߶KـA'd x]у6^7B|4=W%wkL0ĭ:hW{*8j @ڝ|mnQ9V8•{&z ǃj.Ѓ$q0vMbIt~5 9HfE2 sp3=)8bV"H܃񳴜vWR9jCӈq ڸ$,6ꖃG@ӻJV6Ψyм+|fjv*ŃOk}eI/`ԎI0U] l]n琚27 WD,c'lF1e/Q)?wE )V#TK5) WfCH~"Ks R.`g+P% REV-&W+ JhZ0RfFJegyH(3,0gwV]੟bÑv4La &*AӰ5fferҁa'mZ;neTa[mmf*L ? C035nzbJqxzAq3U@$n5I|$J@yZ-E$ZH!`"Cܨ X9 [) 1:\/HPB!M&HIz(ʕxC]yR-AUYAӰVkzogt${T쨀EaoN(״Yd$;H}3ɼyQЎh_ 4CtҤ\{[)Kz8/mخ8Mȿ[smcԂPyaIZpinM`4jOʫ_ :tZm'(ehPRyG4!dyqxEF$V/Toi*"Y/da 3vBג4H!xHr-!A25{VAǏw)y}RpW{0ܓl8^%i&7ܴzTcEP=X1iy`a&REx5$- 2:p;|4l. ] UC;T?gz% RlLbՐ(&U!,p`RwvlZoޮvjvp"8u+!M5FELBMn1Ё<< rPt8(-Fj"h !CȒXn6EM,`"7"JI%~KANE|q2(.e<ytw1%* ĖJf7 ;R#G(  恊)~U!Ulmw@5R}zCE˜*Rl7 bU1bz@ V!(zJ0ct̓]ZIRQe &UR&n|k?PJ}aǥq `%h)̸K)ؕLl+#rb)[ xS)uXdOZA"D@󤉾Q$""95W=򊀖Q %mg̕)Ti@rEۈrJ},Uiy{YZ>Cn[ dy+(F&rp*ҀEm [A 05 #Fr8 `>Rk,+\Q05rڗ۟ەZls-3~Pr#luhxt`T!07G$P:"aʧE%$n/`!ȏ?!IA2BcuJh7h寋SC!BQd$}:^=!y1f#$vX@= b\Xf:W qoU7s. ^a^n2!}WtRK$I_^ ۛ\zP7JIrVwjq^zH{F~mVƤs&|ֳ^l#]UtyL;ӎWd+@ ͢Ҷ\ hER@2$*fMe% dMw\Um*n!|,Ab *=I |임Q~#MBmQvҩt2_netz~:Vw[أw!7p@RwO3Sg)ִ7[mwKDLA^I6 g9Н}#Va#&Hxmy+'!BH*,FU0 rvX5rSM2nK󿫍~;#O Svն6Ld3%Y ja:cZ%?%/W0m|+_1zT5[X67ɹH]lH2*kݓH^?]6UGBO{ ُVh&W* H|Se$~zGckP!Ġ4Я> 0"}P殰« 3m4g,} ʥ^S}IuٳrzXtԈnպZeqK5!9i 1[SK鎎zO/8nbCJ4OdZh_N pv[i7vŮ$qs<:)ك$T(jhJ~BZv?kʛXo2wrX> 1ư01_g t^Hѥ710:nWy6+'6ӯ(G|ϗ ;In‘ KɸJEMR+#1ڟfczFgSXm\1}0QZ :RFyI2.]"CuDz9r(SAG;DQ jBSU2"*&/ ͂,/ BmPa67큻=0c]>>`=x'߾`\bS a~#?`]u`o0KRHnE]r%~?p#9c2.޳Pl1bL$FtiXಐIٰ8>j) nQDXrƈ (%!W 6,v;VO5kNfp#u䒣E>װu37xD1cFեYZ1bN*97P@SFϓٙWGр4=3u!U `(ky֤aJHK2f.[L>9S5.gp3%ޛYrfĕ<zݨ0(|$fFYVŢ!/2j^hq-*bz*R&HK#yCY6&mR}Poƽ*9Id-朾Vsy MIÐV_} >'59,Ĩ3o] .YKJF; ٷ?{* Twp':wJb]7< J>;[̳ B^#t&=)I1ŞEUbL |sydBxr3 ηgdCXd%zG0̒{(wz-迟p[<8(z&hQH/7Tp2`5£Ҫ0{н-mLlSƜ$@MIcFPg 8+p%8{u'[qΕGj1bY;Qq#,,†<2vYyN +yĄKe^׋T[Z,[a\(!15=<߰ 7=ĞGՆݡVzp?}q0GEje6r.7.oZyҵW`I;\DI#ZuFVhZ V' ǎRc>Q377 .`sɋ`^+Ic;!NMV7cGO3*&^xvk3S-`dտU b'km|j*|y)b19-tYHOͦfDj1w,Gv5cNHq2ceg^zJ4J4am趡tMB(õ./%S&Cȇ'{ۏL"l^dB p5+ E+,on\sp#0_: h<R>kGBqH(njd_kEMd{\'sb1DrSWƔ:ȹaGL^:>ϣ)v*3Md/\9LԊpX/! tTR54EJMjyj^X'2 \YB^dt8PlUhئ*T 4zvG@+ϨK8ē?[g'ydg=]$Y&V۬._U=Uh{8k*\/uu'}:]+8ڵMkz?/WoOVqU7J^+y.{w/_[|n҃g 8n`(N8x;qv՟8W| ۹͞;XRwHI}TV$O脑fmT 6ig>!ё/>{N6RZ(gS^N&'c)d?PK ^B2z(55com/vldocking/swing/docking/ws/WorkspaceMenuItem.html}o8 MU@ŮGϽJt'۩ދ@Yr;Kሔtڽ$u<$__i4.[_dh? r$ lu ~w弿 } 9stO_ؚ+Y {rmy ߐ;Dzf?؎<{o-aa{gÇ'VC~{yI֛o#};<葾a}}W_Bjآж<ɑCaYk d$\[rOH"A(< S_rdmt{r%=Ohs(V~uwaZ;*e?Y޸feci砧ʡIѿNNo(-!ig_S//в?=?S. ^ h?Z#AAKT0#:Y`frveM[i"TvmBhF@/*q~X }۲%6{M/S/%HSUlPB8-HH%F($әIHSLeLͧ5cnjL>T>=+TJaZa ?)'TOꨋ;Ba]v'EX(SgY Ftڟ-I+δFV,sȥ]|ҩBcT /^/ðtTS^S%x]>S xO=E%:k+ 9@⥔5m~roBRO؎p0yC / nrZ4]VdEA,~R/2b}:f E qoa6nвw;#bc }? ϊf_Z6ɼ1hfӎs<Û}b އާJ. J]U9Ƿ~ 7i9(s&Ȫ*L+A rə 1dI:L&/*qa3RŴ7@:WZE.}5'M &CTP֓{&hՔ1e&E.҄pN2)_Í!f}\F(J2JI.ىc9lxa]:׼q:f&ZM[lr-&43p;)҆!;?::C Ỵ?E"dCsZBW]޸Q:=/Foݱ/_KyW횮%X9G`2]G7ïo|v5/$Ō|0~`ݧ,h6=D;т.o|rqQ`6,g &p>xlaP gE# aMP|5bpq36dUJ ;`j,'5-R(X5-Fi9(mR/KT1/gɰ2%P,M? l4_NjE}AEPl泋7:DO#QыY.Ú49VT Ű9b}(Tr2l뭠YsoEM^TX 7Y/6 39LEĮ (lj+MA\fMD]X C c{ z:OMG9Y f0fv~8˫ٔ:$^I^ʁI|LGڈs;K:eKP2* 6\AӠ}Y^ϗ0UA'}5AkrveRWσ6P1rS/MyUKoI ͖,7,->dl] x0L)Ek2{ ۔t˯Z(H>6ɤp^&0&n1֫/\v}I`q֗D 'f .9&@@aԵgxČ0!WJx.Z5;mlң+ |>2HL2p˱A^rpP+:IiB\-u34}$dTM2&lXίټو/˺ar%Y+?pPprZ#َYO3D?%,;-!c%zlϡ[i^zm^"JB70(X )aLy\pptgR co ( 0nxJ=Avá›Sي(13+0~=~0&3\ [iÅwF޻aS?_^syEPF\NDݸBK9XH±15h[KH^(Wez+&Z~b,/0- PТVsFKfce}~ڪ\?xnP{Kt\-E"xa$;%LyhbX?>d'ރ. kwOv"~9wǾW"ޱTʜuqиV2$d=Q.v(G¾C wFQUJlcLRHB`U@ |a7 7YYC!4%zݥO-::20D,K==%+z~a n)qV#wIácsZE)VႴ1C BR '@p uAq\dQR4i3w%f-ʛQsfvXJ/Y]Nݔk @Y|Ooલp`#F?$26a!W5Du8 )w |Z ~%oG{=2`6X(pXiYT'  -_ !xlZF\H; 7+ߧ^v){+A/S0uW;&J%\jҩ{w ,JvCez@Rj 8܄AK7@[:ELHm{ӂip#)MaK&u$ scR% ؃Ɵ"l(nhεo{DXǮ;N!h&8A!ݱ5)iV~ Xx>Ea(Xvɫ%5C|WӒPhI▶*z dxxYޏN Nf CC$BI7+vdŮ).]4<1M&@*mXEpIn|7ːx:\$+xt1}Abd݆ !J/Ny$Z}llr3V^[&3s}7&˘$ڙ kP[uMkm;X$r_ä'Bm2bᖔ,6ťJ"HY XW_5~;[%%58dGP$=>(*N'pFĻk0 qoHV]h 7-3X 7̵*XhJzo*A*C sy&Fq5B{vH)?k1WD!:b]Ԫ<}xB;.(j ?02jY)%!Gp&'L4!ƇA v@B. N ŒPHӿCEa(tV}u໮DM=d5#~1@q;17ƽ琺#Xꡋ z:(+ѮߚTBSwi~B vܪB@Fh`/.力῵nxmaoV85=R=nt3_Ĵb@'bƟ79 `wlߏA4)7Zy|SP,Ƹ5 9&Ԏ !}V20xg;?N$0[;f2JpyW֝WâX;nV.0hV""L#U`fEc]iYߏ@}'-r05O9Vfy8q!mC@'yBm/U0&0M5t48>~OfUtIaϡ"_ ?󇒂*XHek@*`@ ns 5G):@_K^|m^wFLNbGjۆ=@#Rn E}b_d,>&;~;^t ?=eL=h7\ b`)a^z@V!$z6#b?`K7;UQImhP{tfۇ-R}pqi-h\F Zm*G~nܥJ%Xw^׹NN :YH\^JhI(ζod}YcYc]01T1j γ~ju+Vҁꁾl$.Y} (6CZ"iߋ%m[xt/`QiXCPaFONӧaX@o Ł$h3IDXd61T4VyA2Jmg,^UVdQ!ڬ2meabUo$bmz+ C*Ԁ$bmG+M^1rZah @3 HpeipkCtϱ۟e{-9H ?`z1K:nFx-UyRIQl\2&ՆJ+u:|:Tש V4}<Yskx1X,`9>b}k̗r9ogS_c;RΣg?F|Ud@q BX}?**|w|rwO[:)_-kR1nQR8i~gaI3X8lZhzoߡԕx 09+hԖ1L皠]) UZz&7D~c0D*O+mו &sE rwǴbIѯcZ|ZWj DdR>9=HBdDd<"-Њ^662MoTPJQ'cG2#f(R b=@0aj%,V^:I.Ah3K2f0! dHOkA&rZpizk+=SHԯu?{QkȒ٧SCc m_3j̞CayRZ5G&(>x ~ogEBc>C/kMлfrT3٢ZD`=sxс79oCE67=+,j[-:A%!Kv7c}pasaf\GT>pfK{UW}A68ESMAU\vۺKJ gPG#f~-;XG5&_nNE "ΩH4դp*?щ\Ay27 z;|췈jc]ȘlV 4UYɅuH$qbw$ Q?[|\&d zuѰ2m& l0 zĎ?n:k5T fs.'mJ%a|tZrL_ÅB-jI3F.2V9FVe>N={[wjXe䑫~&43$tb]b^XٮB Nմ)0e\46 [mQE)X6蠫"¾%"n`C8{Bn^7&CW*q̪)cnĪ֘F3ϊ 8g`3ml1V֣ FW f$F?]Yи&ǟ㲰$ lN_;H.Uraa 'm,B5õtu72I$7Fhb2LBs:n~ud5:NBE~C/)&kja_/"[&ƞlX-b'A lnv*j{< ekV8F~3c-lt&cL9t1/y#9z2fwxXѼf{[2=C ho@l{^f?2[(#Zn'|KWpoK2bAO@/k5})팧{;;ۓ@d'xѥQ䳁cYWU^D%KWrX'!ԊBm>rk^0=˔w̋ZXwrAZ0cMr]OTB˱晛mrs)Z5=y_M$$q']P[ݺRb1)ƱHMd$VIa+ rn oa1w:gӌQFW#GslW=4~~? oNrɯ=Eg7Mc|*$= a4d:f.+>JCSplRC:"X_].tb۪x\$uz PK ^B{ I%X:7com/vldocking/swing/docking/ws/class-use/WSDockKey.html[o^wV)3C^ \%l7/%0ܘ6j{=/Ȅ-m;S!99&j?wZa݃A}t57\TG1ɇ0Nt'jv.¡R 2|j''lzN>`/"hqĮ_aS`Qci4A+ E5GxrC{$R_ꜛځԄbI}7xq}&1\||o7!)3'M}=^,m̅@& (, B1X8[3سUnɣ5wgvdUwe6fi؜lPW@Eˆ"6M45w͕7DGxC.r>;-`%LpG[j<1/"a29kQ%iL{h \+xG̦԰2F* 7wIRPRDGv,k%]شM |ߌYi2=9CF|_,ajAw D*&bjx;Nvw_>fjݽL5gw)}hp(pd{'@Mw~7U!/UJ{ *On^K:bS|{A5Axg8(f4^{(#,ѡgtR' =g!c=KRO`(Y?,i; 3lٓܓ]̯8eƥnԫ?|PGM#>}:WG:&1cdњOJ%k8LxB\3\&b~œ[4¹!VŊv9 3c ])`ɆUAdspށ9kCy41-sd$tҥ# 22B42N"8& w2>c4N~y(ҜJrZ sV!)peNb6x4rϲaA0җn ?)@E,H~7UhM8^"wQl0w~ZLz/72bd=}x49eS3~{!㩏ɨmɖRi5q׮%haYb:^+* [6'MN%`|uGL}\J!W>7Bp2Z-mW9PFT 6qf.gQe;6 "0,2l 0PŊugŸb&"a%5u$qZ,Vs}XW6LgҵE5:p۠oچumq's$Vqmj2tDCcVMiŦKsF{ϳa=)hZ,۪@QOGSs]GI^q!MMV?eI=J-U>WJ=,$k z¬e(Y=\~Bg7[(" 2@n.tGӹW?w>ъk@"7!ӗ {\EX.uɆ{I0h^-6QEOtZ=PDfS7vwH2="dSIv[%$Ku)'"v%;m6M_2(8eXQȱsnB116~œʎW/g@r+;e*3o<Cz{yl.}!_(cEZ"ccLi&m7avq D⪼'bPO?"\ƩyD7X%hRvu+9YsviSW>8pԢKEf=";O/֕98P&#F{ ̰C joIc`C: n0!>73EqHj5- A^PK ^B v=com/vldocking/swing/docking/ws/class-use/WorkspaceButton.htmlXmoH)aꓮ䃽@;%ŜTq[ݧh ovmKBOwx癝Ǧo n} Om/mB:A'pUkH)yQAMgurEHe^vrJ!酸 "B:ӓ+ׅtuAΙ1sgTF+.idRyyz!~ ՛7WstWk-͵`O)'T) o)vΣ2s.2}\%tZhɟ;I,pU:\n$LSp聃"";fEn~i"Qy&BP3-OOjwc:(G%d( Js9BQ˕^MŒq.9\.T<ӝf|ϱAl)rz[?,-.-bKw"[[)==SNV5mDEe Q2L73kXm] Y"IW` Zz<.5ǫϘH\Oo7I*P{B#'_aw rc=lA[Uخg*Bbj)od۟ԡЋa䠧CY1S[M ׄܳaKO])gL691رQ =Rtl^<&^g?#L/MuYSr*5F}pQ?RDydrOy1Dkg7Apr#b//珎b?`\_/]~l.Ai&KG.%$e6'+ ZoM{vB[N=?\  l7ovwխfGE48Q "1FY \ > W)MDS4T>5K2cl^ y1*!DD<#_~kU,郤)=T(I0RʃwX8˿]eK>MHTۺUn,l:P""FXӛN%S>QAPrH_nB&p'%5M&#{{$l# CM>fك)"ml&b(-XQؐ*01Z?pڿl1/le6@.32Bk!Qk\/R20R\בԈuByuIQe:习dJ| YNe[M:bt`@$0ϳe+\$ X&/ /FWXDWh+̟*\.(WXrGzu˳b x@druIw%-]_ۘF`}8,Vקd'g4N=Sa2r8'˩RZaۦ^H:*qhwil+‡.BV)u$r&`έk.Su=W]Vb'cf~URd\ Rt]u>LN-Zl*:N,Ƶ.gx`;d=d6v_̅rEMDBKKZLy՝{3Qety* k]rז{Sidܷ?ȡcaI4Jټ|]m!5`MI33dg#}Y L4EV+ I@o0iժ=)=GBhM|`"Jl.LG N?%m!\Gc\ieA PҺ$Їԥa|`2@n.\hxAҠt]Vw6@a"680ܥґSJ-3Kz"^r:GWtO74`uW-\,]k끫X$bZ #]Qf,btId #?Ď:IS>hU7MgMnQ2:i*_),G F(JЙf7DQf[>S0έZ .2rFC5d#q bJ ÚԑbsJ~?mV6aIFXYL#Iu)1{Sǩ4+TDe(S"J#(BrxQ-X*$dў̛h1ԥ9,C*;Ni2ol\bj-TKaAؤY(;< ցUOx#wSU`ݯXODk4-úCYlE';mu$?[z2W:oZ秳'm?Xz^̝IqaTfL{E_vz/2yIKxC3 P;;0˒u{׾G& ǛF a$K*46CVҢwPK ^B|w?com/vldocking/swing/docking/ws/class-use/WorkspaceMenuItem.htmlXoHaꓮ^ 青bN Tq[SNoCuϦkCpӁu /'-A;pUk(iaDqUgjLrX^zj‚Ap]K\ y42)#T`%_Y=(R"2!I_ iTw³λ܁oG2֡X4?Ry:Ph>mOx`T2[U l {z}^|O#0ASC"ruGFBq˖'}/wyUndS›6BiC2F,%fe2QoۭN]L]=͸Zzv;^AΜcb[UĆ`?>!bbYs.lr;eY @D:Wk䪅RH&dxZl‘:+ᚲmr) p)ĥv]ev)ڮa+vv`apFІ⽢E3=vwW)olF};LG7m5{/#-O'A΍5ZTB|baB6 M|>bh밲'lċqjƩq<{:z4ɗd ͞Pjʕ֯)r>#)b (+h>&܏Cܩ0ێH9LٞփPK ^B `3com/vldocking/swing/docking/ws/package-summary.htmlYmo6mTF;]ӥ-)%LKI[IQV'C-Q{}NyG?Aiti## W4p"fLIh)D IŰ;Bzh=K,ly>:}o4J])N[q6 MX: d]!aY;AFGӽJAqSHy у8KMUi~gtȓjS߃([^ɉ@[fS}QaZ_섡 Zh/lyyvie&ɀc`2, IEpjb-.@W>p?;{=-e@̉,9:Ӆ?%W^e9l!d6? qN\GQs620[UWC&B)wE3&U[(r˰MD,]^\6; H;&M9o^PO%a kܒ3lV'IojMu}|ŴƺS T1K~C1幏UQ:g8LZd(C)VfXUfh*3tw3: xO9Tqȸuz hޡ gX#."bDۚ6J~+ඐ;DYjcOX:sh'kPff؁:JIg"0 >T_/N;L3M w1IVD.VrSx`/֞s@U1kba\My,55J5Ն;ru1 ;4].PG/WMY:UCXZ^&r֯+QY<dm$az;=>/ 'LF MZ e&&55]YLr}:Di( ^3O*wISum0;8ͬUB">#jS 87%1<@:MqJw2knآeA4zD c"as6"؍uF99X )1K{[T+rm^o߷gA;]{cm~Soqc98q?<ة5l;=޹ٯ;q<@ơLv/rvY7/}Ug3L񕃥_h* Tb f)+N+YPK ^BW%5%0com/vldocking/swing/docking/ws/package-tree.htmlZo8>intnwZW8*l}L₇#@i=[CZM4vWsi4 iZRE=E   fxvxAaN铣glvI Z3dOa>':ޔ) Q+וW]j$@WZ=|VCU,Í` OTX54j 5zAs?EoT#t+/H؏(%u[ݭ bh3L32( 5ACn$wGEӵo/=Cn: kO| ңֱ7*j-9ۛDZy !SI 9F>״/ XrP_əf ز3WO?;\i\y XYm:ikϲ%de#ř{aXM rL\q}Õ6L\'"Uh.6v&"; q(!\=cNLG/p 7/P]Ƴ(4rݍrNj2!W LS .P1W=Z2 l q 3;^vDB&$oa$KB3]zҏԓl$Y6(I:pǀS(6]QsC}4`ePVJ@oX"އpK@"gTuC񻔼-Bܯ;>4ׅ:q;"77Vbbc!ZBMp O'3o X=p/g:Lf-c9 :QNz(._ V dr%"Mx oYNiiULŻj-l7R$'tjOH<@YQz+gL+cq( *V H*lV$RkT8@FǕgh$P$艞VO5H[4!KJ:ŐŸŽO+#8\;ɇ4*J:C֏C3&$M9! %P294hø210"zrf> 7+:Ѫڂ߱`E_Ӑ5tTv3z\:<'y;6]̙WLۤ6ٙoKp2>zdb}݉J5+z, ~KT`Vq3}yhǔ[,mJ1[N*OuGyQ miyW̸x[-z0>؁3+ 8n;ʠP;N`V-GF[ŕ2`7oWtڻNym_%lƥxOkŔ?~<{yT]v5[Pє1hƯLFvZРZ~toC:FWvFW,:1 y04AO*PK ^Bi@/com/vldocking/swing/docking/ws/package-use.htmlYo7=Rכ&R Im`J ]ӥj?E3a'paS=|Dž@ºZ>ǏV鿻Ӌ!!ZųV˄ B:cҗdYeGTcҿ$3ψR(6q|w8 ò3CcOɸĝ0ge S԰K.h,`JP~j׵+j<P|}8Տ]5 GУéc(gB )OƑw4h+xeRM(Ep;?8&9Wd?cBGA291,1~ _8 Oh,Lf"a7 `بDYD\mǛxiPT[;AZ`_!Obv?:D: 4௜~RPWk>xɾW;DchEErk:%R 4S1-* FeAeփ yPP2CBqdcSå{qY-ع,4ωq *2BPڔt+S^[bQN}}~]C[۞L&þݾ|辶]grSk9^Gdr(\52SWs}c];&!ѡO=c>c:B{' ȃ"T㍚~Or.QHFK؀^C|@MNpX Bk,ˎǥ-YBܨ݋۲ap;SuCdӂUn)j?CBvآCvH2mpD~C_C2 Ņl~VjǶtlEڡGν$eȡ w\ fB #ub¢dBo޵{ԾEק;3O@bƀ~pB#q;8|:#]ƢDHpӾ: }U9C:# u.)Q?QZcڒ%)hZk}[eCL>gjݪJ E\G[v^۲|}ĈVO,m,*Ct]`}-ӆ4:v]]B]‸A,K&#W Q6HmHƨI2\MO.rer=`x7 (@tZQlЊg; (ׯ5 y3-$hƆ>W/aɶt3>mp:MCר{~OtusVn~>tKbkhўD\^8)vA"?i4f4iDx ]:0=Io񃸌q՜(avi(Kj߽ķ?xЌkC<}O[0W@FF]}KM! 2{͎ \ qA8`HLI9o7uNY9 ѺҪUӛCO-C"Z;A.b(°!*OYG-`R #jHHaD=oG*|Q'M LZ^ruE >`3u\Ur@~K&HՎ sjbxCʬHfVlRQOliUNGCr ~/Ɓ X %}&Dȅ.|*D⹵zA)f=Mǖ? R!CD 镡] 0B9hBhdaqr8^,#鱌=I%u.SC?Q;v*Bbo@k"` ^X K<=D.ӏZ%-P={Ni3<3J_poFhdд]9\_4<Z%W}ޓrY~=_>q{W4c"Vj b?&䊉뢸j%UbК Wd"T 3&uVzN-zKe(AT*G=%w~G |:kh'|/wsWJEZ2!^%|cF:/̪iF;ʲőse);j>]{2ń ~A--~I;Q5zx*l}M&QI!MZ(&ueTq UPlN{N,tD3!ӄͤlYS^t2 oȅQ3gZҠE$O^dl!Ǻ$Q+mmUJtdz_#,3ZX;{.= "4]f),CY Z:Pfl2-C5:u J !,eL2T_"6RQKcD%{AŎ>!9" Npj^x\¶lKtXg$9ˤ22Jj㼳NT#F/caB.*UnU ROS),4E;IYpСzCBq:Ulu-:Z^Oڙ ws*9ߡ5OЩ3 6*Ň1r |~rNPF4r|M}s`7:>0+_Q}+|K|^>/s_ dVѯ~-3>5gBR>c>ި9G_[WE YeQqꭺ~?@ 9,_qá=<øn_!''K%"m:mh[VB%2@#[ڦUmb vAT74Oxad,ު~ω@L9YQĄ-xW=;(bJTf0̫3sB vf,g~[LXԢ:|( 5L)hp 씓8cNxA.hMLh|_-2JK0@,ks&+ k"gHK`FJ9^>o@Wvis{WT1ws`)AؑK8eL= RksF+.)|pX@a:]jNaƊASV{=%IQ Θ83!/נͣ&.// XLa|g pPo9^ Uou(B"$f M>9ώm&[ .OMT?mhHF$'tVu?M'Vʎ!+ t K D>3AhL?CT%S$;җؼM8h;c lFqud=11E]"g%ՊdbUG[/p9kF=]Og(71f(wEBd?Y<[S x(2Uql\ ڊ!tȫP>p_PK֏G)yY3YPcXU}c W#|>{ƐjeOR<Ӫ}%/FX P.u֗C gU0 S5#k@Fj@Ө]cT'N`" u( 7`UsƖV J=.Sowɬ'\Zk?~dZYU9J;=cG2Dc:3`ԥPo/iK*Q:wl>ΤkE]ڜyK =ڡDykľsxNwAc2aR(od s5u ^'^)&*JR7xl O5NŞ"4VʺLtsXq8|yǸ-"{S5> ~ yd "vFρꔱՁbaS0q-yZdCL*dg@sړ րƂ -wuۺwuE6udO/8!!?,c#::@Z%D=:~o@Nf).s:L'r(sOB&q$oFĕk}i=en36c@uI Rj\~tΝYۨ᧋>5gTs ->Q_ Q7I ^Cۚ2" Oa2<8^QO)2nkXr\gdd_(f >9V mG~~{\7d"{7j1B{1'С53w|+&j_(d Wa/NXhYBsy;gM慷̸4e-+KVV*1-+P79sism{Ee\Kta{ gnA1+DJ"YODɀ1ŬF#z}ZՅHǴ tnv_6y+kqtK8*7H!MLVTPK ^BD ?ow4com/vldocking/swing/tabbedpane/SmartIconJButton.htmlko۶{ b)$H msQ$]×޲%[nÐJ4#仳sa|~wyGiog3 Bˣ߳\1ʡ  .c܏HH W4PhsI(ƹPbÖ34hFCջV,g,47F%|g}G(E})fV0)^ 1VXV=I !@H,*҇P庪pݠ}d3sp'NB> eaوh\G*I/C͏|>Y60j9C"|4 ѡwNlio Reu$E/_V],rYqz/-k.|7Dn Jcz1Beh-:?):u]IUO` %(sw ]Ȩ py ts?p < 'R\TM 栄".)uw7)`;d߹_bD+s _9kVAm}QXpe&~bO}\ pqg1tDO7-EO[hmYyCҿp@m.gP9RO0LBpӡKl)>Q p^q<ɇ7VW{DKpm ։E#m;E0p?'cU bdv X(a&A"{{&{ȶvr£;N[jn+5  l)_` ű΁\aKtҖCi_Y-us$<>_BxоCP3&Vđ7:]Tc ȜHw`ꊴ{#K/ks[/S99 m'r]+JSj޲hX X B>VS`1 RvƗoDLiH s W`SqOk^%^*GM{ě3B <ս95*%jN:`ҁG#~ӹ-pNyCq|olpMoɷ.rywJBeoBYS <_jM m" bE3_Ǥ뫻6hQ/[~_ ]$ IܲE͗善?[NUC. "n hbGNm&\L. u쇲2_q* (4|<7"!#߰ 5@\7aSb&FYߝ֖@&ph'1;KF Xt--fУixPE2ɲ6aQ"ԔROL',AYPL%=um&a}-ZĿB7%q꺩D߬gMDnD9E4"Be886( 5l؇0 Cs)k dtH$zV#"m$ۦ o3$zYFjiB̚"?lu/ `Blzgm*ZQU?qt>S(!t@M 8 _ KKVpEY GZ~7CG%#J|)Ҩm0*'v+Hot&DhgAm܌-3͖!!, { Q;Fx -egfi&b @:貈ʤp_*ל!/״<B\PnzU2˟Z,Q=u/N *:U׮Po2F N$#/O'tJ)ЕbE* [QgHSd6Nd%[uW1'琎rlWa+c~* zXokW^%]c~}6k{,P ލXbCz٦VO4$u5LS˥,k){.#l1f}ItB6\2fy>#Edթ m6 hv![Ձ &T;Nm"Ggɉ&+S=q3~v>8l8e\$Te4gy u:5m]'o_x|ЉFʍݭaU) Ʈ UDRYQt϶\qP%cU7\߄z0=9gf ]fS}gU_~gd,]}H#-] u\q1W7_bׁe?Xciu#KӍ>vݣ[o0u<GT"o_ @P&@lo` 1R(#1TO`Pud>7&[\8rQnte k-`4夈Kqն75Me]%K3G^Rԕ)oQ 1Q߹_#syHe-۟jdo[Jgr#s,z_k৛-y_h/nG`-#meCψE ^/]~1!$mZyyfY;w}?9j_;mW߆@D* auJl6f;#?8#5f}ƹ^B3ׅ.Ȉ IFM&fODI&TEC2%!@mJD/oo.I͛wuhԷw2Y*V>J*͈0coʐU<9ߊ4LIB\bL:ڧ%CAtxu{] Bc$hEtZn7 eMG92T9)R*Y)6 l2›΅^6ܣ}8Ueڵvii?}Pc|@t=-ۋ~>^E:*0JL-h6ނ-D:w2f'oC[ea^ dd>l˫8uK:#19%%^q9Th\0\Q9*t Y.t[IM:̕1ojwZgٲG\R2BX!5t?,,d,*Pc?-9L&/kUr>m9hcbfx!Mht+c)V7dc %e eNH?mҟ0Qo*22=A%>+o$]kQ[Ru'r}1춀 .ɛ<1.n4`2+ "7C-1c+UbYCAP44Q}?? k7e`=0*s L967TxMxTΩLzG$WI+(T͢C._.HҲ4IZaՅ8}4X>&CᘜUyR@}6Q Ƥ%b3xBjHZNQ@ڴokڻhUූ[0,h)FI`!1I8nL 7nV*}xbT]K/to{zy,+No2[msYL-NkAe0#B4okqKmlovw0ގ󂪉m s0畚}5ob:Aږt쵭u(=5~*zw1},NOJ9+۳8rN:u)NKgVgk=?}j+y_I3:"]O1ڍ[/t|zYģHA^p;;"c %JDgoyѴh:+?PK ^Be>j(Icom/vldocking/swing/tabbedpane/class-use/JTabbedPaneSmartIconManager.htmlYo8}LZi)B{kRf;O!r5qd:g; N`<\?{!8ǣ6x>! D렱Jt"R 9z2σ~ DWd'5B(:ZO<}yY1tz,{ƌY$,3̘T(_]5p6M޽yN~.K'G!9U b8IQS~MYpq*@4E%|:8:8tB~p;= N 0M!-5JM5Ku/~󭵝' HCOgj̘@/2&<K6 л6˖7)|L2]n:)'*%rʁPӾ=˅$Utb.Zc|'F[݃ןCawf)uʭ+6;͇$= ]fZ%skU#]A9sS C(|̙-N;Lص>`b1C\,k*3|Ey},r7Z|5+-m*/Ik M"$_Ь֕nStUsezA_5+;2BQmlh-nX9v 8q^t_;cjcom/vldocking/swing/tabbedpane/class-use/SmartIconJButton.htmlZO62iMJtw@T4MiƇGMl'ihcmT&{ny[~;/mjAN;K ]I4 Apxk dOv|!A" gjpF'2P3 8IM&vNLI&TM#I$z1R!{7o.Qװի7tQxi9mч6'JAO 1GW,jb5 C$H}HkdM#It"u{1AnC $8EMHk0gHʛSNUL@OS\zJyKozf |;2ozfrk"OՓ,eƬnk?b}G}gID/:*M-G&4PބZJD]}4hh.2[ς\OTشPHLM,Ϫ[`4- I@1Y}\vb :FalY6 3+- lKBgrƪҾDž?2-'L@xi)Y}@]0#[d|FT˜-p1%9J-PU;2\;g-q/V7Po#]45ʪ-:fօx}}Tnpvɪ gp-C+gtlb%*A MN{LCZQ@aS;><7֑*nL>'d`Pdl| l^9 _jk#lVQN%}V.T`FE[ud g{j=Qnd$.aM>ZJL[Xd pgN' M0q D`4,Lg.`w2)l32'fJfϻwg V5sV?mͿǁ3әsXOg+=sVYWzH:|=*%y-Iss: -ҩfQ.k}-aFfO۟2ΰmd(s`\|af) Ffh(&*PK ^BT1}1com/vldocking/swing/tabbedpane/package-frame.htmlT[o0~G?i{USZu#rC84뿟4-ry).bn|mr?|:17flLڍk(.unRr6f;`kZhV,y֦LF?^x<`5+ t5þA`o|dz2*m!/_XpJB؇  I\&7GiYН6\Q]7o×K̶\"\~O=xxu6У> U<-W -$"H -Ai"pz /;G"P("^^#f' >jM`kD(e焦#h]ae,.Tp#䊌LU3矝-O7==mdZu檻\2>FV:]qlmms6n00Q.֓YcKޞtKVϕo Z!Kϊ,vn+ci>?^%pcwWNPK ^B*X3com/vldocking/swing/tabbedpane/package-summary.htmlmoF{&Rli75 L kvڧYwM{$KuRiλ?~ Nq^7{Þx50$SL3~/h 9T h4<:xЧPCsblhfao4hB?ɂb *fKԸj|$N@~Z祙3h5&ZoM9(l:;x'Ɍ.pps;*HnF5 AA20ng9lq](TM)U~HA5td!,vpi-ḰU"ҕU#r]%mN1-6#bR|Dﶵӗ;nC܁Dq>3^fcV;NtsSTҩLc`$\B"RQؐ0.>p9<;4`ĉRhUY>#+MpOc!{UxJybֳqTTm*RŅ!77"Ɋz,gm{MmNMpEIyE=G Nzb4q ہ;g;)n4& htk@ᑞRD?עTZ;;5}3JsmHx~GA3VI--bnԟk3+W^fj t 6)3{Woׂv`c< wcGo] Y~h֝xDޝ$u6Ha3{S I3]=D\P1I=]ی3S <Ӱ\M 8s)FO- {p-) >-OFfru5p to:R.tzKdk<:VS#k2+(6s 8a&71}%@K XОSm˖g^TɈBBRTex3eIʟJDs$ŚN96LPҮtWo(SeܵøqY"b[hRPL[7Zƃ^`mܷ[!S1Li] flĤA3軖h.bl!ͭc!W 3_o>`kHrWs[ )&S>^ 8I(=T}t>؜nM@ֳu]=~OX揽c?ݕ^t-]J^tBxW_u)eCiwM_" 0"75&9t\>Մ+*Xsk?vǗ6vƮɢI[3,#!V-XP[p<4O~Sp #hFf!4̖FvB[M^oF#&,БLkx/Ю +}kT_I4hpwHS~ } ##~GE(Et ˖Jr=x`V J~ghS-ZWYnyv)ލpe@ĔUMLg?b 5fXDD!k/Q+v˨9==) gvy[M ~~44 x=Ţ}^ l$GU1"{~6ܢ("a--A:%pQz1S.e~U˾2>ϻNL|< {|,ѹt28#=d-uǏOKMܹ</vJc C v)|Wi 05H9t bRý1[Ms}Exley$eJ3h#takR hO$YX=Gb\ ɢ0l*'z$DFXqnSRl|W(xI)mz\fOzj[JFQ,/*i >xHbMo|CAѤ`Ϣ p p&a/n^:k*UUt=[̫V[o3>PB bbER5GrçA^%Xo[}Xbjv;vvv%fZY_Mjlwׄ$Ͻ&;q hN;djY?.1`TDl* W\#`d.8O?gPK ^B>n5/com/vldocking/swing/tabbedpane/package-use.htmlYo8}Ci[B{klr_MNqBJC˺n:Hl/~_>;xC:-|BoWAIc5Ob*9zMNX,~1WD$bA#3߇.[阁  v̈́(_E.o:Q29 C=-]\P g@{o`Vw4ׂ5?* Ad28P i(1Ov6'N"WԂ=8+2M!% /B=kgtk{o@2^ &i2EJ>k2Tʃd[ +]a˘ hi~PTY#f^ӘHx50Gso+Do7h_߅2ZIčh<8޻LO z}~:::ZL|0e8NSP`)X0xUI<7cc= *gKx^U cl4ǡJ+HߓĉhabJUIOn,m:)aZ@$nQlު 2ZfLT5_D .h :e].[6[í i6 8h5)`М@fZ㶁8'6},P{&"M;ᔒ@[à{PPp\@P00c[ ߶x-{zĔϚPHnjpea.r6}@ӡ9#nG*2703_:/SR0"Q̆M8ә:_UK;kO맘f[0;fhH jvȜzuLchd(qܸN}h+vzvdv ;l2Dд|)6Ue G6 C4CP"Ǝ?},_gevGU:PzA{nʋljTשݨrgTu[IUoɪf stNs 6K44hsb K>hث^?_;\plZ:MLIܬRp8^$ED> PK ^BƠO3+3com/vldocking/swing/toolbars/BackgroundPainter.htmlYmo>Yih^MBg#JQaj?U&qSGq{BpW*b996׽o <N{o:Nf &)%˘ <˒3[̛xlO=.nENMFt="3 jQx;4cD_hLSFV$!h*<c12h޿?k`ԟ@:2q~e3ѯYd^(zſrGh˾3VZ/TDW)KjN *}awpEHƹʰ>\dhg| 1nd'!)N X.ԃo3oc,爭/8!1IрXKO V Ifן`r=aMk: DJ\H /$`^]&) 48ѡCA8җ9sʓƔU1o @rZ kq]Xx+Z}gBpn /bg6mX4p yW˻<\&$.GX3'"Ωf{g98=3Tn\sܷ1f܀ETnQξiX)sL]ڷz^@V@%64T=o.=kgwGX>6rW@>d){6T_K\XĴ"Zq*x[LUQ76wS< ,T"Q?vz?1vD+XyEtk A\N O#m〃Yo;c֥\qFyѫ7NTESgv'9U^*#!ph>0˿`+Q-\xA_ԷS]uoLAr+eXW:{h<lv1G1FLz9h/Qj. Yҳ©HQ@'rO%ROd/XGbWWݛ*=9R"ֶYKx}~Rw> "ŀ&DSǺ+w}ށ*x+#i=.ېh8>DuQE'Мnjjټ&Ik(Tj4;gS& ;#gež5:0„ptB`%~D`1AW_;RUÃ/=H0;}hw:sIIQ+`K0u^*hrom<nCwGnU"RM I8AK9h+"=\/_ r5c $ob{L߁J_L4"Oru/^l"P= l)XmgAH^9+sv)Ekjײt=LTdX^`a/27Y7Y7Y7Y[O̲Sxzz}ցl[WUA]|/3{"(ZZ p ~S#ӆ t8CBxvAԍ%J̗4rJFhOϹPK ^Bp> 8.com/vldocking/swing/toolbars/RolloverIcon.html[o"iwVjic^m6PvS%!U?Ef0ntl {<#aV"2㟏v}__ۯW-dדm{cr*( q87|!SǙffw_N''^2' c.ڟ}xwI?NmNZ4,tj6si8Bc<&3ߣ>F˃3GBR<@d! $uKP;W$[\}B<JArn!?&úeNͶ raI$3`\nL#g-EG=?tbyf\ئG:(,"PjG迚VD8 X>dfqi8| YigFOorQ,3g b6$9Y3zSO~PQ3wnMf7h@n9OAtIx: 4}o=j8ґ>&.q71u$@rs.aT0ÖW1yZSJf5>q(ݬԃVtؙ6N`,9qIb ,ָRCCDCpxc;ed+FvtG8L#БL9{yc= +^Z{K75ؕ(?PY@`~GSLp+oZtGzu Z ~Wr6QB6nkF׋ct%#lv{x>?P!A0"s[bO9,e ~ |!'҆,$9Ҋ3hZO>4p]z ~$Xa@"&`ՠ< K^ېj`q[lSCBt ɩ%Te M1IiW(i4f~՗&52k$NmZǼe?NRuw;V>i3 u=^L  L9h蓘 dC OB[ߏ!8?؇;8j#K 3:X|KaŨ*HmͯWLvQjEu+d hOdk,z r֗HRȷ/S8:{4Lm#--ȶt9yZXUGF4՛Fa(nIXef&%]sQul4;ႍ*C>DY@{C(G1DդHE1R =YH拱b:]($Ix\y`mvsw.}nv+2lW j22 uvPR,9nÇ.žGeDq{܀hRCxN)y)*Z+|=oްEY$ț>a"w0t KCeh3hV;gP 8eaLx%3y*USGs6jˁkAnD8%)䄗4gf T]_t T#+K狻7:eh5(lldytH6>z  Pc2&:i4-ѱ\c |Б/< E| l7+ۯzv<)__v3a8#P:S#`T &}?*N(|.z`DY"LD (C|͠L%Haw\J*i F/qg^Pᒄ?mh @;OHxvU%LpHa(Hx nAP}M%4Ec@7AY7)fl vM!o--bTr7@s2Q,jchiHueHW"*󷈒o6b0p[u\\_`@s0Tz%MxN*50w,T.U%Y?:N#)zqeA$;Mۧug@*Zjf~Fx—5E/U/xf2}ʀx:jsuas\wZdJ?e_~YZPSo`^?'?zCM y\/,0!ظhf5+ȯW_ +9Owlz"7HQ$NUd.Q"pb\z1h_6wañX5_xW4Z>PF0rG]! y9BBx?PK ^B ;/com/vldocking/swing/toolbars/RoundedBorder.html[o۶[R.;]3$qاh,j"ǻw_$<`1Gx<jtf!]Q%IgMШ>'xH,Aꗧ;G&!EХA>DՑCTvTitV.&!B$JAsABzUuoU=U-cϊ˂"ZH:5)7[>Cchإ Vo'+@GX̪HFT'0Q? l-I:4ly^O#^̣gG9 (yF &lIyde 5j?ݩ_uP3.E}jx ?ĜY|oAvv#|5 e7o +A;}%}$M\G.`re(@rsatp-c l疒qCL\iNe, ,b߀.uk(' {W$ڐeUʈ/Of,%BL\C@ұTBnP&TahO*%Cnd(TfgJ9Kaш>zac- A8H= Z9HHVFnJ*z҃.G)Fި[d\>"8;pu<EYy5+̕z(,#>ݎ|_04b hj&MwJQXOgԻZ%_-ә U$IH4؞G ۆظZ4噻*xO`( F 9Y6bɐĿE|Vuy)ypi'61K߭-giҀSsuPf؄\S`b,)Ue &\4S4I4zNU&52m$3M:q:E2;ط~V:'͟4ǒ.ωk&yGT=h4 8Ɍ 2.Et!s?̉{8' F|)&P&}"E2qj饫2$Ė׸D;NW+c\f(>ڛB}j%atlw&u̼Ld%47fl,Ъ&5HTͤ!ţnH}-T V@%o$(|S{ERmD>:ꈫYDijmm,N , \)KĈٰ1cpP!ٲq`.xv(bT{_s`H"Kn dwrQ<)֮>VnL')yfa(pj623U/p CghhVsN<1PB5|BÕ kG> `U>eؿ5m8*iff`"$<.KJ՜p1E:z|͏SYvUuռNS? ъځjh i_5&EC<iĉC!w]$b%ǰH(<Ʊm 6XiSN7_:=EG~~JƫJ$Ip]Vr}׊#"ge ﹶ2|IPO+Qw&8P/UKwW=Z6S}+P ׏O洏VLsIpKZQ\ e^n6HkS^Ϩi=R\o|շM, 5E٣pIZKxqAVAfiAydqELd\)Pp}`@k҄uYE6TJD8Iֆf vnw!cI~zc*b] VK):_ 䶦uS@n.Zt ٿY&dP.rlU/n+)EMtھUY[-ii}1yVl5|Y)*eaʆ'=2W{U?jr* %/_T/3us4d&[̞ӿ9)uz6n bzޮX*z 7*Ea%JMσ:y 쁰. KGu778)_Ox=zxx—zL'; (tlS% I OOՎhG>!ٜ@3R|HE0d/. u+\PK ^BYg߮J T?5com/vldocking/swing/toolbars/ToolBarButtonBorder.html[sڸ=3t]2SlM $d7SFt1!{7C6 ,kWݏvW+V}^'gMT죫VTXԻ'89 $AKU5=M NWi ;B{ ޙdTh4$ 8ɜ;2{9\>\8LcV=pLUOnHvLy&İ cxFLzfC/Ӿ["g* ڽ$1Br+o4C<(3~I|Md쩙y =47nV]&5LJ}CWǽZ 4W(JH173١`,# PDÊ!o4PO`R!GLaT}~&T Q3^*82D0þ~쳀 oKn-}r v@+R$))KͯBSC/ ltuP.3b-ּϲUD h .,f xNO2Yo`Dxg'tQ|#hky +e<Z&Űؙ͌Nպ!ȔOS 1 ;ڋr}Վc"ie OzyJ$7yE1| 25s~iKK!S^].;KZҤe,V:ߌS{H*U~HѳrYaS{(gNL|YOYx\np3:BeܶRf#M- 5bp[AVnLN/'KQ:ŲZŲzŲ\{--W\MV:wؖ;(><Ȭ=o7V*[c\8^VWoSl#G*j%9̖Wu>ZgcS'n}Q|tܨ}kw`L ^єo¼ &0/Mo|/Ø)>7{fIJQԧ,Ll,J6ՏiG>!ٜPj}E,~NC ^9# H.kًk!) xԼXIjVÏPK ^BU, ;4com/vldocking/swing/toolbars/ToolBarConstraints.htmlko{ތKv^Mй]$<512ﱝ«nW*1y4z\h]5UvN5vTPc8m Y#!&g3٩̓:#1fyHlOxV2j T.9 1՜^㳏NMN*ǧ-A# "!*jrC%c2:+ \;Pȇ)U,r__T-I\WZ Z3 @ ]8nZhAղm'ζ Eja؉\jR|w9[A'ULOZEC_ +?Bm؁X>Dm/NF׻;hvg>~%y4};>> I`;rDe":T?WP unPE4p 0II?c02,|>I٘l!G:T[_ih"b=e1ӢH")x--ѪuaŖ9>nh`P*aK@ 9\[/OC,*UD.$8!<.n#ϔ2n&PTƌEW&#&e+4)SEmhh8+ -ԆU]>vM g[AXS!Kq"ol'hlƎр^'&CГHr".fhDZ2VQ`NjWZJtPZ$e*H& ρՇ_򋰐l s!Ѱh`ݭvg?pЋ6 -M׀GtL[U6uRx~!j J\@4ן_=y1.]^qRO(&\NѪޢfWGե CI`-VmMĮZZZViAb|$PF9z#r!#P},x-PvŁՅP5e#N!~չMz]""Xr^~do.y/SvJqna@.rdgsQa.UwRp^;$W 5> uFV-}>&+E(M[^ c~&.%}z$V j Exvu򼝨 zA~+ݘ-D(^tiw^vt2H'?+ }z@`73yݧIf;ٰ*{JVB.YAi_G25@<0(uG!HI%^k/5w@f/{_;ϵeG:d]vSoqʄ+Z3[ÎuƢJG\HG?o>DL_Z*J0S7]L2BĻ|| ]u+N"4Hфڧ^UF]z_]9()s5ޓ?o\(Y`9kɋw2:Qm*$Z!(cjAdl)eϠWNZgfO[) /cB%_5٧$3; rIw&:ϋURScOzfx vgt}>z>L.Q[YeSҊX^QC3 bn>"i{gƹoY{wVsvo,lED ?ex3#9HJCYai2 γ1cԷ讜.# -p9iodPK ^BK %W2com/vldocking/swing/toolbars/ToolBarContainer.html]s8ttU- 8;K`k߯^Wtuu~G::z#}S~vFhw:>:g/~l{4O雎[`ﻟ:Ƕ:ڴ7֏qlѺ>+ XhAYC~6t`w,zg޷_c >/=kûy^[RsJz&fNѴW7нat:qQ3"2X0 6Q܂v&|:GFm [` W_<▛cOD@вO!.yś?"IC|BZ_%a@׃ ba-\>-ƒ6sݲ8.B{[?E֢r s\ gYkD>}\XPXp L;Ҧ\)Vc{ă;+,R>E~ cl s*+t ׽] >Ԩ+b4\ɀi\r=$LaŹ,Iv\˻Ŋ73z54"{',~hK;#syp..ðӋ3oӞ 8;EimdžiFO(4x/܌YOeϑSV!¶!(^C$OaHM;݆i @4es6.\b*m=&a1xv~ ˺.j*eUJ4W@{ErX5 hæ=h Mbhug3j]p;"cYҝFx9]>mr i[᠎1Nr:[>Əƕ+n/` yQ6mbq޷~4AL:? C'7=~u4¤u~m3~ vy 0.*A;k!ԱE?W n$iT, ))s)q\/0^M~+tH6ܸlà'llܨФ us2]զ DKHj y m]m?ƫ 0̰d<,i]*X597-wWx1xcuTc]x~n疹`:2tIgv?DIHDxkgKm #[m[bP6.@Ɇ&m"pxx5bu>N̓Ul0fMa 8%_T9L;3rM{e# IqAY o휳8_DU{e.q xDDM-Cb1t <? ʐST@ :v%.-./gk S"}GR⌖jU9D@(1[X8F>|D֧͏i,buqb=plP ׃Gydze7 !IKm/3m Bе)\6")~3m14q0qF=Upy2\!6?I;59 ZV.DUG^_3/rr! ;p9k@Xl)@:*VԀ-bVӨ`/SYjA&g)MQFgfp,%+ԯ@P+'U&-7v9쏬1SϺav&-Q5Ca_u]##ha%BWp'*Nu}-j\Boվ>IL!i%+ŃW cvuV`䳰hFm;)Jw]*VSSLFA]{e  [ST~\ǃCo2d,2\o7Cw̴arp=(ۻx0d8MLh}d/ohedh.gh&qu j{#):&fu=g$SXbV+4q,(Xpxxak L):zG@ 7ӒFJB}=Ӏ6ţ(0Bc)?y*MqQ㟬c >NkXxPa.qbg nٴS3u{mE\v1F3Wk?h=*-q5i7_Ez [5Qɖ7?OFn8¼iAU/hjPʪ~FoQs),ukȅ 2t1 v [Ѩk"q :L-yݷ-,v&u5[ΧM:LxLiw8Rn;6P9V_A?O3xu^pj g#0qE :/莪{afL9 U5 ^6"嘶DuF; h]8GԻi œSl?sj\l=r# ڭI cJZC##q(^3 Xa%d% ¤a"3"3b{kYt9!6j*<J@*78T::zia>äs@3ֆO6O;nnwiliB/K%Wdi͚UՖ߫i]: *nk)R Ł"L^||ldMa 9CaPa0~ xi6)6ۧk6%JF*j~se2# -Ҍ&"4 kc;4t0h z"dd"R g;v|sLƯwA{u2S EdWvS.XPJ4G5rq6"6 Q+AJW3]9ʯCɉT<W^@k:rPj"]ʌf]aG>$ynu[_%t%ATܸtB3ʝF w$Vw癲 iz',fFfniՠB܈[/*,`[&X!Y" .ي~2ǦnhviR>=^布8lA?\I$VB9ﭣ`iTu4#_^~rGOqj4ji=sHPz๤8 2mrweRY;BE5mL!PM$pW"?vxT* o>wt`GbO53cVdGٙl!w 9O J:M RC䀂R#*[1 Ԕ3SDT)bJAd0P< -3r>& ֝Ep8EVx/iuV]Fl ]TdѤRw`Dq>=M(vrt9F@@V0g H/W P,Gnc y.4FvT@8 9|,+E"2ce{>DÕ){rK=Dq23W wÙ!%1+A5OA"AiO3U&8뗎v`-VHtPyI]?Jl9l7򒨋FHRR Fذ CeQ<\jhQn`ʸr2V$w.iԹIdluRDHk#d3eƮBq!JG쉝B❴0r.Ɏu@!lǍEDa$^i7z2\ZX| >1Ur+U7ZTA(7·g՛)`#"1̘VXx8n?p{Gh}e"'T) R Dn\!-"H? ?ˋ);,,,]vy]ڇ:8jؚeиdL/(hZQpi aHe@ hd^]fIvD$MC[\ח:!MpP 8+xR9)U, qU)aR*1: w,1HS"@bV ]Izp׺_cb9!p4AjCӈv3fs ’2b\  b&JVVd&GKwիz@-zkItb$DH ᔠV y^JT ƍ =[Vd2I/BZ}#W/ ; [PQU_hx>YNr e!p[ǀ@dblG AQ`6zClH\Cq7DTG*%ZVXȎͲDT?CawO,,QݳN֎xdLsJ7A3 l|Gb9@+g lB4qYj{>xΙaWۢUo3/V?V IB) 0SąN3h[bj#r6B b_S#zFcX~ 4uj\շ8%->%2Z 締AH5)Q/J,'WZJы&_ i bD˜(ghA݇}Էq3FƐV0HEUC=4VgK2 q5*ZM;/Foe`1;l*3:ۣAj V& Yvli30%߻@bJϩ#> -seoHd[H~y1 95Mw0='Onm!:FOtg6i@ 0k7w(_k;,!\P њ0r\"/mgAon_6[9NaT'M'-牷ZӹM:7ki>=7=a`MQY">W߸`kug3j]҃֝j$D&`z՝XzQ+i;w4ث,sڧ7t3ï0Ý2Gld8}FNK#2O-0&66jeuvۙm73#Icb*FdG}TwiHHZ4SǦy[>S"kht7Hs\ΠݗyY|♮[D:\@"NMJ ]htE+Z( ; %W2`-1Di'wDtn;K#We΄-p߻Bt̞V Kp[UppҎX||DS\tq -``+Xr.,Jk1@pdL4x0 jތO|ܜolHOP @yCH@2~&<䲞5 yX M1{3Z܏2gBo rB^%dHsE'cd Q4Yc`5 RnP`\Vqnp+l^? tn>{w?i-nb $SH5h1 )PK ^BĞ!,b0com/vldocking/swing/toolbars/ToolBarGripper.html]sȵU?tSyl̎€w<XHD-p_Z/Pq$swN>}uwIo}ߌhCN^ӟ?߼Esp[c؝`Bo>t:m{̧خKp}9[sB<^ˬae af ]mo?F/[z;t۟wo޾uo˹Wgm6CgG}wd93;ԽT|}9EˤZh:>v'aE cRYB+//Zv'?*%x{wcs&S:2#<ܡ<`0vQGT2/Z԰cLN0Oq:i]ͬ_yь!98{QJ;1xg9_aZ60 0|Dngc{ZU끎Ob m:Ҍ1Pf^~PT,-lr`ʾ|ۅz}?,ƀd+W?hiUi\gه4)$4y% Hs ''HVc)Z> zly]V,|^+=͙n]r!ջކ⾯qeVG_eHV!Y ֣d봙;ԼmC"cc6L"s2 OhG5X`6Ze-%ƈf~'t%lS;d("d!WGR% $Id_;ߔ.lb1)ϟ } QЩ0P@]ZөKgN\vW ۜ!Yʃζ^Uvf ?*P.UNr`4 a /7ZA󈤁1pIʉDWOvo&]+hrl>%":O7@G*g  A7pL "Ѹk_~ęEɇp"ƻBýk (cԵuز4l/]oJÅE&DsM9VPi `KX<6惾fw77oɀLhJMܫxkTr |HUhug3GPJ1:^lW^&-.^Ed33+9&tMQ<߀8Ӈh$E 2r[Lc.3W$%f9F+` \a!Ynu?̾F].7ٞ>IMCӬK[lI] ǪFdu<×+1f;`KPi3wzB l4-C^|1/Zjb;kl;C%? ׍m8^u Sl]+2ș\|毢/_MC Z:qp=ɸ?.Nd9/7'w7(nn'cu8 L&Y6zIsVye8Oh#Nq{|l+:?.4GLj2Onb=OM7ڣu %& :\K5 r:S a'%@ƨNi;qBnJvkr`^ME$@iZj8Tp0d Avo%tA4`NS )E]Fp`gRm2?i4eVӻջWy6o8E_%Ψ,V/bpoxꯊ0c:j$e쵴@5H}>R(kŋzmߠӤ)}75${@[C ^/rGY&NkIdǟdݒ)CR%>z y, 'O;|fE;zRġ+F[nȏ um@Q`9mcCɤUj2b s Τҏn3{j1ח;Ӟm8:368 ε(`?B٤T6e1Z8upRHTJTʷ`#+Sr`ՎN! nXB!s:g-C'⎻ax:10ΰ+w黑O<[bl:!czNrȐG90ͮζGÙ!G:E^kHWKܟd@?ce0Av.+T6!ٝ?[|d.otIs~'lH Aa:8!dnm?F UC) aG@<|+GrѳYu[L@2H ?hɒȵX"Q)r:ycJ<4!D[x>b<8!g3kiO8ޅOITJ(谤чBc~>f0T0|l. {5 `:WR{2{ ^a=@P'l=k PU0 f뗙8KD&;uUN5bX*#:YECQO$领"mߺ%]Zo3:6e Ge)߯Ŗoڄ嵁gi7+S-(;;ʗv>P ,Y>PR('Þ5~LS!݅y5d-wEJ~oFj-b>h#MIsc8#-[V0x'[͠?B[kQfO.jwn 7wY izXϢVYEWqdȫVmi@WW]l`:7F<>Sut` "A çzRh  K5,@'j D !e6O}@XӣǮelW/1BQd)o_['UA~ Jf $Qj4j~[v[<53~p?G+ N xj`[=c=b4b#amO3Fkʗz+b<}<-/Kw$o~)%Utr^[~؋$9e $<]/&ɫM/at'wKD'xIHe QW $}Pi 鐰d2rFwC]!{p,YK$ o u-5X!O & no>*ET^]5 _p/qd+:K>B5 6扒aL+j7N3 {q_ә_-E|gZD7vCVXHoBѫZd8t˻շƥ-TUC Uu.M_[G/qi&-fIݑwŮKxihK1ÖZH_8wI`i܁J 1-k cS+h!1:Hįeفhk;I:ZO }֢؂p0"ݺCg84bx6tЪT ,EGbe%/2j4ﯽ.''^L~swVїeŀ0:yOI0ud|iX"lr<{֜_06P)%BeI'q¦5_~ k9 U`r0hT1aIz]hK8Ϯm]p)+ݑ36ƃe[5N i Ͱ4UZ_*I5K]WIa`*S*^GӨw2h=},\FH2~GpI&-SkMCS, 9aH|$FNP6c@㐭)84riя}4dHt4"[dsޯf9o-:/VU'd_vЋtj.!u8t7?jsrYk.ϕ'aq3d8J&#&JGELr ΐi=kY!߼s*ʈ<͉fӰxjYX;X3k)?,sm)@j 1y=Dn(ƉC9:#`d1˹ ZP=L&:3>/I) M#3v+XH~8 ogvCmL?G-]]գ+΅*t5kUle/V'كqMQoԝP;I)ft_M w?_u(V^m:)S)&?e;ȓ9DGۖDZ>1|)oàqXlE; ?zmx{[|d  ''n8N{ضN1UWHϷtJ߈J>0YLL-tAc3󜥷icmK!^p9%'U%_%npFf2ĻCXzke!r?"X :P.usLDHEw7k  .Jȕ YE6};(kBG~CG)m6YH된Fԟ D]` <1xg"1g%L*5{&mSdɡsm:4RVH;݅noU oA 2,㕃 ;0h! Q4zPTm9 =YT9^AhP^"왾IH̉:O|E[$a0<ڳa~Fps99gӧ/F{z,Ny@j( p=qLusڌ;з0JЁkApBR|46ÔE0)Vؠɣ-fUkfI91v`.T8P@0 Km"ܲe7)=5# !w.uJ#qB\a*RC7G@CE}QfA ƝO6H,Y#Q߹<5A6 rWDÒc # ` `,J0{/"VG9DjM4 I%nqDt/eMb^̈́<4SJupڸA[86ł10[ED\=x[Sߖ1v@^4VqƑ2 y?PV蝊b0(l$Z3s}\-jgmJ9/X9aT'KIj_&njCBf(Iq1GQf3y?.'Єd9d'3hʞQICQa`ӛfqr3JolqZBzS!sĚ Bmw,w;7nZY(RH{A?%(\R5' 8tɄll6m܇\dd:spLeG,VVOt|GQ! wKDp$Vmti+|9tuQ?r3˃ָ@Xʶؙ!J7ˬIY326{Mœ#|\_HkPWEy$2xN=*uBqIXkyGnMZmst6?1 sؾ6Y'?rڹ8ZbTA:j;o$Ă 72B([v7 *ƞGŋu{xZc XKR¡# 墋LP "x gmU3P\%gS|kZ ԍDr #I Iߡ SS< f: N @L"7ARЍ虄N蘆':j_^7ڭˉT4,\N#c`!~(X xҾ|4;[E)oflmϚ/##C@"&~vZ}.18ysW.j ׋L5+w^=O,tDfyŸ#`s~)UKq/K?'Y uyMaC3仇>H+[u`UJzA[&e'8 n~HxK&Mގ.Gxy!F dln.L6nUv+!ngMV W?ULbM;~]5Z𵳉C(Xkç7MN6vEtye3А$3؟K""=U*x2yhпWYf١ZIn l1ěci_S&sĢL\-9|JmJsl=yeet}p" I%Lwȿ8PbV%TKe¥pt%20 <,(*CY/e>f~̹ ef2t)MPUziO !! U({T-ɑVgM=Q'Sz!xRx3%yVe1 SkT40fYWR9CIGkUMIMExjx3K3ǪVrmeE+|Zس@ jSJtp2 UZ,LDYE}<zbߴ^K7 Z~nvDomɽ 9z]UY@V*eKWmoN#+zW|1.KNGؗLj۵[\E섆ٗqqeH BVEuüi|"b˘Ub}Ai-;259naw$3?~-ףV:^vNy/<D=ZD (ȷsA\sA\+|GhNy;2#(ʑLT'6 H(~.f[;_]hDs"NJ<\g(4їCA@< YrbI9NPK ^BffH >+com/vldocking/swing/toolbars/ToolBarIO.html[oì+m<{4nJBhwS4L3x½w{e0nv8Fgӓ&AA3ZݖyCǂJĉCP0ө?=y:Pۀq.ȫ:ZEdzU5z̐ȍ$ŒD7CGxDNQ/SAR(P"15An㲋ڟP}_?6.S 9ݜc< g,Y0&spXM@[/ʸTH\0=fNQ9Bfr36r݊!g&Lb<t櫼m{[א Tt/4Krvָs1?îR/]z ,#V3'-2x PTv5`A(j`CP;eo߄$1gOQRB]K~*t R%1$R__,#V?d6a'sV1yJULiI=S|ATh.Ky:퓕ŋb4*9ۼͼEz, nF,H@ }6AoES|exT!ȓ(4+R4f :sb[e~ӌDXZ3U$p@Ҕ!J"UCnpzs. :DGAkԯ, WFc!Q66tc}~ۧWƅ0G^;[(I)8i:*>nh} =sFTfm.pL5L_mq)uBU64ʙ釧G.M-Un0e擉C%"rGV]|j q31f|#sd`(cmgPOu-W3z啁bOiswwo[e0n%E~9fM&mkx,9vgBx|TƊyK+v=[1?^]JWW~ ^])?;/x^`Y67)kW\812ɓ²D_nt0hwmU}Jk9H%%%ʄDy 43com/vldocking/swing/toolbars/ToolBarIOReadInfo.html[mo;D*3 iUBzU~̌7ƞM(ww=gyR sϋ9m_xvB^5{ vvoCJTp̂!ou>ө?=a/1{0!c{{?UCxHPjZ(0=q6?5Q[UnT0=:\Gk넣;txhvpxΥf >byD| P巳n(OTt5Լ8?!p!u/XׄgZ{g(A5"D{H"<4dP|?Gv]f8V.6rr^H:@&"l盉}c; tDBZNȫ}T>њKX ClgizϿ_KКG.6~\Rbp5gb"Q_"?`êXP=Aa'v/Pf/Mxa@"[_noX^CܐQJ`3򥺡I0xAhVth5(P4,l2 (МQtSvc+ڙ=tKɴ&13CM-X$8DuZ >ZLso;:Q$Xt+E%! /"&$q2ULmxحTŌԧ6#’*쩔3|-f]0P5[-5M3Fbܲ@Mͧ\OfT=؟ψU /qHrR6b=8S=&ik/ }ܑrH 8c}Z'xtZevmul6u-;r10ӥd tķ g0G:%X #4oT@8v}}= 3CqaoA"rI$Z܎/Zݥ}|(E(p\Oy$$B^m4껛$K#F[]c2.VxEĖս֐]B,/e9CFtI=\!Hc l c;Z!5F+,!H(j0͘(lfg$kӱg x(ąN{ eba \V˫fe, 7(uv0J x#[ 1(+s1 $i;rT#SV'Cv & G+D}bѥ%3ↂNx5R-(w RH@a7ڹC8 5#3>e9]/oG"&n ˕~7160`2鸰huw,::? ?w+Ps^N~Y(ވY_v[uj?ÎE=1P6b 3BpSw2cWȚhʂH^˰3|&VO7:? tٞe;4fFWXc1B#h ,&b =q9 ׺goXG=W4 J Zjp1V;(UzI:YDM*Z}4p5nn\{NG!}2O<Rhp"$BjNy_c>y4@]_[,mlvl\y}WKg2bP}nx}I`* (v^FC]e4Olը iߣ.ŷ@dlw`@شpfh"bwAeD8'=Ӭ wkk퓰yzkٻmۗ,gJjJٕu37e>кp$3MJ\<Od8g@w <=({[q%\Ii fÉ6,XXAGTay1ch\<V低֩pME>o]uc(T@tcl|_~Fc7 狷V_b\zYum_1+͙[̭ł/Q/.Kx|w]ܐB:YSdK !f-̌o5i> ,pQMe<`kǂk}d6fόRwR^Abf'c PK ^BJy $x.com/vldocking/swing/toolbars/ToolBarPanel.html]s8ݤ*]l-ْ'-$E Er ʎ^$Lr6- 5h4FFӋn ~<\``/~yRϵ`|CM? ^,fMu~8Gqw/[k K!rק=2lQٟ+6ߣ߬(wݛ?B /;z?wh޽y+$[bt5_Fŏ^Woqh!9 Q-=7nx5w~AvN{4;n0{(2_xut_5`qmuzBOX_:=E'o_JZϷ&hnPLg߽ do $P%&\ G( .@Hq?9+כ/^ ?gѷJ+t,JYz.iz;}z,` qo-OD@q0k (x#Oa U 6VaG*<:BF>d#~)tnvrp#fJGFLg̶Lܕ'qEz%Aenۏ~Ą3-74]3Rο?18 a VdHKE'(HѤͨW%|\]\ s4.Ի+zymwՎnE^ 9^İ~W2*wkmWLC).qW>ݹ}n{\? Dt`D`z^J/Y<3y+k&jLzg}/3Etz /c`c"~nOBʉyO(C-%[mPi'=IԸ7%II3J6>BKP Dےa(ܰ֗N[JOƣ?1c(vDl16{6h8![Wy/FA^cwָOjx9?!awsjZ2ՠ8$Sx_)laT-'f@slY~: oQ)Vp߽ ]mvnL.g F _lxo(KL0N\pmds ޲_Rm]6Y}:e ?&;6BV0;!6^_@}!k sޓ`l_Y{o$Dt^jE(_!n5CK&boOW^J׬!ݨb>FRb']JL|+qrZsСO/Ԇ>an}_yI;3痌>F G5f:f<_Gj0x}=-0 Ֆw: H-C;,@ bkkYrmvL6ҳq+_2+ 6X6:Um_y*KKr5I0j Dg $mYR7՚ CC.ad4֘v6Z3l.mr ބEÔp)sz ^s?̾ENx[p0yHz,@_:uuqIJ3r28!zgg)8uΤUVlTǾ3A#nuU1e8 `u:n1[u79b;bqG 0}/'7f4YL7& !P0\nzyw98(o7㛅OsIl^сU}܌8xjҫW_p>],wë7F%lϹ,zjv j|3M5uPf躆:aǼ)e˘)8nɀU|:$jAT ^]OsS x6 A 8F[tpP?4)@Φb26mЄ|Z#28'CΞbb񂭃=. [..P| U݇ޛZb-s~o-gq+ Z^#A4 )q;\-ZZ"M?"&Vص{gQpIEOIp˦T|Ѡq̴ap#U ">^x'ΰ?S hxEnO^$q%U|0(Gɸ$@*^j<Mn~19Dr. #llT!YIil-D}$_4qU5:v}k Ciį۝9\X)}:VSr9WrA胰,1.S0Oô햲)F^~vIדX$ڪstr/զ'k/g4"rtRsĤLȃG؅J*,pt`nXǾL"֣̌^b┘%A1mm66@h'72TTސ m2>~u)mkUV)}/#PS֝M܃g-JE2jLeq.q%Q 59k˳Ij60X/zX,NiazQ q#6\[& 63||Lj-[%= R][]ɑ|4m?۷9h>I0Qg_\3h96G';?dwjj+?wʱqe_e"mD=  f2OQvҷk;V F5F*zXc5JQT݄V4'.e1D=O)2~ץ2E bVLc2 pqb3J-K UBH6م /38HVkŒKN!g9@!߅R55xө% F2:ŝ εiӕPX"oCk9vP2DE3Ѣ\C9,E+}v&ݸU:R82_Y;'7K skVHMk*zc~&ɀ0N?o sZ,"YË=O7ՃzQ!847 cldg 9Y&86E ʽR/LZ֫1"6@dٚX5Z(ĭ6B_v-w# E5^H1U[2_{;\SlDaq`1Vi(2p@cV@8Bĺ="[w蚢 u0gQ'PRhMa#Xnq * PǼ槻0u/! ##o4]&SǶ,5 +(2UW 9̼u~Gi @q㍵;qmDږ7m^̧:.,A$c4hJr`"}]H|`._^g:,cF!51SP,}E`=ZXU&DgXLW0neJ!ʮGMӗӛ7]٫9ojIyGo* ~ߔ*-:ХR5\19mBP)@)G -w#DS)7}R|g, m1ٱ2W}_!q|4V?=2,YkkFI&.!2[Z^ץp7t^ץlj*КezhM]mq&~g7w>H:'<0 G d;ig A:-~QUq #YYY}gȼjHVVA8 >gKAU¥kKo"g(jcɄWWu&vwUS$]C[׎{n嶗H3_9Q`́N 2í } UB5Rt gnZcg"@fU`YzqF[sȲؒpc7"'zTd85bR=MHf(4:B\t5x4(6]5:Az_:sD0ӤP|.Fc^1!! VsK./Ҋ[[g3? #Tt 0+Ķm%@)YUΰy`^l)N"7n^(F+LD@e~^Y^7[SJd<)f uyYRCׂ*=3a'xc9i7ѷ﨔T/Xjˑ.4!E~M87 Uh 6 ]cj&g:8ٱ>zLhAԮh!V&U(>׋pkZ fty'!E=L 5HjH%`W TRHB>)^3E(Q/Y|b@_qi/i_  DH}i$DJ 0""9(WX)򮥺e]ZndOG- ( ӆ}sByR+MM"4EK;Z;-b9bF4} <{4җ#$x3p< p1kQ|qa=qHHqi ώkͭpi|ԓb5j,noJ:t^'-yRxu]^"|߇X42~"AYGTyadsLEn6~"ҍsfTjJb M1 8&ڳIEdfqT_ƭ۶O3 ,iQ)&t a$QH~09Pk4-M'0<_ZuLo+6̬ZXU^ IT^/o!oin u+)*.k@~ʍr-]"l0_4]1U<_5 l"jv\sj}+^*n^Q) b%QokFɁ$/.&XHLmJmzG/k: , 8cc#4"[RK@@2<i*H7^̴mSy5T2G"l$MڮO^> ia6/mLAO҂.$N_>0 sujWkM3PWu0L W\<:F`!.RuFaEPk)hA LdfWG!|ГZshK $ h&Ӆ?ޮ9dطi1 &xkoN:0[Jr&3Ed=tZK|n> }g9zj [ Rr劰?+r+Oeɑ hE«zZ"hEz!YMpI T_&kB4Gj @TyUu= xF=&7M6-Оd& Ƌ*RM&R` $")Fl4YFxJs+\iCl~<:{,7 AÍQyV|NIaϯg&\ܿ^/]g˧Q[H']x$&`D}$+Ec;g=eUƪغVlџx6xY> ~Q' `9;5'ZVBVމ?;{V廔W˅u .7񬜅ҢY؀N ִyX2}{?8P~a+>UL۴dʸ3+s}h_<+?bBA$ 'bwFBU (d6 UY,n?pa;.o9q8\y-o?O)Ň(;7tjɹ_Ku_`E{sxtYyL QˡIvjY)12C|^[ʸ&EJ҃IQIlg%R<]m߼e)zOdZWc]FeSAQc(9Xd1o >^@|%R<].*uQU˗v<S-k˳IPjv6({sCњD:1O !bcGHܙ&rۚ~rO:àkhs`Fq*i6iuσ=-,ָby8NքYW&Ɯrp \M\9_/yk푮@?f"YMbև:)g.Z1{4ŗ8NV@618:}Z? Ҭte)JgQd1SXT;0-ۙL,Z8CO7jK-w8*m@&Hk&8*ͯg960eN꺺d>_ )$f\Q_;}V7%h4\ QvN+l˟O5~:PM^zAsw"{'WYK!N x;?>9TQU7q-j@~< rHy?SϴZ խ|&u3v3̚VEey';6[?) 0Vʊ`c6XlP'<5O XNt?W!`?aF}`uoJZjO2ΰeOܕWk*~WVhȹY sJPU*G܇9݅;֝ޓ7s(Z<.o MN\okT:>tٲe@{u$WpSeyա8]1cNkSqlg9r7'W.<4jB TA_XlyΜ{=FM>щp50.nB] fBD5dHKE'I'SrEWP~`^[΅eݲQp~OE޽yɻ7o@W!^l7 /E pv k p_PK ^B J4com/vldocking/swing/toolbars/ToolBarPanelBorder.htmlko8{ &@-ޡicmn)%F"mw/=,ّiE*ќp^1sS~s[E몁eaY^S~<:Fencϲ.2Fg5٩DCwk{gyA@0ǨT6!A ᳐a 3"s?D`{⿈GIYX?I >-zוgOÏ)h >L7i.;A+ߚ!! ә,,ҪQZZ˼^E1oc5iХb.Qxhlsng:qFVEzKs#ǣFmˍhW-l彖by,*=D\D"a&9/5toqɱ<;j,~:?-Я)B\ "Mۄ) GbGS[ѿJf JNI xܑWPzeH䯴lLvAEӾJMA Ob3jZ^oQ$c7dp\[E =N܏VD\_6?2>z#8=?، ClaO=aP`.:i>pd9OW&~Dze!4G2R"`=~iR18q8q\^9xU# "~ A*} M$D1bWe>/ K1j:X^s!QBO,CaBx@R$A~znQ$xT k#{@-HہCj ln) LND Υ+ܕ27^s}wSo_&So2@-~If([zy_^^}3ziȥ5ci-a#7:nk׹͹|mo$,Sė)8g|y=:Gt?8,CS|p o?` fIDFwnJf˘/eKgibydʺmvE{Ԗ5UYj'kYW>%n~/HQtH|hF0+^5ͅ/c3݀Ξ!|Xg)&Dol))5>$M`;̺--taWN/J; <66v%lг@SYqm#Le]`3)kU$r]K#U/V|sWX<-*ϳ@LI#+ݐؼoL:76/5|xuSU8QwamoDŞ`W]m]Z}CBK*rBbw=͎d}5uNΩT w)K\쁞Mw]킘+|^Fַ̹LsBE,` ƅG`–_/b^~/bKXxz_^%L:_*tjazdFι[6 |D|8r#NUğ7j γ1go"nѷ|EB&AYBAB/5PK ^B `W y4com/vldocking/swing/toolbars/ToolBarPanelLayout.htmls6Augd&M 61 ۻLQu l=}`l If71BzzzߒoZ)sFW>ϚȪ:?CԉhL{sza!k{ǙL&ӹv{xAƮUj]T^ y,:]]gEOTY.enďkzb?x5aBb !ɗ2fADz5˶_Z5D5 }>0΂愒V?*^Ŝs6ئK\*QVv$hDCʶ' Aa<9%п޾qG }v+ F2R=8(0'Aepti\wGԹB>4JBz1d^1P{Ay"H5s0&-LjrB(Pc,@\Bgш08Sg{iDM8"B b[VТ1%* 8z&ZKU,r w?δӍ24^h`#N^TGYYjwq^,-\FLR֭ LUy\xaJ>f9#OQ❑P6jzCgRE6c8" rAbZD?`vPl ĚO0A &#~}} a=C%a{6q.-^Ȉ@<Ȋ?q'lƕͣaA Ù;:DݚB. 1AwypЇ澷O=pV'Un0ՠ0qmmpF+p`t!>q.$]i2gK{Kp V=y%choh7-Ti[t XF }6 qL] x;rX؇.ZʪO|G%!vT&fGR ѽG7dC0op}8u#ՈoU*Lᴟ$A=o,ҹ^r4//n:ןktq};81c`W L>鹨c{1Y5`bץ|X~IBO3$zG|RW#2ȳ}}#1?0w0rNB2 *pV] j .!CI!qhR}AT'p nU5灙÷Ja/g6L\]i7: INF5" &Ɗ}nvrdUG,sAțpO;\rs]9;g6bsYc)-j'%LG9m$(mqvUyPW>W~l0!pN>r/~%׌B}Fߢ Vc=9LOcyuGd%pc&8(]JAnKaSY + 9yZ^`k"c"SJ>%ZE" &iuv>\7m{/[&=LNpai ]?|r"vRCԓL]:q$ٓ3hGU^Ry9x%NG"X^vP-I; Sn}⦣3ENk.`dŌ0 [8ZOćP()?m"?6t<+)]ڢ" s5[DZۢ}nۉ5!ijȭZύU;\S3F,=[D6ZM 2axbDWU^Y_QB=29R27锭T#@ӊ2Бؔ;Zhv4V-cʊ0(G_ [-AEH7B[f~S;iYIKxõ!{FkF>\v:W8T_VM_f5r^/W{\m7.WX]_M +֖ZW=T̈́`cܺ A'.xqDԣ`<Ȏ6yk1tM yP`oW)PK ^By=v\6 E4com/vldocking/swing/toolbars/ToolBarPersistence.html\mo8wh{:5 'bmq#:~7Ie/qMq3áس_[7S窉n>h^6S' ;o#Iq̩,Ƒ]\; HN=o<}sb"8q8{gT*蚌opJE^(qX lXu'O<GGûw@ct}{z|n;Č%HX7 $ *-e#l@/QoqL&5faKh of\\ŵ\yLRpn2/VRi4? `˧bB)tgpJV#>$ |Vdr8l`{  s̹8$)X6;ifg"ˇ+ǀ0ܷq'Tu6ku$yR0BQH&N-j~31-ݴS;R@tl0AűZ+o4C 5? =fnq,`EhSjEjɰQ_+JA@x'ŋގۋ=jgh+v3ΩSi6O3HG^C$#Nb=dJw%5:!1|`GTNGlg*C)*J8$a=áx{) #3! rg\Io528r-q3DbXZ Q:9xD唂D:cҕaBoJɿ4R`&" ǰsJMDYWvF6U&BÁYzӰɌ)PIrʴ,|/ UF&#N3.{κ[f{YUuYfF)h];-j1 RXZO ROTN;C>pI9@(A@eyDwxn1?RFrC/= < `<΋%>VQ{\Ql+XtE"Ō-."̑LЏe j٥Xy>Dj EL#!̰7.y5-Yzj%rYU#3Jz Bh3lfMh*MBZ&6:XOZ l ~y+ANmqz&F&D=4mAD\￯`!ְL{fe~[9kܹ MwD;ۼSw@*a79gl>^ x))]Վ^†G|![){>eP9es`-6Z>I۹B^$JW{#ͳûݲs%Ӽx:tX(6(elxX]Pq+[[YArUyįiPZz*3Xny*l(.[O)sjF *.x6ݭ#0w6qx{e\5C|p)H-9hۮs;A@.p{MURNR]6B SLo頹9߆pSi55H=\CҔAnW_ f4@M!Gt*M\D a pRW y;jO$fJVٙJ zd͡nU%X{u3WyY+{)K%GJ-~8yKKo\(Q_(tZWӗotlPzkR?ZIM?O>OzҨK0Qz,)1$`nC{$S:><|SQHFb`# [b0oe/n 8@(Iݡ?PK ^B^ W,com/vldocking/swing/toolbars/VLButtonUI.htmlio8{ $@,hw46]'bm%HCdW|#S|'Z4B75tpY 8>8NY/'aSA3ǹ""s08-m`̚%z8rYiVl9<" ;ݚJ1x a䞀F+9_s⌍xdG""nix$+I t5i]<̘ߗ`5 c:eRk(A0OOM&ǝ&<0I_FY):zvVX 3p w<"2@f2ךwsLނɤLC1a֎:bv6ʇY*[|i -eLϛ%mIu1\ƴ \@`ɐZDIik`* "4&q-V׆X2<RV 擎[8Y| y9=vnW){%0i=Ԧy]QxlGAQ{j6o-̩k_%9AR z4ܿj\YިsMyZgU(Vd5!v@Nzqud<"ncؤH$V)y5 'M3ܩ/Lx,iE8 [ml;Lyf'7"v9愂} :Fv.z ˆ|KI#.<,'9ۻZuPP(~QWEuZ6Y~%b3G_j _+bRpjp$ xBP<}&$^.Qߧy t<=W&zg H >^_ժpsS#F +O>^ Dҁ5) eRV35+:U 9!@xd퍙+Mh_(4")f4-6'b}R`a+2A~h?T lϭ gMʸr=8&/j>jxʢu ua,ĞGwF PLCrY;e_ f[n Ox*;%VRSعKX׫i\{?̒>²Z/O>fN Lj MQ.W ]_pl. *0mVKC삫2c3@M_f 1]6\;Rjme/1/cBOzeز.hFY+p գwGz3< כKoL9%~gKm=:}\B.9b7<1o?sqQ   >P{8RCNz _ZKOz1g<25KC5ӏx;edoj볊ĵ?=:@CAwG-ϷDVY^`00(GK?dudxlBMq 3V*f1'q|0Fk4ݣg:@ϿV]k5'x.dm3}&R8i9xVd5aP/u˳:) X86fw_'xc?ϻJ|_/'/Ie-zv%,[o@9aߧg.vЁ^`&37<#03kxkaLzǾo7חHS?ahP  >7o 颅$ڨ4|jYSSm>8ml,BxBa2D?ÐG_å/b#.c nЗ\!w4as0}R9&|ꃼnVjxG0>!dԇEީʩk AɄ8$\3,a>a-Fen/da}GL %|еi] Tvs18=C ;ݠk,׆(=4P3p3lQ߰1h\{B" s'y;4Nɩ `qH嬙`2×.Д NH$,j2EU$g Sz ؚ <+ le@qțqnTj5KL!~rL pPA2w>xe0%97=d٭?'3(&C0]>S4+2j9E eej%qk,2fZUG_J|)  e8n3l|8YCQȝ^I?Zԅq,C͙Urˁc/; <KuyF6Y`젤[4$P"Vz.fXOb8S:۲cNqLzY-0j?<Zs-Rs#@7Ht s0iwX4vS5Y\Q1Fg>$kg_d66䘅cpvKn ?W .$H*uUf |w8/gρ*H7U'.v#ڐ\#9/ԯ7HM%kXbYDt\~ZFF`,KY֩(KXZ[ӭMQiNV/#ʮo@rkJM&-mгo!߳tr[L;+-\ }Ӆ94q}^x'α 4EFW"e#zxIc)8V`dP4\]c(z}}cִ"geV3Q /OdzLrLU)9T}w*qxX9֝4ɾKy ,bұޞ6 L-ljs=}(Dӈ}ܵCt$DafƄ} bQ i,tO J> &EΚ 0*1,(N{q1Th$l^UZF*-|F%:MӉ7\z=xG*|o"d/ &저(V܅~,5q7\S+ˉ6t~_͂W9F\mn0Jn{(A6M}U,wŇŷ)1_]A t =~CG(QѢHTQWv·9!__LZƜB ˝S֙ޚ+7 _>̶7Zy]-T-=E^9]XdEZjyGVtyÛ3>&qQK+eTnɥ>]]zoޤu^w4ޜ'*gƲH$Ѫ dVcc9g#8qqj(Sxq]00$e(ٞ2 ®1Rjk$0F蠦&Z>QTm_B+5FI 1E l)cxoѲ*L+j0zV AM 9iP\Lɒ}>iZoZlr4#"A|)I 6&!X=ϐ*/C)Lî>o|-iN9#[ӿ5=L<՟TJSH"ׇX*̅Tr)Q޶9N )!mFaE%Z2iޚu##צMgB #C/Gʈ_c4`gJ__m9,Mr^m,awmMXUڐXxc3Tcfn;SB|-ړC] #C հmơX]c(3 MWhMvG=S;AfcdW 9ަ*߹EmzˆPhޫb6PZ2Z>œO۔ZSh[mJk<Hk/fcH>neg?VX3lMq`d !~sĠdR?11B֢Y "K.e4Q ~16+θNz`.0ڶoT P;@ gX._R ;Ko5D|@[-@9+c&M%|LI7i#75~#vɩ !5ͫkfS7&j‹L`$ҋPf߰Eκ:y)IW3Z55l%Glȷi1)!Y_]ƌ 8-o> fQVY6xLtײf>`DTմfNٿ.hZ~aa rFCnxu vۀ2~3idk.&ЯuW39o/2$P/{k/2-xS 9ѺR_1!orPfxm`qeD UpLg8͆'R.,H^sSݛٌ}@3wҳlj`# 34{@M_)@3JMCq<;k `luV<֕b! *뎠%|W죐8}@_ǗYل^|bTgl0b[kj9ʋRyږԘ4_` l[RFo*i{9[Ng/;M'7%#4{86Qeil hT'!dztMd.M67!hw 2bk~Ot̛Vs p%'d-j~O,[m#w˦{KXa`}ՃU8hέ@9Hp+:iG`co(l*6ɟi-:ЯXݛtkG&A'E'ibF- 6 4\NGVX {|QfPq -YYY:A!YYKEG:U OH9P-5C Qv 2+S *{7ڋ $Ifĵ; nHsLNڿ{~TJ(kCauMa/ &: k= YcΈY@osknuS{!j#J` k pXڽGtd]#&/Iӻ+܍[ 1fʨ{м^NZbYRP7W_=_ Fu$00wt@X"lx}~ic`k9`lCƶ}u7 v oyl%YD5_%PXu<н^l)"VD+!, I۸x#IFa`a 6]kVo-kh)!{)rI S;~՗OI̪viE]w~NBkv齸ܤ5j1aXL23pxl_9 =gpkrFΠZQ+w唼4l5Onl;!&E#\ ,'(Jb|"8b-ޤ^&PI1-Jxrx3(8ȝzPE)7 7\JOZ(t{e"d~"CiJ qVaEEқcg\beȻjF*5]p '쫒tOwt48X(;`N(r0{"lyr3ha$^ώZr4 ^8Яci8e|kBoln2v[txO*èkԘ_rtfj{ Leʣu%W5 pT:_yƯB_D??0pJE/6Y~"҅kfS+y >+ԝ'4n=$]d茀-=⁓S`z,x7(NtBc%ylI|vƩ hYZS`3GtƻdW{Ǫ{ Ձ%jk2Ҫ ϝyp, @/re\L Iù 7Cj*[.`I&Rv)q0 \^:YwleZJi~^ pKu1A#q`\hLmp&A2fS @q0<9Cՠf8;k`VuAc:7-)L+:NK~~G0ly3]<aL':kƵ7ϒYv }odovC£{VctԌ&ӵY!/7{2 p)Sn sx4Rӽ|$C=PU 2%cyD{ԚF[ !ECxK*bpP#Nc\#Q /ՂuRy:iC͐v5(]y>.44ʿzirTB-fNStajh54/5 <Z`MD_9CeF.+n4L訉;󦬺o2 zBz^a&dRoF:0]EITpl~:`#՚]Mls7&r-tɐ iE«zY iEz!up *W0Oo7]+oQX㨪Yh#o6Y'^mZġ=X'bt8~r1=˫&QRP4'|DHˢK^6,cn_o!;\FW _OPۯS?8d*֏c8^" @0B|u#"pA3{h[_ f>_poovoP:,mEhjx,gI՞T?3Qk Q?m|s] nVAЛs W@cg9YazJD!}Y@[6T;`=LWheDCiS쀛 0BfbFUo72$ 1'!D_,~dǖ55-͕Gl)bM6@ߕbG̼VlS2;V&|~*A6cp:9> e( hl G(QH€~8pK٧EeXUc2&*\c 4Vpb|_ާ8}?ۼY}`\&k 9/:-Uͥ5yl#0-lڋ ͸\f\N18UQ0,9{\ZNėX5ZV׆J(kL"8WNaSݪ7TQu%go0nUl|*'F.@Ƭc䔻)0x X?N7nMYUؙ);]qj TSbzr ݏ ̄:9JJ [P($J(6\CoX7asL~x q`ZGcϤPdMhՊ+Hn3PvZꦡndWͱ-FL-'v5Si%lc r0ĖZƲ$P۶?~P!]=;bۈ|ކ̍%p Ƞ@,CNa ɗ6r2w^:T>@m-]P6dbY d<\!O8bhExV(ds A\ ͚1uEnuAԬm⸷ wV 6[)ru960K#78m^*fs α"iu=˼ #{IɊB"\r ꏌliȱ _^_3{pPIvyz*5&ڼIQfPj *Wp<'$[ TSsCP,( s|hB] '[JjN|Uڥl/`k5}&^'f>eQ*t'h1q6rsFFMIs콖اi _о {t $je$sUV *c2٪Wwht.n 7q|0fGݝ}=?{@ya-ﬕZ+'S3}&q|'`"se8}P/iF6lg -Wu"=E/4Z.`}Hc 59{4K< 80V\nHK_(( 0[/ˊ*1Kiĵc%}B 㨤_U4p -4m51|@lctt @ٱ ޲P|L L}M "+$[~ZE/;PJ^"RDh /&9=;fZw$/vc$M]OM9i!it  k-@3R<BPt f4 H8_r!^NN@IG<> ╊P K8CqUZXt0~\Ș}]Gw?Ȩ(~v1ec-ON3-;PRnj`gwǃ-3jVrTc a$֎kqէgȪ;Οǎj=ԎiL39ՏF#{t`Qi_;x^;,8س]Ah~a_%}E|x3F_=Iaxg޽}菡ߢwo޼GW6;c4f=8ƨ_C"< ]{]n: $ȇ. ,~LaAᅰ,0Ea cFxB8Ș|s #mX޶!GnX7Y"vto,nD8ZHIZM!W[>j,pP-oگDF ɯۨ@m_+>!Q? Mق~S~8J'U\AvɍrQ; ,t cE#N"<a=nGmt/Gɯ6r(A{jH9XtSa=9{ړG<8W1410g ,!`(q.!f,dTGc[ռ͒, (B~-@]I`DŽk=&ܲ}ȉS(='NGm=/qEx3nUpH7c4',?ipsLm;g|ؑi4Y#gOw =IIv lK`;S!SxFDVY4aؒT^üeG=\y Z|`PTl&iA+VtĘq|mK Cc:Y=aD\z)oXO5Ђ hLI䶜l!c\U/8 >Ɂ&SMEVnT{o!B~@ c6a@2t alꛏ2~e~ylAZCY%$xH@h-1ijN`&9H|,y8>;AjLDF""ZY4`iy4UQ8 Yܟ225PO"c%0S}1l>mrĽgw;8#z*X^5 LT?wKĤ#GHfzi+|=YRKb M )I WB˨}:UL 4S (v[؇<)Z^jNJAk"lkHI#rߐ5aQW3a4Ֆ +2_xE ZGш* (Sѣa[ =땘p\l۠O| OPuAq֕z̈Dɡ KGԋ(nvWLO! I *; ! Pĥ]u0p"Xm1{$ni,16ϚVr³9LQ3(s K&-'Rˋ5t~~t}[LŸ&3LиJvF:A@nq=ddXD4]H `Qbϣb@Cts=< h[=9e@(% !˙R-,|N|j&y^?&H2ѥ9 q7@4T.je3P5(E,P9Q7#@!VYg֐?kۆGO=jm$!H{FV`Y!MIHfYɶhn=SxtrXZ5IeWŅШV')DEmXp/ ~Ǔdj܂5Ee,^51+ w/>q^@(cC&KӒ>[V&u &)7 z\%-jy>*LqcJ5#%gVqNVS)Ιu19U~b|j6\P۟̍4Ih_I^6Hv3nB⊚ jt?!;lUJ+?*s{B݉G`uyMM`.?.G/~V?2}y?su9Q~Ab:~Y{*)̵ ?T|.1<=7{Ά=)TD{q5ӫ*)u?/_(.6@ϛ ToRc V%0,PH0 b^00S`c\kgUW|UA(oyҦ!`i{}: ׶v.?sIXvNW7ڱY^女:prccQrd^\yiWjU1Ý+WXՕӔQ)H)m!?kU,/>oǬRD:W)c_S__ۗ'Ŗ}q ƫ/qz|9@䫳 υzfc3)H2 Sa"0FzXX_6q7$#yEgQ}<6y- Fׄ\K<QrBIiw__PK ^B/#=com/vldocking/swing/toolbars/class-use/BackgroundPainter.htmlZo8}L$pjiwD)jNSe_MNNBѪۺ}{wsg-|&]]GU_I_ -h5 ,IIj6`ziMvXSVKbdtHxS$sI[0Ò Gj_*-hL/ idvSNVؙd^ PK ^B%~rq8com/vldocking/swing/toolbars/class-use/RolloverIcon.htmlXoFaΕz^>rT z9q>E ^`v8TٵMB8ڪWBz<3;?N>. >]woh҉:كZHDseB!7=1%!:X7$Ys",MNO|zl=So) M3c4.xe S԰Fh,PY1<Ԃ} L~7 :ԫFnp#Xfڂj cVy2 ڞbDRnh jjp{$z`B,I KLYgO~…*x2DiL3M}1d3&{3zwt"#oUOMYMhFZ6ݧ'@E1'1ҟT^sSXШ%{}a~ dR.r{o3_OOL2똯Z0,\C5 l.4K#%ךI,UUV`2,A@հxꀱ-]aH CGv_@.Feˊ/1otTSW'Q&k~•6>cx^Qrmvz[y>Ӑ`+־^.TmV?';?ՒŽ +ȶ'R)SE <9؏^cOJ ̈́ VaXc#Y؎B_`r-H5n+T\?RvDcrx[$K.)u^\@UɇΙϊ9pZf{)ɝmU7sxOS φ<=,#3}33D 'rb-5"{]+wP\SעXہfכ۸LgnpIu"q#ש4jOLhvl"V݃E tw؅cuC>TTyKOsZGk3]Ps_o(OKm04yzݏ{4F.lxf/h/h?A7;|8 H 6- &Z/0V~#-Xәzz\p@{Fz< xh4 ~=X.:Oop.PK ^Bt|9com/vldocking/swing/toolbars/class-use/RoundedBorder.htmlXoFaΕz^>rTr8@wU/eZ &@G[X^{fgS>؁fOo!= M47\&Tr^ZU-jB$BJ͂^V}:ab@dz,qiA%0`)P'@H)T` IT1SPig|N9[I5ZPpӿL?3C!AЋ{$%&7~'zb#jKX,|KQ),}hԂ0rfHXbngU޽gd&YPvu̗}!6Z. \i:Vնےaq}t3^77ipF6\̷Lti.#K雝-zSySh%Bm%3}cBLkݘ;ѷ/|ϩZvo{^Nv%=~F="Æ""HPd2E|.lюkw]X2`Xbloicy.O0fb#; }7ոS!rwD))E$YwVеVˍ[nIYѣ:g9NpP5a8f~.aߖJxǡrdƑDżj7BdC yN kX$ a31[첹Kτpf7\!7Xj _'mwA-|ɡ؅V OomB:Q'pTk)hnL 73&"dZ@)df)5 b{ӓ+߇[ 蔁[AiK_Y5,K1TLi4z_<>d /Vz~NjeI3 rmA\Kj<zeFJ1J.ZT2cdҒ*f *)`+pT:\n$PH%bC[a =_ɯ_O栘=mւcNQҰ/`$l䌇ޝ%;ݤLHk{cS5zMO"Bv}O*Q)lШ>0vHXl³6܁'E'yhvȇu̗]!暎6Zf FJ4SAXfj[mϰ<.FQϭah>c4f]=d%F|.BP˖=穿ż)7QՒO]6F W`p9(l6&}m/%%g+_gUs/3Ot<#8ȩVdVĵ)ۊiH xr;m -!BcMF1V8c*6XBAgC=R>Ppk1B=nKLK6Fnm@=:;=s]f)qo\7si;VKOSE <=,#3}3HAOZ,*x-D>P8AE6`fm\y&37* T5F^+Ȅm;R1r:qcrX0g*Mÿ6Qcߪ_9ywAm|<`gھo4HGQ>H^8?\_pϸ5Qch.NT%>CNҲMht Hx tf^^o.&О""O%Z. CKgKÂPK ^B; #>com/vldocking/swing/toolbars/class-use/ToolBarConstraints.htmlko9{Vj]ީm*ОSeXn{e(:]4}{3c{ݿ;G{z7'mBBmr=/D**47\ rt@02&}Nl6fTCҽ #3NDJ͢Aagl֡Cahg,$T fhS԰zsxO4}Mvߣ-KjD@<yc:]hwv3^hAP/4AW\ #=FʤG88-6ra4ޞz`xͤݨ5`sG<6f@f  Ha)pq%@y1iCZ0Rl r̛vIn͞WOM5 Z~jS򎸈هA1!1o5aلpg RFh2ɾ.'^3;r1bi/@Pˉ3TG,%U&`಻х=ۃmzHVg4LmGSTk24B-wC}Ӱ\xԔƓFyǻWhP9bߓ$qN6E VR r6 d6ֻAm6cc\=olThfPG1ɦ4mwƬ}VEao͕Ȓ*bƀXԷ>ME^46G*0s: ޑEArUK".r(`3~BW_/" 5*@Ӗ1akrZVYx8W'tG ޞd֥VT"NŘvˑY_dWvsbY|jn%Uui5v]HƛfS9K13Q˦Sgʹ=ˆ ;a}\֗1[9E. Ű ֡!nM;_pU!%kDm9N}f+h-daedVJmN4Kr@)8MIȊ+Bo3\P>t`>Ƒwy!22ܼwc޶^}SnۅgyUb+:xPos{PvGc!wz*{ W4PHLfX!/!22AlڋjR{rͦ=k5~Vc*y7ʸ>⨭=l(6a۟{ȁߐv?GB[cWK^w% KKqls`3~Cﲘ}Oyա%[˕gͥy{~|v'+j[ 5?{WSJ'uM/zc&W]w6U$%i iҖWcԣ[;pdQ? R9 .=cܔpuppC2em<-:IiPK ^B30(_&<com/vldocking/swing/toolbars/class-use/ToolBarContainer.htmlmoH{g.MH{SeEQoO kf{f6 Kݴ*J?Aow=vzZsv Tc^޼' ~]P ^xUaۇz*"h7I% >w Gԕ+8gc"--+$Pk[PdNW\Õ[sp3_{SE F2UUk_uY߃HfT(Uu~V^ 3A' u5@yy m/嘇k+%H]ծ:Mmgghjn`R9UģPbA>F՟E."hzdz3ϳ^20Z6E[[DH1 0Z󅀱+I{i`MH@f#{f7noF4Zc49Odb#&KT#)G4u>J׸ t4Iowy|DB*T~/X&("r>Evcv.#|N4鲑C}* 0 Ɣǔgbbۍ)!ShQ|4.mi F)c#^pU4 i"hbR|D2&@Wߟ;,RԷx[S (PeA>֛Qj1T I SUܦDN"O堚 ]fS?X`TDsL}wØ-ȥ" a̕h:˘^+m\-6OVfF1$[q(qP;jJiJsMc3苛|=;jv\]Է"1P_ ?M2T&ܹ$lAܦg@Լ?|!"Pg`UBΝut}6\0~Zr.JnoQ_"P\: (fE0O0>6VcNbi~ʛVUr;خO֗A.RyNW˘ *bZØH{4Z /$۹C}(zEox?@]OOBEӈc nZw |B8oҌك\HDseB!m1!"XRH#c3DHYث^>٢KG |U h2 =5cFb;0E r9SC%xʗg7YKT^CA\9unLBCPa \ '@/H)T UOS[El!΃rPYd PӔ . PMbXbBϚY (&BO`z̘,S4!=+6 G-rCN;lRD/㥽:bmHYn~zx!Px/a%>1gWk&k*5Φv[{vzBHjye||^>gbi_`a -LA_Ʌf*Bآ ^uо|s+%0beڦssQ 8jeiEOx-^ejG.S`kI#~&aȕ6.exPiqmVz+y>ڶUw朳g)Unɧe埢t0%fȭȪ(RT٬ p <9X^-k!Ccc,8jct1fb})#av9?RvDcrx.If]ͳVzwr]k6l=3Pf{JmWׅЖcti:DY oW—.Wk?VLw=CJko:Qŧ!Kct'f|?LyyW̻B~bͽI@E?"htS^_8⣱j|Z\p@cL~< gWi1?)s,:KrW PK ^B>ax<com/vldocking/swing/toolbars/class-use/ToolBarGripperUI.htmlXmoH)aꓮ䃽wJ9%( t/v(ovmBw=BzcS6?z7!Ԇu O&!=8M47\&Tr^\.e-jL>8'BJ͂^Ö=:fVbg8XLY5, !Li4נP8>^@reVr2ָLASPa(gB '@/H)T 5UOSoʦ;Egl)jA9UN2hk ^xh(1,1g])(&BO`z˜R4!C=(6 GMrCΊ6)b9^]16kؐ|%!f9KwTz͵zLaC!3# } 0+Cͬ;=!$K7D>ch|DXp 1t ȰVr`R3ԉl6lawU?;=\}OC Z12F.jiYS׹F9B- l5iϔm<e sQ,u\D^k*JsٌU`wb2QR:bcRez?))j5Ek*P<Kjj6M&D0XQ~F8<ɘ m[&)hG¸-S!r[{vS̅gc퀝Ֆ)XC^ՃvD?loP5fų-: :uxz2'faȑJ!\BmHmj! Wqi gQ ep+OG~THXӌȄm`ݐwuB)atZbaXg*{/¿QoD{2Tw Fu>wDok+}N3Ȼ(~zHcl'f|?L_X,H~`"νA@3E"E"ht3Q獟(x VxbZ._6&М O)Y 0,ƏnŷPK ^BGi"pP5com/vldocking/swing/toolbars/class-use/ToolBarIO.htmlX[o8~p&+Ї\:jj3ffO!8 Zc'),>TjKh}u O6!=85M47\&Tr^^u#jJ!8'BJ͂^:evƮAiĭ1k?)jX IW4cҨjAzqxsG |^&PZݻzZ#eU3 rmA\+sLg#QTEl-A5I2lT`BKB/F=Ԑг_Sdf#1f<0% nXkfMB/H ENyiM dW=V<5etlkX|!Ԧ7{Ry˵rLaC!3+GJ`< ;-?b8=!$K0D>cj}Fw p 1t$p6r`Z34]l※jAD]_ y!k C\EBW=owbeYs$(eIRȕ2˕[la~VֆC= vI]lOSg&M3}* 'rb5ٺ"k{Msv9k+mGom\yƅ3ׯi: qrGpvT FHJ'&4;V6 +!x{5B17:a7Xf*{Jo6{q0Pf/ ¶eZE4flzݏa{4F.RjxV b$_[_eskg`zͽx {o#قcEAi~Te@jcxvZ@Z=].8M= d:`S<4 ~"X_9IWPK ^B2G=com/vldocking/swing/toolbars/class-use/ToolBarIOReadInfo.htmlo7{W%R 60%vۧpܘ6P4߳}wu*"~{уv5 =霵  EH{ Oj &.*9LI_\.a$Մ .S",M4;ze>0C;c@dX`9,aprSC-9^U\Ro ԟCٳCP3^o5 TkYH'H/H)Thz(Y2Pyi{Xx-èvpD<d6cB F F`% ?N_kPL4mV)c&JӰ`ظD)o"7K;hܘC)2ukU?41TQxq1!1o5gрvz\IB]#|fd탗'^1;L8TkCasC%X`KLf#bW0{"_iȪ6i.yp$t^|C C#Ԃy?< KqI-9 l8iy\ s 8M[ȢF?-C=ͨZEv^6$#JJGט~v^AE".HTNPyNu .zoSo1!j ݌ ]b,St=YfP2bvO2nST}wD2Z$s~Sz>t[`ceL-J2t1ފSW'/;cQ m& ߴ.mFۏFW]2[7tfj- RȱyX7p<2J[PTT0;&ؔ1}טQ;gY yYO&1ܔMyh0S01-7<LoC -K ܏N_$WTloIqT{xC+" 5*@iI!}DgQvz'ZфNfk]=L%RD\z?p;?+,[mhh_$G[|g _V+\}!4e˘9S9UL^M+籑ٷў BV4<9̼Xwh?P`A;@mÁ^dW4lVjMo.3NzAvwz5Jcl㍆_R#{ jƏF)|Ƿǎ|#TGBlBEK+uPo>lⓩz4tpnt&l#.P.tbۡxZ$uFPK ^B J 8com/vldocking/swing/toolbars/class-use/ToolBarPanel.htmlYmo9 RNSԦ(JN 9Y'1u+INۻKC\QI6}x8zpnvE :oOZMBB:lr=?<U4pPAeȘ9!,FR IX:bzE &'ˎ7ؓ~)sAú=@E>'1Ts"SQxuOk_)Uhk.C=B|>&ri5Zk=Ʌ3=%g͖UMz7._B݁w'WY![k2Sr q8j?< K8:Lx?J4n0|\Qiqm 9,a$S9lxL<';heAu.)_# v)|"y>r>yyj| .g5)9 Y7W #i3b,;TP`2lQ8w1袌~-Sp)e\o̴LhGiIKę7n)p\Éf!CG!_%FC喙~[,_XY̎Q,r qj*V3<`žn>`0b9q##W"T9 zX=oLh+m"V"P5΁t7!vN\$.O7MEl|To+AQy,`9Μprnb{CyHdIݼnl Th|=)cnC]#z{V'oQD"d &1,*Xqh0#letr9%HYmd=/mG≠P*fEWw2.PDNA29yciT΁ ӔB<0f?c5N@рVf]j<$RD\^Պ_l~c6:,#G-Wi| xSxW𻿳3r<]Ș8S.$]Av*Gu˘՗1Au{en;_2,u:md₵5!eՏMŶD7{AcmSZ^JN6]r$>jخDO*A4)wA,VB F>(īb9ݗ VbcrG FFaȧ,`-:%_Pn jW8lH7&8AJ窢lƫʕ|~PaǭOn땝o {7` mt"a^DD]Ⱦ̻ŘzB[*0-|qV ,'n}<X 1rqz}5F5F5FI%Ó̊;:L8yS+G_!Mpv4x` Ԫ'/戎.Ǔl. WL#^=/:MrhPK ^B>x>com/vldocking/swing/toolbars/class-use/ToolBarPanelBorder.htmlXoF~aΕz^ Va^N ⻪OтزxUwvmUU|cix}S{'6!=5M47\&Tr^^y ՔDC23 qAICtAi͙1se S԰Fh,PY1<Ԃ} L~ ՛7Wst"Wk-Í`Oih 5"X d=)ň*D8hQ5 -b&;El-΃jPYdFڂ N ]TbXbB.ɯ/Â'sPL61٤iCZ{0SlzA@ʿMrCΊ6)9^XԔmX3״A?=<*Bs`m<ٗkF-3Ckggk*5.v? 6,$0ˢ5\ӑBRȥkT v* awлܺOC [12ƺ{ojiYslV|4gʻ6'\i3(:]Nok"/ۇ픥lbA&ks[A()ϱ9(2l"EUU(tO֦tx=66dg,q(rO#fRƶ9Ӕt#aܶ9?RwDcrx[$K.*=rV5?zW_C( {ym]7EH8Ϻ <=L3}EDAOZw-D֘.!q6reDfm\yƅ3: Q#x*My#$yF_ ͎MdJ{x(碵}=yL7~GșސoЩe$ =~1jTe~wo+}{ ZfCO~?>p1rGsq>q/[F.s/S^>QsH`S*2`h6x1 ނ+>W/ gtlȓlv!o3"[iV_PK ^BS 'x>com/vldocking/swing/toolbars/class-use/ToolBarPanelLayout.htmlXmo6 A_ I-)\pmsEC(CCNx/GrUߎ~cm|B~k DyPAh2̘zTS ,9Rj&Z'W=)߷; M7gh\%LQbmCeŔFP ~Ջ3;j2jo\0DP-Í`Oih 5"X d=)ň*D8j@&t#*l2StR͡T:\ nϚ$3PHpJ肇zvI~'~^O)lḧ́ Ko5GTm4H}*Dpkԝ1\=ޖ5RKJ{@/Gn쭷@Ui =9;Ϫ-EPfʅ)^m[׍sQ;')γCLtQxP9] 5Kȳxk--76<™k|Rr(c` <t<#Ąf&2a%=p1rGsq>q/[F.s/S^>QsH`S*2`h5y1 ނ+>W/ gtlȓlv!o3"[iV_PK ^Bx>com/vldocking/swing/toolbars/class-use/ToolBarPersistence.htmlXmo6 A_ I-)\pmsEC(CCNx/GrUߎ~cm|B~k DyPAh2̘zTS ,9Rj&Z'W=)߷; M7gh\%LQbmCeŔFP ~Ջ3;j2jo\0DP-Í`Oih 5"X d=)ň*D8j`iÒ1n' ]TshՠW۳&Ɍ3z1ࡩ1L%՟sXdf#1f<05 bXkfMB/HIxY&E4G2ث+2 k&Z6'@E1y'1ҟT^sSШ%{}a~ tRfda"1_>wY4k:XhXJT0Rr NPe[aq]t5zWӼg L{t.#+t=vZ~i6(Gl' Wڠsy)N#ۚam;e)q8[zXP .Z\VFP)JJsl;Lz@ê"۪"HQUiUe6 '\>^O)lḧ́ Ko5hE8<͘mst#aܶ9?RwDcrx[$K.*=rV5?zW_C( {ym]7EH8Ϻ <=L3}EDAOZw%D֘.!q6reDfכ۸ gIup/G6T FH\ ȄTHQEkmzx6nz6,3!ߠSoH{b7F.W VR@͆󁃯Q8O9^"@Ǚ #0 #oNcRνNy@KG3K"Mht (x Vtf^.&О!O)Y 9W,n[PK ^BE/q[6com/vldocking/swing/toolbars/class-use/VLButtonUI.htmlX_oF0J=`/\0U\/'qR)Z[{g6B8Ԫb!{=3;?ڻVٻ6&x>!7 iEEP@h2Ęr,$꓉ ",MOOj|:l٣co) Mơ3a4.xg S԰+.h,PZ01ugWL)Uk "I1􄐬$.Y|QeYb@`ca\@ɥf*lUm+E sиOVC0beڡ q ]`H_ lYS[*#U-U liԟ xq pe\DޮvQ\p|6j]ջ9yFP8 v{n"E7M7e\]>c+] LJa}QF<2 'WZST㶱O#e'L>(ےd.%8[{,7SlCg̎E`s8\=mB՘ζ>l@#CL?LQoDż^Bdw yՎkj[ a=1첱K/pF6\!Ty@.A BSi Ąf&2a[{hb}y 7~p|_[#U=}ѩ TH=P}a? m+ {Z:m0эק{D]=:[s¾!¾zd(^)@}Q`FZ_1M0zqk O T g:CI}˥[qb\uyZ|o?pPK ^BD{EH%5com/vldocking/swing/toolbars/class-use/VLToolBar.htmlZmo7 aZ.e9CK-;,JPZJbM "oHzIp3.sU{~7mbB{&wn'D]gD(eX4j=}rCCͻt ݈Q3b3s$Բ hP1mpy8J?_~~JhϟlCqV; !5jrJ>&y3<́ךN\[8NINoNHЍL qJ3JWIی%q_qSpy fdB03fF`JZђ156$!ߥ@'śэIľJh٪v0\>C 5.[;2eQiL{)MAdT s:qeẸWa?>!$$ܥTZ7!@ gZ qf7\U:N9P ku C\BnZgqerdGU3>I#\mZ ?0e.:rKVШp?8f:PHܞZWn Vat\DJ0&R` ߼N$F-ֻfTZLkEGޥ,l0\y9c*D옉,墿ת$ '7iC#E*6taVo7Za(zĐ&cklGVǀ䇙B;|^ R ݊yNф?ݹyܺ }fTG@3A~^|TKAj˒5nFYTv"n{j!o7L _H}*fC?efxj<kƁJ tu9 {($HN@Z]h¶P6]Ʈ!>6][@-6^.]"O#_,,ܻnl}:CS>U/C く4S}u %U)r}2zkIN!-^yjR-+VBNvw!'Eb0~έv>M^~lA~1qonQAZC*R+_yf*g lďIYЌ ĭ@ _}}1x{H̥43j-ΨeGy7Vk+]pUf)ܿsD63&}8t)6|RYL?(G1#ˠ{(N_g_FM]*xxZ j=%VdsAjxh r5Hf} }#7{l[W4rP.=Md_fT53xZi‰tz%ܵL+"? 9`+&#N EScp*hwKڿ}h@>;+ [FA E Syo4>V<+qv)06gT.ήzw_+kd__>GA)S燎 0⑞MǁizQH`#**[c~Nx'|_7hlQ?ic' \&R|ffi H--C^PK ^B/iv;com/vldocking/swing/toolbars/class-use/VLToolBarLayout.htmlXoF~?)Ü+ȃ@rT z9q/U/eZ &ʵU|cinZ}@uOog-BQ;{pTk)hnL 75&$dZ@ dj)5 b{͓W׾] ߷; M&7gh\%LQbAeɔFP ~ՋS;j"jo^Ϡߎ^ 75?kA%0`)vƓIWlCtp߉pxMU@f{El% ΂jPidԜ N İĄ]_ɯ_8oOf=mւ)cNQӰ/`8􂀔 䌇ޝ;lRr(㵽)ۘfRi#~ c96Ɂ$f_z}c `oN! Ÿ=RA.޻דWd&[vq̗͏] !R0Tr NPe[aq]t5^WWi^t#0F\]@%z\P;-zS4yj#ԒO\FLyØ+mй]BQõnL57|ϩZv{^.v+#%-~&=WaIMIWR()URC8`UzMWOSb$cF1Hc*6= 6OnS&RC~۲&YwwOimŖ+,f xA_b9X!_hV0lنu}H 1] A: <=L3<'rl-晻"k;8@9R2Zf۸DžS)* Qᔧ#v*MyC$Y_ ͎MdJ;(䢣nw]y7n^)۰E5-`jQ߳[Cyb=:_hʇ(>2u/zy9I٣77|}wL) 仈] RPHZ_ -1z~4L ԫsZS:GI6;KÀmcԭBw/PK ^Bt$3com/vldocking/swing/toolbars/doc-files/overview.gif; 뚹h]Ȓ&[7F>2F4hTFR-2%131T$K!!j,x>/ϗywE060D|4ұxi<v&N_AO_iBΓH!1Wc6uPIMԌM1|:UD$3DMBv]԰i![QǦ^m^C^4O^!+?M+WFIQ阘i*u:#cLy6{ac̋E"P4=-lUk ;6:[R0:-yՔ>KT-uڲts],+vu/,f?t1^a%5pF+0;[5qaX |O#{Sw}ַH9jqǝxJQ0W9/͵{w6ӤաmD5u{С 1krRHӍҼo|M){.( w8Skcoxq>z(ڵe}K6q}ebꚞdJ  [5ڊl(P4Dw,!XI;/Aj+d`o'Nܒ Pa8T?\bxSNbلMǜ% $t'#&ߜ㿝m^-X#4R {v ׀[ߙL6)~GŶN+b;rMG=ţ<)yl[!O^ D<b>uBocV%p]̿ SWm[ 7k"wؙ3$.y4 HR,c9i*g cC)VC\C UKnu[MLN6=jMfaē ;E (hes|sȹG:|d p'G$)U_V C5gcƒwy"ٿ_(6Დe){XxOIek+ +ђ9ǜi6T1*1I.mMd'qIqvEz3_KyT¶E bO/_Wݏa] LڇP z+ Tw}GTk0ʺs!`}=fePy/*8ej ll,Kx n vmr1*ၒ:rB?)ٵN+Ƣ%e 5?A`;rfO8MS$vBl$*іqqE)ҡ[ݷ!L7E'Tȓ#?9i\j JJKOV|&][z_c(D=Lvl QQf\f]=NK(8%6=-iMf@~qYu)xyV׋=iT^/K3,]ʟ9?_*XͰX$,:o0l⻂?.9_]ه@,آ:%6N3TaKV3x*2Ju*p>A1t$o{w掬r_%Mn0ȪE~1XY#_OU4N ~SAt1,ޱ_9[^9g,l$%g&ga]UY7t@˅x kJ{zK[jbura|Yu$ kN|=>Vc st}ɝXźmi`{I: 5,X}a#vnRI0,9i?p9!V@LEE~VXB{2o볳Ns̽BXoW:\ea'>Dx/> pn1qB5uTRw,SQk/mT="nGXv{HUįcATw.JlRxI}hcv}ӤɰLMAU"ܻ󌩽bzvOws]zWO;=(h)Q.k>9;y]3GV;ؔtEqn?d`=&g$"|(ֆ?f+ïXmo/܆{l'<".Ho^c[ogJMt/e Qs=_."")!v쎘ٳWD'ĻgcG7 -cu')i@qč ;EgTO߽LB'Gɷ3C? Jy/ѓ[䆉gAJƴhP&fظ؇ڦ-1{9]o99s=04qglƫۜu3FVWpU͟ 'CǴ2*' Wz6ɜ⋣7n ?Ϙ!{b䇋aV_|3&{F_S o"]\5,:Xzڤf]WNJ>ZbY4W4#|O@r0Ed XF&τYfGO=2F!;Yƨt^nlrʎ:rYtE|+|x~^gQ+QQ13^$nJ!HW"~_αT.ۈ(hKܓ_QArz} RR+MQxW*T r{V\g[»2ę !AYGFAͼDB_cDKZ L%Iho)Q7ƟZR4@BR 9'`H/KF^JF9!T: A;40T b򓒲*s)Д%eew"G,OPJT(A)PR0<LS͵`m#6p_׀ei&)Nh!vG2S$ ;I%!Z8djksSRU,9 RÍ׌aRbWkˣZa~:htbGHmKR떌`;1jm?jq {$ͫ|&F- \7Ic]I3QS* ,l]=Bܸ҂{xjԌEp_Ǫ/~PK ^Bkfȵ /com/vldocking/swing/toolbars/package-frame.htmlQo0'?}H t]&VPK;ir2lCʿߍC miSmABssoytGmÛN?(R ~#ͤIl$_ kgi _1]щc*2܏mL?4<.y:dcɪ@09n.]̈́kfy w+Ö,V.6hu_];=s,|_HN^?;99 FꍵMH@i"ǾIocm_x~0~6վp-rv´ԝWsu3E0 i7ULOSESg+?3=i7ؤp )NS"c&:(R;}"nH{s*AV\o7);?j!!:`YߙwB"-݁IA @in&^yxJ 9zA[mmƘ/-׬G(aVɊvh`jmؒ.ȗr ۯeg~&,U;R+|^Uo]( jw',-@J-^ r2lcp;!6үAd o#Bϵbe~c@q_~-_PK ^BF[< )-1com/vldocking/swing/toolbars/package-summary.htmlZmo8av{.$Hݧh - $׻~3$%ˉ Z[ Ù!ŃݳN?:5?;Iw}ŋxgFXr&4hlm$,=%dl'E"2lEqTcinET'%RۤZ. Q}'А*edØ"aWa؏km)uZ-hn/LDcp:0M^y>JosxuNOVȄaAT@:>H1 ^?^5EYX2 T,-k', [¨7?̕(ƕ1E]3W o4X*e9@ω0sZ\N9+ZYL'1Ψ}ݰDt1R^p眥W jX].|]We-[}|y}^/4Oɏ4%zw҇pKɤ {!\M\[YL TLm+-{F\I,I 䲑5vK:E7ms:}^9,V,#/7ErS9/Y+Bbn>XwMyѣ! xJ _B`<:N(ִ8chw9_1l25krcbtdsT 0\y'}piC*絮+<,JgxӑeeG|]W9z\tdtaDU4L{lxݨ񰶡?"ɚZH E}|o?eCwTxB&/&bErK1 ) V`b(X JۻXVp+p*t+D<gZ|)so}K"2]mee681{ I)fx|MǞ%F.^eCou8a7/YH2߳$ZK*o)7ĉFZM9dKC6>jߒg[u(^9TN @ >E Ra0P_@^4@ML;ܹʻ${:v?/Rukqҩj$ cvC@N pl pgcgGkVjƭw^RX[_;P(ᣩ*rփc>DxwTgIބ b Vrfjbց֝V݀n83 tX>&kCut3-,QG6AL ܲ`jGRwX[EVԢPn?"zzb!J zfXTB6 ~D6w7Z!cq 9f‰Y2ԘO`^'pb4`; t/P,fm"K*FI8`F!rAc\&H9.%O.@irԛ2AfLXUr: t< cadٮ)ZSu6~L:7Ojb3 -{Y-S!J/f]~Kכ:[xLW<6ӼƐp;VK8/4mSBQ*}@o_׋eɂ}tkԕsCNXU&\ ^FG51Y-5Q ]?`9̹B8^.톌 TIFWZ|u}S4*ì|dKލ'ݺoqVw0].  BO&UsN} pw4LtW7@ (!vqKCuw뫊qo{\DŽ,g&,ouTz99eTSەc?G'1mLllivq|]z!Tnx"᪝- C9^v>%-8J}V31ExR ADI eV m$&RU^Q.kFLb:u)C!n#1v;T5Ԕ"TՍ")ڷ^`..g_~K;P{'+o_ ׸{jϫ995 SA/W)r/JK>b9m&8 W_R,xThlaogE>R`6 i@&V.A7A ge1U:LPK ^BUG}[]0.com/vldocking/swing/toolbars/package-tree.html[6^I4bv+@OI g6plqB8nU\b}={ >\e ƿ?oc|1?p54$PL3+9/ wr}$R6'Jw JoD'./lOV)]yU{3l1|J5Ati8>h O *՟*W?΂$)o8J/9UJ2j)堉8F=" 4G8PKWy: mLh[1'>lNk,mwt |rFFUj/;|B" &MEYv~~cMl@}6oזȭBLbػ/R.ccBIV`!c;inZ+aw4:`ctc_%1mʹqi&28$y%0pp|J*zV@ǜ޳օd+JwQz#?G9ϼ|)fuE{AKv*,f~KH̵.Zr.TH0pNV]S蠽w`Uةiu=`pNt^CSw8G*jq{.Rqc|n+ Șϼ!4hYaouȡ 8)}3ܫghegE+N yM]xǫ"X@D=f=}g$VZag$£mO8fG>q{7RHD%wgf9mAi Q?uϲOj J-W B/#F֦/f(VzHWdd)J'6V*pf:dPa=bÌMr?dZ@o&S Z[\>?|L$>Zųg/sօj( xg5:9jOrJ߷β7J1)} Gq5>1h"1$ԣ%Lz$T> .oA3Q fFZ7&fzǤ[@sGn&z*_)ըh&"H5 }zGHM)R- 6ޠי@ !hi53L;Re.'W]hn'OO!5mK:E "!27bnyZ)}$5Cpc~f:f=|. !DCPaM9Udt6L QTt- =؆!_Per\o];Ҩe=XS$܍QGٳ>^oO9mC'@e}DE3ԭHQUۀ kgpl /K-ɞI_$Jhry^dG+- }ƲG9 |m2OdE5$wMVxxb0tG ޷H[)MC)t">rj=HڬPj`Rc\J\gl~ jcΐz_)7-y]<72SPL:Xhm[A q<'<q̝وjhQzI0ND!Ihv*F#`Py,gb ZOeѲP*k3D s((]D\C\phuHu*sPԕs⡳C{HAqN_8vpÛnl~ph:FLJ!Tawg]:,Nn݃ꩤUC٫ݯe?/~^(EQ)CԻz]D1/֕6RT mƨG7fܶÑjioR S}sDfAbKZ$-E.PK ^B constant-values.html]ms3Ti;nH.mQ n ,Gmlc$c9oͧZjSFMu.:rUj(N89E- ¦( <(f3av.Hz?6߉m{D}xwRȬGjBk![zXzXX>XhJ\G¿ɇc[_&:NO~3mi<7|4ѥAL}xKe k.]<&3}D‰p|I䍁˘YP^A ؖO,^]N~}`1 ĬW<n-}WA.kzWn)1CXm}N?k8~ŇS+ 7!:2 hga:N`( M0¶I\֏rd>fAw{V1xI sro1=i[˶HiF m0 递}6ɀVZ.+B\|OѪ_b$TΥN/!=ր]A3nmi05uF*DQf:v 16Kf] `L`|=ӄmЯWN\buNys~/#f4tģ~+ +5&oFXpQ%UÒd lI~z)ȰЊ Np}3 {1Qt]aa%ͬvR!0غ  "zIc;8͜%+8 boڦ=חαڔ_d37C&2 CbwjJD+>g@w!0zN;K E=[3[oO>dp"gϦ 3I.i6bE.U8Go_:>"G'8 zcL"vOwJUM,gO 5OĎ*tM]*[{Rfa`p{248L, MB)Q,*?sO {`CUj;G1BZN2s]fN]lsTؔ`uŷ j԰^e E{K|xe8e0eXW`7blʼQ4XuE]IiˠZp- "'pވ2oSCÛ282[ "k \tavh[ݖ;/Hu+oq擗 9ԛס`!tWn߇fʢJ:_agMy6p-Ai BUw >gS&a"q7jܗ[k Ly6L^zS.neUz)ld )V,n姟#zj~iZOV#V:mMBڦIk1EL=ZnJ}Ó(0ȾB!BiJ15۶y| 3jny;EB2>~{^{PAa]ǗdB.BR- rslzUMAli!}GXzJT>ovJD1i[gү\^Տ-cg#EE)jOoi^n,zo*RڐmnQgcu+ 3Q<6K!H"s~UH"<ҿ{# Īg}.NxkSІd!Z9zJfJA<4O@x] v-im-+@<&#l_KgӟǗq>fp5SL`R&ʎۃF⒯PDKkDO7%5JB b Tc#^D ..{C9TIg;GJaq=uyVpVʢ sh^\߭K)GCO+){z-:&%hR b~C8.vWs&]B!/|oCDݘb  ˅ nA(۾oW5> e^Si\`4^h7hIi0xeX!%]2Mw2 F?2dkNox!#oBuڝ mzy1|?RFbnuEiM"xAqF#OK.b|qK CFp FQJ+/Q m631h|GDɮ1zɻ9S,dDUܣ<# 02KtQ0VPK ^Bא&Vdeprecated-list.htmlXmo9^aZ"ewwj H%>Eff ;]dpJJE e^<όi= ߇~tyÛ.x~~:aoszF$i&7:}*XBNU8s*B(::O>jH&|ߌ)$=X)%q.+M$0^dIbAmIB~7k"h4޾~yQK3iGSI#k) =X23It% zЄA+tj?@"m/F}"hgg $mO5jJ@S#nTr /u ꅟ~"%+_-s"ׁk^g ۥԆ$,tRFgђK?!K9o\Q|SMUm[x!<GQdDN(҉+;Ԯhbm7R~" cΡf*|fG`#ta aVCYjJ: d= Zigg,JBPWo4K q?@m< Ʃ4^1~z_3fxUO~plJv*=Ze @Ҷ6' T-(ljLxk'U*s?+1%LqE-X^h)gzHzsAUr6gC-XParǐ9itk5ZQBaN2{IhOL۪.@7`4\n߁^Bk1|蹩zx9//닯G_T_~Uė3_ ]h58 ai.Ь_ߥ3|StdϒLLq9[ajWZ l PK ^B `j " help-doc.htmlZo8/aV&-%i9I^b Z-ndQGJv}o2-i[``p8R9lo. &ɧgIr>>/C+VjQ Y"I.#^'r/bf.y2)<,:y8 4BTPr6xihr2O/b5`_قe2WW?Y ?7%?ܞ۫uONo//*xu.Qbs^ qbq J$EJA*˚("à ^ Q>(:缎^U_$:\iHQ(a,lE:UCvd;?S+dG1m2_n{ =u\Fj0pc_*9=8ɞjGϒZ>Bc)ϙX*[ńLh6)ѕlL\jㄈUȀbd~|z70ӏoNiF-l޳%[Lm[0"n~0 nj!f@]T(]r}gSxAq͕uu l3c!rULܸa#J [>`"#gcgn1>vO)jV֙p+.&q`7L8USO4rĀn&&z"ӧxMEQ!fU jfqĆ&.z Q5\~jX)mqZpfgzt~dZA / NoV --<6#T[Vbo ͟%:]f.ݨtpea y r Y.5ܨ+ſ)!TҽӪ*-3p cNE﷎i+3v*u%ˌhk uA|AGhd9L($a;]y>/&Jgu??pB9| ^S9gF̠Rr!Pa`@XI`ss;5p1X)+qMA c Yeek࠹o]ex\$896gNP3Qkpl>p`zzTLfR _;,"mHj5ð=VorcA NR6pLjx[jQ#H ۱Y5X[i% cA7В/mıC`x%'ї,QDJV FY!A뮚8dʰ{|U`Q($f>8pL-QUgI:z).畭-v m))GZpC'YUo/q3T؞}\n-nmy`58o;.2іf=s1Ss3FEH,P ւpBq*g^c))r䳓]*TXi8S~BYKe=`BVBh3)T.ЇppJDD @F'zZlGh[9sG`oSm6~56'2o*{Y鍱кc9C#s6rS}1S&XSqs@7WAy / AqM;=@8'\5zm2'Ծ٘/Dm ?qYz:0z)q&-jt[;}lxiEQ% ~70A\&OFƶX)m8#€E ZێBD@6EZ0PwOG:Þ-4v*W2)j}ú%TECrOvnk_@]^n; ;àglk-"xwrECX60't$2(pa $zƶ=Ρ %d\ݟ"pM[6>ecfO cؕ˲X٤fZIh1kGvH"4qesmc8 ~Z2I,eä-f>@S9Lr.Õh4ǰэYe/M5 ÅsE( Do8^{V zhY-Π.K7)_$-^s{N\K4u 3RHxli4DZ\s4*x~7™w& NM| zO$ D(}˦ Ap-9}97gaLr)0S #ITNYc#*!f:w,AwM(1H趼:`4M_BV4#9&r QVR>R&sG",bm'A}^lҭcoEh{՞(?. )9l9 :C9 >ts+5,L'7ެgƵ[IČH ^>ȴvx|~vv"Z{_A٩rE]绨?E߽ :ʉ}#C^]+dBC9qr,N@J^l\B`q<\ml:;pg/2c_ '_PK ^Bq:index-all.html{s8/#;p\~ۧnlW =3'NT@"dq"5$ex AH1e$/H$./p|~q|pO% / vvuwdl6;4^ΞF3? cz&8O''=ꜜ@ $xxψW4" uOJp^i;9O}O$q~Ώ/?_g?]uNp ^Y}sz룟1M[~9tPA$4H~9O8p 997#JC'y'=93ӳSlrݙ$D?txyD([a @t ;=G#/I4?9Y 2ROY)3N3>B3ӿ]lOq}5C-FN? g1N>+_9OG;*g}81#^8#f؀I+6ucgn㨽yfkg]z/HuX!f:8ag{ԗexqs^!8.YūGg't<&)̭s>76 xK_((oyffޠ=ID0O|=Kj>}]P#ep!_0q3y6G+>T}^{ǦPG!$ }>\'! e3 Ϋ ㅃt??]Q#S8֨d) S&t&>yc:3 ~L>>{RdEMgLQwuwit6Q' bzI_z+Ǔ]|^`W.W.ٕK+vz#zz3z]^]z]^eWnWٕ{vz]y^ybWWٕg/ٕ߭W`W0pND6.DՊ 2G0>?(aPp|\e8g_2<5KhyG:IzS)vx*aWtt֕F>;'-MFxӚd@oբ du) W܌7е0CѱC+&Q8L N:/+65$#8x'D= xC>bjj@K]M#k.#{Yr4"\MEcj *#)8SpkEh8yPEz`e+e;d!8ݨ{- C4zlu%l H0qa'Θl%6o%&& QgF{ ($dQ][(`8FC1,]litbJİ%gL|JQC%ߧ.{=|rT_?L:͠btSfay/l0F p{o1X7>[C8xz~y7WLa7@=%l)8]6˨kO;2}ﲉMl1(B񒓻G) qpbqX DWW_?8=XXlוg_!\O7_/of=p:pg;cRjr ټ/͵뻫xx~M$;V=M(Dwy5*&b09.7=vFK&d0O z>MM|6CϹ\ S%G_ WMR.x;9fMK0$Ϟp,'x 2_e]SNO:H8:>rD wsG^r.`;L'eG!E%"o&$%45Iw][,gwhT(9$Lщ.|}@N[3<ǰf0m[Xi>qYG̥7 CUrϖRA0oMˮ`]@c*.ky(>HBvIKRCٸ]8h"Ћ\_ yxc8SsyWR=X! T纫+Q4b =Q_[NB-rtsk}-QqkP,C8?a@+4Oxb6ׇgP~@5cT=_q*e1USydD _o tIܚi&Kz>[^A =v a؏ޛDʍ r;Iz-x.0LH|'&bs4pե6~FW(0"ԕ Vflf5@|F SH?kHLmQpȽĤ4C$-7UO8|_]*6,t1qMc S-5b71mJ%~-XJTU4 |ѷAjYcg5VMq]3; =QJ01&f ,_^P4>z1" 3,`~;#߾j9ry2F+|9f`akuS" %̱Rcea^6iBdyFwi`%H)V9/s_"Qs]HIaYuiudH_(F9nACIxq0r|*pCyc^%l%ڇ zqF/&(8a|PW6ARy7-7*Didh hd/Q5Z?m.A?%{Za:>)XyGBHч[M5cgRa-!+;#خa!̉ !>7xS =h&hHBAa#f"! a! a^ȞKtK"f'V,iR? j9pfS-IxX8NW*FSW#0)l~#7O@*NqYnyu'u-' Ei<QQ ^vV '2 E+u>k!9 FLzctRJl󹗻wZ΢ӊQ#]xeVMkJډTGP' pt/i=ѥf[(K̬B>f,,3OK//v{<#ב} YNsSZw *^}g~Nk]޾IQj͟9F >"_FuJK t;wcK[FS˼/ef(vu+|w 6ml|B1i:ب NJ! MQ4&?ԧ/p8,aﲭy^1;7ɍ1eEm\^K}*06x0 ) GmSYY.,m4w-1VhZ.k#l+ТbctSzg.D7NӨ0eb.k'(]<!ԥC2-sȫNȐ#zuLM^{xjWј&b`"UCEapcB_it !|7%cFů?8srG9$?~aUi'>0QLLKœ뾾ry4#%ߴO|:fKX ޜl F΀}CqkS ڏeB8"Gy7Lwוgnp`>My&nDppČtuN=8wFW5&Ե}oxp:y1I7ffq=ʢzvX ^~L")D 措"-1XhIY(׋G / C'5~|pSG (h>k^. ntk "n,¼UK2k?)V<)syAmp`clGst܋'>e]Z@ ~&a~[qHh'$x6YמJo$cjP}!bzdS'm#}G# !@0u.v0@6>eר~ 0 F[9xz ̅RAډβ0t\z}tJK,Ky 1F\* +Դc }cp{f {MXmJ)Jʗ4{Y{'1=tz^0Ď~QӸ<>r`b#5 Il3>) oAb>/N젱i u< ;`Mt$ {wcر˫ssQ>'˄}953PLUS]8DTf'jL3[bͼIwm7%4N%O[9@Fqܼ/mXSȷ3׏vrrW{X}|:apniBhae;+Q=a ؁3˳d{Y‡A׹X5[ 8v~H-Ee# |lޖ pY}NQc_4蔖V}WKp֮#İ:)nZbe \S)8aK^g 0qkN<ퟸj˂ﲭ \~oGy䥎h4Ky8ۉLPk>}oOnepޜTgJj4NC.[x6`2iXʀe#;N}+up}cѤUZ֙z'1{F="RmMYnSsoˠb !䢵y/u v^-dG2ed/P5)Nvi!{/RD#7DCּyl1¾+pm)Ԛ+{>[blѸtru7[ca.xĀ9@4.͸p@ivV*{h ([_vyshSq{*OxdVnɂ'$i:v Ye*# 2 !XVSX5 ~f-io/s| .+ 9<ǘ׊k0AKWl? H#v Ec)CHgksJݪ\W׬ɥ:5pID%0.5X:'rsu~y}!,C2,;r|C2K9WOC]sH2?8%gU#_ߐpJz*j˖e̢MzWKαO, [.eԹ{e;vޡy2zM6.'A[hA0#sߛQT'{zДr7E/A˪[]V)aKoDI3vZq05xKp\&(c'(}9JuMKԑG#2m49da]R ˩ Yャl3 W2d>p0p{1[FeXYӧ[6²__dv0עԆ(OWy?ëtP>7)H7j P4W~™nf4Q?Ǜg0So[dM13R6)79&'Z>@G$W,x~hd⎩+\W z.,x]xYˤMo58 ٷJr̞}:tLRD!$3 5/+JTᵮv S1?)Kj%,^e<%?d`k'P F,6ɛ#.S{:w.]2FllʿaF) `"NF @V~}܊!gU]XA+fECM1t^eN+β$p 'ݯh_Ip1SgFx@.}_nXjlHoX\WԾ%ѭMF.ks@vrP%TpqFrl'HmI˗o$^l= p<& &XJƎ}no҂aC Ec.M%˭|ςhc|-MlO`DT uBٯ>?XVh!xX0/NhmG$ߵl}FhO+|\ѕ37Pi0Iq*-*' *OK (jQBiKMxg4:hXͪ"nh_-")Uteù h9/N;/`&>Gq&$"rv磦H Z[TU\<%B809? x=&u*s#4/Iִ}Vm+,0cSMjwĹ@Q( w0K:J@ / Ju6ǚq9O4&S ^4"иM81dBw)[I.UHVmVjSzSU)}Ҫ=i}lJTQcOjA;!>;ҦNyE *F6ͻ)εVcݖԴ2qJu!J .:\!6rRS ^cs͈$1X{ (wbh%qgT:`$3 %Й7 õ {g|VOli ^Kqٺ◠{w+7T($D1聬p0,UNdAj{`&YgK~(?R݆L@9liH#\E^-u%+=#y͝%2 'ln 0)"A7hq^3V<(6e^/n_\7_<1KC~. tUc.Fdd[q#d L+x%^[M ȿ:M棠yQ^\~iJ{\Co3o@|DYdRf ,-+9@7s& ʐX,9 `\j;gM0ϲF!9wUY۶wʚ[ȡʼn־5 COvd-=ޘƿ ˗(4P4sz=JSUgwso'gP4m-ҷڋu qt٠pb-# w]Իk!E^UYrA ) ۟ƛ6|z'!}M1h!kȺlܰsgAM̉ͩ&[W.usj[ҧ!jE'{>3TZX˓HM<~oӚ. Sf`[uIDK k<w0{KФ΃NxrȄ-ZM+>@W1CkS;k hY"32} i;CZHŗD$P8UYiE,*}CR*#1'Y9!֗_̸:MPdʄ{>iyf҈ڸPz]Y]Bxfɘ&Pa; (r7tRK넇ѥGi,s3'TIz.^cb 4UZΖwKH^V6-SK daQ5w!J`4L6^↳; ~~ }SmPU\8z V&6@SW%xCo|FZGTTr1CC [GaU}8Ԋ/4=zoח'uI3Λ&BBr$x?|mYBnqHIuap8˭TmY zkx^o\/MiKz~Pu>7i }cJm}O'KyhlzgF;o ;> M~P׎L <2єM'Gǎ}cLL:`=f˄O]t_;7JމR*5G1J9+ԇɹ]{G߰$MZ {-VN/xl!};9Q0ӦSGC#'r^V7Q\* G8Vb *o.t=PBa>v=)Ҁt2űkն$X"a=9Xrρ\^Eop3ՒgS -nSnprL$Y/a& zKsg9>ɲDc=:kq5dYqv- ![ \>zrs ,(Q/=(y}=āc|uk qplWPXۻRx3;K5/>h= v~ޘTm.t?M(&b?ћ+*ԎHTXzQFw~^ǹ–CK?9Ծ1:DYjZ9"^.]BY>n_-A,JWMgR<]ÑƔ)n.ę?h~9z~qG?Wl#fIL]4AO_ ^"*_l!2Fc@?wa4q(}C/=S/T+܀k=A&!FlDو\,&m.}Eq@aM83%V9 #t1|I}(7ro;\DVR讁DXhl1m$T2iyi[kX4`{EPy}\QZPA`bY`q%XgX!@^Dqq5a9v9~vhZ[6qlZp)rd$Èίo؂^zۥgO?>ɠyb'r!3Ob kvKnF( ҥD\44z|_<ۄtK W3Nw~|}SSH'Q|@"\ܸ+^EheJYD/l-uSyn'u%9=-I31O KdĚv5 #tW`ATe…W$^GFTu6vR+WgPpa|;v)شEL)yUDPՓFMBl`(sV* 9&B%DD4ER co8&Jꨩմpy%mT0鹣81{bn1}<1xORC{ DC%+z{i$kUY? ne-kkKiU?BD|2%*WaB^wc;ks#Ttc Ӫ? :{穖9gM.뇠PbciU ( sy-=ƛ<`uzZIB;Wx nC`MP}$Hk@l{7q}=^L[.ٛ1[؂F\QԟoUy|u+meu2?C9w,2 نh#)2lҞfZk΂\#uSuj-&-M$ Clc̶-;*>I`ސ)pY?xLc72~ΠXh۰0ȹxqW5yL%/t)lSBLqL7 oߔuD,No4v&>4n\.hY40s@.f<0g0zW1OpBQW \Ϋ͍~ 1 짖w^$n<0$v&sX ϰ$ٔ4w6JĺM~<$.&{R֋Y t涚Ɲr$|Ay5ay-nIy'Ӈٶ:$#$=koM`褙7uEIќgx[qҾ:s@R#.a맻O#sA}=>“'L!!7a֟Vwt%\ZE5zн7'KX34R<[Fr}r (7bN.mQkp .tb:xFtۘ)CxU3o'S[ aP@J33[TeF~ԟ;`Q,ϞfZyLҶ5< }>FG# Foi/?uQ>9ާ<4l|-ơi.,7i8dn^&д18TVy:],JD0 UV b2ՋWii^"+VS.S|,~RXNalo &HAl[JBD0DP9SlVLtAUJ&M߮o~?Ғ[$7 ޕ:3zC) m;QFů3*]K?4km;ExF nN.KO#`9{IżY:{b&<%j.[C넎cK $i1׮T1"c A^2\bm81F`x9>:iP tFq 9J;{|.'ʦJ"0i0f[it#bg93HC? E [Gt@Yx|9 @Bl^@$dcTFP5N>;Yɥ ߊ'ה GL^obxh֭mG.)ER?6`%OL~Y=(l? %g{-Oƒ%\3As\Uk.Jt;E%̴U]xKl ӎWxAix_I GUV7+PiD&T#yʉʔlMJ-)T7U%y ߍ9LLN+y:ǦPidCS?#^[E㬆Ml*9Ca\xiy ` G4=B>|mCt0&xkvxVӪMpzzzv4j1JJEx8҂8x@XkϠ-[s_ʲ:AS ]w'x7>?I=DNPQD&-TMilZ a29{Oَ Z»H}K{c&lbYڷ4wNoX~.EBF1f`'BOYC"%D#@ ; )xdZ ,8uGP'lSvzAz˞VԫnaMZNdy~Eݤ#lgAWqeTL[Vnb%Ow7"Jsh] 1h1@$p^_N BOqa~t 585I^^OM#L'+:]!Aŗ /վɖ7եi>Mt7Ƥ3{lC,P߳ib`^)N k?Lp./؎$ d>R+ށY}&}skeYcijZƸT5;*. 4dS}@R["o2[G ]-;}`5':&5ErzO=?o~z|8i恱~8U=Q4yky@ !li4ɛӧ`}9wE\a8yֺU:םlUgU/ A( <붘3/ Ks((#Wˇ4tj\eNF*)<>W1}7bxM!`: ?GJ؞6Y O ѕ1q -!RCx 4 s˽TY~|aG,pzPdİ?31YpGvT!d?)Ӷ?vZjd u+X'Ur k>u T6%b\C{RSBoj:IƀҢ-[m?${ҫNcC&Myg+a1ԂK ˏU(pUBl;pf$V&{kzU*y"!`2mSuX?X6 q @' Yt~ No|Fӧ\$hܒH G 6qEO.XS-OK\ A"el3:ixHMՄۡ).Ww~w}{|}I>>^9}mWwM V1`3/1ďC&Pm`eP6wI؏\bỦ`zC\dR(y,éCh%8:p(iD2#͘PFrOEF$W0۪'jٹ$vx4YրPj&g q%S &6%͒g8*o`(V*ҩ^‡7\잭=[7c2ˈ 97XΨk@Qr=V)37KF[۶Rl6*"|փ\[:>˗W}r= y3pb ۳wȣ2,]2n8E?T@ߏwOccJtbFG#-?n֭P#a8=H3:qAs;S%3I΅U RH>ph].-XnVP57%ܼsU:=ӇAĆ͂+UӆfhsZ(QM*a]su _kvVVIUTݿ( S8/E_\GQ¯Y@ 0CH r0dI `"yw;2H a'eLn$[T>v5\tL(v/72Uy@~Iwd]؞BL0yh^3*B;R ň֘SRH%T*w r Y|G}c= .1IeP.Y5^1}Ykh`z:am Dd? a2f9׭o.f< H됼uIa %sӭ I:Vev^. vn_On|=&/>b=oz%kc\n Ri{.AU[IGAq|Q?}zl)u&wjvwJ! } /_?=:9qo!яrXŇ?|6G7b+d&Oܒ +DxzGw-kvӶ\L3""tqyN8M]0_S0 &1A7!LC@M}CӦ~K&XiNؔ>JjD N}d~?<`܎TZ [t?Xk0un\%ϔy_bB o8~?;z]2}$RUrg@8sw!l-;eh%~+*(| ɶQJ40) Е ȶJtw7_p~w?ؙwcUӎd"\IGOL r $`Ô,PVº <=^ۣ'> sj|ƌm 2Uժݮ*SO* _h;ߠQ|0>.ei+THM4꧜[IִQ%ip1,Bˋ:4K;g.Y%|q1X@_#} o/h0;D2zUb0&Y#%= 瞺Z:Po6/ dVJCx |[#twL3oCp*F5y…Gd/6 @~Qt(dnl2^#7҈1M0= _-y:!oA9 "MKS -!4DCCC* jn=G;)YӦمc g'[}ހ}?, tr| qH r+ gl#]$(Y6gVK hdS%;ڳE|tO,XΉ%ރC1`>{ C%Quzk+X3[WPg.KhWn*;$xXuxV{߅v芩#ͫx$$c'쉭0Pi&sBuoqUX~#<=n{#ZCơѠ%WWuTn. AbHZ֧,*kH{6+Lr$1?'셎0&G'n|Nq,ie g.k.F]d6Y6%|eIq߲o>jhO>|^qEqVFM!lVܥ4k :s9[ s߲IJ~RXp_9̵p T:FNEc["2P\sҧ.7.]lE;|;@0`";T‡Sv"Xԋclƴ"*47D/l o)x8I7&cNcG`"38^݆L|Q)+ねvw7 uj ${4֔4Uf9G oڴSi1.i.a>&gǝ\ᄏiSSkd}b}XvL%I#wv4Np*[<گ2]Vrh5 v8OxTҚ= |IU:2J0`MMO$·NIt=-گ`: _ `ECCp:Q(n.m8\CNK^4| ZmAm l'386KYP!]0!Ԧ)JJM䂜m섩jP=ZM?)g?a}7ͅ9u?! oNܠ*\Un|F]7L\;JR麟]5;e4cxؒ#wI_M/@dȶWz*G#:+ NW3F*T;PvEHߝ(oHjLuP/oV@n`uG_]?]]:1UHC6[NvF>јn]> ٹ^x!)Ee iv^Ղa~ +wKMG7LHd zՃh\1l3+hO6XiKFcʓ3!,iHN͇Foi+|h {Jo-)1$6N<6[:?6GX8[uS ߀AiiKb5")IqW 1fv$S2'C_?et:pra@Ƅc N2[V>%ݔt%ViW`6OEgOc%WlKh ;&U u*ܪ^gc@lK9 Y*[^*! 6[vR| 0 Xĕugf+Yj ௽vkoϟ>#h\FdBMpDSBˍN:Uh~ 9U/}(*߾K~$ui;&̎jrz:ɦZEgu) ދ3]}NkJ Ҽי2!ɔ@Ņԗg;]qד^Z/m:Ƿ6w .wtV8j?2ZѷG7CwiS6|.q bl%A3 tF$f40jl33sPؔ@%Nl[Wꭑ^PHJO~Qw$N. q=w?IDI3T*=uM/ 3*VBnY']d4F-w?b(M=_kc+8wvK4Dۑ 9O5If>WM26{m!2N<|* .B1<(Jsy{?>9 4QV3@)KDTUXTr6R g:?ǂ-,ɾc[KqqUxsϫ\A QIq[9ap1eZl03KD$Y̠rvf~RM^J;gmC٠~qG?WG|/1,M_Ա28|B_~ =c֧8 y?|e:tfF>׽ܳ5" O&E4+Qt Dxl2_Gvx{[sǼTԾ rK*/s4:sbx0⌈x3uu=X/6֒KQlUZLu񚵝Ϩp:Ii2#Nh_u[`Gs[: fŝ*\\7a؏y7H9e-ZoJ7<i>Qx$^9u)o7܁O@0F1 >plp;9TKn&H9ƒ?t Lq}VX{vMۙoߊ.1D @lbKɑ Sd09:vy-!Z4o t.W Xb_+`3MV$[{ ۅLCAͩqu[k*. E}ʴyUHmqqkb]fWwW2c\9NHHsaaF/N6ae]`r1w?:ß`e~U2?>g]0zx,?$(/LaE:8z[>R-ov˫uþ5F;-XCeQm& OIT7f{^L4ɞ@*6$3ĺ),`0,755ޖ66bV[O?:b.!Qa npWѥl7 #߰%1NV+OǁvNlI"LMWm[viW8| '|_ȂXŅҔ#IPw_:_ApwyY\\*D.~Y s⩗oZ]?X xWdF84yIX]COY؞hCa$oM/is ȳ=^O3z1SA ^@*oC!  4+os껗B߷tpn[ӧ#SqnvE"[4p\<#cL&;6 ]q2,os̞cLݻg{s }d&Fݹ㛌tekL) {wy'O<;_'Q{ᆩ_*a-K/# WB|.p=/{~ߌy PlT;C`uiFeEj8qUZ=jȽVFܺ^.π̂?\MJ~qΫ磆%KaK S}`00~yP7@m*#~t2 TgaO)"7>Zׂ-C#4  %N$n<[TW E HU ѱ](KgvS{ۜ %DfM/ Oaxt1hMƊ*Ͽ_@/q=֍!5/|B?c+;#e䋊z["opM8a~EM I) + [(b45jX%@6 AMDQK#vzgȸmSCg*'iF@"}BAb /EbDzKw69jQ&͕%mK4Nz3猻"=uHs 8g:[V@DB ̟DVI)Sd\KٹKHMm @5 2a7prBō%_Tn^a = eݽ 'SF(ϗ.*ڢJ~-n-ڋƂZ2[b'e?'N&ap`De۰jۮ4-"sR'F3z1[pYp6-8k-Lvcny /"J;,RD"(0=Epkũ\=cמMi'0 JYW6yF/#c M! *Nhz٘o2+ɲMtokYlklֲeL6}xz|//皬i^۬j'(aaAH ÅI88y>O^i`ѷ`?nC { 6b.o g0" ~U芤f[[kS |zL.ECvS:~ȘBC~}\sqs;m&Fi=?KyaŮtoW@Zvg5O/ZvYN/4N/zh].0W{8z{oiqz41/}>\ΓØH{ìM<0ɟv6Ndk )mڞ] i3sw;Hi$NqhGt0p%RlIWpv#Q[$cxQD(|`jrpyu:pbχ9Fv3OFF;4ٍcs)C1<3V0x<4X0D|=4 fCS}ȭ 6g|9Oxrt1g@S唐e2]zr;,uK/"o[y{:5/Q7P=NtxGĪ[,jw٢{)(r P{}K_o ?NI=qа-˜gt@OZTm2ˊyM6(5DRd,P!2%\pf4S%ǑXgͤE֊2&C;/\ĕCS:5_O@01#xz@4S΃HRB˔̱ba5=БgS&>}=AM0x.Ui'ԉZ>78M<`c] aMGT{"L@nӓ*֝$|bzw"@@EvL y,)TX3T@Z\ U0̉5ld3Kƫ汚;0@8GSQo78? (`֤L[߽ds㒖a..5?,7 {nSؒ^NOYm3Uq^YsAM ˵f]&α:3n4 4,Ynmk eGuU交P)˱̥Y j,]vp$z ;Y96(?7B%!\djW jtǎr8>iq4*Cj) 1%vV,^$I$V ] Ѱy~QȄ] l Y`')J1nbS9T?,*Lr\kbpK#V ZxƲgzɢ/͊)*(@z^c h^q7|HQ,gfѹ]J`H[y'ۻAޒրV!{t;pUu ɜp~ПA,,^/KTJEM. RKAw+趸EbUhA۔qÏ!4{,i™r SKkP+1Eٿ%pN= 3l\PAvC=PG #$ݓQܢ{^ypQd_&YREKˊ iPo&$0bLW.Iʵ[d:K8YUtZ}NhgAd] i~B ٩-.C'  gFr*F@tGLrq)dk1ַux3OO fٳ /w0*bkxd8zUʶ8 BP@ОڐrJBh9l(Ԝ7)[MP{a6хUUjE|eтKTHbWR:?(+m+,sSKVڝ{ f2ZU!E4^H .z8a7*VƂjV<˛óH⩘avN2 .1'Ig\; g<> ܭ,hZ,s?.almHMEB.,yX<{BpˀlOW$,FXΦbo؄ .9sD)Pp3=, 8zaz ƊC1FҰވVTxQ0SN9i>jT} &;lO%kYS+W(K~Dx"C$rZP`:fNb@S%'&s4ůgI c)V[hȬ8N-VjYI HҙtH \{0_<'[L; 9CEp^E8H^),@҃U=Hֿ*7dx(D-R+k eΎ3(ZgXay@>f afɑ#5E Dp ɭH)<:1,土{,XMoۢ%o;*=~31О$LM_^YaYK!c+sL/lQhwBuׯ(XMylxqM٬As3Xb`QEs| {OؠEUQ_ZKaNiD*7ㄱ؇B_oc_sFPnڵ_t~c@Xp\҈L'\ö>fK9t1K{^yX TjCDy@飽ԘKی {en`,zs0AAC jP(&JieCSDō>y8S7'fL=a֞'fOdxk|Gkk߈Xy[a[dv\/2*3Ϸ "ܗ+wJ.l JTn=`QhCEgۑ-l cU5…/ďє a fqx-?󝢱iTzW7T2[X^4"x[YNia:L5Ff'` 9~JL$5/yz21AMT/wOs%PQ\fS!+t7,"I 'myrd:mq8Sv"92^Ez-1R[Z({Zycfl IQԑ ]fP-Vį0/w)nL.?po1tܵq)z Js,y[ѬfOpłN7x&/gq/ E $hӑo&9\hP;%[r]17u^rRWY9 a:-~@Aϵ#p,e _TURlf«=VW>B M;ܩC?((C˯AJU)w(Lo^V?^,S eSm4#VZ'w980#1}&Ƚ[.K1eMb]@E /סZ1=gٽk ^TVs/p ZÕ9TIA>}h XUŇ>i/j?f՟ O@CgB"DnES#LEg/mnoR3WvTCu96OW$8:D| ] l^q- c,'DZ)sÙms= ̱H@(P {)u V 5Uie( ->mb/&5NHRlB2R0&bBWz"; cw6Gnn/Ҏ,){D^NHՎuK̺ve8^~^;kA5yKvÕ͋wf,Y.Jpɨ/*W[UY i#l;z$ǾdsUie!>^!ZZ![?qv^5¦0K;}N?nxS`2y]jL|#(v@۩u9c8 hҜ/0 bM'f(z 8L+`0tUES1[ N;(/̢8xSnJ|ANy^֚tPE~nu GzMgj@TC;2e) HS,F'_>'acFO\ Лɴ X2<2`*Eb[[l+mFsL j%U}nf3IWemY\?`mҔ\$_+xK_:td^hGf}萋6bm)ε$u_:/a>R%3vck9_#vkgߣ)&>0ɺgհE {5t/cOy?B0paWwvCR#uN7z" |F։*7N\R r:IR<_|i@;#kEݥǖN/V}._&qx" \V߸!~O4}HF=]d37n s)= O|' =%ƶqwo;1@-4Z-OoW[}$(&)qrWe^p搗{>'L 3f)h0hl})GE"XZ>BD8;xb'Rsa0-缅 rJPS _ ٩˲pshn0> og-Am`[7?Z_IBV,Q+ɶj|Jdt[OWK[t&][:$MrD-W]|SX/:Xx%2A+G{ۭNfC 1d #H81% 87 Uima\QW@ UUPZD@0[ij(jyDz3^dFc0k)9mjzc}+ԚdeQv&=:hOlN7'yGBK /![ '!"s/!>#;)%߀ l2CJ 6gUgF^f^3 '8'c:'DXj<]fp1ʐ DIۓۮӍ$ږi1}UlfŚLZkkG(mG( iiF qY].k -5g fKpZ5ϴl,\"D( ~H8Yү®H X1dz'M 2OMG,+YMJyWe9Ʉ<ޘג@449΋„] g~Q )'%#X uMn!ESeB==0K/3Bw\snv¨u)'K^˂`9hilq*^rț*ycjOV"[UNc<vf4<;䀀97 !p*O5)v(^^|I Ep}h!~0d "kGWC"BJ#xeJIVIUV}\x-`6a9ŎMrJUSrVmhe- 'D,P~繊\ii}FxLP gt &`pR{vo11WƌЀ`8 'SM <Pz-i斖[i: D aHÍ;To1WD:7;S0kew*֭$?olY{ Zfr#g sO^~;M/>Tue^M]CKh䭧2-r{GO剌c7AvF[Z+ zSS`"\]^h`QKjuf=G| caUD7=eVy`\b ߾> b~nA3} Uu+jZ6^Ihii}rIM*#'hwY'OE] ̟t;f]Qt_9:8Vdg#,'B86>`кOHIw7(E֮2Rd]jewILW zeOxҝhPfiEm@FU`yiHPne, DFO`ȹ{gV׭4 MXyb5.r"@\&zO̩0.Yɾ8{y]^EhfvkoՖ>cc6G +X֎d!Gl-8;w mSeW!py -:({YOx[ 5B#Z}YoFx ֲq%+|VCs4 xQ Ŋ+o$L'X0G`FS]iErT1 ,ײ_ W>FEͯ li&WyDG9k.W}LI4?p8hc8kٜE#2=a$ᘠT% PJT&k1OD4j44j 0<Ld6.5}=uf \jG)ϊ(6i1~fLS0(U L*DoPhIptC Ɍ϶ i㴒}hA&Zut :o>:4tôq Y<˙ RbEA()Xym*얖kpZf_+s,mz;o5K1]>v@qQTea3{6+-qhvCMnE?;٦\=!t[H:hAcPdZ{ZzMct=F [Hdа7EI"+ҵYL\}c̒fOinf?]v3hB|?2g>o|˓3NpWNΰJY~" ,#&qxG 2[_FoJ,͸ Oچu,v%1f\Wȓ셵nYc ^3iH̸1 - C#B| Wsc-(ݧn)ICVg9$nu_$u:WW: 4gM]wvwI.X];yTZ t,{3̣I)-~-B/VO9e:F N ̵:`f!vWmufbgeH=8-H[:N!0fOĝ 4ѐUEK^POδT֯/S~KsX'p`:5wiAvxIaQ~7GV͝%|G4wFn$4/=፶D 6;D2J 5T~K*Oo1PD$DBeJˑsqr@RSMЇ6APoNH&*NQ|8 @E?!,X;9kـL9n|y<3ed@.N K޴y$Q1;q@RB-[C7iU3u zq ~?{D,7ɘ 9S *2xVp$#ϾxdԂ%I؞w+B0`:~M(ۡZS;hpAi ؠ KF<4SDcɞ[" nr)nE1dKI` X!v"Ȕ )~mjSS[KDҥ:#(G?EWpE&"S ~YM" &1eHHd]en, 3pb_ZS( 2m!cޙuZra^}d+?K^MXܝER+V]~_&FqДDϖrVuTS^_# G+[ hݞ7F 2 vQbZ:JCJm+)[R C'y%"xD/Q>OR3D ]n7N,;t嚻Ip`m!E,I9%($!-.P&%uEm.}EP$l XcUz3ݹ(-ŶZkA4C=9eTTEatE";2/38ObbJ D6t#tB.J>W셼{:I^0[j(os+S BWO("a{lyl].oh4rE'ZBL^Tkz딥r.{$01GÀ-TGb@_˘==mfᥱ(WglSCբ=}ha!,#^q ?0 LɻUȷV!V!MJF$ycб"E $.~q.~-HnBD ňfv}j.PM`n?b$ QtΎ!|Y~tu̿@~ˋ6J-soC杄a-?۟q=zχA'lMֲpj@ϝwVlSWmг 6ti O UGN(+ϗA(K)0)fxQTnу0;ޤ"$,2,`7[0뀄Ei|rQ@7`+ulS?j7m}LiSn[KI5A 0ffB AkR֚k(7W5B\PvQ9l *H3[w YĄ".1NL$b *-kKF걂EX-FUY^~PE|%%gZrNKέ%Z||%%h'kɐ %ђ%Z|\ђ+k5-Вk--hZ8%<諵 Ⱦi%rE[?vtz3>xFޗӯOoD:'| z`Ӓ-޾"ZޥN%"r/ "_>!1,VrY ;M]$U?E } p@ca|Uxkjoز=%z퇨h+BF/h5|ȋ=m:YS=DxA|3D't-zo*4H{VKRA/Lb4\YU"޳/ T5OqwEB)%U\^K蕫Wv#)'B"dOT饙3RzK o.<&Y5EOCPW ɀn>~-d;0Nluj`']oNn֥6ЉqN=(&F.Z>' ]Žk(Ju:Nj[&2V^<+TT':Cr]g e?j=U xkk?\X[?4΋ LM79à $~?smo *;,/\MWERm}l;f p 8_ JbU{t}-II8x"ϫ֡})ZB C~x *Q (+`2[,¬wl}Q+: dv@`Kk?JaTtIoՕRi4' ZN4q`h`T<$Gh~w9=V=C.Z9S7^:?+nd@c|ytLth+~WSE*9JS%IcIuK f}putn=.yY+޴oꍦPK ^BcFoverview-frame.htmlTn0}GiZHll ܵn=lu}s9vx4&? L!a~51c8el̺S ˆBq5434 m,ʖf-O, 479^ <HbBP9yc?Š!o^J[ywN.n8 %N#1B8>J|Z4$d]^,dBrk@V(LH+o` BB9!l%%!`4xoX5ewOEڄܶaGvEm\ԐINJD!Qr)>jﮭ-̼Z5[le%ѹ0!Q,TV.T+7wlD:ZFqytkV˼k?MW;Qe,Աݪ+J>C+>;ǵ8Gos OSKDϒ/ ꥵ4OFawJu>d {PK ^B9Lqoverview-summary.htmlYmo6kԒt'ie)%LI[5)Rysn؀mQ{{xǶ ~_7x~s݃E?bpQx6[0$UL3E(q! / y)4fP'L(I<;RI4M`_Ȃ$" C+6l>6>< )VOO1fLsڽC9xs!)Kp%ɌBN$lpֿ>jG=2Ψ&"I'Hp7"4՝Ho4i{,(TM(e~QTIGUЮZm,[aP$Kb2]g\R]l\(4B&%S crN_AZ𚿌H4.D_gٮ ~{qEbg*V~@ Ø)2oR% a;2FTUɑ`pׇ۳[(bNB,m>)Y |2UEĐaRMY֨u`cx0P~qĤh\2sQaJznK.*D({x# nSJV?jd544EtZWCLTnE&jp86 YѾ*i4%N%j>w[, [Y׭tfD.=&rLGդ[Ol02U5PվjbdT8qMNݠ u8I7H;PBZxɩyN"yw:X"ۺoxqDU!sZ`orEwMEJ+5#&AYGۋzC9sP<] @)cB -D] -E~Mksx Bu'2^FNxV3w5 *_'ci_IF7]mL6M=bGX-dxbU:T[Oy,i?'+9p0% ٤^st9=K ͅsrd,ZȇH?9R9’#{*2@'OZsq0u #!FC$8+UBD%j$|{6tO]s0C{_/Ϙ@>!2i4Pb!A!1rf͂LՐ8~ƅU?SP\b7k?7 į!6>y jh THk:3B5zKG~kF>s~?zlfb^T .A[ rSwׯ C!?:l٢#QY=Jw.l/s8ft[.7 0ـO@{a;x<  _@GQsо?&L(҄߱f\RϏ\G"˛A=P2{kȊ d[l>@=ŋ vOm (8F\b\!A^΢ cR\Y/=~W- l'V޸'?Uա\2 4F?Q1acOH>5CYEj@1*@\@-F7s_ #@δ"7 m?.< Cs6m6aݒ lF6Zt\?ȦiX_]H $]YKsq!lb#ǽԔț`.((vBxo(4swh*dJ&ےMH ^oD7Wo(:3F\2+S$*&oL b^^IS/$z+#J)1jƌ7kt UYj摬gA,=I]WiT=yH]DaN*UƳM|(}/l/ +eXBKZ\alU%@-#1V{3iTS^c}9a.42eIB{t8'+%}4J'xv-9S [=ɢl @v& G2;%ZaJ"|B!MσYP.E A7(J"8;J*>!e3H!.6GgqI5SYcV cAj_ct>A>2x}ެ>I{RR.Md|(WK)$h .|2r!*Jl}}RzOUe=I<(Dl F+V‚U \S68>a 3GEU:xac$I $+,l&&h9_8;+SoO=s62d:%GVj #Bgv\KJEjJ˜TוKJ-kNyn\f#-v6$6>|80m 8˹pں%l:Ɵ_^@J3/|g-ՆIm;xF\bE[K%D<êg=(|6R)n-[ll^,.S`W:y,=b7:&DrtByO1>v-4pM5kLGʎUbbӫReҟSW ԛp%aL(uqO h+HE:|z(VRsbŵr2I-S(Z `uҋOv6__h~>flC,Z@.ZKnFT?'Pu,"mհ:j#/f"`N>~D6:k\3&;`e^2Ve ]U޺w>z 7{(PgU4l''+\ɚ6Kgc:ַ}thZMIcD~!m[z9 "+ްUΚP|s1n1ѧ/0*%HYCatX-:p*8Uz k"1L#EUsiUL {kϼXwA GsrQ,"wӫ\qf(1N_e .mRB {'ASфO n[CP@Jz9=`O5n]6"?;`O9v["͢1]XNzΥmή1s׽"vƽ޽abj W]L%z)!PB+iղ[FWJ/Q\RKU+X@z ihʣ]z󘘝iUS_߬ՂBC |t}gU,"oailS7E%m{\LקcgCǽd lPbGPͩgm_?r!=ռ:FlQ^JYu8];0!Zvg'PNކ`B_y/+ט}h1emoԶ+ j+u\dT(DE+Ja[ڻec: ĭ|kim6j6s6-*1V4B竽T,2ދ[9Rڹ9xEب+c_vV { _)s^3?\;vJg]ui.dR3pRObSc /.d'˷T ܁\`]q1v<_1kR$MlIt-hf 6m6!n^zUufj{XĒkn@)K #ƥK^Rwbܥ"A2(ЊGm7.m#[hU̪낦oz^A>Bw಩>B:t^Z&EqjG'ʋ\Joiiܶ/@{AV =64 n54~qM[=@% ,ܳ9ǚ.XDxPBckFoGEh}tj_QLL$%.;՗H+t/HJ"=Q("O5q`ϭSb&ڵ4.ɩ(h;C#طXo\t_-+wVmg*ihH^at|_[Y6Š&KDS뒭Z}e[{*,mW6W~YbeuXmB+ί%$gɸO킝^;ϖriMTkq`=eq.-HG*Y@/Xষ[6l\bEz!5JwnzA_M* ,' ~v9?; ӷ1l~%3 -k_";y]0.HSrJ(2<[-n.N4S@j,:Tuv|@'7n}=iQ߇dazO 9x#ӧH.W4Ma!"Qב4y %Ӻ7q&x[ ''\b/k,?|6Mv]Lj2cK nCEOrEض{b`kY3ovPA.Ą^m ̤I6GJ>; rP,_3 UDf ,n&ĥ_;K t޲mt*Ih3]:狆P>jB #@Jv<1;D.f?ע3Vj4KjAmVw~R^_eIۧl4~z<_Lx.|ttp{ 6o~:Ch@-VH0XHǬ>PK ^Blf0CJ package-listK+IOK+.P/W2nIļĒ\r?]sCby@^tDczA_uKmVz<[q=\r<[p>]s=\q;YmBbyAaw?^t>]r,z5L3M35B7^ϱ|>" ?Y4t@L.0bt)ӌyC8RY${˔o""|rʈ{?$(Hz+?x򽶾֑PK ^B^(V))resources/titlebar.giftW5QilFP((* tw3c] }u9=,%=BKo!dlKϥJfn"dȱ B^BBxOA`@89;D;T=H_WGW-¸ b#F= Y=X5P%@%PO_.qz|$1*1f"5 j$NTj"\J\IΥHL&!ǽ&Ž}!. ـˬCakPe~ddirJ"SGQSQPNnP?k20 w'9)4+g堑)hE5HU`-M،Ɓa\WK NA5k˕= K8vL=rh>b68^j`܎1 'BX%sv G3_$21OfͿ֐rf BSujܻ$[o"|q2$Ya9E"uT0PO B}LxΟWS2~GجS:X-[Ɩ/+EpC(\XϮg*oLݨ:n}gG>qbړNJln64ѹtn\yn,G@|4OygMkˇ>YZS{ (O# U-m^Zo4[De=18FثN8 q&s.#Q}QKֹmD_ࠁl@TZ6l{?0YYfv,m$yO ;8y48)3):p 8O3T>&<u8穘|O+vp3^oeV P2k6i-ϭ)j-s{%Uw)i.?{q8_|Yf?SоuKN{LF^mm./w2o(n÷RG7.x)w1u3Tlcj6l%+vЕ=pgQ\':Ip?/8r#Ki,7aӇIͫAq/G@=읟T>|2hV9< v-4isS4{xyҦȲG嶠۳[rONAjGO(JN@d?RP5I%KF7aQãYyj1,q慗RxŒpy@L^YX%†*Ļ!L/a HcےrߞZE9'w_ `?}sMd/+RN?Eh~6^ПTTbL)Q"w,P?ht3? g>\U#ԛyqCnz%܏rZP8Qi-9uHB`%Ť6y7څ; [ž6̯߉"6-FGeB۟w4 ;%C>-dq?xNzhaq2A׆.`DU"k(rm MITW󒝘9ō$pMU%S5v!o3W:Sk|bO&rebL|*&sraå۠ Zc}d=G{5dzSq1dj<|Zcr)qBX~PcdccY3KhyO0mTe@X9'Y<)!qlSJ GKP/17N^'pS=pInER}/!M!؞Wl=+/{zSE>Ȃ_#{kpv"J=+r8{l8_k#]ryL &)Foh)v6ʯ"mdF]avT CUvd'}_cfɥ%ʘK;0Șo+vfHҮkhխT~HɊ:zhxOHԯ:*hx򎕅j/> Dܣ^\"G)~:. >)gˁw]BüI!.4!Tïas/݉#6%qW[ 7|ւXIWl}>ncI7e/z)Ǘ1g!V˃m3 8 pxATK>[ | |}B  z$ .H2o%H:?X {&&P.HU5XbhQ B޳Ąȸ*5BlPǓo' lC,NCYy~ iX|%cB~4"“Ta'@HX~2"K L=—.,."=L2*hJh#EGKDyGEEwO#;W""ݣIR=vJLTTTdK~p{h{1f) O}K</ہg@*U;=:xx dQǢwM:>GHT & &r&~TKTJH_9"I0YO0N#- QA:Y#QM6NLHF,#""-4taZG`SATGR)oG=%'-%|]:ˑfJ5LVI)il`D^Z JKV7;oJ 4 +v@ՠih ivBZ8!+lF.A{Wa]S$=lVot6$,|U_/Үq v`}XإXqBXOߊHL@zrn෬a9 pƾU6c ~! ̸ۙ4aq(K쌂98|d&g0Gf=̺Rxkh͐N= 8]A=.z{rCwn .'2C3)yekEM5g:~# ɳZ6y e[3"2俴~-+IISF }X.trA'2qVkWGfkNYDX8d9'[#+PNT5],ġ3tPa::/c, 93 ‰Nt#5o]TD 9fpEESBBgZZ:p\^.*,>AzO֊/JhK歋OJ׋%B R&R^/\㨳":.H pqƨ1z X䂳\ zUȉ*BkK{ɞeʕʔIJgBeQ:Ȟr#  & ѮwϩoT=ڡav'\?R vvv?] \Ƅ1bB L4f..X lTW5ˆAa2pA^T\Wu &_;Ccq L 8Ǖqkq8<EcP8' /|1uik/|lmWmz(cmF-f_0^=]v%9cBxͤlQT,#@U(\[oqr/3S_]y߄֯x՜6uHG" y5^ݸ H m|~Q7Eibߨ6܍H97L嚕M4w7+4kUͺr-_&kռ/ZEZɵZ|FڶB[6Z[ ض8մhn3@9zLY0ɵm3h il3n l2ipiw7H2ihItĘ1uh lϛt۶g˵^pGwVB;mVFkwGm[Hw3~93㢥ض k5dۍg^txu]Lf}äݻk9.g}"Фw{kwfzw>4@oE3w|tŶsM=}ǁ{q4\<y m<|  J xec^+3 }4~12Ҽa7yevQ]_#| }FlzF b-7GA1KX%e33Pt0g7CJ,$j8 ƒjI֗cަDP |Ct!/P<r"eJLzDTgg̔TcG!E`;R+xXx$wyI*2#UoNN &&&&IS.өɞɪ©I=ϘrщJ)l<\;UH'f_V[3xg9iخffp1}t52-6'dO#05'"6+nO};{SkeټٜLcYέWbEs*SEZOW sJZsb_tYEyE%YEK,KZs%sy,s.˒b˪Z }gs޾aSf+ZoW| 6oW#ybVbWW=XVR KE95ϫeը碵S5ӭtu|5zj ʻ_ߚyi^"VԴ֓z}ZXֽb72{k=˘+dkXka30Ȼ6yZ(Ojz̲UͻYWv[Z F FaG0?z5;t~;;7wk2M^޹ǺK?L{uxWj'κh{CaWobžHݞ,}齗X<-f=P(+?عw }p(/~hH+bPЌrs‘c%c:غrU|l8;6??>u8 9śDo;&!N$?A)')P,yYybi>ܖ}Rq\ xA@S82p8K\`O({ӧ]~B6ֳY Q%?rr??{`HhphXDxDPlL`td|\01$8!-  SL0 ^P[UVU_YQK@66%b+:Au&6=kņ{#s93͍IRsb,l礩{@ҎATFM`CΌB_}/N  Gm[?rLmz8×cNMm[Pfxkb} eՈb/zk."o=ր{v 76Adž DkL)0/W)\0&R [r{;z_~PzzMH͆_eƝ)(ud *t$2^\uC\0Z #5ӹ[Ob%^~ X=xOZHf~"H:;I\#+Y'w՟cWDN?@#_񾭧OS?p۔NA>8`/>a,Yv'^F[8[G YFא k?g|/,ʹS\Lh(_^l:6hgM6IU")Q[6Ep5s緅ųf<;6 Bۘ3$2-VRێ?-D@+O6w|?ov~^hߎC/z8ƹ_۠;Ly^}hzs(Mp؏.Եs~[-k (gm+ 9Eպ$־c=v+g]u;oD@K8ܗR)ɔIl-لWqBɵPو JH^ϵJf[or:Wn:TfKbv+i14W@2W1XUrͮ- eÍlh d> *2QU|y3SƻEBD&f͉ Ϟd)69h,| ߙ锞ɔz&0 ېwk%Afw+E}meZ6枽QEo*FY.y17gP 4ac"4ڒ#vب;*Zo72ԟ $y"poҭ ǺҪZeImRz |wz&‚S'?h:w+`a[8՝FAC[TQ_KC&5pDRz%Ow.,nW櫈~xgOq IYBe^gW9:Gꓰ˽lZAa|z7'uzˌdknZ}r+cécRh#`T҉Y7Ap7& d;,`eW~hUvEԢh/q5S@e7dω8KkCz㐗.6!bo 5.ʸϵGF(SЦX!lSGh$"hbT je]N xJRXHOFp?sjףj;"{) X7H#WMZ B7.OEibs.UeɼA{՘˔hʹX%k]7se_"mxҷ^axSyڗ+VlS F5"rFʒw.YbkU_͠/,YOo 6nm4t^_G;VWW_q]I Θ4j2} v*yxb}nLx<X'{ ؏"֙Tm1Ol?ω=p#᪅:BR,5'l"P۟XV,-@Bq˳x,%}nn{"w#mINWnix=vX/ԡI }kQxp^t=Ο EjHUU `=%c?MP8n(j1mb1rPd+W 6+YP{o3~:v՜ӷqvvРm䤏#|⫫Ο9JyU=mk;cشwKٯyԁJ/6 aRmo8.;]S 98pW>k\bpgC"E?@20?I !JG&%hw-:P7ո PhX{Hd#n=al#mG4v~:XHqMw: 5ƅ [1D2hV/ZMKUaX%sΨe\O{בTӖ\?qϔA~}#t mVdoOD=#WSre?[ !e`4)`jdeX$! /< LVjvUv,)5U#9ń3K$ǘ#7UQ:O623gR'_, rC 2i/ҫSLl`[bFp‰'H^(z\}G<#CٳJNjL:5:ڬMK_;!s"#ϥ e"=`IB 1բz > L2\\ܻ_ xʐ/4f djIsd6*xN);ˆdJ Ys烬ci.B>1@pY>2,#+\qH |?a9Kqlrg '>R̃ƏtBoy>?)g| sȦI ~S`ؑsjdD'Z(M5j*l9ޏ@2Q!]q?oaыpTB'4tZU9|Wu/< ^yPhNܞ:梠Ȉk9é%tpb߶8 I)|F)*YW0F18ْ'^t V[Tu0_gHƸr6`^'1&?O;O~U%ؗM5YlU5J0?{& W$4ԡi@ɫbRxpNyQI]ɼQǺQi Maa^ihىyqSua֫8&k\BEtEw77Cqaز2rMxuT%L4s5[zCDF9S%*/ej3bW;O.D1:dլqiRlhakْߝOT/7z6>=4y$w.:o?&@t:2'*rmv]X.&ke.jή^hp֤FחЂ/2=TMnaj hQ[wwFזd_9mE;W}W"L1w_2szU833QtHnX=f`Ct`:b7h3bb73dԊV0*1q*} 3q{96 0jw9`:yn/fا.O4q|F5Ev#Q7S$)$#Ԓ~^@_dK"p,.$ƐbƒyFǪzQIrl<&d:39V=9^2@E%PK ^BUQresources/titlebar_end.gifstLf`x|SM?,ztηgFkoU4il+׸oxVV3mz'u7_N{_*;*4k^2mpCLb-zǚt6m=TsAgg֎ K݆; 0{<;Mn_5-06 GN25}ZX`v՛yVXkjYܝjw7Zߟ^08OF ' DZDDښZ}&L4'ÉusfZ4g[z9*&VfoWm;vnܱͅ豃GyxxZz^tE 6mnY߻sF֖W_=2lYLLOhkQxXʡʂWi 0E'Z:x8\<'+I0.~1 Pe1 +Nj-XN HXtSXkV@If' GVm%zEL"ClMύmo0W a?ptjg瓱h(RMM^sS;CS兞lIEO5O塳|#?h|^+Ӽ{ qʿ2[,oIV|^_\,6͗3w3~}v+\:|<4*01XPK ^B ˆ9serialized-form.html=k8znl;wIڋ~$dh[۲%;")(;I,,VbX|߾!Wt/c!vh{.u7ҙs\.{˗=/wY8w~;Y gkSF]|Cq̌Q+. sY@Cfъ.'iH~\r9<ܞы×6gMw 7~)y9[zy{;"'_e5?g!%.9XT=7dnxF/{ 0ÕC•5C99Y&zx+Z;k3dY+up3@}{BoLzXv-frw byNI9|q=`y41ff뼒ݳ~_C_?]/mً@ɽIJ99ʋ2 %gAu #(JqO-ܒ'wW%9wK#|UO?jjaO rO;!W91Pau҄7f.sz8:Z҇ -?ޜa{]o& Sm g~Rb~8Pj'o RQ5.9~$W}z~iBǬ BkRpi,5d@u'0$$j"(F/ k)Eqx-^3)7R]כ`'C䗂6)3hCADzLq<]]X%8?JȞ,^&. 'rT4}js8Z\U-Ѐ J!PO\'\" {HU{'ю9af:,EII,x$]\*l(~?;S*_yoXr %#&xp$ wN0Tw]k^JJ Ⱦُ 1,)X%TG$h2pxq?}ۢgtĤJ[ުȡ@|1CZfg /G4'ġRu"i'Y@i8dS,)N}JvycfcG ac13r0"7w2eoyp/p۸ # ޿ <lKjC%=&BNVvS[S-uW$,hq&NQn6xgN+;X>Qokv\: ^-3F ewF b?K6Aqp/o GZ+PkB٧p ~¨3n =HN9uai&σͪC VaCWr32~T+b\ tT>WY瀉7+v(]QP:{'| QAd"kWqR5}""\|^VT93` .'8tp%tZAZꆞ_;BIeġy@' :Is$2hVx0;@^fxVNXu4&6 KPLԌŪ|m<5IN`)=:vՕ?rJ%K3- @ݹK!}Ps>kÄ;YF0|kFBzjѓ:"!_Kvvğ pw_w8C./f^RqY"_;lNR8"5֝ !K@Y@ئ"VgĂn;XXd ࡍSNi znwdpymo,ေ+gЭq@Ą}*')Ȭ\T\JήHAޅ;8VZX57z Ѧn\o]94K;_|Ol R'ơ!p/ 71{F<CȀkr3;$x(WC{[$E#)jcI $RɤwzDS5x4i3Ctu#@B EА(X-t8v1.  Xs QOD2gն[ 3(>4m'a v؊zl&|j KgҍSAd;g1񖴦O݉DDbѐpFC1g4y#a"ijJ8yn^JK4K%}*wGpdf[L|~/w~8AWY KoeDJ}řŦIsԀ&b5ǖYrؐ>tg\ ҁgSv#űxe-y잎/#m~9&Hw緑5k=ĭcz\#JyBxMq*Sv .vctZX.kveQ@,:1|9q Q N )[>0S(QY`@v B^yv|Gb2*XyZ2>Z"QD~&[smkq[ p/;ebx^sxVG0C%Q+]dJDT›uI[t8֏O;ZJ *>Rgń"1*ɓ98'E$^d]ex7Avv^ME1'.Mz" `;9g[ «B†hj,8,Q儗l *57w?ohs,byԷkl\ P `@CGCTYyqEKo=YjB0#y,+[m!l %EI/0*QF!36ȭcل5;g'V$<6WOFWn“V:ڥC*U[<Xddt&> Y_Q>Ƌcd&a1Ԯ)WqTǺ 7cp5e0%v0SR=S08chFS@29 4ǩm66oM{mA!HaL241ok_+c> Q`2fmI%~,m[s.#judf0pF-ʆɑf ṍ%RwAEVWTdЬC6 XCȫ]$oFaӰ{峝Tg1b l&zhJ}?|y9Oe߁J1BEGKbZI'"`RN4%na%r8L|Qmnjn-Ch;2(!gujh2/%LKwb>1Yq򺺑% igFͮ,r4˖(O oIrUh 4[%a绺=?j~6u0"+Fm8cX4hyBBnݣ$8O`Pؿ` G`7xrsx 7 /Ơbh;0R8ƶ;ZD` ]&{>H K=gX\R?K^v'JMn炍֮lÅy%1Ll]0vg;9yn Mrխ6RcftF}4mai "ד[nZWǰ5aY5wܹ/60zZg#u¸wJoEH֠-k |Zx7LSw[ힵHJAMgcvE}HMdۢޢ-!t/߼);%Ⓩ7-(`X/@u. w5Z_hM#{<ڪQBØ;(&薎T?wGcŵfG{qV$m9 =.p븷8lP~ie}ƎD]jǴq0}~\7\T #>Y7o>[l]]&71v+Myhf1ەu[<yGhMoX6fZO37Q3S򜺹5P 6!bkmJTB1}o}wJ A|<]1g_[E̍Y" >:h/k`x+`ss;w^lxNS,{>>pmݗ}fC0awhf|x5)=4"RG =It;C~' hdIknfd<}T#k'~46LGh F_]Sނ#aC%N\7< Ō"7VPrgg&2hu[Y+-WS=%i<9b+ ӊ1@d SdPoʬ];CQ2"q[pFCyb gFv`h~t璮[ns0d5*K>hoIy V_'=Zl5.^\?)a X!Ó!yKNoÛ+r}N}VF.5]h&KOSE՟w޸OpaOe SL` W Z4^Y\iY !TqSI+rI1/h>JJF$oio=f€}~'-]?UmY=۵.u*|peg0 Tw &< (dz̪-Fupi,5Rflf$DL?| =3x2j@:Rtmw5Dž~ZzlEqșRЬ>y~1ɷ0h`4|hCAD1#s+F.RNWA9_! {rZ_2ÕzDM¿!QL﫱-i%1Yڬ+"eTɛ2%kA?oMs+`41xE8YO^{%ٌa.R1z@#Z(PK ^Bl]-stylesheet.cssk6j?EEp8"m%C%Ňw p3-0)sTNQT7W7o~> sqO $/+$kV e4Glj0s 3}[1GOTPz\ӊm x>+3ՖT\_ጳj&( I VYQ'6[-])Vx6z8ϱłsN4{/9_ i~Dqupg,r-/R˷nejyR3|vZ.+s \/k6BjV*L8cζE&ʃFTɝ=G P\T^*׬oNrNfK3$ڑM̄ /# ^G#޶L9l>`BXU|p&VcV)O}Ysś=րqYkeR f`i}{w f䅇D Hݝ;,vvcQa&.岬Z .9#$vK a'?!LCS|>ȼ:B DPXf(}ZE@( R?4>Ҍg@qѦ'0ɠ~0U9"\/t&(_X's`?#jZx"Eg޶UIU)KAbWqY# }ap9+HlNWH*зy~\?F:S #vvc+h!-)*hqkW*Wx:qoB*bylbB30ݎ8>e٠I3`X*aWD˅eV> HAt+->;ЁwgDbRASz(0ᴐA4 ]8}ߎ{B_Pϗdwx!AbWk71. c6t7I71E!}7f|PvM ˒cm'lǸ9.Q0[vrU۝u.{5\2Ir&Ws I vcVGWUWw.\vS+zV$B/L=oKM"Ã>TWŀL5[qmO:;sCoc lM$L\haHUo " __aWJ#'bԯͥkp=3I1@us>F;#5S>N34yNܓi/{Cjd{t#ЫہA LRY& .:1x=../ gI$p RAd|inE{Yq )%Txqc:3|i zXD_ᘔe$TtKc!,lh~*zu[Ѹ^Fd"ujUq&^;]Ub ٰ 4Y㵨Jdo PK ^BAcom/PK ^BA"com/vldocking/PK ^BANcom/vldocking/swing/PK ^BAcom/vldocking/swing/docking/PK ^B&Acom/vldocking/swing/docking/animation/PK ^B0Acom/vldocking/swing/docking/animation/class-use/PK ^B&ALcom/vldocking/swing/docking/class-use/PK ^B&Acom/vldocking/swing/docking/doc-files/PK ^B"Acom/vldocking/swing/docking/event/PK ^B,Acom/vldocking/swing/docking/event/class-use/PK ^BA^com/vldocking/swing/docking/ui/PK ^B)Acom/vldocking/swing/docking/ui/class-use/PK ^BAcom/vldocking/swing/docking/ws/PK ^B)Acom/vldocking/swing/docking/ws/class-use/PK ^BAfcom/vldocking/swing/tabbedpane/PK ^B)Acom/vldocking/swing/tabbedpane/class-use/PK ^BAcom/vldocking/swing/toolbars/PK ^B'A%com/vldocking/swing/toolbars/class-use/PK ^B'Ajcom/vldocking/swing/toolbars/doc-files/PK ^B Aresources/PK ^BʹvJallclasses-frame.htmlPK ^BضA allclasses-noframe.htmlPK ^BN (<2com/vldocking/swing/docking/AnchorConstraints.htmlPK ^BB-'K B.com/vldocking/swing/docking/AnchorManager.htmlPK ^B;k h5)com/vldocking/swing/docking/AutoHideBorderLayout.htmlPK ^Bq$[/5com/vldocking/swing/docking/AutoHideButton.htmlPK ^B+B!h4Zcom/vldocking/swing/docking/AutoHideButtonPanel.htmlPK ^B'ym(ß4|com/vldocking/swing/docking/AutoHideExpandPanel.htmlPK ^B'~ C:com/vldocking/swing/docking/AutoHidePolicy.ExpandMode.htmlPK ^BU+/ȱcom/vldocking/swing/docking/AutoHidePolicy.htmlPK ^BB]  H;/com/vldocking/swing/docking/BorderSplitter.htmlPK ^BCխY y91com/vldocking/swing/docking/CompoundDockable.htmlPK ^B}sw"d5com/vldocking/swing/docking/CompoundDockingPanel.htmlPK ^B xT@com/vldocking/swing/docking/DefaultDockableContainerFactory.htmlPK ^B 5 d1o com/vldocking/swing/docking/DetachedDockView.htmlPK ^B-k l11,com/vldocking/swing/docking/DockDropReceiver.htmlPK ^BSL WS*7com/vldocking/swing/docking/DockGroup.htmlPK ^B  (wEcom/vldocking/swing/docking/DockKey.htmlPK ^B(1/pbcom/vldocking/swing/docking/DockTabbedPane.htmlPK ^BH)*Ө)com/vldocking/swing/docking/DockView.htmlPK ^BG!%۠8com/vldocking/swing/docking/DockViewAsTab.TabHeader.htmlPK ^BT).com/vldocking/swing/docking/DockViewAsTab.htmlPK ^Bw .1com/vldocking/swing/docking/DockViewTitleBar.htmlPK ^B-.s%)J=com/vldocking/swing/docking/Dockable.htmlPK ^B J9Fcom/vldocking/swing/docking/DockableActionCustomizer.htmlPK ^Bq w/2mScom/vldocking/swing/docking/DockableContainer.htmlPK ^BG< &LD^]com/vldocking/swing/docking/DockableContainerFactory.ParentType.htmlPK ^B&=. U9zicom/vldocking/swing/docking/DockableContainerFactory.htmlPK ^Bw /3vcom/vldocking/swing/docking/DockableDragSource.htmlPK ^Bv45!b.ǁcom/vldocking/swing/docking/DockablePanel.htmlPK ^B;" 1Hcom/vldocking/swing/docking/DockableResolver.htmlPK ^B ZhN& K7Jcom/vldocking/swing/docking/DockableState.Location.htmlPK ^BKaum.ŷcom/vldocking/swing/docking/DockableState.htmlPK ^Bj-4com/vldocking/swing/docking/DockableStoreButton.htmlPK ^B( d4com/vldocking/swing/docking/DockingBorderLayout.htmlPK ^BL1&6com/vldocking/swing/docking/DockingConstants.Hide.htmlPK ^Bk&7com/vldocking/swing/docking/DockingConstants.Split.htmlPK ^B a1 com/vldocking/swing/docking/DockingConstants.htmlPK ^B']/-com/vldocking/swing/docking/DockingContext.htmlPK ^BR/v4com/vldocking/swing/docking/DockingDesktop.htmlPK ^B̏"c-bcom/vldocking/swing/docking/DockingPanel.htmlPK ^B E V K3ĩcom/vldocking/swing/docking/DockingPreferences.htmlPK ^Bx.b$Y}6kcom/vldocking/swing/docking/DockingSelectorDialog.htmlPK ^B ρJ1com/vldocking/swing/docking/DockingUtilities.htmlPK ^Bf=1.Ocom/vldocking/swing/docking/DragControler.htmlPK ^BG735kcom/vldocking/swing/docking/DragControlerFactory.htmlPK ^B<VN7com/vldocking/swing/docking/DragControlerGlassPane.htmlPK ^BQE7!com/vldocking/swing/docking/FloatingDialog.Resizer.htmlPK ^BBrIhHK:?com/vldocking/swing/docking/FloatingDialog.TitlePanel.htmlPK ^BǶ$a/\^com/vldocking/swing/docking/FloatingDialog.htmlPK ^BKFLU(:ǂcom/vldocking/swing/docking/FloatingDockableContainer.htmlPK ^B>6 f2tcom/vldocking/swing/docking/MaximizedDockView.htmlPK ^B z#Jcom/vldocking/swing/docking/MaximizedDockViewAsTab.MaximizedTabHeader.htmlPK ^B9%7com/vldocking/swing/docking/MaximizedDockViewAsTab.htmlPK ^B7 j9com/vldocking/swing/docking/RelativeDockablePosition.htmlPK ^Bb^8 ?-com/vldocking/swing/docking/ShadowBorder.htmlPK ^BƬφ'8com/vldocking/swing/docking/SingleDockableContainer.htmlPK ^B5x)/com/vldocking/swing/docking/SplitContainer.htmlPK ^B\ C+Dcom/vldocking/swing/docking/TabFactory.htmlPK ^B( 0W7Ocom/vldocking/swing/docking/TabbedContainerActions.htmlPK ^Bv;o (_/Zcom/vldocking/swing/docking/TabbedDockView.htmlPK ^BFz :8\{com/vldocking/swing/docking/TabbedDockableContainer.htmlPK ^B!E[ >9Wcom/vldocking/swing/docking/animation/AnimationEvent.htmlPK ^Ba!< com/vldocking/swing/docking/animation/AnimationListener.htmlPK ^B/i<com/vldocking/swing/docking/animation/ComponentAnimator.htmlPK ^BuΡCscom/vldocking/swing/docking/animation/class-use/AnimationEvent.htmlPK ^B|ƶ&3#Fcom/vldocking/swing/docking/animation/class-use/AnimationListener.htmlPK ^BC6Ey8F=com/vldocking/swing/docking/animation/class-use/ComponentAnimator.htmlPK ^B{I8com/vldocking/swing/docking/animation/package-frame.htmlPK ^BWGa:com/vldocking/swing/docking/animation/package-summary.htmlPK ^BΤI7com/vldocking/swing/docking/animation/package-tree.htmlPK ^B3b,6Qcom/vldocking/swing/docking/animation/package-use.htmlPK ^Bk#<com/vldocking/swing/docking/class-use/AnchorConstraints.htmlPK ^BƟפoq8com/vldocking/swing/docking/class-use/AnchorManager.htmlPK ^B`Pqt?Fcom/vldocking/swing/docking/class-use/AutoHideBorderLayout.htmlPK ^BeI_&%9com/vldocking/swing/docking/class-use/AutoHideButton.htmlPK ^B@")>6com/vldocking/swing/docking/class-use/AutoHideButtonPanel.htmlPK ^B`N#>com/vldocking/swing/docking/class-use/AutoHideExpandPanel.htmlPK ^BqJ$Dcom/vldocking/swing/docking/class-use/AutoHidePolicy.ExpandMode.htmlPK ^BE̒'9acom/vldocking/swing/docking/class-use/AutoHidePolicy.htmlPK ^B2o|9com/vldocking/swing/docking/class-use/BorderSplitter.htmlPK ^Brj/dr';com/vldocking/swing/docking/class-use/CompoundDockable.htmlPK ^BAr?bcom/vldocking/swing/docking/class-use/CompoundDockingPanel.htmlPK ^B\pJ1com/vldocking/swing/docking/class-use/DefaultDockableContainerFactory.htmlPK ^BZ1V-p;com/vldocking/swing/docking/class-use/DetachedDockView.htmlPK ^B:,;gcom/vldocking/swing/docking/class-use/DockDropReceiver.htmlPK ^B5-4'com/vldocking/swing/docking/class-use/DockGroup.htmlPK ^B/dr[+20com/vldocking/swing/docking/class-use/DockKey.htmlPK ^B:?]o|98com/vldocking/swing/docking/class-use/DockTabbedPane.htmlPK ^B@*3<com/vldocking/swing/docking/class-use/DockView.htmlPK ^Beڄ$BDcom/vldocking/swing/docking/class-use/DockViewAsTab.TabHeader.htmlPK ^BCǤ8Kcom/vldocking/swing/docking/class-use/DockViewAsTab.htmlPK ^Ba(5;Rcom/vldocking/swing/docking/class-use/DockViewTitleBar.htmlPK ^Bj@ 3Zcom/vldocking/swing/docking/class-use/Dockable.htmlPK ^BGL]Czcom/vldocking/swing/docking/class-use/DockableActionCustomizer.htmlPK ^BB3"/<com/vldocking/swing/docking/class-use/DockableContainer.htmlPK ^B>j-N:com/vldocking/swing/docking/class-use/DockableContainerFactory.ParentType.htmlPK ^BIN%%CYcom/vldocking/swing/docking/class-use/DockableContainerFactory.htmlPK ^B<# E=com/vldocking/swing/docking/class-use/DockableDragSource.htmlPK ^B:^/lq8com/vldocking/swing/docking/class-use/DockablePanel.htmlPK ^Bjl;pcom/vldocking/swing/docking/class-use/DockableResolver.htmlPK ^B[N A3com/vldocking/swing/docking/class-use/DockableState.Location.htmlPK ^B Fv& EL8Icom/vldocking/swing/docking/class-use/DockableState.htmlPK ^B➷{q>kcom/vldocking/swing/docking/class-use/DockableStoreButton.htmlPK ^BrªNq>8com/vldocking/swing/docking/class-use/DockingBorderLayout.htmlPK ^B>DA@com/vldocking/swing/docking/class-use/DockingConstants.Hide.htmlPK ^B@ps _pA*com/vldocking/swing/docking/class-use/DockingConstants.Split.htmlPK ^Bž?l;com/vldocking/swing/docking/class-use/DockingConstants.htmlPK ^Bb:9com/vldocking/swing/docking/class-use/DockingContext.htmlPK ^BQ9"com/vldocking/swing/docking/class-use/DockingDesktop.htmlPK ^B읗7com/vldocking/swing/docking/class-use/DockingPanel.htmlPK ^B.<$p= com/vldocking/swing/docking/class-use/DockingPreferences.htmlPK ^Bfr@com/vldocking/swing/docking/class-use/DockingSelectorDialog.htmlPK ^BDn;Qcom/vldocking/swing/docking/class-use/DockingUtilities.htmlPK ^B` 8com/vldocking/swing/docking/class-use/DragControler.htmlPK ^BD ?x com/vldocking/swing/docking/class-use/DragControlerFactory.htmlPK ^B XtA&com/vldocking/swing/docking/class-use/DragControlerGlassPane.htmlPK ^B_ouA+com/vldocking/swing/docking/class-use/FloatingDialog.Resizer.htmlPK ^B{-wD0com/vldocking/swing/docking/class-use/FloatingDialog.TitlePanel.htmlPK ^B2Io|9u5com/vldocking/swing/docking/class-use/FloatingDialog.htmlPK ^BGu AD;:com/vldocking/swing/docking/class-use/FloatingDockableContainer.htmlPK ^B/Nt<Ccom/vldocking/swing/docking/class-use/MaximizedDockView.htmlPK ^BXbToHcom/vldocking/swing/docking/class-use/MaximizedDockViewAsTab.MaximizedTabHeader.htmlPK ^B|wAfMcom/vldocking/swing/docking/class-use/MaximizedDockViewAsTab.htmlPK ^B(0T UCJcom/vldocking/swing/docking/doc-files/hide16.gifPK ^BJL:Jcom/vldocking/swing/docking/doc-files/hide16v2rollover.pngPK ^BHiZ4.Lcom/vldocking/swing/docking/doc-files/maximize16.gifPK ^B^3(+>Lcom/vldocking/swing/docking/doc-files/maximize16v2rollover.pngPK ^B8 iZ3mNcom/vldocking/swing/docking/doc-files/restore16.gifPK ^Bx+56='Ocom/vldocking/swing/docking/doc-files/restore16v2rollover.pngPK ^Be9x]x]1Pcom/vldocking/swing/docking/doc-files/sample1.gifPK ^B'^X  2~com/vldocking/swing/docking/doc-files/titlebar.gifPK ^B ^SqO4ɸcom/vldocking/swing/docking/event/DockDragEvent.htmlPK ^Bb4m *F48com/vldocking/swing/docking/event/DockDropEvent.htmlPK ^Bnd U0com/vldocking/swing/docking/event/DockEvent.htmlPK ^B  K/=com/vldocking/swing/docking/event/DockableSelectionEvent.htmlPK ^BJ8"@|com/vldocking/swing/docking/event/DockableSelectionListener.htmlPK ^B ' 7?\com/vldocking/swing/docking/event/DockableStateChangeEvent.htmlPK ^Bxz $Bcom/vldocking/swing/docking/event/DockableStateChangeListener.htmlPK ^B10 =C4 com/vldocking/swing/docking/event/DockableStateWillChangeEvent.htmlPK ^BdyR#F com/vldocking/swing/docking/event/DockableStateWillChangeListener.htmlPK ^B%p "LD com/vldocking/swing/docking/event/DockingActionAddDockableEvent.htmlPK ^B}C$V B>$ com/vldocking/swing/docking/event/DockingActionCloseEvent.htmlPK ^BpQ8 LB/ com/vldocking/swing/docking/event/DockingActionCreateTabEvent.htmlPK ^B_' GA4; com/vldocking/swing/docking/event/DockingActionDockableEvent.htmlPK ^B;bFb9BF com/vldocking/swing/docking/event/DockingActionEvent.htmlPK ^BUaOA&<T com/vldocking/swing/docking/event/DockingActionListener.htmlPK ^Bj FJz] com/vldocking/swing/docking/event/DockingActionSimpleStateChangeEvent.htmlPK ^B? dGh com/vldocking/swing/docking/event/DockingActionSplitComponentEvent.htmlPK ^Bm; NO v com/vldocking/swing/docking/event/DockingActionSplitDockableContainerEvent.htmlPK ^Bj PFw com/vldocking/swing/docking/event/DockingActionSplitDockableEvent.htmlPK ^B-`T/>E com/vldocking/swing/docking/event/class-use/DockDragEvent.htmlPK ^B 2> com/vldocking/swing/docking/event/class-use/DockDropEvent.htmlPK ^B]C&:M com/vldocking/swing/docking/event/class-use/DockEvent.htmlPK ^B]wG com/vldocking/swing/docking/event/class-use/DockableSelectionEvent.htmlPK ^B*l#J( com/vldocking/swing/docking/event/class-use/DockableSelectionListener.htmlPK ^Bcn>eI com/vldocking/swing/docking/event/class-use/DockableStateChangeEvent.htmlPK ^BӉk;$L com/vldocking/swing/docking/event/class-use/DockableStateChangeListener.htmlPK ^BxoMv com/vldocking/swing/docking/event/class-use/DockableStateWillChangeEvent.htmlPK ^B]p$P com/vldocking/swing/docking/event/class-use/DockableStateWillChangeListener.htmlPK ^B5N com/vldocking/swing/docking/event/class-use/DockingActionAddDockableEvent.htmlPK ^BQA{NH com/vldocking/swing/docking/event/class-use/DockingActionCloseEvent.htmlPK ^BzL com/vldocking/swing/docking/event/class-use/DockingActionCreateTabEvent.htmlPK ^BiD#K com/vldocking/swing/docking/event/class-use/DockingActionDockableEvent.htmlPK ^B~8:C com/vldocking/swing/docking/event/class-use/DockingActionEvent.htmlPK ^B]Fl"F com/vldocking/swing/docking/event/class-use/DockingActionListener.htmlPK ^B$2iT com/vldocking/swing/docking/event/class-use/DockingActionSimpleStateChangeEvent.htmlPK ^BvvQ com/vldocking/swing/docking/event/class-use/DockingActionSplitComponentEvent.htmlPK ^B Y com/vldocking/swing/docking/event/class-use/DockingActionSplitDockableContainerEvent.htmlPK ^B| pP com/vldocking/swing/docking/event/class-use/DockingActionSplitDockableEvent.htmlPK ^BA銺4 com/vldocking/swing/docking/event/package-frame.htmlPK ^BQj/ :6 com/vldocking/swing/docking/event/package-summary.htmlPK ^B !5&3 com/vldocking/swing/docking/event/package-tree.htmlPK ^By)v'2 com/vldocking/swing/docking/event/package-use.htmlPK ^BFXR .F$ com/vldocking/swing/docking/package-frame.htmlPK ^BĪ͠j}0) com/vldocking/swing/docking/package-summary.htmlPK ^B7&bG 7w-C com/vldocking/swing/docking/package-tree.htmlPK ^B2 OW,fO com/vldocking/swing/docking/package-use.htmlPK ^B? .T9\ com/vldocking/swing/docking/ui/AutoHideButtonPanelUI.htmlPK ^B  n4h com/vldocking/swing/docking/ui/AutoHideButtonUI.htmlPK ^B H9w com/vldocking/swing/docking/ui/AutoHideExpandPanelUI.htmlPK ^BT8 J61 com/vldocking/swing/docking/ui/DetachedDockViewUI.htmlPK ^Bf6| com/vldocking/swing/docking/ui/DockViewTitleBarUI.htmlPK ^BQ U. com/vldocking/swing/docking/ui/DockViewUI.htmlPK ^BM½ \[6 com/vldocking/swing/docking/ui/DockingSplitPaneUI.htmlPK ^B gd5< com/vldocking/swing/docking/ui/DockingUISettings.htmlPK ^B`{C{ com/vldocking/swing/docking/ui/class-use/AutoHideButtonPanelUI.htmlPK ^BC>W com/vldocking/swing/docking/ui/class-use/AutoHideButtonUI.htmlPK ^B5|C com/vldocking/swing/docking/ui/class-use/AutoHideExpandPanelUI.htmlPK ^BOx@y com/vldocking/swing/docking/ui/class-use/DetachedDockViewUI.htmlPK ^Bɶv@O com/vldocking/swing/docking/ui/class-use/DockViewTitleBarUI.htmlPK ^B&q8# com/vldocking/swing/docking/ui/class-use/DockViewUI.htmlPK ^Bw@ com/vldocking/swing/docking/ui/class-use/DockingSplitPaneUI.htmlPK ^B'w ? com/vldocking/swing/docking/ui/class-use/DockingUISettings.htmlPK ^B"9 1 com/vldocking/swing/docking/ui/package-frame.htmlPK ^BD龃 3 com/vldocking/swing/docking/ui/package-summary.htmlPK ^B2#0 com/vldocking/swing/docking/ui/package-tree.htmlPK ^Bdt/o com/vldocking/swing/docking/ui/package-use.htmlPK ^B\y- com/vldocking/swing/docking/ws/WSDesktop.htmlPK ^B=f ?-& com/vldocking/swing/docking/ws/WSDockKey.htmlPK ^B TV-2 com/vldocking/swing/docking/ws/Workspace.htmlPK ^B7f/'3J@ com/vldocking/swing/docking/ws/WorkspaceButton.htmlPK ^BUׂ <6g com/vldocking/swing/docking/ws/WorkspaceException.htmlPK ^B2z(55q com/vldocking/swing/docking/ws/WorkspaceMenuItem.htmlPK ^BJGް$!7W com/vldocking/swing/docking/ws/class-use/WSDesktop.htmlPK ^B{ I%X:7\ com/vldocking/swing/docking/ws/class-use/WSDockKey.htmlPK ^B߾+]"7 com/vldocking/swing/docking/ws/class-use/Workspace.htmlPK ^B v=E com/vldocking/swing/docking/ws/class-use/WorkspaceButton.htmlPK ^B8 j0!@ com/vldocking/swing/docking/ws/class-use/WorkspaceException.htmlPK ^B|w?| com/vldocking/swing/docking/ws/class-use/WorkspaceMenuItem.htmlPK ^BZ0&1P com/vldocking/swing/docking/ws/package-frame.htmlPK ^B `3 com/vldocking/swing/docking/ws/package-summary.htmlPK ^BW%5%0v com/vldocking/swing/docking/ws/package-tree.htmlPK ^Bi@/R com/vldocking/swing/docking/ws/package-use.htmlPK ^B; w8 com/vldocking/swing/tabbedpane/JTabbedPaneSmartIcon.htmlPK ^BX/ [? com/vldocking/swing/tabbedpane/JTabbedPaneSmartIconManager.htmlPK ^BD ?ow4 com/vldocking/swing/tabbedpane/SmartIconJButton.htmlPK ^Bg6!B com/vldocking/swing/tabbedpane/class-use/JTabbedPaneSmartIcon.htmlPK ^Be>j(I com/vldocking/swing/tabbedpane/class-use/JTabbedPaneSmartIconManager.htmlPK ^BO&0>x com/vldocking/swing/tabbedpane/class-use/SmartIconJButton.htmlPK ^BT1}1 com/vldocking/swing/tabbedpane/package-frame.htmlPK ^B*X3 com/vldocking/swing/tabbedpane/package-summary.htmlPK ^B9,,0& com/vldocking/swing/tabbedpane/package-tree.htmlPK ^B>n5/+, com/vldocking/swing/tabbedpane/package-use.htmlPK ^BƠO3+3 3 com/vldocking/swing/toolbars/BackgroundPainter.htmlPK ^Bp> 8.: com/vldocking/swing/toolbars/RolloverIcon.htmlPK ^B ;/D com/vldocking/swing/toolbars/RoundedBorder.htmlPK ^BYg߮J T?5N com/vldocking/swing/toolbars/ToolBarButtonBorder.htmlPK ^BU, ;4lY com/vldocking/swing/toolbars/ToolBarConstraints.htmlPK ^BK %W2]d com/vldocking/swing/toolbars/ToolBarContainer.htmlPK ^BĞ!,b0P com/vldocking/swing/toolbars/ToolBarGripper.htmlPK ^B:؆T P2< com/vldocking/swing/toolbars/ToolBarGripperUI.htmlPK ^BffH >+ com/vldocking/swing/toolbars/ToolBarIO.htmlPK ^Bf>y 43q com/vldocking/swing/toolbars/ToolBarIOReadInfo.htmlPK ^BJy $x.; com/vldocking/swing/toolbars/ToolBarPanel.htmlPK ^B J4 com/vldocking/swing/toolbars/ToolBarPanelBorder.htmlPK ^B `W y4 com/vldocking/swing/toolbars/ToolBarPanelLayout.htmlPK ^By=v\6 E4 com/vldocking/swing/toolbars/ToolBarPersistence.htmlPK ^B^ W, com/vldocking/swing/toolbars/VLButtonUI.htmlPK ^B,*+" com/vldocking/swing/toolbars/VLToolBar.htmlPK ^B=U i1M com/vldocking/swing/toolbars/VLToolBarLayout.htmlPK ^B/#=Y com/vldocking/swing/toolbars/class-use/BackgroundPainter.htmlPK ^B%~rq8a com/vldocking/swing/toolbars/class-use/RolloverIcon.htmlPK ^Bt|9e com/vldocking/swing/toolbars/class-use/RoundedBorder.htmlPK ^B\I;x?j com/vldocking/swing/toolbars/class-use/ToolBarButtonBorder.htmlPK ^B; #>o com/vldocking/swing/toolbars/class-use/ToolBarConstraints.htmlPK ^B30(_&<v com/vldocking/swing/toolbars/class-use/ToolBarContainer.htmlPK ^B t:~ com/vldocking/swing/toolbars/class-use/ToolBarGripper.htmlPK ^B>ax< com/vldocking/swing/toolbars/class-use/ToolBarGripperUI.htmlPK ^BGi"pP5 com/vldocking/swing/toolbars/class-use/ToolBarIO.htmlPK ^B2G=Q com/vldocking/swing/toolbars/class-use/ToolBarIOReadInfo.htmlPK ^B J 8 com/vldocking/swing/toolbars/class-use/ToolBarPanel.htmlPK ^B>x> com/vldocking/swing/toolbars/class-use/ToolBarPanelBorder.htmlPK ^BS 'x>ܟ com/vldocking/swing/toolbars/class-use/ToolBarPanelLayout.htmlPK ^Bx> com/vldocking/swing/toolbars/class-use/ToolBarPersistence.htmlPK ^BE/q[6 com/vldocking/swing/toolbars/class-use/VLButtonUI.htmlPK ^BD{EH%5I com/vldocking/swing/toolbars/class-use/VLToolBar.htmlPK ^B/iv; com/vldocking/swing/toolbars/class-use/VLToolBarLayout.htmlPK ^Bt$3 com/vldocking/swing/toolbars/doc-files/overview.gifPK ^Bkfȵ / com/vldocking/swing/toolbars/package-frame.htmlPK ^BF[< )-1 com/vldocking/swing/toolbars/package-summary.htmlPK ^BUG}[]0. com/vldocking/swing/toolbars/package-tree.htmlPK ^B)嫠u- com/vldocking/swing/toolbars/package-use.htmlPK ^B y constant-values.htmlPK ^Bא&V2 deprecated-list.htmlPK ^B `j " help-doc.htmlPK ^Bq:index-all.htmlPK ^BҢi index.htmlPK ^BcFoverview-frame.htmlPK ^B9Lqȷoverview-summary.htmlPK ^BPX!Goverview-tree.htmlPK ^Blf0CJ package-listPK ^Bw_ Cresources/background.gifPK ^B5)#resources/tab.gifPK ^B^(V))resources/titlebar.gifPK ^BUQ$resources/titlebar_end.gifPK ^B ˆ9Fserialized-form.htmlPK ^Bl]-"stylesheet.cssPK::y+vldocking-vldocking-3.0.5/jar/000077500000000000000000000000001243334202400162265ustar00rootroot00000000000000vldocking-vldocking-3.0.5/jar/vldocking-3.0.2.jar000077500000000000000000014021241243334202400213510ustar00rootroot00000000000000PK ^B META-INF/PK ^BZXcMETA-INF/MANIFEST.MFMLK-. K-*ϳR03rCq,HLHU% yRKRSt*Lu 4sR Kz5yxPK ^Bcom/PK ^Bcom/vldocking/PK ^Bcom/vldocking/swing/PK ^Bcom/vldocking/swing/docking/PK ^B&com/vldocking/swing/docking/animation/PK ^B"com/vldocking/swing/docking/event/PK ^Bcom/vldocking/swing/docking/ui/PK ^Bcom/vldocking/swing/docking/ws/PK ^Bcom/vldocking/swing/tabbedpane/PK ^Bcom/vldocking/swing/toolbars/PK ^B\b;M$Ccom/vldocking/swing/docking/AbstractDragControler$DragProcess.classX{|T&30!@2"yA hf.ɕLvf֊ROZV@wZuw>׶vݶۗTܹLBg~^w~|w~w=7Z}QcR|)e7gUf8Nу^}n)_/#scA6^Kq /߈xxpFnn4ӍWwnU/tssOn-7Ȅmy/:UǿOgRsߗ~Gn^m'R}Coʐs_7R֍:}S6;RF=λq FJ'NX+0 ݡ`$ H9PGȬZ<>3S&apЌ6Fbp،ք#T*jG,"&G#!3Z8T$/fM?^vgW+j6D jeimEu&;#ҰfV*˔AġLv+Vt6+$Sjd N`&`.sa%uB'k7(|kޡ G.a=*L&|tw;u marmcκchtZf8{w̞-ܟA6a#K@%>"- 4`Rf`6؄-vcNAh[Pr)/F#̀i1Y44)ɔ|!mgJX8CP6F23(N=M]]#,mP]k͡|^4 G |t*6K>J$m^Ur_2bV^ 1V5:ptso _+YWδ;, Dt;a,pV.ۋTNR4hU9n00cn2h5U1TPAku\ţf::G s]:5^ָ 8J݌'dpAdPQZt@fvoqݒºPV̰mĽm½:m6rIqN>Nرꊒ!&A4︝J3=&g׌Gtq"٩˦4xޒ{JA 뢑G,rSNj^5 |S+R4+*n ':Z ѤԌ2J.< G˝;gmb4Oyb1ߘFN0r;1:/4R/s )DC2v8w?j;ejQqkIn$\W~K*|f>k"] G# ƥ K _^T$ r@%MMIF+%{Ƙ.AV\v. >5LgkzJX` CE%22la-~:ӄ@RV`FI7t/z KIax}šHICYj}Of3g;;0HiQ𔮢&'˫69GF$AZ|{I C~AH)/X\FE [J_ˆMv&,=BٍU7oYSKxI8_.\uQs'T@ kM)74N>ƒM˙+j(#m⾞[4.z99ݲ!fX2|y& "@2Hewr~y\@ߗ*;9#}svŊ'9Kٲ4oGlE䮹 D΢4'c㠦+DQh mn?L(S;AhgA(oI\dxKO $d}ihr0^ r70M{s(5(u7R'tȀ}gU2xru=pzs:q~LhMLdaRL;w)LPҋnd2~FՋ). 1zه0?zY(<A Uy͡󷕜A _y\=,yl3mT6/iD+k|7(~jwh~Vخ6ky<"VV.SxF8*6Z6|Dl2܉`3 $&MQ%T/Cet1Dr|Hc%zHǾhi} 4%~w9 z:6^+4U3}08ff M><iõMZ b lan Q+oE#28ZzzQ|{e72W =#=AUgk`6њ a ֪ ج6nV62ȀZ!R9)|t|-G&]7"Lle$?#PǸ}jpk^V]$4tia*2Յjo /MrKYv|#M\>1^ XyQX90>Ⱦϛ}u^1aѤ?3 RPC!Mge%e~J`m˩,H!0lC8fy<agQ6Js棜Ņ 9Ew- p$h`lcN.eDntnܓо{Q쯦%ξNbsZ)I%*7(&n:9ai`|l0dץ3KpB%&9gb|Փ zyu(SS}Ӹ}D}  >M⩕3Y|λvl?cxHbu9,-KGL)F qmx[8vq[3PK ^B[,GCcom/vldocking/swing/docking/AbstractDragControler$DropProcess.classXyTTݹO"($1314 KMi$m7t!mbC1iK&MrzMb0*ow.};'޺zIV!(fKhAX }db$! F  7yH>%ܒ|L ۷'a>Oe$|Q—<(×=(W<*n0cboI||ǃ.A ߕ= uX Kw+JϬvj;HXmFy.-\^PkݿG Ԇ1j 7[ eYT V iraQo r[(A%V z")ЯTn=br/?]FwPk!32اvݯw(&[!Ї ݯi~$f[*1ԥk ܳ BN`m]z8Ys\CêaZ 5+RyYG!.H/âhP &T{:!L_3Ԗ&![ 06B5~R}j ,lP#PU4_껒H( #AXItiB<Ε}3N& b~ަEAVMA]1 !;.]#,! ]A!sr{,h7i"f$r\!c /2&;yv؄w@C2~1Ԧ2~hA`zXOe G$ńA1R 6' 0m2ÔM½21Js(cZq< 㽸VƃxHxD£2NxO9KW2~048=3ͻЀSǡ& [1<+9/w k/$dew8k6I{(g֮Ȋ [52AuįA% ~bJA?u爯 $N[mФPxΚp眊R3TۮooۭE*Jbnj1g&8[뽳TM,ྔP{L [yF-1hB5% >m[fai ~U˚ԒO WOj(vGfF^j+B-,6"abx uX jFϟJ:DIb&=SRx}Qo;(KXNK;b6 oyWyb;q,J&VUiuTR=yȞBMO^1V $*k(B+3`'+;F?p#'nm8_ ;+>\G!_h L܏;s~24L7P!!,qətߎɖJ)JR{8Jq m b" 7(@ބB=y*ҧ`ؒSޖ.[v7\etYYc7o)6`t-uFqexjCPK ^BkXiFcom/vldocking/swing/docking/AbstractDragControler$UnderMouseInfo.classRKK1Ү]]ZoCbEAzP{OQnMA8Y &d23o$/OXB̸s16E|kTav5UpRܷêշ+Bn,&k-%7jwPL܄q~cFl4LU늒FHh eh jZ(i7"T:סߝːٱR BW"ǂO&5m߹@uSC| c"K3䒧8-t6k׹Lɡ5 p1r7Y0|GHB&WHݑBd:%OprH'9K11PK ^B|=21>7com/vldocking/swing/docking/AbstractDragControler.classZ xTEL^r-"\((BD]uHd`3zz_APx@iV̑R@XO47iJk +ޞ=+@8%sQ0S̜W. Ƅ*aŴ0Ќ@&̟/4$tɘoȟI9a寥oeR|ǻL`B !~УpsjkOl*Rl*O&әit|*C (_m*hM wڳ% PSe(T*T٠rTC2Y9@*q.g|t^BiTgtӘ-O_a/6)EMMn8ДYy+z66֮zC^Q%EoP}MOfrfT!BN~"S (mLUbiSvDS>d3t%$ rz]iskz+{n¶;[_6AcC5l?"`ߏ0)LJ9{צ[ϑrx u%+,kIM%,% 4a4\6 vt]^[c:aIGmhĈt`(̔F8 ,,GU{Dʳ; ;؅)iij,1g>Ok>'Aʄ|kpE11v@v*}%"㖕윥Xp$܂68zs1A:mpi;-:[G6RNX2aav8ˈ"^cvUZ j{,TfwOw.ێP;V_̊p * HɩzZ# Phboruɵdt:722[e'才28SPf0fqRt$3_Y +/?VeH-u~|dFYX,hj"s~1[;*<b jt@ȲSeV_.s,qkl Rm,V=Y?(_by;}Y '! yq%(;p֎҉* `"] / Tٴ;fQQVS^|B;;ڮ;KD63zj' m-? ?/{HO4 ZaI>=pj?st9eCHl7}؜$qȬMd6PN"S.&m)jF RZmԠ IK(Be h I mAIiLB ]N46I<{u:ln)Pm<Lrh%>)$lOГ66m'?؆sR8!`qAtLR"bC^$A>K,"|0Nso='w9kZ&$u94^CxMc=)f, 5ulފ2]J^4-ѕ`*5k6Q? `p@ Y@9>'Øk`a`r~uJzkvXJ/Ћؿ'D/Kc z٠?d`+ÖeX'4Fi/ T EeheF#m-6RDM`q#Z(ͽP~PRH(ZMj$gˁ X7#m\׀?\:Zp~76Ih A\O&TA=y@sw*-VIDZv8ӛIPiy/*#ӊ6R Lơ+s,o-ӳ+O<i,a2SY(N`үoAx+o4bG4 L'Z@o.--mq9 횟`^r0P7c[eaw%6Tf۱P`3)ؙ:_oomߒdU6V'd:S=Mt(`-@"W`(!p`1C?MalH!)2I'i kޜNPܺ[>IgY --.giEzsωP_7};l0RD љ4TU]VHcdhwk_Cniy֐3m;F}腲w qu>Ict"2fZk]0 -tBoz+8k(^tj.u<7t~y/,~9 Oy 㔇W=ՏOT$5OVS5j&W\\N:xCJk+& f·ټ>X/G)`ǺC`'LP~Уb @ O}iTjGJxRru2p peJ6u} twQH f;k`~-e@ɾ#X\#:ndXm`nGh8HV נw=4ΠĽ( !?[_-HT]p ]>Q׹u:?:SAcenAP1&Cm߬ i76ޛK-Qwk8S7}jozZk<@,m0Nnn2{ -haFB]( 7R^B"đ'6R~;;k;7Ci|.yԃ/|b̽Pkt*:o^EA3[i5#5t7AO𝴝|?л|/}GH >E%&'JM1eв v%."<}.ig@[h#:3P4kt#F-!z%Qx%, 4DfR0!E%lqV$^$(>: h [4 4dz 6uRFᄵbE nR{MdiڱBXԞQbc ,DhŽz!9F{}: ҇oZMT>k4QJ'.teY^c+-i,$-i!P-yJ#( Z*l#>[(D;9CeSԅ)s!Bq Ok<{1aۖEn[&d`J43\ $VC4#fn8`ԛc@.@LAx"GKN-yS4 ʰ轓5m6_<~N(SNWAa ȟ9_҇}_+|;˻xť'q3OFR ??7W(7_{TWgU~N'z77jQG89o/B,Aq 2;5ptH`/2 SgQΓ>^AkƱ`E>0'OUwH]vh!RzA>{ %-zMHPm_=i!|5@pWSf#[v:I:_B1z&g3 O3 £0m/2=ROnz{*DQ<_?"*xSe+"WuIl”>mtXƨKrE^Rrb'<FW5JjCNFH5&#ƙ)pQGjM'n.cIg$}}g p!! zs}Sr?K}^C gv6N޲} Ut sHՙ[ґ•JJ<)Omh#SK +&Y{3K"Ζ-h6?XY!^;?lKD IM>S>C>S'}N IL/S/ʔIKҗՒe$}Y)I_f2J&}]%X5$L<9`?:Z+F~)I izT'DxB\c#ce"fknHOdY_x]i.{li{ʘ}dq:';]Q_(υޠ#6ʌ2 V'AϏF22!$AQF4ND5,TSP-:b7t:.GsZDU%ݬhZLjz ^R!zO-TWԌr6 R+y:+PW[Ejv:Pr M{V]/x.N]_knTYA ZT7#խ\ݦ檻TjTKjG]֩k}j_ݮTwzz^mT;&ڢʧsu t0}EHᴬ\GsĨ F2{+ {q@wjrBڷ/2_>?O. uaN2v—J4OTND&]η"s꽗&17c쟛QKCinT=AM~?PJcK>X%-x$PH ]Iw! VCKKGiClo嗆hVP^)L4  V3v>?z,(`zp/pe:Z'ۉUH>4f'4> EAHPu etQ_lW^!AtPK ^B%}v3com/vldocking/swing/docking/AnchorConstraints.classQJ@=}h뫾_;-h|DjZF4t+4hjL MOGw(W.='gι3|{Hc!,zzj]^ꄑjtcM4#pjlIXPGm[gFB^ON0GȈ #n Z}[5lB }ˍlo"$NH-foΝܘYPEED >!ƕd:_Q {<[sf#@ 6I(Jju\'VMk(C!+93<ʋS=a8zTAIi&B-L2*}1TWP)i$lGXhwvO2xg̴kQC̜3{o|{:| `vF#AC~!`X #bU0&qb `R2*AhNJbw s3Vy%zWKe5SvML3 X^eg&_-mp{E(LWҵfBMz<0YvU*f68D5]e'S5Ha GS:#xF U=1kG#z4a\4U*[&sݤ~;-шU`=A1t,;5FZ= .B\ R][$! lk{}ԋV湳eL8.ݸ`FE D&" TSR1yY>3iX*XdXwR9*{ 8XQw7NkRΨ8@04K lr:̥,qVT AV#e'ʧ~H/dzy0x\O2JAG'7 @]0 DIZ79hD?E>i-G68SJُ qe+U,@g9϶Z-QZ< |=Xgs5Ehm.4j}3N$BB?1J>Ydf1'ԯaϑ',&=-@!v\5CRJ$et5) KU!qvz6B!awDfQ֧BO/Ѓ J.EyT>?PK ^B[y !/com/vldocking/swing/docking/AnchorManager.classX |Tf}pl lAH JM7qva ѰՅ޸W.6ъ].rÃ.<쒓.-v˷g˶oRS De5BLfT~̐ B1#m(j2\*D3N$ "H+%K]$;Uǒ#9٤;N Ah2|SlBXZbWM#*U&=(iP`$#kM^2cJ,F@ ̹*f$2xun[3 0"%)ȒoR 8%$#؄G"!h)oM YUZSkkt|+RGKu,DPŸD*@4`in8Z#$WtLTc"45 9`7񖎷@qZ!uajRtw?Yu 7>M:>{lHwps uA':ƄY \r&:!7߬k.Bc6Ek/k. ̘ DlN9D&03"}_"FaN%M7Ռg n%H`\N3niK$P/Ր 2nwĤc{@|oa&qtGe6`Rt`4({&0iwIHxq`kVJ9+T1MNpImx &/Ј(ye5IOoFK7#<;c@*H2V0]`[SԖ3B˂ v|SL|$j0;VJ5dl4,55;+BɃ◟IG]gN;v6.`"ʌN՝P}qG[ ;a6ނ(zq<Ht8< p"C1 ίcPj@Iz2[ .5%/g *&XWlر83pfd5wnI߂S\||Ҥu'u,*nJ:8S9uE=v$m:׬%q' ;fFZyZnv䳂އkaVMMc2-c@9yVTǀ} avX!|/ Ǖ؊ ly _`kߢVq"OInNChsDY!teDJ#=B4,'$=3Ej}4˰#o?un\*TbJ$^cLhh4_&)ȑH@ԩ]=JD j?r]{7A1i"5‰3ssE.+B;=\xp腋Eo\**1k X/nqv/xJGk^@CR-5<ʀ6& #g}L..qr7AB2hIo/c># Cvʙ14q6e!7d6CXɴx%9$&+&b((Qt{/:c:?T:g)ORYѓ-UcܾF.ҰZB@UӋqI\9̆J:h"j|RA[M*h =~<TPLSLGN3re2(0j`f#L$3R @Ń$"nbsҏߟqbtU]u#M ֔.7buK0RK5SÕsZ՗FBTyһ`(\yelb_Ιl(c?)\6M>0.'Ltw![EJD_\RIq&BCP z ',ѝ&u尝2.WIsZa? ua+[ :*P:\\_fc͞Eg ~%{:͊5P2ӹPukuLn`岨#=d_PK ^BWb6com/vldocking/swing/docking/AutoHideBorderLayout.classWo[w~Ncg˥uR+ I$J[uK4-'ir';>NݖFaP6K@Hhbb҄HTq w7uE_yo};(F`1ŧ16d4QpBLvK=&5dEN,BQLi1s(hphDQq,YWKxV8!Ia ^0ᔂ蘝f-(5keۻǘ n*븝weX:nLqVe->pvTPc;bntY4cFvp,7E;zhGt6cMZŒUwѵXsdLǘ¬`r8-47]o;kst氂1y?-v Ov*ސ:+?md UФqs~8]MUϢeiCx CG1WZXt(wq^@|%,k|uh`D nw^ca1syMUƕ$wn ok-_0{¬d2j)Ц% Y)ܬ_[2 k˲\,0Syt3S6O-6ȚG,~茙-<^ۅ^5u;xz;I4HuUuz%t|Cy gt|[:-.h6Z4@qNǏczqq!B<]:3wE*\GҬlwtkǵfvЄcx]EwZc "ldMu3ᄄ'>g1Y~UdsZҲǩdbg7Zl4&BȫRV8rLxlVあ*d,zNx]*7hh0P;F3VƝa5>A55ĉ. Ÿj%t<Ш6K=ƒ=v10"mPp;TԈop( 98$t C>Rx~ #_U+ 2R {X3Ԡ7q; !%{q6G3 Zq<ֵ~>Ѷ:n֟.$f?ݏ:$WԙnvNe[M9Kjӗ:'g5 )"8Xa#vK &UHz 2\G&֕FeZ J,ۘYyw2MHq df.=,ׅ&WH!]X"`hz\%l&F({r&``%NNO~0 Jι(K-o1+]"hSȂfȣ95Cy*i 저6ab+F/AH70DE ܏s #?EF%q}*2&nmM.~PK ^B-I2com/vldocking/swing/docking/AutoHideButton$1.classUSU&t#V%(- T~|!JRu²wop_y36e:>¿qlD(~dg{s\{]#wt aT'fwW4\e2یI 9i ut`FGyf 2;a^M  @Ȼs2hRkv7$p`y-gų6lw5lZ+r玒ߘjB j1(y+R`rY~,9$I` ̭*M-3SdnNmIW+ nKN=#prAƬY ^ŷLAd>ZYּ Y簠hc0ܔp2Q[ơ3 'wi+փMS-)E0j:=5ֱ``~<ҺTtyE x*U]1GL +ſb:˧RGTiNn/N(:(Ca]q [P%vf.%"7Ebjݴ,pm7/6}3TvJs[e$gV4l20Y_}$6I<4M&iӤ}[YLL4_ΰ,ҥ_>Ͻ=㞳\ylю;"9# ;͸GvV !|_ B_TAa~Y"!!_o Z { _oqM9>!'e%o yZw<#wxMx=!!?C$/$*Ta" AH4TJw&LhXҶItiiX2rd֪O㇃uoH@. ucq-izݴޮ:k+*c%k%8|:a]4O&(E2'NNQQ̡a{ vRE4,3=kK4,M1+^ypWJکN'ryyhgz3鵞CʴL;V=9pXӗV;eps?!v: B)';6d<'N0}f`gu #N&k3;@8&,^׌v㾵aG=n.5/PހDE.FDd" cV/mL[GtJڧx9'ܶ.f3%Mc+p5>,Oc!1w'옧\1:S̲Bv7_dklSp$:MBf-lkapa"JsMǭݶ<76I4uE=BWGv؅:#V`LtYQT;]+:&c(ff14#5tNZ%\v 5?ŀtј45BSA^:;:ޕe \KJǯEo[u| Gtd9:H*oB.B:618D1E!+ɹPBP(z8ma*K#2y1vU j>*TITLLSqup6 YOl]wDo5o7J7L[-Ji|Q;j#TÊ1J3(>pc!\XVӄz1N?scTmw'g{R)zyvπw70뻚̼ۉg3^p9.\9.yٙSxw@ػU"TT5g#=x*-rLfVvԺW6&˨ Q)T )3.zq^~A!AR 6,&z:?TqUrl̾]T8u`ezImc$ 9h%S}Fk+sX%kc\jx]KnaAgׁ%w2w,X{{> Y% #(rj<bSբvReSuZN *hqx ˹gYSx(`me4 \ĺ>AAHxy|CNj^2rqԂ'ȞdM=Z;+ ȽCZ+V*(Q ;*;ֵ"[;,db؟%y<7 n5<@/Q^pp~*F:~|JQzWhTzM3onSMɷض&݂v՘K{*nGiѳ.kn.-W^7cgGS -k{=qKsiT[E`n܋/|Jq QQI;8=X`n>,z˩BGqtQa4O3W1vMre9l"'?PK ^Bg7com/vldocking/swing/docking/AutoHideButtonPanel$1.class@YxpOZk7[x(1/3u" -/R-rI2Դޚ0J qHm]nk6 !Ҟά< qJk@讌Q)G|JzBq<`>QSM6W;TQzPK ^Ba Gcom/vldocking/swing/docking/AutoHideButtonPanel$ButtonHighlighter.classTmSQ~..(jeZ4!Hګi6co \auEE_4si:wA4&Þsr m)?zbڏ$͌+^x$c^c_I+t,@fG uJMݬ1HVIYNՌb/.e[V e+p z0{r6 /|.xI31󪾩V5o)=*CeZʠuVdM&N)v/IxV"뜋sFG`YCvԳaݬZq@fn2;,^ACtsOI@`ov5ϗ5Qԑ D1b!Yl"O[Z3),(C@FZ"OK2+Xx 2 n!ꆋ!UP+iQEDAjV5Ԣ@ 6CխJ&&=?߶+,`d<Rmpb@k[ ԰Ūi FF7zEݳ\GJ򊪉qz {tGqh!R6h'tB;&KRș\0QA-wdD+xG?Bj4M:EːH20Ф9ƛ`b5k΋MP}Ǹtnӱ[tBQs4E" h)A) 6PBY #D! rsEaEAƎNr*99>/%DTYM"(x)]3wxpxPK ^BFpzb 5com/vldocking/swing/docking/AutoHideButtonPanel.classV]SW~N6a!(XJ۰Q#Z?* B`Aݐ5]AL:Ƌ:SLB(2&s}}ޯsכ_88ȫG7:Ѓq908T\L㦜0טOq\-˅v,⮊{ my'5Z}*U|8虮eTM׳{0& & ۟753#g3N͌gnŇƚv%;뻖]YiVrܲ' Q#W\rVkղY߭Fj3nЁi6};}U.{oe[tڅyh)mެLQ2Fm0\76Tqǵ~plߠbYGj·Ɋ[ŭ!l_@I3*i$y4۴=5T\ \[@vo 0)%8ي+jd1WhVWO:5wɼnH%4 wI4S qBg\̞pN͗0$U=ۆ965**5Xx jXLkp@i&w=ǔg[t+!9ZM61Rii@ 3^Sga>7"ܛ4lGJ&X9:?-Ymwd!8d5{˓uey^Bæӻ=(ۓN3盶s}l˺? 3χ` {?G?CȂ.6#3hK=G{*3 D!J hCO#:" hxt"iIc{C)nသ$% q -=QTUqr5^%D yBC+*W_cs=gx&ۏ1c|0nqh2R/;A=%N(oС]PJ`I2 CeL#'l`N FCvH#zbD8 :U1bwH.^~(Dh1ִ3Ѱөg60 `c yIlv6q;#mj8$[\W Ec$Hp{=t(UPK ^B̪=z7com/vldocking/swing/docking/AutoHideExpandPanel$1.classUOU]ag,*څB *P*]@Rue/]gf5~į4&ڗ ~=`5;")9;g?C^q/šYm9aE*FlT8.( JRO_jVd\ :^1 ofIY2,: 9"l>7]{tsWg{naІjS'I^PNrrf8H-E3i.I^nU&\5RCݖn(!:NqtN - :' >W@()3"eL`ZKi3DCCȂgB!w` °k9'\1FiZ '~o=褯n+q<`!K-xt ~"Q#k,8t3)%LS`uuӥV+0q}Wx:Qq7yht"!j|yk%$sΟݽmnU DAZEQoF֤u&K5e/H頮)Bk5(Ѧn.+ F4ROBk{&˾~B2Dd Dߥ?{CB#w~| |Y|K|Do:V~  Q!fɶ8$4H+ k #IztWI1o,4'h >軏7N'52 ʨPK ^BC_7com/vldocking/swing/docking/AutoHideExpandPanel$2.classQMO1}u#WƄ&`L4n#ե%x0&(Fo^MLo^:_+- &M0 '#Wϝ$Ճ.SH_IO \y\ K% ^+hO0TFRx>= d&T*kD0y t6oxNǁ+.e' 됨"iDÆ]+(ѿͰ2;|9"*r:EH NNFb=֠1j5UztL@:o`w^)*"[j_F|BXD5@&X-PK ^B*B 7com/vldocking/swing/docking/AutoHideExpandPanel$3.classURA=C%r1o1DeQ %KoVjw)~U~OVeY_b3 "Ѥ2LwgW Vm8j=&2MJ:f8N݊~'rJ (i0^g8Yt=ySv4e-W5'"AFDb\W LObN9o M1wl+%9 ;bf1'e5tĘwAORd!p|tI5pB ,tbqE\ey WP00f*CTy(*q\VK2t*rcH8T?WE |A,DF"=g!9%e/ӻS' P"40ʯ䗍 gpU ]Y iYt^Kgz<ԞP<P} T/*zS}ֻ@ͫaF}S,T$15<%/qOWCJpʽn: ~^>T;(:[8 v+?ut?aNiS]^i_ [ɺA40^e_iMNk oVK&vb] >:%$y%Ve\BrJЩS;|@7>jTu%~:#Y7W4Sb_r\u}"o&!_Obzi݈#nNj zDPK ^B!*-:ne7com/vldocking/swing/docking/AutoHideExpandPanel$4.classU[SI& 를 & HVW5d`w X[ͤ Flo}PeU^,b\TҧO|}| `Љ. ƹFt0#11FVZϸEEM.p9 e^0᪆k r F,_Ke^uTpO6ggU^y{+ȫ  Ѭ_ ,%Q-%<ݖoswW5tFU0'Y ~|GWDUϮpoǭ|¶ܺdșw,hҨS FiO(:+EVEQ#JI<*:'_p@S~@^Li0#I#]1Y*̚9 yӘ10_5fœy4,7:²V3 Un2tm-7298mV!S2{v(KJ Kw-RЩ`HC:fyt|U$6G/ \ke=Ž(wb[?  gT7n}D6n"ңtGkG{G3ƛ!߹"Z*xMJhK; jcﺼP\^4&UsI+8MuX`V~J\y[xbo+sG6 p !Gs~-ԬA8$hz@6,`Se~g 1:8ԛ gBaq(/&p?A_@̦ITT%=33??p " "\rpઍk6< L 5% ,=4=ХdU?qb l6Xaa4|_dV;*~}M%>#|fZuw>e'][5);# (5h%)iF%I:IC"C' hh_EdFD&«dA}@5[D#{hy('Ğ֝rD|C`әpܝ%EKtW{?:qIj"*ln7pRAb.WN{ݏ$M oPK ^BN&;]Bcom/vldocking/swing/docking/AutoHideExpandPanel$DragListener.classVwݹ0 Ш hhhi)$twvԂV|) EEV$O=A??xZ<3;۰$<>_b؀a ˻j1?a?~F4F! 3c޸ |d鄆,uL34 I6C0<#au &O25lqS,8iϨxV rرM+P[63՚K%ĤeffNe]g4w ;9`fYv lie H@,|$;5j3FSĩsFjH[|U@ߑ6kf6=)#1I}4QR͘3&j̸fδ~m'͙Vz:Y;IA װR&AG|nw(uKx!mQԞSBY"aX9~cګPqLq˻q~zRVb2<]31op mqw4S᝵!'N[|k\&WG+t9&K8AP̦Ǚ]/E/%^VqR+xUkx]ůt7渎7IiQkg񖎷YsxW{L3.x#2pFo𡊏t|HS]gL>,0/Cb/N룣DuZ$q-7m3UT.ul▏MʭN*JMA][o:nY}:N>Z)˵xV ΙB{Jz:^NL\Bn/@Q6\QR<F"AO[~Z) ~vD=>u ]uCNNY6^֓4&J Y@K윑KhUT1͜+=KK]:{knRAL&%gבy+>LQ +f -m}~}4CFI&ߎ>iHZ7A4_\7yX  br-[Va+ x;vd:}$q?YY vDx?XGE CR5Zz6Ŋx,$.`Uqpj{nwZY/k./C;vRֆaW$uEjծ몵ֺ|/h+)]W()R>#bYcV-9Y>/: ] zb@$"/OqJ*{uqQ7MGyZIg-F(9Q'+mK^Tʰ엗@)YByIQ+хnDI /NXx{}fŮQ`v"ec*ТnUau @UGiA}*|1/HДNh匮E ߷&6K!#aGZ%[OK(3I!,1|UGcom/vldocking/swing/docking/AutoHideExpandPanel$ExpandControler$1.classT[o0ܔfظh;X iHL6ionblr[H!(qZ4x)9g#QM &naam,Z$-cbلP횸}e+%* JJ1OS2l5FqH~c=6LmEp)bħD,Qe4Z{P@$ &t_2XT8p੘Ŝ˘J9g|B癫| bRe1\T_U5_W𒂗6Dmy5ϲ ; @zڞu^3cĬٖ@s:cO'vfʴ&enG]}ʜ0ݝL5A 1&Pc!gږcx֘(.nU &CedIN2O7v%mZfZdѳguq8e]Ŋ}D\ܝ53Slx>'^Ҙ3,/;>Q%U-P9险~}ƧM,.ȧ\e1G4FǞ!]龠[aoHy-79tjw6 ĐB?4Rk ~+!a>tڜ6 ]xS"niX6=G%1'' W4Fc>J˅ql#ПB/Y$?i38 _42j%.ma]z]N~Ot'AN:c\FzEHQ=#W@9K` ^Pڙp+P NMTxGQf{-G=Y39TaZs= Z߯>HYrWqɮSlAtG| k7WttHW#kya@^!wO0G5.Yas|ǚJM+A,[ksr$t7W.(CEG c]uP@ÃaGMc+7J=O+˥ȏ|Ub<ʢz(PQ$Q^e4 l̇=!epMzq+zz.飥 4QDn?Z迊 4 >FoL4݄LB4!oB\Sr(qqQ A$$N ^P4-(f7QH7/6QQ נ"62I#H`/G܄Ysq(9pwZɺp@APJs9^SU{j*݇s-7QgeAwB֡FvYl@܋6/ǖd8kЀݾOdClx+!]Vw0B81l$1l!I4TD]"nkrD.bGKr:Bal!|-b[}x/]6Uo^Ė0moa6s;(w.a9.5f8aXX_v\O&[nSq \^T+ǹ? , ,y <l!J3{@ٽ[?R.fk"E7NC'X2) btI$mC )4;\zyű V+Dlmq%2-C+4 ء`قґQ0(Щ|D y3/a$DHwEDNQ9b$(-nx. wf8N,q.pTjGHBHMľPK ^B/v&QF5com/vldocking/swing/docking/AutoHideExpandPanel.class; xT眙M&$$laGYB( 0a1P!F&3qf¦N]Rw6qAb mV]\ZkUjmsߛf!}s}ϾLIl&$MXVi.&"MT4mlf4[4~ Cb /Bn7j x .rs4WJs4Wkx;dW5 #IsoӍS2 o/ǯ{a*/oxwz/x7fW=W#IsyayL `i,0GÃ>7(>!>'Ȃ]40M >昆knmTϤ/L$4rkEI& +Oٌtw6`ԏ%rqS/ * fUM4CePyrpFHY"™=W5|cep8s69WpK٦?ܸQx7%Hba22cD3 bpOHբbNYGN ߈n"f_KcaQ;qfx@(xMvhً3s-X78e&T\{7M[JvEGO,  | 4 EX063l/Wz]`Z`a$ܲ2ܺ  a)Zf̗ 3a%9 /:/Dp[П0]lZm0hYtHᶨfWmVEͩPSXyU柰zR/.Jo-sn CpM\nZ$5e=Y(!&1$ M=ISY3ò&h -b:"_}׸Cb4'sSk _}iaEE_q#34A 0]ҵqtdYUR6'-o6ZMb9Wp21I[~P>$M ^ŋOe_/8՘\nㆊ983x/_ꘇu̗@؟qO'q 3‚/j/W hTÿQ^cKi)•"*$d>4*i "ROe: 挧Tti:͢u:f48MJgܓΣ8Vp^d|*iT݅bIytrRa:UPNU|LU3'ͦ-hN! Sܲp${Qһp-]OVtRF:-:u1VuV鴚ti5Z: K2Ysu:gWUNO:5_'tj :B4nrItQ {PHNtNbk2ŴfѦ VVV._\]YfºrT,Te]E2-Y^R:[uFX%ֹDKiFu. ەidx]5svWu\Kuzg5inM4Ͼյg$Uׂ@PSM`?C~]JѳGt3"ukEѷt;VX,޴m߷8; Hص::!)]0u)],.wD!XHDP祚`C{u_g=:ji7&W~ EsDyP~uzH3EH pWwZU2yYv~7$M > jJI!/'PN"6: aEΡLʵYj>-4DUsGQ*9fr}2e!S9nZVqYVM/+"F1BMa Z#ԼYe70Y|8JrTngLj-7yp a2'{ټ?,_]Uǡ,F{H@*oøh5|b);z~/ ּyw=RR^s?N-Gk9pFܠ 0Z5&XՐ8JϻoƬ wJמX؜P3xuG/WnjTȈ"hfX>'ވRĩl̓^JT+[ث:gCf,e7"FrRkUwLg`m3}3@20˺/KZbݢ}tSoc0·u[e߈~ [ڢ04y8?~?]![x]߀7U;߲?ZmտV_௪VV/W[Uȕ7Dnx?4c' 老qnwI?2// fd*vw Y1p /9U-^kǺ`|Cq'L脢xw1]PP)IG`r)`TS@4,M/va/)O,Fy'87ٻ`5LJ)gf< \pV}q_b]< NwUk]#'Yg:Tɝz_l=Q~_"O]T8Cp[v'c#6Bp'lǡ{ !*`  +`&`5Z8΃fb[!!WAV 9> {vٻ2G0aЁc '3Fs]l0?^ ?[G~e|O~9 .,S:_Q$tqUAA 3إ'|K4}*\S΍s3|> >T-XpVV&'a8)m{LDp{i wb'BbW-s\-k7`@&GM?59_rLV1A*µ;0uFL ["$q-GQ`[΁1a3[ n}[Ӿ$f2*KB1nt6ꦅa2(7[ v"^r!nP\[x%(;!}ê:X\ՂP#@DZP`0B,R1~@J, 5V6ev`fyOwťBF3gZZӎ9qhxK£l'~xwƴ۸̽ G.{ng.9|n;!.;B^kQ :`}q4 ȏ_ w!4qlu!F-0C0ð[l@p?͉L"y:9 'Rfj8ټ#<TWvASuBd 7gE 㰱 "]ՇeXPdAQ7 *$Jzʰ2,$(-egM8 . e(^*0CXe}M~pʧN&9Ʋ/z)0/x9L+tհ_&.Bxl`;~ vp+{f8p :6xo6Nxwb긗a{3~\`=+gr/.!.S{v~?pϱfh8N/pj%fł]*E5)f?OO9[3sCv89k ! ]߃ }\< ;y1}K,8 p EX&b ^LJqJ#8y>epW qV\vދ\ ˸| /_&1;ҮFrk^0]-uJ);?3.aKܙo8Vru3o&4(5 dSlK,$&n3üŸȸN›7~Wrʮq].ǖ+L_YÇZ3W` @~f GkN\J8P'H ݇ڒp]Fp?˻yy o=#%7;kx8F_e/`y#N!:=8&& ]p3 oa_Ͽ5q|]:ٙg//7pUlaWCaa-!F~i9 %Sa&@}0:޻#> :5x[*5]{% XRmOrFnW=r+ @mj ~{% XJLd98< `?σOpfkw:X_y/ <.Kޗ8@}cC`D<c8?2S` ! Icxr-ʇw>EOCq4 i4VX xMKߦR Mb4ޠi{ LWflו4Wśf(WNhƸ >lw,sk-Ԧrn!72U y! *L>x6CC?iߏclqt;+q<2E ɿ!*,%qJfK`؂脇%=#J2Iqn!&[[K΅۬>AzQՀ2- o¹{¹\ RpaQO8G +8<LdS-~T h 0j`*\Zt6,:hz8 HͰ6i#S[&}+ͤլV%BjjˆbkT y/"hXF9:&u_سKH$O9nXNqH԰]Mlp 1*#{"VSɘ}WpulfFavrfKΌZoZ4_=i; .JaC |!.~&E7G}1\"urqGl\BHopM4,OpNvGC+G]5ם8|7>VRI a'"; $ oGt*wC?:"hKe /#BR-~PK ^BMZa0com/vldocking/swing/docking/AutoHidePolicy.classVWW m("XZH>@A $@jHP%LO]nڞ.څ=G9mO]u]777ߝw~z0>qvhL,0fBg"e&v\p!όXtWU&9p؁^Lu&޵=mRxߎ$W3r:9' @:d59SrvBXF!_|8< X|"p/A HӹOZA aqr"^l$= GtNc G}༼(hr:3Ϫq Mk|Fe#xGv`03J6mYZyY6DswCTm'ࠄSTaz}PM+, j =!kSrVehϩ4M9%3wFB_s4յ$u+pՔ/;bիgb\"Ƥv?#Ye*VcYu镭rk!bQ|䪽&!n m iTsy%vq{.;t.@n* Tj)lx[+낱EmvUU Znw 8 M(#*;[VM7'pҎܸnt3qn2Q&@]ϺqM7p+nbq,8 {y Ϻ+-+ JΊf胶a9э_9E|/YۤlW[A?/рV">!d`7{*ދ}e =v*D#iȸ9㚦^3QCz4Y[f" uz= yf ,%XIu-]Ӏ_(*1\i 5 ՏMfA*L#Epv9J°afCԎ{0bn:V"6>-XD]Ȼ2{bz裧zcĈC1h6j-S:[Us ڳ<ٜۖg0t3Cy^i><;I7sq&+L $CԣI5+r]TojkIm6aܤnQR$ņ޼VsNorMJωUL0)j3SRHuJHƩ8խB_DmgPKv i'Amk^ /s2&ϔW\.׵3]󽏗őљD :Shoh\|OͿPnn3RL7Y¬Lw!L ~HRHi&򗐈"&4|Bdqb;6=Gh z-)d;)-xT+1WPK ^BX_ 0com/vldocking/swing/docking/BorderSplitter.classXy|Tnf7AD` 1 $*Nf@2g%h- Uj( h`PKm]mmk׶v͖p7ww9wл0U8yPOl>c7ޖ"܄UY"x9|^}MvUߡ; LQJ۰ܥvJR;gqE>ܭH|hܫ }C?Te/ xVL#VUscMpF3F$PT975D5V)ƙ Pmi0QԤ3IT6bUk±H*NќXj3&x]s{5/IbISٝ"nki(e5aYP]fMS>`ITHBӣ|rF1@:քa} ƊgH|^" F>=_blR+?-!X!RfU҆Iчű-lTZm݊&le8H6iz5X+yG{$N,rP9d24Mrw'bk!vżN0A f|^ãEVI|]UoPD>A0Y9f"LLY&5M|K&^'&%~dxO𖉟g&~LGj~V%įkߘ-~gJ;]HV>ğMϠ_WRmM&JĿo4.:% WM!8) Kja '&+n\`b ZbAfKp 6'A4à "՘@<LFӪ5Ճx:O Ic#9۩@ v\uW&nvSvHJZI!M.-,Ix>&by*r|#ˑ $pJ $+dEsH4|Rcem;K~dOѝٲ77!*4}:J\>p~~k) Ϸ:&;${cݖj#nm9=]ϏX`<ʕ:!gWz3%CJ u*9Kgg{+dg^?*Lwof &a鱹{3ԏ|+}¤_#" d?Eo RW}{ZLNWZ_vl:us5p֖Y@!s)"U77hZ8K_ZEr"Vn8Is55-Z.7 @+l%`{6Gu(((xqT-d8Q`&G'ҘsRPI5fcN s,ptÑ4T1-Lf$VKÎsv&l)8g]pEA.c^/5f-,z HKc15|W$:^p=\"ۉ~2j7N(*E~nx.gj@g oyŤ.ttZ IP~* ۃiqo{&]J/$,850ѷ9?W[v\ͷ=p#PoEYspp!srObU\u)㹜:yKJH|TK%VH\Y% W)·ܠZ/= 8bw)݊]8>  =(;5TouNqb{>~׹Snr;(G{?N4|sl,(Jcc,y)#d*dZ2=6y#nMx#$bFk.=LDzZTDT/Ę:#:6Ny+oӱqst%،{:J%pGGi@/+x WjG#Dw>T#ν5>+LNP'=zR B( BIܬ7=(T쬗H,y>i[T.Y'mxݘGc"gnFUXILۄr@UpȆy7i@MMAVĢ>V΁Pg7 hݴdq'X73 Y 54ghlSc8bgNncl米]L]X ܏ Gb+x q~{tQ+&b89xJ,3buxVlsb  xQ˺80^XBDJVezO{*Eӥ\J8LB<75{؇%b=:UGXLq/T#;&n}'-Z$XF!qĵB&AƗ/()})ߣie=K%Ij/TYYΙWK@ň"kGRLT1bpk9+NѳJ{anvrūŽP?!Z_Q[gm ](ɜ튣z gfaK*Y7Fſkgw~*aAO8XO`ʼ6 7vԫW-o_NVЎhNvLvc5|HFu>?巻N1;Fd],塰<2/!%}uLqr-#Ʌ4{$}0ekƝ 4p`+|L ?PK ^Bw E=>6com/vldocking/swing/docking/CompoundDockingPanel.classXƶ4zab„`Hȸ|t- @*$LJBiz%wCJڔmzPovu|HiF;ޛ޼[~M_0!3P !AS 8݈3HB62)iDt=f4YMx,>?(!-c6 5pOK|F|JS}Z|Fs x-_WVeRǕMcaκV=nUGk"bTd&WD${VYԞx_~@po2tn@]ԎSʁdZ MOM(ġ<`hE38/ֹɬp>bU0d;ق>J\Qi7Y4A=`4jؙؙ +S׻R%Uq0[)ՅHdT\dlJIX&4o|BY ;N[3V:F"(R;.9QJ#vw6fxd-/!3<VTbw_crf4퉦lVQΊ3Zj->3ι%M$2^yU%.I|CИPnAjk1jO;1՟2K{D7. +zĕ3`Ӯol7я2, }p-O3"^x?ďL?\^a}K`?1q9If"9kC*F&㲉7pC&~7M 7 &~H{?L6g1Ͻuu&?kxK`Ӣڟ-Z~&w?fy/n[.J(Gm g@GEA`Caui5!\?YiJ_VLS6dD{IcavU!VYUb̲2ЮdWngtXurcjOV=84d#c#Xb#(m/,}>?XڿI zT yzrwVO65 b!]?e ۊ|;v f 3*:4T=UsW9,^Ihїl(P/'L-oPk(&}> ɶ2(*,55K$oWQ;Y u;vWyJ}~hn}dܝd{]ФJ&&`Zbp^SVƿWl8᥷ dE|=6^\k/B>֍jX@js wUu'fqα+ɼJόSBk *UpG%v Ea= ۋoV=Gaڮ9wph*::V yW\R AQl@  0 WnrD)eGmuE=HǴF ڋm&+0ԒWIBC$ZSW' \ǝ`9ܥe lז`Hr7p77;pl㍍kr^poOaAX0A6b(p]x48SR |u_}8Di{k^O)rS>u5G 0fl/JǸ?{ K<*1.$NH<&qRq <~@@ń Xkh-yQK]_6 8)\/PK ^Bg)ZCcom/vldocking/swing/docking/DefaultDockableContainerFactory$1.classTmOP~V1 L"*JD^bocdoa |*JKn/c ?e< ?FLss=yz=í^bޑqW a s_Ƥ)j?TM@m; ܷy$9c<7kynVoq|h1D cv!:`r^&Vn-L Em#{oݝL٫ݼm9 =ps$9q M+o U\&zN"5IW]!cZFZC$ՋU:Y!?d;r';)7eDWC)Pu&a03B%kџPK ^Bl Acom/vldocking/swing/docking/DefaultDockableContainerFactory.classVRA=.R1\$ Q4 J4lVRb? TIW?ʲg)IJLOo=3WDG?&`u 7u#aJGoyZ.AaVÜnLjHjH㎆jO>p_0mt2:-i C{ɛ aۅ5]ki w\voCƭ/cz|(*e>ۖJ: Mss ckrϬАaЗkM .8hj/HYzJ0+ZJnd8o 7^,MNK53_0k?)`9m9#˿`ߏe<΋^|UyؤĢpNQa2tI 28]l "bCDv 3-dբMw\r$NbaBÅF (7W+I15~'C6jQTE-No۞(w^'huH#F:NI2P9%n)-g{) b]^P4g8J>F/1Ae4[Ah,UK` -uzţZ:GCB_s@Wz4%*?t[I 43)} !Jy@ר2"/;B}}F{)eІ7A.s%tS  A) AABG >up0E4Asag(dJ(4FX>&4 ;W=%X)AZ8.y ypzޢ{wлGJ8Sͥa)2D e9AƔ%23#2^ N&iwC3PK ^Bə22com/vldocking/swing/docking/DetachedDockView.classW{dw';&JPMBj$#hj'ffgMVZV{"HVj[Qk_B?dM Lw܀؄k6|FaLG1 q,8ab ٦`i:28AVVMh #Bs<*𸎫`$/'5uB]κf1S9+G)sޔ bAsLD$ӉtݦٓSҮXiQqKa`2mMYνLD1jgRGwj+gc)8ABtqOws88',aqNe! U1E*E3B!uyM7v@{~_vMZ_b"ћb!6x;{wBDa;Ĭ$ˊ!1dw Ta1XFTa&sQ9I6/zũ%"qJs~5`Ed7!NNx?+~b]fUfuQş\nIz1E-fsq/ 9yx5i)?eˀxw'` ~ew~/?} \2g>lOvMKE /΂ ]KO|&UX}VhKFή9d:^/ZYjZNtXIThQiFJY "yж.P+.=G~LRKPeD}ʬ4_,mR ďۋc~z.[Hk}}70uמ.yˏ>Zb0[}`sp%!;|poaF3 %ʁXGWS)N7c1+Sl7iR6--Y[ҫWRGπg:t2.^hJ&٫h??V3x̰>w"#u(gVD+ϻǤ}xPQ11VVLCt>_lL^uo;'6G/dZLCf&c9յG g~ɞE[|6W*ޏNHzx+Vl΀Pk,Ԍ)B;m坬 7r]B2:'"(j@u}ՙ2wcbp+n+VaDk!pk{jzKa`fZ :|N#YP䴗.VPUAhj צ^ia3+ WŅ$h޹ ݕAO[n} IܹatKe{)^] V8+E?9i&i#I5FMȶ(%E 8W,Lx OxeqEg⮋i#rZOl=Ʒ*^WϿ*vvy8pochP$Q՘0FfRL~B3~s ||4<"r<1MP@RpS9_W @ :yNmJ}i^aΛzTH'>Br{+ɁRpN DaqFϨ|fF`9X38qŗUjiIuhn]Jruz߄-zmW]0L8=8рTKlbqQ%V57*queE0,/3L$ & Q$$d$ !$y$#8 RڪVZjIbݪ]ĵZ[VڽVׯ̛;f9{゚wtMbrs77ps/7qsEnzK}<7qsy1sZ硠ZC?eyzCOyKO/ tӯTGzyC/%/In~롗WF6voh|N#ܠpc4jI%"Uhǒp, -@gFUS8f6ej.XPw{pmk>kG.ζ;g;[)P-{ ;2k!|q74r#آ;x"~U$Zc1v#ɖh<9H䂩5Eᔵ'$p @mXSmp*›FXjC">j$R&> t*ml';ã M7xidzRᔱ(2X%BAhUX%Ly Ve?`VŨ鱞h<,0wocF钱a!e:5Vk[ڋoWtDbFWzH6 '"fZΈQؚSltb]-TZw! ]C;ba+m5 pG$2bmq]8H DOYXF c$(d=d̮[>,`V{!ԱHH_|.|ϛ̒rģdY@d*d2COeB9@$$Zc4a &'?UA0SR5:{;ڙZYwHs__U^u[Xmd* [Y/NXnFʩ,F-6 (8?&mUaSUW*f%tJs'zSu"i7mGˏgen1۬e8y즿9<".{=x}ڜDEHt+t;9(2n7(y9ADƖ/zK[xbMok}WQ7q? I.i_:R] xBwu 1eӤ@ _^O.EVe jKwQ9[Ϣϔӓ𣻖jdj"N1_5Y1?-k0@Hd͏<5_ys|-Y󅘯͚(b&uo=Q:D%}H`s1ѣ,z3˸`_N(hav%91"Z$n8q*Gn6N~*'* }fFt9݀2 e.EiIZBcnMÐM3Z3K0V_i$͜_O jSRU8xAw5xGyx<+#NL|=d)l>q98yC/dzj&x%2/UZ*JkUX{ ^/`-ڇ; c>Z#+ w@]PO^FQX k>amʚVBhqf.V,5lVik`m6)`5oo1؎a6Oq P>&jY\~o+\U\1 ؘe'DWtrIt)K6o|"%{mDV(|>8Ȓ-f2com/vldocking/swing/docking/DockTabbedPane$1.classT OA^{,RKJk; h ww|Q$q8HvggovvvR  Fc8 ]F 9Ii\7U0!T2nCH$ &L1(pVRū[UojfrdH붟c9,tMٮc.Z{!L3+w_l ՀOiA?j*.)2\1zMHdڿCėI@D 1ma -  *#ÍkqQR PK ^B\4com/vldocking/swing/docking/DockTabbedPane$2$1.classRn@=X& - o(4@VM@lBAH*@ݏ# +T@bQ3Nt->Ϝ{w@]8Ԁ.9`Mu8 @{bJ2 l?$|~?CW2T+޾GW@mDJ`iz6=TJH( e'SmEf;.U;`tj({2z-q־Ic8HT$p7=4pCs:[ZT?L?UGSc,C,МD<<&̔ɋ/6˕.?OL:9'UMUE< js+XbE.}q/7T>ӔubX vcjk~Eu∬*R|$ŧH *s8O]# B{7PK ^B_ D 2com/vldocking/swing/docking/DockTabbedPane$2.classVKSWzhZ0#GD8:q(yt=$FҨ1Iʬؚd4I*6 l\J#(Nǹ|{nOwlhDU/8 x␂n$_a!W8*VqL xUAEsB 񚘼. ѿ)-x[T!㤌a# A۶45\ ވ6m);cvQ}0a?RFf;i˴MoXt1̓BNڐ4aFn,ed`QRptԲ!APB"4m!LYo{D .8Xl7vdjoް=\n9ѥ{cKM&)eOKumAZO%C*i%Ǵ'mT 9r"Xe2,qF%l]4}OfJPN.Msc.zm(BވaX *6┌Q'†-WiY2<9G@8&TL& 8=)D972U R*>EbRC쒌*>\cyfFg*r.qéSIXI0]`I^Qq].J6 x͉̘Kѝ8s ʍ9b1X}yᲜmfAZ\a sih/=.{Dȍ QXhwU-2+NPu oF`F,h iN߄ "e<xsb~.L%uA1̲Xt_u'3)a;\h|a/aJ. r1vbΕO7)cvc6v k X/L,GG uIL^AIbIc|qUKebվ+J+Wu/q7}|- wUWVJ o}(́(vl \y:ގ\E9*L=EX]G@ƌ(fub'%,E _{(|2^*?^Z3 ؇) 4_MY#_} PK ^Bl2com/vldocking/swing/docking/DockTabbedPane$3.classVYSP.[$]J[*DPq(*?WڤӤf|GQq|/9xn(3jSvrsnr}| 1ܮFB*TF.DuTEr[>< P58$N)Vpʽ+@/C$aڙr:eKZ:9yXX)wZX= ggO_gxt)aFz 9/\[iq8])7p$k;`➱lDn/sˍ&4=P;Rz < bQO sINGPDŽnu9=Re0niۡ$w)g44ᬆ4*8ܠIuRkOԢEv^Eu;/8<#9W+d6 'humX~oJʆM ]H>ܼ%"#%!BMBfqǶ9\b#fmK0vYAIqgɵ~^:6}JA2com/vldocking/swing/docking/DockTabbedPane$4.classTnP=7uMhHi$nS ERPnĭkW/,D`C ~!fwAdi|f<Ό׻6RXat9",dH\qMGEGU@?cMZw))GW)]2I`uW %kz08>9xdovee=1~ÓaRny(a$#IR'( TCGtqU ̄SvxH;0 }[wYYXS,} Bʿ^0 aՀYYXu5X꘡5Iy.dyz#ſrHѨ/"Uxb8ڴm:mD[|™yq`g/1-N/A.M yte9:"-9suaALO|R}t$N 3䓎W^1lq"GzJv}'N>6Cz92:6ǭA[Dʬn P)5ǒ4;TWyCQ_)wwb }aL`G2鄞 9ac* ybJ:G#dtPc՗RPd/Ѱ6࿭cˀJȀUyL[Ste3s̐@$ċ}}"u,00~1YAov Cwmܾ$KdcX:Ưp)g,FAPK ^BH 8P2com/vldocking/swing/docking/DockTabbedPane$7.classSn@=cq:)ЄnTbM)R Aݱأ֭3S "(1v{ϙ;o߿|p;KhwXwAW666KRQ2C#?8TAD*< {o)|:=e?a)m2XC 8E12UȓCگfw$H 2A994'9OYLTyg2LTFE~".w MBb> u $6_NODH^R"[V*f:\ԯnaH7T̫k2ODB"H:&ft`zq&Z&!&v}taa~= JvMe+ }Xۼl >0ޣ5-vZґ ,fչ-BFV.IڢPzPK ^B~2'_0com/vldocking/swing/docking/DockTabbedPane.class{|TU9̛L^* 80I"&UB ,E@TFB&f&ӵa/뺮( *$(ZuWֶ)s{fL ss={j^k ui\\Wqnb7k$Rl6dFoA&[ A../wx򭗻Շw=2ͽRl3p vyAOAF)v^-A>G^|‹Oz){&||^d/Ji8_"?k>^˷7/R{Sjߤ{T`mi{G^5=/il҇_kFjI[Ծ7/Pg}ߋL B~'b H11%58 ѠN<{Lˀ2j@j]p7uӠ#KzKs5@(_jZ$KQ4P4$ 6P)IqP0\^IhcP6Fy5%hvx)&H1QIRL68KS(b4Ot!E4SfI+f㣹4OZgV|Q:At^:ti*K!y./bAa!)4ʠUU#YV]PFCQh6:>T GMD"X:v|."dHH]u%ț~Jpup`pMlPY^774Ռ V tI\x\ VGUY\uUq ʸgMmhu8Rb %/ɬDC*bL{&P"up)A1mNxyu0VW[uH֍l51  .."=*kաS,YUD +#e_WECU{HDк +XBјHB/kKCY,CXN<3*\APGpMTYYV- εPɝ`芭G" "&gVU"*$kΘ Vdh}<&KUx wa _f4" >O_1Z16b"ި-:6Sْn"v-g򉫟 ى12> $90V;4dېD %iRZpY,T+?qXa1h&sǥuJYxMiH SF4K ZXCkr j&f];OmLUn&GIrd9U,jx"6>R[ڋJ3C*SUэFk±C 9voeڨr %DrRʶڴöEjǶG/66QC("'Aٓu-Cei6*ڼ<,jX68 WHZs²6#[RfmhUdu(6AH*8trjaVTZN"sbҷ`B箌f—`x _78Ą1 94 4,<ݤ_lIg9O'q$XŮ I<)5\:}pt>7Фb.K04 t]nt%c6hҤH)FךttެS]u<^s}Y٫gb&jNM]IL9`utIԤh{)S[ tI72pIЭ&FLmT/ۥv]XjV{LWZ!c6gUIk+B5V+\:XcYG4[g`R#|ϹID<AmCIУ&=IOГ=e3IL<5?LUʣ OвÔyޤEv]ZҤ?欈pVԆmtK%dָ)l+HL3^Aq<21/I1Bɷ!83ޡwM<Yޣ[YA8߷cښORo1>E>4#ؤOS>M\ M<ʤ&}MbVLx w.p61mxatۖoNm2C 3{'~FEt-,uR!S{,pIf-žS9V?S_yU|*P2U29K$$<q'pCڞ2&.&A&/Pu0U7UGFuRGʯ:m>jnz\kI{huz</ĒM`V} TBC =JĖUfhSI&ɪUܿ%9("a/$(0T(Z7}q59h 0m|pvP9hD.)" inBQ;R~>mC(iW^ALV@gmHh"+sNrM doṿwkL|U(KJ5]?-lŰBju6!-ˢ2,+: ?f"]TaYяs~m؜i;| qXbE)e'N*[mG(c9'ɐMfPM6_h8|ޱj&Aw.]5. ]Y-LeZfqO&oY۹[bT;ōj KmuJV4Ø=qgͺ9_KYfO*x'M\Ґ03ua*\Ni j{Ki,^b bU4`Hrr.lt.3`"FLXW!]WE9P+/>O2),pmNFY4KW M2ecݡ$˪ZoLX%E Ԅ9,IѢf4XW+;9eձXdJhmֆEFAĴ+ͷz$_;Fslӡ'?kp&dAgxo_Ϸ|t ~ >ϏcD?I0u } _q+kF?1sNN0v/@;!] 31s'dJNz;NGj΁. Ѕȷ -.3 ~r2py+Vi+Ȅ  ` B%p,-pRIX O9LJGky3(}Lx;P($2,g˻f<}K%~ - "]+Z 200PXp o̾ { ţE GEc 8i,X0P,cQc `**]C./^?У/5ᐦD}0@i]‡6-~ϝ\,R ,j(hBܒ`BQ[#?:ؓ͢Űg ::Bx~ ϊ0l@eNJrwB.w/ @Q#ЌgptF\D7ѥ.5;-p5J7@k7\XFэ0?ύ5< M>O>N⏥-.7`B-PX lO=~Y~=tO"2vôaƣֺ<]e ?߽ "nxrWqJZ:Jl+<ÿ 0/!@ 8>$]7 aq:i*5YRf`&LtM`'h#C. v;|=[;cc,Ɓ8p.'QZtNdp1;0~#`jQi_m5]o/cp3nGcG#1G0FqEK-0&dڜ1]-E`k8ԥٱ`m)֢wpÆ#l`K #!GA q,}w,@bBE]I,GKuC f0 &vWQ-d>PJ.XXNhE%"F8i0jũ 3厢3 tF]hOgyc3 ]l/^?='#uz@V`Qq/*]PY]Lo۱nW ۱nǂEnewbRNzT~FX) mU aWk{y3t FǠz4*G׳LVV(۩%ƿ..#9,'@\aRXCP`5,\ * Y"p?z!_ SS,z;Asu wXC!auصh e/,f?66V~รH50/f$ɛj`Br-6Gq|mM9'Nx6v8|\;g;-u_ap<R :k;5eggS?k;>5`$mJ~~V@QAogMi?͚f~}in曖E9&o qe3Z{ɶ<[CGj41[.| .*gj55&Σ\_l\/uoL4k;?c'\gmfdu(͖shi?i- W,d2^gs9f#bd #(Xثan|MuIK5JHy&!S_/ok5'af aBp/r#$}Ǎpf4mɀ l625 g;αu:$w粄,qXpvG4a`&`Bn %-Y!R\*i7읯 wx-DzA!&71x9`o9; ne}7@ˆ{;l+qlp >[a xgix :o ?q៱.M싯p0GX|8aF< ?c5~x~7x~;x~/ Gk< MH9D  ෣Kc)I'PUSR]Lzӭԅ PIP/zzӏG)2FHꯊH 54D-j1 S!:JUFJU4RMv ^I)jMuyi+fٮ4UJ]#ױ5NtM]صT)c {0F38#-d ιZSux2kx3om?9&7q7C9p#\G25^`S mx*h𜆗bg.rzة媫 t-1+>kQA(`kvn8'DvWWth,{8 {]]yl>Q8F:=q`OuX&+q9{8߯ue^a4u`=% :hueA\0k8| qL]{`:w9r6_Y%@ϓ0M0 :`aYy\S#f {%JmaApKJ6/l[J Y p~+oҬ7.b.uVX[l}d xg wKsq|Vy$ްj[ %N[Sϱu|pI&`ꬻ%85iMgAR,پpe;[[HvQbMמlA&mZpHLhx)fF+a0UAT 9TTj6^5!qM#tEgt&N~'ٸ\LN:,]o҅]mRʥM] BW" E*ZOe \ΗAta9f][VqKYE]@W:>x`T^x3:=Lf:VLe:x N=[pwIr[*wMaw:OlBɬ}=sC_@ p4} ;O?t f~XBJ+Wlo ئ2FxK{*>T u|H3fU]HuÑ;T=qꅕ/TEx*`2z%3dvJ xND;׬IjV$Iz=SdIܰjIy~aѓtXVYc nJGu YJ‘"u($B]uu+cpSlA ;9Gr>H ȫ(NoVM o.()j'\gc9ˉY ]d^v5^N|Ǎ4iiH/)~-6B &(T76[`,i.c竻du6Vm;GN WHQs'4X+uh2('\k\,8̜՛7l8$r- WL;EcH 3 'mv%vv2<z:Gٶ<gZZ. SNɪ r6mY=YvY96iCzڋK$}sFƾmʘbƤȡr]pcP37@#GܕyzcĿSMOÂమ}ecci/3?՞/r.Ql8f |2ԻlOL5^lNk0a͓ڇ2Mz#R[2၅KcM<$GE}xU}IP!#63>e a0W蜮ӾFè9 g͑~!ƌ <+;^ٵFaΐ% . tmn~\/v/n<%9}L@'4|pL0AuÃ!iPgh%K|E%=qa-1qߕ nW\IڕnOW6y6({XO>O3r-9w!y7 ۜ 㚔a庎.>MxKC?jHdx[RBO\f4*n-cWʖ]R-;O7- LEޤ[ z,Y3d.%mft <8Kڦ tw,y|s0 v F.Nq0g3LI~Haw4QZ4r MoMY9Lydw :0 _g^ Ua|[`٬QqF"QY>w~-5xT7m꺓X%cEӮnQ/ƁP +plS-m2 KIRlb@"Hwɒ6vSdQf]e$md*n;تYO<G/֡(\]3 D9JC Ah,QW,9zl/;yti 豝+Z' ch[,a&DhM_"`otR:se~&RJ~=ʃ ,|;@L )r M4qRFܣ"Bq+eF,;x@MQ/CGYeT+Hj(?;*1LK)kUF/PK ^Btջ("*com/vldocking/swing/docking/DockView.classX |\u2ɼK&i˴iiiiI" MLdLTEwuuZv(B'-DQ*^x*x"G{5M?{'_}iLAVaRAVqgyxH ?>!xDN>)ä >-g)cx<Σ PQ 7pc_&K 2L 4tGh2rOGḙ:;3 =ňJH$/N r ӵ8)e2X߈>ƈ*L 9]Lf3AXm z"ˀF*scat@Lƿ5eABaG2t!#o^ѝ=|7 3#Ė̬ƛDG\IZ[ڗ#Gz1SPɖJLs55^$F d; N1㈕cdHs$:S:n[AcHdL!|LƞIy ].׍^Z5HQv1ߗc`r``vԦ0NqcS'J%YuuPlVGy.%L2ZVldOn1ē&8rTe3RԴ(9rVMXx,1wrۑLET ʅB+X[.Uh%X<*Еa \k9% ,[gq=bnOaFxζƋ WVg*OL'" " <$iEBK"FWLDiA4%,rحKg4Vi80 ^(xi͜&SV o1.h-pqP-BQn3ƶ*Bz’ymܫ j9+VjTO 5@b;@wgh6+E+I+5jD4jAzhvӨL[y.\!#Gn32:”mm"mt5'a"VݮoiV:hB. v5M7^G$-t ,=}{pXk58P Κtœ:Zըh@A灉ߠa  I5܋6a,mpGB:: 4iH Q15}5Ν -ϟtt)E9~C'|@vwkNjC BG4ӨF <*y U[[ݽzˆs=n&$ܾzꑒMQ= ry5.讂b%=sA4QѨH%R=]ݾ,qsWN91]1653 ip>:>{=Yݦt~}lHJ5vJe{cy(| :MJs)620ap]q1~;븠X=s&w;_Z-=Ԕ!v\-jča/fIzy\`ݤ'MH,-ڝ_sm}8õZ Z+Y9s9CC"Lt^-<: }*1yuޞ6V3_ \_"dF|rDr'nְPt4v?bĆG8X.cXq=ahwue_n"w/0fg KnvXMNI\qSQ'ӆn]/Yq7R rŜ$B EÏPBvyV Qw6[.=9΢cN@NѯX8܈ :CExmF<y^(姝f&o[Ƹ1ë(C)IL eQx Er PAUgoq1G(A;*уKs-]͢E~el]]_)12eP;&ڦ$3яLiY̜,J!|с7Ժzf\ilLfo`AͧM L1h h*At77dcɷ8w6BuP;ܧvg-Yl+WL2K^wX;q '.opT`xIVQ`qŒ,. Hbi˦o.ڡYoWQ=^Agz5J/yyTscLKIQR—_+$;=+w2B"滏}}f˛]u]V߅ҺG*N@,χ kg=c*l{f*{Pk)dKzSTtMh>MES#0eoh;r9[JTNc8(-`FR좻EemuSؼ{oWddweס{RcNeh2lI\R`ڞE]X(jG'*TEg PP;.|} y|£b3gp9Z|IlІ/b'̡5_ 9ZDCq#9܃q9/gb*W"x%2*9*'THTD5&ROtPOJhbor6a鮈b kC3gq }$<^r''@5?r)&|3U"=<{GfJ<@1+'BCmf^A ?܏WN+VɺY??^cѫ9,L$ y/>dn{9cSbi\Ӷ7BxW^NbwK`[obaMn2T ?._1Y3ׁ8c 3 X,>3\C+xQG%t#*uܮR!h^c ^sq{q{Zp:+](]XJpZ c F;A]pSwmT9rZ}.[nIݒ%%>DМO!3r֨4ZD]{ ׺dtdel{xq<`q,>4nb)+;4d6+Z4-~ 33٠ɟ8m-PK ^B#f1com/vldocking/swing/docking/DockViewAsTab$1.classTn@=P.$SXDIZqԱwJx(:"fvf̜oV6aNP5I5q I} ^vR;"1#CAdwxNaѾ+J:KoMa(ا&zѓ o;}\;rnр' S>QCdϜ9EwXQēv ɳ8&9jQ"&/^maNqT|#4dGu`qB* D~ b˃xhfa g-,nu p 4-l -3*G3Tk dBS1\=Icš34t'EєTtĶ WH -^!;NqޛA/%AnRנi%]?A='yIpS, kd{d+Tv vR'ȝ + 淼y+Xuʗ F-9o(ǜ PK ^B1com/vldocking/swing/docking/DockViewAsTab$2.classSn1=IlPQ.6)<AHE)B*Pî-7WH\$> 1\B>x.>3>g=WњG 5j V q(S~K'6: ExOG@fGfP uxp-|OPIXOfNf)k"N܊1Qz'V | XE\ygGۛA۟Qx@ ^ ^ \aXq\y.Um}BWP[nU{Xs5qmpMPK ^B!N$n1com/vldocking/swing/docking/DockViewAsTab$3.classTms@~(Z,j}A 6( Ա3U>-Ɔ;˙ZgG9%6:Bang/h np-qǀmP<cn=eXnH*/R=/%cȫ@V /F$ jc! %_ymrDz>_7У=vǐkgX1yLؐ,]S)D1 3k7x=)9Y6'RiR ÆN%b~K6M'q,,.$YE\"5 gQ(*;G`Gju\K $埁X gjr~hN_PK ^B|L^B$n1com/vldocking/swing/docking/DockViewAsTab$4.classTn@=1q\P.K@y+ !YZS MB*Ev DR?Ξ3sƳ_}`qÆ\G&smܱZ2vEi3' -)#P!C^dw|9Fa_A穱?VmoAA :o{!]Fːkɾ`Xx>DLؐ<S) ę3iE"n\)AمTS æI$R}M?x +nc퉑@<)]9}$!h)VRgB˾yvVtpi'(ad96{JTh:s(s;i:Ccj3hlh5=3mV P%v(&'Q$jYta2X)ɪX*$sPJsfhX5>!!-x2 ".Y< BTvvcWP;h>-pg2qfq5PM@5|PK ^B^x1com/vldocking/swing/docking/DockViewAsTab$5.classUsU.m6 /A,VLР PZ)lK51(>lf7nꋯ:+S3<0<71ޤ36Vr{wsvi/v o`'xo7Ї#ÄDj8fmIiN|W 9=?㴎ig4h>COF#T 8W\)u}w%W"i&>5"qVKҝ(Gg^V|խ_vٗ.ʗ3Gm7 C/aJf{I%;Z ݞlq=idiUyK&6U,*5.K͂X)q7&Gnp$V|"l^^Gm d ^⋭)UҲ?e2}vk ,L߶-ۃW KK>}-h+ j*>0 c.eYM$na}!P{5\Yrnp5aJ59+IXRߊߺ9mж]AFEv"goHS|~ |_5~%&~-oKi%D[$i$Sw$T$g8atxeYt&$=?دĦ)Py'PK ^B-s.1com/vldocking/swing/docking/DockViewAsTab$6.classT[OA-,lֈ"U{Z^ I1Dߖlw7c%&X/̴Vm6;{Ι9e/_\@q:&tDqJG u\FFFG9qN&5Li3*0ʖ川lwSEu5scm3L{ˬ3DJʶo7jܣ,ɲLglI ƒr䘾2=lj5yɱ-^aKf |A~Y/HQd>j`Z[fMq"H17gE[) C%Yp-G`@@1m`4\6pW5knnR3{(4p!u,pZneTyP Cf>k#^[ Q:&cJNgny5Kpa)\O+9{A4q_F}ͳUY15ܴ,T@kkh$+H )BoCtI$ DgszGZh3S$i5 e4Ƒva"D b]&"/lI}Є&#Ub xNKżR(íHm)(*ޡdcm!aNkhxC݃`$`da v Dc'?2qZ$(PK ^Bi1com/vldocking/swing/docking/DockViewAsTab$7.class[OA-b/@EP( && }m]MwJ?eg =bfz*u9BmvWRƟUUG2i gKʍvM4xu6n} ՞@Ҳ/`M+$SK?ݫBYᇫ({-ϕn(0jVY;V K˹-آ zPڮre.7 J -*ff'~^$oČt>! sKپjICDvbMQud(F d``KI 7 -Z`B~E3Q岇 NqSRFݍ_ s- +0TX{ ,4w33 H5&x.#QV3N"A1jg=_x?1E G16TzqBbdN #`^ ]U:;niVJ?D #SYAkˡƒƦpKy~C"Ͻ~GENDf8p9›+mE?PK ^B6/com/vldocking/swing/docking/DockViewAsTab.classxTerOy/G{!$lHB (! %y$+ݸXN穧"ݜ 4,w޽޾n 3O_{`%\,bù< nTpM^Zp <\,<.7v@9̅F[ovrQh79rѦρ~l1*U 1Pq3-*neMc OPw'r$.+xf=(xi*v\grG.l.QOx.?Xdx!7bK:2œ/ n^j.kM_qq7x3oeܻyކ.*v3ܾC;U}7UW}?\<(b0>GsDmI=ŵxFgXϫU|*| T|]7T|SŷT|[wT|WT|_T?e>Ss/_9Jo*8*<ĺ#3̵_S@b^U"UiD\Ba"CfBST E VEB35^W0h2]f#08h<.J#}+jp€/rB+]# YayG6*._KeC(T1K7Ys.,P_nM혿xiuȬnlYh2^Шs}J[+[H%16VOXkNfz#f{YBf \Vk n[f//cr&HJ:Hb,EY8]>W 㘕`4|FFY_F6W@dfTH_oȔvE!/e8bnn=pgXHq%b%4U8K4q8{'+g9ŝl Q+hT*H&V&Mk)O> 98g2+z\iZm𴛙[Q6RjuX/{fԨu,)DKe,%jȤQ)KxCyV􈭰qD(I Gjip pkXɖ5 R.b'I<{8ن!6R&$99@--ZhMl$CxE&|¯vq&": ]QKr0oUl[L p2uhyƜU &U HhrJyȳKβBK>*C/38 fPWyS=ӉgP踁 i}!GhV̛ݘ>@ L-O>1h F]n+/M%}y}q*(֓=Gz+g`]^EgFvk Gnѕ?,TokdL+F%xYfK}Sa-v2'--qq[-ζ\l,8#/ !\ˡy u涢]j:;쉵J[&!mh\^Ceg3l%y p&ߘb !Ҷ;|52e=m=Ca/>FP"K\6A`"gnROcdb)}$h>8_=:o޽@+2O"_&. %Wx:Y+(s*v&uKy[|yƥ{ºyK2".k͸f> oJ0$;efkND˭,Z'I8H#> OtJLM͠A^Ÿr[o%%kl"I_q6N C-%k]F^v{ 2gHdI0 P y0IV&)MnӜөcw3^Y]0ɻ á\0!To.jW, ü,T?R00K`$fZ#aZ ~8XN$aL&| <IFtHew Hx Gx<$S8 Af"T# L37Hɂ?X `A;`!Ba13ua_)&:ðr:!K;!NH`>|fZnC027- w@6 7@cnZ00{I+* %qrJF!, \HXOn$@no-9Qrnr+I8rɕN'7:\rkeo1%T̠ݦ vf+ͳP$8p !꯰P! f)BQ~ M'gc)u*(ޚwÚ,뵹a8Nבϓ|~:9t>sY8UcއQXCYN2K})GTYL(đXrG* VR`<#˜{`XO~ w74Xu 4TiQ6#XH6k-+D ת{z㉖x&e6ݫ%f3 XRR +pp +m>W|JAʀ2byLeZH9'YB |Ӝvk14ЃsB֜G Ao'i0 8`6TL%YNф dyA5[;-9< BJ%R 21cƐlmu[t&sBe–dXL*G**QMGU b@>±FͫI. R°UQB:;V`ԡ8E&1I"HlG[Ep vYx;[%*u H:PR;!5FJ:c0Y3TPG_;--$LS9Dp^ϐ?-" Qɳ$ XY"QP`lahfOC?r<:dغ/of۴VXr-27Ǒ%JL#O6\!xE,|[7KYK'[ΞvqO UO7F&Š#FB}a -UwthHkHD̂K], oî*(rp9W0iSHr\59nংis,m`QD0&C4+I'OMx8J/uX"4]'3b[J%]9WkߗioǾҥR#mݧMkQ&]N~!=tqAR*% $J4]}Fi|'HYql8 f+p~ю>! Pdh9T]xFsAPZ(R)ꎤ$G~BNrz$\~m=PC:HIb΄xMo  X>K K'PK ^B}O6com/vldocking/swing/docking/DockViewTitleBar$3$1.classU]SP=V"!@E@EPmA( B-e*6$ **3qFݛ ~ޓ{o_` nhBe$'_MT)id$ J%6Cn8є!0(9v9wԼnۥoӤ#Лu;ˆ[S͌a8C&ts|!%oVePHkҵҊfa!I mtװEn?2/2\7m-IM79Sר ]JghZr5}sAxb% {ma-[糆(Wy͘zr[Ew0gaL] S0)YL+0+>(aN¼<8!X(QaTv0 { C :CsŶ*vgI3?L'xb/J%Ptֲq*N H$XǐRА;R'Ӗ2m?[fZdl f}N9,us<2.bD^Dg]]/ _!L#~Ȕ/;5R=4 q!O%HI>@|<>a('*-nG#NK!pEUo'zMaSVZ)ATPK ^B[a? 4com/vldocking/swing/docking/DockViewTitleBar$3.classVSU- ll)@j/M J lnaaMw/Z}鳯>?@o;)i>t]PɘL{9{}=xVQ *8"RP BsVưF0&c\,_/Es,# bbRy(hū Z0%9zMN 2ސ jڲ3bj\ u|pRz3,E[_2*ny na$3e! }\y $ˮ, &i[̼b(TUydCɱKG4kBu2ZYKf;N><Ý$H#P[j~Ԥw⚾4z){ٸ!kٍW!z,ݴ] 2]Nt89oxZݶTh(QTpQB& *`am U"T s6QR%EC׸a3MۮdGĨ`( q N`?g,3ҥk`WXAY*T q器wit"ӹQjѡ&3yPs,ձK+IAK,8:sݮ)G+3\F+0,[kCȂ4,zwȱ5`a8FQ㔼AӰ匒 DBp(m>N >FRE QFg,ק$mO 9[~[p%䫄ڽ+r!.K m_J2o:F~Z]mxx}I?Nz];g8 JvV7PK ^B W4-4com/vldocking/swing/docking/DockViewTitleBar$4.classSnP㸶\B[RP$$\D( 8G[FG<BQ=MA/'6"R5A!Ȳ7EbE*c9rBWl ݮo9ށxJ˛rVo2hl C,k3EfZB̐Jm?>J-RZ u9{rCi*lQÐhGx̉Ϭ /쨅g~PaȨ鸃u븋1,o"l"ϐ*-Vڋ<]}\sa<*vom6r~f5JQ+OA,7:' xy/ ѩ U*U#2՛L!RЙ٦](ǐz*pҔSL13F;cTYz硽T1ρiTMۑR%5Y=]PK ^BFvW Ccom/vldocking/swing/docking/DockViewTitleBar$FocusHighlighter.classVOU2 [\ڵE.vіZ[r[ogw0eZ5hcXF1&Z>a|4>oFc Vsw}~؅.>48wc{d4*IF\"} 〳 MFȸWFNH֯i±9On F2κp:D{\&ͺrBq)j4M1кF/ibfRҝI u9D/f95Ӑr8|z~ Il#:[q4P>gLU]E[ȗW7 _߈r'1\7F)(MCi=5#xdsiA3oYl z! ȗHO ^f5;^W2Ul,k>u<<|A/*%w7(x#ILܻ{_-Vnx;5~q7ߴ6{90ߎ#؋n.bnFxE{ D{p07(:1|<|ҁ)nsOv 7;>~ğ/+c&^' g~ƃ9_/bkn~+ܼʄ5~+G<V/ _o܂y׎?O;ׂ>O(:C=>ւ4҂^o ywnBm Ca?2A[miھ뜆fg˹!Oz=+&-mۚn9ӴarS ;ݭVyCaoôȈ @(׊fZ5 +54A{yκӷICZL}gdOƖԗM=4<ˆANJbpS5(UX%WI2Hcroj6C0ʈ_~b2 6)!ԧ%-^XZ tіw5BFv~UɆM]cNM{0f漂Ãv iʄfluO|ZCLgb >gA;)Ɣ>٫u _Z27sW$w)? BA:s$vLwFsxԎ'9_Ӆ q˫Jy,k/Tcc~& %0,h%U7ef3B'Bݩö%IJD"+ٻ(Þ UΟ?af(̏QY02Xh,y}ҍ-Q.1qr9ߊ b 3q2QEi.ah#pNA\O;F`X8N2ļo ;|hAh>qg}m` 8-‹ ? ?sxY*V,gUJIj_o* <»;νs){߃'W=X ~?T9x*XTkw֙;~Go ?w"~/I AIEDr3}Փ*l"SY®¯* P EdSQCP"I>T(-ihm*PE*Uc* '"ըUdB '0cf )yVEg𰚫íiI1QLxX.HUbaɧ4UT骘%v1SbmsTQv1W.QM1&01Y7HǤSQ8S5b7T=Q3 u:eB*T1_P.I[(^Sq>7,F,KPRr6 .Vb5ϬfhP!R;pJ_7Ī1U Ze8IMYGle}!zYyUY me#a8<hj&o˶fj)5_h{C^nc'96{^NfUߣ[}w v;6yH2llG8L,;^7__̧%yC۲)]dOgۻҿo{D1Y. O #*ϒ#-;_7I;ĥNOT>iʨV$G$sz4͓a|5jw2^Um7]inKĮ L}`WZTZyH{ohP2pH>$YX!FsM> =1l̗Z;u@72e?ai)B''haI@Gg/39ByDfΩg8tB-M.Z$J}lĄ;76nw,_S (o·J2nx2^GﳌhL7 O⫃ 2w 1|LB!>OJx܀O{[?J <+Ꮜy  /H?g?%^Wk_*oj_Q=@ G!{MԾ zlS &q_uB #D`0t@!â(fX2]Ǡt-(Ipʹ'\Ga Lei#PAܟ13]tYMh8)pΉ@4W;]zgZпIaX8֝qPNx Ep.L>@Ű .!g6en@?|C!\ed&pfāQ̂Ϡ/^<% Hhnf5'IJh ca$IޛxeqMkY?uD@9e ~Ϯ>94,VKUKMaXv7mqE?=J-:d(YK}H %tWt9WdP5ldl4@'cRb0Ȅi&>Z;|͘!aU!x=W #7%Fa v q 1D[y <M@!0qXlS>{agb.gC-dN@-{mpA 2;y.:!ȡ!WWfuN-)iDyg83 F2& 0o"¢8%%<#Kd8sA,|8a7R%J<.> #c?. с޸V=3K7HgږG補f^6D`uG`hurVCeȖض,\AmCPC>1a ~6/@7(UtlJllQ$d>RYR-TѱtA5)R=ʥD;Z#C; g3ֻaqj.5B6ۖlǡ2!Ӷz Z#%]b!sW!_#_pG"yހe& +t`|:=IIePX6 O>F7ڏ2^,èy*81{2B)5Nq:u<;)ErC8^9y:BŠVTǟ*Be89L*?]5YUUFWeA*J2LYऐYNTl#r$:e(.,*M)4!{SgiXAF΁i8gluq&_ISO mHFo:bK#[{e e0&;7vWM@<h} AGl-?*ve6(>Y\7 E 쪉 [rb*QA(-b"tR)&Q{T3aHT%b\!f5 n.UTaQGD騼Ql*B^<*|C"G DP>vcYv]Jx-A[85 0D< G||GBf`SLH(; ft: ~3 Y7E:8/NM߀6Xb9+aXbESCL-'Ϫ?:HbMAZ>ir0|$ ʥjQV(&ٺf<:hC@hzܰClhD+|IYr7 .l'`y͌3. ͝0vҕWU&)Pm=i{vZ[bBuOn9EEtKL[:!m=)iXڸfqMthM}Lc 1%& j]T\#M{h[z-DsL9&ѥfs| 4I .&_tM4( d`@tm%2xU9-^r#kR.NoZlHc:l4/9(S6B_-{MN3]ГJO 1qxygwUkTMTtlI!pZR$;BFv4 t)յ~m{G@LՔ U.)5bLo6lOڋc j/^ vG$@yQ}$t~^˝_R%p}p p(& ?;o3ίHx1j[A5ywMf>lRAc'T.g,XK7p6ls^^xj< .$ (NT},^[_PK ^BI^*com/vldocking/swing/docking/Dockable.class@R$N@=8:O] WsJ 03`C!&ĩK#ku%Ɠ4ޡL}9b SMJK`.*Em;/ޙIU"j]/Z8Mr%mD B&"Gs^PK ^BQ:com/vldocking/swing/docking/DockableActionCustomizer.classRMA}8.j9՘`֬z0Ah23tq`̀Dc2V7GLUwuWRE%evL\5qpS {C`;h?ߕE@#¶ p#ߔٓ(j~[u]GMUP@ꊣ`2z/C½wCzXX5x7VFMkCh^a\CSÃ3NTn+."lGGXl1pd%%-~$(bbv0򑺆%h 3+HUx\ovX"g! B&aH8ȪI/?LWMs+?@;_5b[`">]Osxgp6|ȿbSN>0U9<ֵdV]،ɪY /sk&׺K1xO+[ܥa[Ͱ1ʚHJcKB!ƼgBy!1Bs/PK ^B`R3com/vldocking/swing/docking/DockableContainer.class;o>c.vvNF̼Ĝ̼tF} \~q9\RK 5J /-JNuIed '&:$fe%%22E"6DRVjr ##0020300iV a3PK ^Bq2%tEcom/vldocking/swing/docking/DockableContainerFactory$ParentType.classTOp~ʺ+6o( 6l -Ů5]!񏒑he_  ==w]o(xLIi 3z1]}XƼ! "b 3/ZnXQ7 EZqjk؞ lplM4{ֶ2t ?ey4x+9񠡚[^.6Պ+UbADKYBQiT)T78cZQE4,$SQ;۴Ğ2eTZ-Ut/8%˻ڞ4x.Ϥ.u5k]sMma-ii"- E:&&;\JխV#{QI8-W7VL6ĕYkQHxG d"+&ӇACĘcN9u˱I`2ub%խ]CHp2ssZLfiN{/2K   0`a0[ebaޣwѫ cI >?pZ8,+1݀019r?n1Cx-M.z:xHt.NP:FRѥ#m(~ 0 ta6Mg0O*BNbmX<_J|PK ^B:com/vldocking/swing/docking/DockableContainerFactory.classUkOA= m!""H}aS F>H.,d;g $e3-Biz9__Ĕ(10f"12w"7тD&"`.P%9a㥒(1DV-p~6;,=͐EO_r2CcwSӑfQUЕ l-U!߻D ÇxCRb?|LjX<-]O T'Fkl.ψP$_/ ďX T3^%e*];<2|u]{u! N'0W K(T&d?loKno[m}٨UX>mqrqvtXI ݸhBCbo{,i3t8%ׅ-v2,L/ +\a%=+Lf|!z8J6d;SKA%&'ka .J.(mРLb=4}A?`8+I =>\+jZ\E0 tuܨrI{0~Z3 vo9(RCͰNE r7<>1=~]~ 9Ձ* bN ]) vuVQOm"B}eYљɾ}C VvÖxiʴp ʆ "lcٍ-2A"-\˜G*:ĈZ|JcR 4-90Sp{+B]ti?_VҦr(:P<}Н1p, }zl䣆:A FS0ȝ EgUhH<`NV+.Mx{⯝sjc7aW.l{.9n%8)eRd_Ǎץ]}+8_QsGt!}(u6TS;#y*IT&(N9bG4-CiΏaZՠn2=t?PK ^Bҍ2com/vldocking/swing/docking/DockableResolver.class;o>cNvvvFTĤTF+ IJDļt̼tkM\* _Dx0֌ \Eɩn DaA;@32cL#9IY%l L b1I&6PK ^BW!f8com/vldocking/swing/docking/DockableState$Location.classTmOP~.n&((wqlCP$N?QuHh4|GϹL"169O{ "2A(H*&T,e !rpĪ1Ƈ4Di2&Ubbbzv kճhX bVM9[=H4ޱrcYS$r}ƕ\.-ʼ(l^vRfT@ W]:2&K]Ż,dk@vfuϪpK6cCL8&2:Kƻog׬nwR\j.”޺%" ]4a׬S%_Zⴓ7.f5Սu2jzڰYw#p[;sBcx"tL".f:،bTsYSsIH,~aɥC?=yqL$/ y:aa:tucmocQ(ό2q !p-B~B-91\[?)8~=o0OAᄞd0LӄryԙىS"@,s%i%|RSh'JR$DK'I@IUI|-e^o(Z0j C DI(p}tCF龜 #?p)SFґPK ^BXy/com/vldocking/swing/docking/DockableState.classWSg- WAj"pQZkZ4B$[\4 xt:'܇Oq:luQηB"2w~wwϿ. !4 ф .,bRĔ p CM؋[">OD| a;AL˘ gA[Ǭ9 4 `2+I盔3Ӗ3߿;3ӟ#z熨.Kg`"A:yEx)e+ME4COYз! Q4']8qR9ngi+7ƣU9[ަpfz_a}װOlŃfI'{OCfΚr4 gE?mR91=k% C1f2kJ&ɹ13ЖP!켬Jj㼝JY5 ѴC234f̻}_^V0Pu+0 >Kj8Xp& 9Et'QVDHU,#u^S|v+e@kYFs|,; 6ƼhИ2Ig!Fmi֨080fk ]7gip d񹁣ȣ@AĂEw|O՝])+Ǿ㦁'>C䔁2:? ܊VKeA1SV"6B:w%/ h## y~c!#9oqXkZWD# P|,$OLNp483?5vZl,vC4Y+&p-*K3t9Ӑ_A jd9q;1): g@K3h=/p|4z(%1^ W}8Qxxxq]FcO2=WoG*OĢ᳕O %mtX/lK,'-kyW'ؖ^َ)_Ɖ$hlPA1PK ^B7i5com/vldocking/swing/docking/DockableStoreButton.classW[sU&[v'6 AXC2 YQB $6 (I, *x/`V >X>i,N6 ,s}{&^wal!PC9C*y>Ag a\D:d",//\yLfC`X0-~z;wp-A{A 5y-1-׍hi@BeɛjSӳ֟$!2ɴ&14fsi3_ͩ6=P2e#It٧"bdNE^'uoV3MY}i=Tj⠚-\&nd{aSB7 }d0Ըt1ݦRsHjT)rc'-r5M/# r\_!U( :qz+*Z!Ĝ9l}˵/^U 1Kj}:|G]Qq&!33yJF%$:ϛ3AcNTcScs63b d fi=b$Kr&iX1ݔYF ZC4;v_d,۝].>Rcy9hc+Ǟ ⦌xPG%U+2>fF vpJBYc{eA|!K⮌o0ķ2>,FT|'pG8%5}Ͷbckxz4>JvAKV-Yn[X),(-7HIo?QYkQ {1mA y1bCC q7R6&C鴄ZWb#OLGM=M%+~Jώb)IlQc}YmAWhJ(*QUgBbV왚w61ב.u1iuhnUZBRe(WEi%\DHV,""? =46=Y[G֓da;}p^:'оC;⃮U}64HH3,r8,6 P~ ?,8NjiT!Gz^[r}EQ;J65`] s8kIa̰Hv A| èC&0W+>9fC@r9TP1  QH1m>&a<'SxG%yFg%yN [ yI#IrB$9 E%mʤznj٣ h `ANdF:R 4vgpW&ͤb-$(kXCp6w jj;MbTamѺdZCLN=fD&03foPzg\tjdeӻ6ivS i@eMYaX+k72άfQes(7ZԵ,^^#n&O7̤CDuG+@mdrs_##'요$2龬E_> QHe *'&mg-ddi-ejgV@E5Sa|b5t!7Wj(,Fbc>i NĽ۰,C/nl3l5]{ xM[Ub :L~XNQrĒD:+Qp՞FS&IHƤYrhnMDm+ۣ ^R/bt.WorA&U,OƛI[Kel؟0z  ZtTtɕ$$$9'U~*~.NB$"b%7OOOGggcDq"y""{V>Bw.f\fI>E[DRSʕ#,SrY=Yx._W)<)ܷ_˘/~hj#niGn0Q^F1dm્a+qk&EhPh,|mD%Pg? l)JP~AyG"~9-:ūm^?Ѝa6] 2=|ߊi@X߉HAUqSIA{hikV8soUۭCD|(?Yc[g!aH! ax]a"nratv7*f5QnSN o(Rp`=o?PK ^Bo04com/vldocking/swing/docking/DockingConstants$1.class1 @Eh4QB,FXkR묍$f UZ8!j %+j4efmuC>'j\4PK ^B͔U97com/vldocking/swing/docking/DockingConstants$Hide.classRN@=SZoDA]1 ѝ ؄Bc\P6(7&~e3E4s3/֑Ě 5lhdH;ɠ93$+fRӯlS\K|׷{'dxNA2Lϳ-M?5Fn߷<׵ ^CDjj(1bh ˞Mt,!>ȈP6BӰЌ!'.'YBz}u841 .XSq}(i(l̿iNm2yu}S Da&zq̇LӀÑz&[kuG_NxXB]/6^hK/+l0׈JhP+PK ^BQ2com/vldocking/swing/docking/DockingConstants.classT[S`=_ iʠ( *l)hf*elOL( ?w}KΞ{럿~4^ZBoPPb؊c[B=n8*q @@Vm-5yjD-'RQMՎP)Vnݞn7¤(޾Q!095!(Q=:af>_X7`xt3ޢ4@su䉓Zs;6=Õaī&}&%JmK&mQ[q??1:~bQdnVS{HI $%J-k+5N7xnLeC3ɐ5lTQ™KLCvNKX n#PK ^BNw 70com/vldocking/swing/docking/DockingContext.classZy|Tս&Y.Y &deQ԰@QBpc d&LXmŵֺ+bTťآںԥϾgE~޹'ϧ3{o_Or苧%:y¹h;m<0F2Hq/0QI2NSetY!C¥3K\頉\%+2Bf0G>uPv'(G z'5Cxde蔡K›7N: t6pCΐ!"&^(ܧVxC^ϲ`f7Tаɽ]kC!douܑސia= :[:}2Fߢ/<[kyqW]lۘ!vi5ziu]@W!Pn,{xDl5^N{;"` nj5s6_˱Ky͑` dL ,z|OOmq gq(|^:3~X":@ èJV{A[5GF_YĔU:s .ӎjoSoot9p׸C>y7.Uhꂁwp{WxQC_͵_<6#SVo iv?߰8S"),xF0fQ8"D1ңio[|&{4$OZ$} p+j"T D0ͱj;$&!y;1]K71dA2XlǖGxRiѱO m@%͉o'ڰS4_=>YYڸ7/̚ h :> n҅t>сJ]stJ~V)H>Γ!,C }r"?UFt}Syʗp hHUT|t$^W}%Z Xk: TAsqBVzTIt,(T`z ` ̨ h^ p,°DžSfW͚xʷmk b;T͞ (T;v'5*E1>T*ϻT~a'K4Bo;*U~Ec"/M{hQXfwO.DFK Mb/ x|bMkU}*?NnSyVy?HgT~T9TnF:>V ?*,bdxd=RWg*&CV ӉLR*P ʿT5VfgDT1]7oRcEy8KKӪ1fڞ1MʭTZhf>b 7:{CZCak]i[4]ox^lg^r4e k@{ɏGa^mJxBʴ[U_ָl(>5=@Nɩkhn]銯^9#ӱ4څк_9) +=P$ydvdl.Uf/tdwFoKa7΀oe e *2" >1Ur4EJ^iF LNl*fo^J^zu#+YpxGv_%;z9ȝ[a~ WKs&׎W.@fӰW{zOLGS- F Z2ScF9adqlj'kԚiߢc&US+6n*"H"[}؞Ll7= θGKX^]LW<u (0֓ɯ:fLoQċ,5Չmuy08љ/$ł ؘBlip#46R'*=1m›6ރ缸p{Oo<}q[+3߿ 擱$eaFlq~d4ӜVm=6uĦTteF=mU2IPFөfQ ͧV3h\rcw[թi;~.K eOZOon}&H4ᗠ 'ԑA 1A. czeOf ymƊ*`A-a:@cYed~*I3dVOTTSq;ngEټ7 03 %a!aEiX0BV).C$!N! *t#sa9,؉&)֘ff0Nxv.&~{ #sB w<(1UtV-Ѐ:+Y 1դda#uA@m1 oBc5Whc=0l9=΀;MlMVþ½ w7SCV13P8c ,a'TН ܇-1V(cq&Jo'k@k:q" Ρx5V(3}i3{Z'~ `qiW?`YjqR887{>03=H?LC-F--݇@+gP"ݻM^t][Nk9/_+uwY[[^*c2<ߧ<&чp\7ߧFϣ +vXJZn nTG㆘FP4B'$,>I{]| 4|5VBn`"k32 #0[]Vu,aEnY1MAD>3 Z;MOO?0OZNU$ZMi,5ԛ ~B̅#ƪd*4ukL? =s/НɐKflM;"iS4WbMNhSM+{NDuR?qQMM+Dž5!`cN<ŕ3@ Q N:ٕS " ]i*vGˑdj-$.pPt0&u0Z 4''̧*C֭4gP Pj.v\I\E~x]ɳ:C;x.=ӣX'kZrA~zȴ Jψ;@sp~&Yg:B ZޭN(ҋP8 짃2tT?\|;ϢdWVqzqM-Ps0~/B+Bo}A yާ8#`_íؒ:`F4KƊ=2%PkϮܣY;}?-CZ\r"ˋZKiBb// L8xUכ\Oo Gwun"(k7N) FPIu2+F1EYA/u)O&VOJّ۶ ܣp:2'n"7Ϋ`TnUXk5f5* ODȻVD.E?&F}%- zA.Nzݫl6H zN~ϟr^6'4iK$>Wi smHT3CFP+P!d4UX׊xve7@4=TE'NA\(n1P i?G"RfJO5`ja:͈wb!0-T ja.S;4 A,#O_!G$ U07\Rk?~PxRv6mg-KJsuV-iM =_뽐Fň۩/.__z u-u멋oMXMrŠ,Wm沐)nҢF:u^HU#VE9UQ|7b=ZE}XE_E9UQA5;}ZsFЍLv= ۓdt>M5:42udL+' '!}D1ԙVOCgL?G0dZԩtt v.}7΋$HyHT/"R@h:']UC,ҝiJ$AY")5xӫi>sS! |?տώ/Ө-eVDCRǯ]dGF}'Mg*Ci)bWG1$seTĿ߃?+LN*/,4e'C+t#(lKd~%;;õ0&[gvFFjZF%40Ë ZrtB>>#$$$Gch[,< b4R%PK ^BWM_|2com/vldocking/swing/docking/DockingDesktop$1.classRMO@} j-REQЀFo/EzQ{/e#Kʃ1GEd3f~~8<0cSx軁CKqj26CΖBE7 1dʇ O'/1^sMRޙ/蜡Q%0hq|z<YHtZ,V-!xhR"-dFC_q_BBxTQ_tl0`,'2O?-#)jÐTQ5X %doβb}q/i.RFmKϓ&gXIF64VVk}12PK ^BS03com/vldocking/swing/docking/DockingDesktop$10.classTSIZ" ˢ$jN9E!s!(w RJo(+@qU==7Y=Wy؞a8(ŌnuF2y՛6namܱqX'ljlDENL ~+o7^IOJw]ɮV-F\ @/B?ן2UKDr}L[Y'DDā{ g-d\ EH>q+sNܽiKpP)+ڕ2n٦ӏdž0^#]N Ao#0&d?m  ڋ=3_>k<8] U woឃ!kv;85,;X5ZXsA fwG}e_yh&x||BWPM㔻n FXaTCa M͗i,4xxg4e}`q_hkn$DoHVzj.LBTVmwh/}!uS_`TUtpp?HZB{;G<+[&cw?a`lt7kr8ïY-g^op+u>64a*#Ϻîp1DlW+BOBoqm E;+,GW~EƺzQOb}M$Lt\I:l00t.(F>qV`S 9ZE`R.!D6y+cǸ)fbp*+"#PK ^B|r 3com/vldocking/swing/docking/DockingDesktop$11.classV[WUv6KEAR ,PKj@Zk2d0L//像>|gt.$\,Pg>9᯿÷xU4upIAIT\p-sox#R6b Kȍ ɽbS%IJ2-Ɍw$fU9WPtbIrH(=B1Bg2lM;6%-Ƌ}';vCmÄx8Kc©iƪpU%I'[KkuI @Цl[cy%cm#lulas3 p.Ewce\ W;%&)&Ŕ cy_OO y'Ą)p8n遫S|ZPV\Ђ%pS R  kH+h0-+4lHI5rsF6ѥaK;E5|$? >>W/񕂯|C:VKVCsX1#Z:o. V1V5i/ ZL 3adad9*m?-Im#H}Fr3i"o42ҳUS)ymz=5htNR3WmSN'ۡ"[f=#T1˧xS<ҖJbMNɛG==-k|A-Hr^u|(pfӛ@zN \MMbl"ȜcVw|S/I[rQd`[!D+E ^g_pD ,'\?Du ?:VC>bsxyMPцW7D^p"zU,ڌ ].\u)Q@\y9@)Fr [ ==M}eh|Qwn $5$=m`Qoаw=Jf8>2%+9r3i7*T]]3h6,hkh LM,ZA)|G~4䧿,,۔'/h{K.n| 9D%̅8 Aڀ303J}a7\4PK ^Bǹܶt3com/vldocking/swing/docking/DockingDesktop$12.classS[OAV.[(xA¶\&X ,ht²Sv&Q4>Q35BtΙsWSYȠ_5 duŐ E F-7̏3؎ܵ P.p'Y7nt2X(3KrC0ٮ/VjGH-y*=*A0|_% j n~brn*Yi=`|[z|̺/(Ηgwvy5I\_KRgLQ }Ǔ!"ڒF d1f, &0a4n[fp[cm )n=l 'bl7x0 Ie(Q@$H23lhEWBwQsa&kEj}¦[ոGce+S{0ό,51a$wүQ-.Q N2h3:X.&YF4 ы. TNd@Ԧu|°0 !#yh&M{DKS1}Y=8Tw. H.FSN{$/J*:=8PK ^BT@_jY 3com/vldocking/swing/docking/DockingDesktop$13.classVOG \/Yhc v iBIC&hHϵo1ǝuw䟨To*RFЏԿ:{\Ւvggg~󛙽~0|Z1&qm^e \ aWUkrcJuLRz3*f1'oᆂ RpapUa咶qΜmva; K l[3Ha$7ۦng7`-ȱ 3$jXw!CMCc.Ϙ$iIYn.qǐ뢰F"dvӢH&w]Ax# neδ !Mm~xTl9ά\MJCߑ)yTK׋nyޏJA/#6m/E{Ɋ9Cк7<-5[WЉ^) y jg1aKw5= C|cp YV5䰦5l԰)-1V&%|f]d2\Oh y {f8^ڛ$Kmb{&yW>j߉ӴE gcl)X)B_~LX4A?{sdD 5-'`P%էG vFv45N;8)}Pŧhd}~FٗȾ,⑳8G:0AD)!փ)1.#~TD<qs;h5Gn>-{f?`= c'L1~)@_*A)2[ D¯EC?M|f+Z c?_ \ @ ZBPK ^B3com/vldocking/swing/docking/DockingDesktop$14.classSN1=maqZ-$K`[/U*^B*zXa/**x%ܞHVxؾwv#I0gK m[ w@NOJ 4Hvث0PJvyмA~M>0/ U_qjl3ںGT:i+Mw/mf> P#)%v(X⍡*G"[7":|=fF쉁 _ ꞅE:S9ʨYp9д̱Xf?/ݓ~BJ]=/88DQȤZIEjgN&X%5޺*JH$n]iL7DWaj4 OZgWܥc0yY`lQΪqڕπB~ _ 4Q%=szgxgS(1)"tGл2 (}aXBk8mXǚi=;aϙAwy;"mE1 su<'zv&M>vD0ÔtwbcX0w7vvA&HQt69"ǴP?.dT@ճ]?~GFNFA# zt%J%c)3:Z !k_0If(xж c^BZ?;F+ҟP>u.|D)S@x2ޣIIm]5*d aw t́9ËѤ PK ^B2com/vldocking/swing/docking/DockingDesktop$3.classR.Q]GG/chw҇*1ވ"9ffZ#$x>JsTăЇٗ^{~{y Lǔ L0,C2{Q°Zsdt^piG~e~_DX^`z!.3U l Iy!3~IҪ>?38QW ن$Cq#] (Rj)WmOY# 0Q#q,)6BI.SmW}ǰPkp@;/C%c'Z){ ȕ_|ɤ;ߤ>PE&l{T-,(L0ʮHܣڶ=2bƐ-s20 eNnq)3+ɑ5FY[^`<49vbsLa3g24S~vod9xvJȳgk Ĕh{I>$?PK ^B1-92com/vldocking/swing/docking/DockingDesktop$5.classUYSA V<@B$(`$aofĕknP?|(GIViJ-$1Uٯ?>}00т2øH3")q 5hge,2@KuteT y]Omf;){RfwH-povSZ{"i(# -+%j]M^rEQ9%%55č]!6 y=tuYf|tdhU|DHJaR" ]_@AF&S4nakm|fKdS_p˞%lC_g2Ur}ge-je8 4605p3fQ00ywm" ,b=TKE:g?Xdh`/מbX5N U/eIߏ p\)*ӦS,IO`)uĊ_OWת ecC-|lЁV!kjB9Fn艾m{Խ m6xFkШLYO+exG>^>{r{ 'KOP7#4E~g j"H!q|@>"Og &ͥ% LF;E4C (e"֣%tK~'=c襯:[iFޱ3-TƑF/PK ^B\S15<2com/vldocking/swing/docking/DockingDesktop$7.classUKSP. M 7T,PTT|`[R@EY #%qtXӅ;7]7񻡌:HkfrrιsϽy q9uÀ8 #8P{0V)F|feVz:Wyq^%:~`:YuXy@,nLrKk-|ֿ誔_楿7Oov@6Ոc@4疥@kvTuqNz͹ 5%"tP) VEǑ^b!Bn5= k(S撙5oY$ ;bmRi`ͥ$0fv&0\"v+)M4nakaҼvK>V=K٪_%g3 Uq}'ep-k8c6bY5 GQy(Ĕit.ft*kfs~qsVaFPH$@$@7-K~O1ZUt 7vqӕ'k^q~!ZLmt+qB_ ]]G%,m*`_{NX~:7QMesƅ_U/)޺!ZN ЉJmmmꨅ0PaXk:W馺;8SZAgtps\nJ-$9wν<p $1@Ntx :~IEN%pjh8aJ+m:Kl\W.NM#ZU;H d+tf+ජ;Ra[Zmߔy\ǡ%xޫJΊʹeg(וqP+J?A m"oj;M+dOI˪t7s̙ÜܔnL9TXk[. L]_PvACJJh(:ۙZ57nioɒe+FUr6ZP?+Uᢁn؋iPP4Pe5pe W ̠b`sg>f6CWn6>7gƛ@'LPbiu tӲdN%ϪWLH_` ̩<7wf0_}O}HwS?f:8#ltoLJgEWeF=)dO{{A_ݸ|~1 d9~3byP 8@ zюNHR7-W4zf/C܋l~$m Iq O8\1-g@~3ϳ?<<wp2qZ U+M*46~@ V "98V'уxur؞-iO~*uO q}FPh$T:/4E/cBG'L]pOO+}ifZɖ)1H@ dZ#SˑT.!m/\"$Y.w{rJ2mBc/AWF QMl;LSag03\ !x,l$vwx&{F:3im T"T"3ogw(|ժoi.Z*K{Km~E_01\xs9"uܘDh#O_ <@Kc$n2U/n>+g.p-'L>PK ^BtPѻs =com/vldocking/swing/docking/DockingDesktop$FocusHandler.classVkSU~NHa\mSJK!pi-Q@QZnSݘ].Ug,xq8vFc&\JIHɹ=ٟ}!X2BMM*KxKBRSA1-ofFxG¬ 7eœwр%| ᮄ%ct˞4+ό%= ]ɴ_eh%kǭ5іf% uBQ:b}P?έ%̓'j1xfnKf >⅛.Ƥssz!+EȠ8F& 4fhXvGй13 ljݘ;"E}UnX}=EI3\({,59^ v4l8KV2+\3}͎'i[ꬭ'Wam:0T֋p? g*Xғ3NקxfȤƮxf$yn'm$s4Kp*V'~ 0UwA5W i>B DBh DKHR+X0N(8 0\Σ+Yi;kjܜeL y QP(GA _0;Q̑7R졩Z67ıfפ([`("BpWJ'ʛi6V&JyjhF/8L\AIL2E=:ZҶNsSQL.TvP(zfhy-.[\v8PZ˖]j;.vmq 5B ^T Ȃ4;O3r!<-|A3P'_K V8N" K_`wmb?1="ۄ4#16s_# %p:W~ 嶻uڎ@)7HB#]c bL ԿqO}.QۍaE8-YQ2pQjHk| 'Pdԏb~&>')uۨ" ӄ7 F^O9SyץK C@C$4kjAth bAMÄ:"ء2Irb"n&$ CghK.wũOG@k?/ i4| qV<qQp2.AwRe\}˸=+ʸyՔ)Z`q)e^|0Iܨ|0Iܬm>(tەqF9[q:i8w(NLN0wPp/ne$ Y}qe<`җїu>8jP>K?j8ExK f&zeA2{ Sg}OK5%35CywT83?Pp^ TԶTlLÎ0 `bf!5hm29 Jpj_*36``VPb'5T2ˬ#LAmW&~rmY.7a'ϲ̳-b >^G\@V ."e^L.y5e4ӘP>6=-zk)멦|V6 nww .̦=>^sG {IA%~  yx!ja(QºLjx>NEH2M4ʬiASS8 ~D1Ye>G)MA/y*J|<gH!j%*eBte3i_W[- jM|2߶ЋR@\e2HM(#i2ߡ(]{XK=,(;-#zY2?gT=5;Z旖e~cƿ,\eOw?mz_}geQ2!J ZE1FdoK KD&IJTxKZLϒ~K8>5S! ($qdSfe̢}/e%һv d{فtd'K|䨧Ζ̡DzՒ,%>JdOKho%D&s}2O[Wzߗ~oh("A CHZYsJ 0z,D`4K')(Ǽ2}9R"ЍAfXk"Kc>F1/;o<KN }|d/'SצXؒS)4 sgӄ/`%W )'|FΤ`)C\ Q0ԃ4S*Q+!뿐0xb7Rl{'lK|rY"K}2$WRJJ1vqEEz|y0196<%XQZfUe'0`S+jkCe` ڌ?g-8gnf̟>nY+V[S]Vj߸&,P4o"URYQX ZI~K+Kb~ z sSk+jf+B Z6Mr,d44}mBhӢښ)eOԚʪqեjͫc\mMMeWGZyheMl%+*جU WD8O;ӃqXM+g2kkM WOVae*5ʆ%F䧄6hAF&ȖV5.TWjkuu6Mn,[**P%ÛD/*_1kZେjErlϒj68<%\iaIn1U\YMA:\\:.c+ϬŐpz_LtruemЈU N+ 4zbqPx-RZXUTUZ_T^rnSsk5D'8SJ7/uz8#$ n² *K4HQ\UY]fz:\e%Z6D4XU|sG hZ^8)E+5-!WGr/e+JB^Uw:ՔO( Jȑee5};8QhF:DyT$ ¬|ALfuYCv҉.JDuU(6:i1SmTU^=rì 1 gƐ!fElգG1eɠmr+*ե !b6nJrmh2~*T37T* z̠w>ͣP̪`ދ R#t#Kc/e3ZաUhn^שVi䳞pVmEFG2}CeZWBcJuL͸ڲ @PT0`V3ԼRŚV؊: f88`O\ݪ 9eh #yri`HZQ*u u!fFAf0QQ[}8'Vd܏=ZCT n~mݽZ"QހMV0_(JEi0tV)GVx=40jiU&M!VƧ+e|d2(?\U^V$͜KQ[R@T5DAȴ0 OUJ`ʉYws7+yQ%8+%C%kQ`N@%2tzpbFAr--L-C::WfXKDJ#1ȎaEMZ))4GW~J)P *4KӲ'R!cs%=mW\h:gyF 6KNKbE1AvhTh>DF &5uf^Wn*4T4qԂƴ<=OF@U'Y(B/4qcI5yi2@nb(`IG. BMw5VW .PGB:ݧRۻOk|*nbm{7MY {{M)K-Mԁjy(VPg)u1kCuYMӰ:-7fn 2u#Ģ2 +IʛgvfU~J8d,ֆښ&·uٸ\gs}M`Fa>-\8J7Q[|ZnH,Q eēsB%hrUՕ8( ӂFegL`aMUШdB%Q;6 4S߄C% pmXoWƞl&Q ^+\q,qkMRQvFm+62GB/B2RͨchqE|'Ω^O]rb5I`آu0eu(DFD^V)IYi6QOvЖ#kP# zd6Ǔ,/#I^R6Nf@n0M/rOTOucܪK!vٗ^+BE_g`rN| U5G,J $ؒ ]#pVSX4֏-JH:)obp j\ӝn"@y1?:]L8;Z8k;&7'A$JvʼE,$YGӻ8:nccCo0{=E3U 7d&PEѦQҨ wmgzIfS\Ͱ뚚C[$ҾoB-ZĶ*E#EU?n/|&UWk!ฑlܦ9ei2݈Naqۀ= |Sc56C3Ѷ,E%cibt$EkV0ҍLZgkAuԭp;v`m:nc ձeuaܖQK~5;]S6pkh5T†S*JGh a'ZcΫq8xM>&djs~6zZYRn9Ie|Z՗j_/|+x/| ?Wl^b%w: D+ 6c$nZpSem %71݌t 6g$cͫy8 &qlPm^km l`ߌb0?Ld6_ D>;jwG8-g L_Ncv\8Ws ׵ZV|o7!6ok7Cm --fom7'66N /ly1_slEk%<ף7f-/[ C53iLrOgl~?w&TɆ?_(ͨ-/BKYWɩYʩr$ZBٰ1?iqXh݌_>d5&䃶|ٸC0>vP(]?NZC˶*xRmc1˖|–Oݶ8rܫ$>mc"fӶ|F>d-9h|m8 1IEWWlyHd˗+|~M, /Aas1hkt9;Y47 !ZXj-%߶ol{-ĿWp[?㷓B.J*ẺK*߱Vn0p{|_~`OP~Z>2lSI S >`DlwРNe |߈HQR~sY?׻j+VTn"rCgԢb˯7˖+-w;[ly-GToŠsj*sBN0vԬl5־%yjlyTd-!*P ~sRVBLQr5(g+,&>^mU S)-ƈo+$ l*b ]91/:Ǩ Ur bDHk9e92/B[uM9JGGePIzCUU"V*za#ήMHP΄O8!Grb+Y4a8[Jre몒0<Uk[e#Wjc$_U; ?(`NԍTgi \Dgęp*2x^tjqc"Bj0 -Fq)@D9B;Z1A۪VUU\ T> U{u=q [ĹXZ1hE95hE"Euh'm1S̲tnh[ Tl565|ʇQTl5\*5V#([[ҪD 5^^:t[|.>&j2 _)آ*T5M鶚Ad6rfm5UݧC$2F}rKu҈UTg[CW ztV *y*p =ao%K[\-ō-n@-Vj ,j)6\l p9bTWaVm4&Ѷ'žlJNUt<ѵl=_o%4S!q-~-B#kdaN9TCǩe-_ xI eKtl[R[+*#=VqTWۻlgJ)_y8S(oYHx##G+-|#h=yGF؊IaTךPWm)ٿ{t#VZ4v[Ve5Z4(6`M,䧔0Ķ9+Xr"uTȽZ_ʉ@ xLJ(itѶTUJA}lҐR8ߺda}TKNVՄ! %7ت^m'S%7jڄxd6۱Us&A|h:KmsGasyF 3Mnw0\̖5ˋFf*o~aX:5ڒUDU1"9#qj:V#.T#6!(uj bRu mqPt7lmAd J!TWju{][L] =-̼)P<H`Ljۜ`9rɐ- i!C.FluBpI9NOGiU% ט F6427mh-D:FB@AkF_ mc 1ap(@\&PmWlNJo1Mݮ$>N Rwuoq.;Vjv}JrV.NF&ԹEJDDc569X1>ne o7c B}+ Sh{~ȶҙ1"A_gT^LOʲU1մKK1Z'ۯ͠C̎tGߞrw3 i؅s}ILʼnHIy,mTK0˻︥IM֬bQlA[ /e2gS?M3WAG:a⤢-VMl5W|c:sXy+os&F EӼ2BG}S1ڤ5w ZlPHgUWVk6%n5-"@:Ia:]SN}/v11g&Xp͗ň@-V};Mq .y$s`L֡YV ]+ޫo'1F4+9.2f[o$aJ"ED8aF/=X=>k^瞏\W3йXCyYk&MY4xdaD.Tluy//݀Sdo/O9w-IG] 1uX^{훡,4x}eᨡh}qcٴeMX^}g#Y`h3w]R6դ1J`#}FڋMU/h;kZegΘWT<"ɘۺ&QCKIGIT&n"ɈxZ GK L:3hnx6 g|{ fVZҷokД &@&_Wdз9݈'E4[`x,C 2XOEĎF.Dx_0!%O3z)u 瞢eqT\}06T^SFuD-z:N[8ջiOi͛yg;RiXK,E#bmfz>t2ȁ|/ azmL|,So<5V?׻ s7gag9U?/_<+J~ο:&z~j4]ڠ7m}>ou3`XN Pif?~$ӶSwOVo1XT,MW)VA1ӕ9@sR퇴E{ }ds21ZCݐYm> b "iC#ir3!0E>sh?wG#~ =i7thF솮b7ttEcL~EY@`F?hޢ\RnW$ 톾G (>p7 ` C1>w/0(>z7Xqy0>dbllnp} g! 'hD=g{}eMSD kZ4>kz4!kF4*k&%( flqs=\zO3Yg:O] btF_{5{?,-ө)|.YCޭ0RLVUC V/%D)5B#07 XHRdXP `%WZfx+p5~u\5?6 o+$֊Z,-em ֞aY-f]مug7n֓=zYo2~{,}itn3s>F>mم|/eWRvfk쐚Gsb%9c}~K)A, 1) zMt“YkBAX7-E5** JPnX+TNB B#І6z6b1X( ff|=_GaƱ<) 9{ڱg;}AȞQy^+!d/F ^kp={na x t9#C]ݻwǬ'.HR'A= g>aݼ~:6Jf vTyvc,)dbڙ|q|_!y(k$𧐮m81q=͟q?.rǕB ݖ ئ3XRF;7lMեnut{Lw<20 A=\ !q*0e?\(7?R$+D67, Ȁn/oN{`[/U};B@[v@J^ПGAn aJ@`,Ո{ԼH4-z$v0HہæjN״2ܚ6,wlꁝi-a)L {9vbGmLqyBO 7r#SR~ҋC6 ':ۥ,>!*^zkhG`^!,.w'AÓ4{awAF B4s#B`~K`_yFggp5_ 2x n^&xx Û| >?~b֍_?Mנ 7fogkm ~b٥v-w:~{?Ȟ(g'缞,1,~B&Ed҆)z_Q<Ƒci 8߄T%\ĘKsboāmdO,]12|V=j!a"m NKmLR}?Qt2( T?;р=̲sz"2 dqo#̢^38@4'ܳQj9 #qs; = ѿCH4XKHr(vwB~xn%Q[dDM7DD !ENh0].̨r'ci3w D~:nՙMW֔ļiz8zx)w5I#|qAG)jni;#[ s?(^x5J 8A+;A7>a4O`?JoHWp%n=?H)0 !ca~D:S"Xf +m)"laEJtc;$z E/vnynQ}1@1|IQMtT2?͉ҳS_Tgt^~b),/ Ќd zcˀ.MOeȲ`F: KX `X !XQ:%*`805pXW p׋p8-8|3b+b >jN\äeY;q*b;r[xq.ng 9akĽV`JQn>{P<=~-߉gb?R<͙x[YV<ϻxO WćXK>[_ Mńy4Eʌ9#Moj5ts`)  44a8啕DE \5gUs.`r G>{LTlx=, LQXTsE.-K3CFEY?@w%Lҏ@(윕uV+m۵D Ş -w :/߆A//A]~>O)?የn(.{#އ!1urN& %z3&@v? fL`hT!dbtML 2BN M (bzE M2=ez)Fx?y!|.C{>n2d7G@8LE]3)N~NTYk‘z?]cBH3N,ct4C4j,^270XqG8678xqRM8"uS_KW55!~9;U0_oi]囃/3ҿT[`X)῅VrIMMQ0;!ݸQ^1ꠧq?`AG`(0E9ݰ UA8x.6^+o0^یW5xx5~oN h'NG#F؛IN^-N@{À,]t'ߏ~r r@zJ tV:Dd1ޢsq!)])ECҢ@e0{XJN'9F}8e;e(QaH::吕$wAA>6>D5| `9,0ˍ/5F# ]"# Fy"`& *lAgwQB6)_: L`R ֩P9kP@" PzL; S)5|qw]l$(~GXr7䓝 ,gf"`?ɺPtөR b~=KY/ZXz]F{0>`n?\,o~h+s%5 U?*l@n y-:5Zu::qQj?-z ĪEY`ts䙅0Q0 ̱,js6i嚧r6 f); ̕lYƮ7װkٯr٬dfd>f-kͼZ0w xvhjv(}(,>s2iԺLz-cr'"+uڸPB# e1ɋh܃ E 1ua!{᥎ˊuHd/C{ٖ^)% v EmX@(p5.l:ƵfQ{Q nErv!BׅT݅TC)1t~sޢes8PAV{9uɓEWfR:K5yכ)JqA,xQd*f+R4bqH-jE>R¿e̐XlRe;Fv`IreWV("{[(%2˾,,r "0v#69!DZr"{TNbd,foɩr:H`or>F.-Y٬9Udǘ+(ɮX1}%E'WumI ]Ҏtrx`cJLuTLIqhDOF$ntf?'s1JR!ʾc(SS;`$w࿐UQ9TwjDGim¬k\! ޼m61\,I)Op9(s6>VVĀfZ{d,qiwB{r'a|` ~ $ u5rla|.`'6i5aZ|(hFk"ע! h۞c9/~ЎaOHO~BUNnOG算t7 h>cIXh?[/ Ȯ-_l i3%GJ͡^U w8cӽO~8; =3,Mz`HOJuI^E7w'c3~ݯHYZn@ZFJ |@m8;"#,8 [:_Aw: 1 #߄-XeBgu6Lգ7P箆t2@(lClB|Hl!%J@iUVbGA% f9. (نlÁK4jf~V`3F/qh{L=oj ~<4'h' 9/Kwa|a2GE&jóݍD`htC 95rn@ncrDw"sq.+qKs]ބt#X#=G#%ɧQi@w5J/F3:/:kXdeYj1Sq t c9pNsQ.u,T=(gP3h0u.PSi3Hhz} do(Py|s@8] 5j0Ԩ!A s0T ɰM@~ BC_N.xo{9fx(p^ N,!)RWFN,p srֽ8"*Z"?VS1Q$Jn 2`>{7 r^?駣l6FWDª:-GYsVU"?KgF;h1jQ'9)8b8UM)ɳ` TWn6&j՚ Qy0"ֈp6i9þ!+F}TGpNP6#bM!@"ttځX(*8}w#Ѯ"EueՑ]Q^WRl/G\JV!X URk7ψGgOwhF(pHZHGKFJ!pn'8q[qp/^ý{ ו'2QnciXY5F3 ^d Iֈix-hj!N*ꔦ[NV7q>՝C+ƝpnmYKES.ly܃* Z9@.fyY>8AENޚ%FA7X7vll}|6?͖elSzu+7D}d{P܋y䩝ȟP ޏGCP=|GB=.Oj7܈zT<73zg9V~P`!vzQ/AU6\WoM6C櫷{LJ_ jk8w-V鑼P$>k6. oAlD6XMb3Im*qhMzC&[Wo<h{ˎB~c uyV P-?w_&MTtrB #2nm(h1fgk'Ṁo!}:otWjw{مJUmW9ZgGb۝'@)_{5VכDF)C*X;2 {G/%*wB s022a`ej+*-?l`[,jۭ OZma^K:V8lueVcdyV/6FYyl&[}l[jgU@β 䈆+]tbw-[mClk;U[&i2t6YFҔRh}8bVZd3ݾv@l8U*dі8u6 ]0 pez۳i]R6G(Zvճs5P"k Xȴ5zY㡟5FZa5 e֔:(גǶ%m1?{?jץnܵm}dc|V]be[R.d͐f!]Hrs-RA҂ !ZSVwǞ۔Z.q\o,7r^F: ΘsN{Y؃u9(JHldBo:au̷nB<jm(-(n;.xȺ8`W-PXփJGKg.zvA^VhcgL[b=JzZwWQfwO݄B8-rrRBҕE,((XA]˽W Q*ĂJM@bA(b syxٳ;;3ob]t}M<}]<!vFGwOя +ȋ(6{ύѯTIO?ռizuonh7oC m&Mnh7 mM4-$0T6N%igV^z2O/T\[ZD,k޼9-\:뛓؍*`cf_a8د23( vr}jCj-a٭hRKǘ]@3LiY8kcsy{,L\2u=  #  j%2-*qk>v97}`/߼SE sy/J/F/~,L+<…*q{FP=:aRwf'O[62G_ ^s߱8&xPuGw!W,9=R,Et}&$HXjXIE^年HGzozKR:} pM;S˔ Uy{*Z> s>jH/ĥLݾ/#q}V5Xc_8ƣLm M53by?+$C,m sY['_ **VJ%)Z|ȸXDc|X^;µ2qrFbNR-V*+1ʰ;"iwx~yO)ax,:(#+h$Rʱ\TS )su5*hkc6kUZjmЭ ᴒXߊf7'd&yotuKc.U%1PYAJ1_&D=*H3w&醰 ^^{1wem߇av%`0NWb6{^}{-?SQX±e90F@1Y棄.^E|L tHc,Hb'I\M (Lv3KLKTkz1 v:5dпR\Ü1>?VJ,=1D*K 56JHx;J ^9T w7kYgvȸNݢKХT<ƓY% JD+XyW$*Чgv=u 9 o#~Pbq/bN_& ѝhЏlsʀ;!mf$m4)ʭkVk-0GmdCfϻ eAD{p 5~>JH}X3S8?47hoILm.h'Fa+} 9P@ܟ+~6,ق߈ebf@u>M£%ypÅHݪ hSj- ?A l!^%ks!DW@/50M#yZ%U)MvC@r3泾1.e җ˦lU[T}KS=8(W8RjjsVOh|v+J(?5R!FZ2ֱFfPwT B:n6av f0B8NZ d?.8ImbPUq#3~[?og>C`-BdEUyADFJd+X0ZcUʴPg)6!Njk3#'њ#Ug vPHxY+Ubހj[zC T}TaDpWr ADX Z} $>^ME3M"ě>AQL0_Q+74 vV:j~%嘝_FVt|3eȧw._~/y9}E-NA3, kA%3YB9V|,Nar<.ZY 烌OIUUNT`ZB{ZKZ 8i2WR%>(vT>U>B fa:ޕ[RU aVBT'_Y^)SYdCѥ2:wF'5ݬYq:j|J3Si'< h+' gb r&˳0]9<q兘/g^ymcxF^o)/'UZ]tEIF}]"at4PEIp{k=hI-݁:R`7IԱ7U*$*|bj% O4c}0y#Ut'_*~佘EźC6 e_Ws gWZq̻lwMYh gi;1}a^ E:y]=m^ 75?AZi{&U& ;f y6Yiڊ6r@Zp|a]*7KCҎ \n}SOS_Bkeh"C $d%Q(b|JGq\Ml ΐpLMN>[H>%tB>lX5V k_0sJ \n~ _G +UZȍ!;Z@LaJy0#Q|)@KSQ|%jg-CҦE2rZ|gon@?OKh._B:/ۉF͎`iO%$Vs*ɜ`~'m^ٳ{ }ILnM{"DJ*qU,:v5p^(/ KBjO~VQj`Y:fqFVPU G"yQ&NET4j)o&gTb.%R/֟A+LIwM&YiiarZWfFO~B1/UF_s"q$uE5kLm Kb6 y~vmF԰s39rnvέ܆< vcs'Nwg!Υ/t !J F6 O=FIř-1JIy|Βәvu>*V={WKaհ*Äj ;bn"AZ-%GI֊XQOQ4o<.yJrV * 50ZTdB%-"XhѺgQzF*fdo4po6'$֖J>n?H\[gIףh*2LC -#!>4ss?:;+@!"piΣ$l=+Uw&KƠl ]kG9q |oy0ڃ> 3,W7ilwXқ&K)[_q"7:d[[rB5DwI,s~]~cm''ձ\ y*RǂT"]}eZCxf$.Y#'¢J$YcLhȆ=H"%p2&UX(IOEYJi=7 'q6]>T"#Mv(FoҘQC>McJ2v}'mt0J >2ŌVQD aXVxm>GxA}p!K%fi=xQBM ,ĵ:ߦgr:_#-oQ|G{ p~pGt~xBקнg;uHRE`8hcn[[9cU_yK P"UOiYS aq|R dZ:AG$T6P|:旨쇬FXu6;auiw#!Y|Vn͞ugt\㕍N:^́[U2  ~VEe_.`*¸UiG񞢫7Q>װ8ǒ|~37mFn'4uD rv{L.pJ?fGc; GaX8]#ȶXy K>k*:$sfhLљjgbdZZ+Ր LRӑ n |<:㐽jqZpM՘\ !U.q{u%" d1&;C\YWzEiFOQ)͋_*:U.x4 h*k,}Zn,$2;iGsX0d*ߜpYP?F*=Ua$PQ~ ު?"uCTc֘; {r(v{&0= cs0=S8˝½rgz"^%X^J2lp/ ^ݫu75B/r9lsE ĽQ,9b{pt61՝'vqP,v͙o5RJ VeqU}[Nĭ"+rĕY5܂VER U"ǁ|W-[IBERbJ)&[-Tc_qՒvléa! _CK?Qꗕ'E)/OZY5Cƽ`*ڇ_ ],-vSV$u(_HjجjWEYU &ttR([ʵTIHflT vk6Qa9G!SIdqF-w5BZ8:^V#nDWwXInTiBgq7}>੧L0'MU+G3U]17(ivc]qՆ,B0x_:57kR_-TWZ]D7hQ:a?N'MZo+Ւ+JS$B˴Wi^C'Ld2Tmv@Jx6i]VP[}v70Oώ]aݷwa/G讋0 Q(]v74;41/z[=ݰQw9 !uz%eBcGg P[%Te0IUNV'TY'AJJԷ'Ak܈슪+c{JF|Vyq:TNI9zos#VjgJ:EWxLT쬼<\ڜ*nAJ :E7RqF#v/W^{4:V Q(񺣃Gyec>8ѸAx0l (FGo ~wx 7A$EooKT +rG= j468:z{'Ӗ&(dOgɏyV҈Tķ+Jm#f5(PiT=N/>f1Zt` h^l Q zxos;0,T"b%V{5$~2&8ɸZoW] P|-A81P0c~% *D(yƅ)ی6:Ё 9:r5 9N4·ȹyj :i !J @VDzꅜ-9q#}IeiJN 91)!c>5'ܯjF 'VZʺ5=^`d AQ0gF?iug%5Q1P$hkL߉49?320F#5YcQ5.Mn y0ʈ]֋ZYAj)*tİs :'Z'p=|uJçZxkf^_{x5֙u<,ÈZS/Dj*b*㔌t !ťrW 4:8͠$c"qc1 4}vǮI;c>ۘg/f|3o  ʋPK ^Byc v.com/vldocking/swing/docking/DockingPanel.classY xTo23oJ :I$!H % V3 3/REkmtՖnJjkmbkk[vZY|ksν/<X!NT8TqޥVۏ۰O{T(x>(gއ0nWq>%UQI+>S*rNwn=>܋栊"!9{D?sp_!'aHR!_V_/__òGTq?T#ʴF*MzlpVAxΌƣDƍ #F_q;&Np;.s('v"h|)[ٷ٫ǍXd*6i9,Q:Ricbi!IU&M[{*CiH )ހFҔC ~Lg(Ѻq#iF-f/^d-iy8UD:j2LdLF6u[J{KowMQ)g=z :O0'C|7' ;Ҳ˄8Ij"NH I9h2 t֤?%̸b (ꢬ1}qc@Q a=^@MPZ8>OAMF ƌKl8zQ;n-1EA2J$6-.0ߺK-Q2CQe-aa|;F"p0W{ }(_RӣA0(4#.Z$E;:,yK)WXfg+*S%K0OGc4O#: s8L"wڴgj޸T"l M]XD>ߚdbӱ}Z~E={фHb3yS'qgb/9wYr=S^g%'16?NzIl/޺}^Uk`&=ٓ:{t75w7qny#f 9d%xhu[HAUP)K(/$}]o-$kV:c%[{mg?-_6oaM_7u{'焺bx`ZѓI#ό/&EƁ4;֔N̙lj8 gC`59Xg>.؞ˑh!d XY*a~Be/Ѝg5qRP:DAb-@l$@/^35lAJ. #A(xWd?bKj s.ȝJ}Gs3ȃ^'gJZZ؊mJR\BP+Srz8gp+gQ;N@-{Q٢]j? *Aג1ʠj9֬57sbNcڂ}&М9eOl.nA8nb!z 9X̜8 v()&O  r_"mJCD"u`s7gp| jl5{>Lb4{e4W %Z9ş^ jp~aZʂe_58y}\.GѺhAvEX, ҚVaI5OZvϫ59jۏ֬کnY*UOuWfYzuRϒTDFXv[>zq5 &|+ރA3JvZ>ı;{.L<<]xi\WpP5]+-}*\#qubFx؉^Պ؇iCL+2͞왴^aҦ\iե1D2\Ξ V\&у+UU!V u0O.'차9VpSeʔD*L!+Qp07 *_Lޜaz!34P_#X*+Š NogUn+o!7[ oCBePm|Ԑš0NY\}F+e2hne?3{%{kSUBKd{36[e˓_` K |/PK ^BZL 4com/vldocking/swing/docking/DockingPreferences.classWsU]G  rl$ " "9&/ 3lBPDѲ,KKR*%UQߛ= 7~uݿ/*8q$"؂INDq) EdDʍʧӒ,Ir>Bx=x3F c,dH!xQK2)Ʌ020%Ȇq1 ;\='i!HN6f圂znH7' qThS3TZ0^ӥsPA < mn̘-ԌQgSОHZ)#e%/U[nZ[m1.la&ES ;Q=%-CO(h7/jhCsrkrImJkӦn˰lFIӬa[e`vOȘmia< r |α2CYCBy(^FgfۑTu.~*3 E5}|Ctw}O?_!?l"(E͏ Bn ++$@܇wټ]s38puzǼ= .z'zXlbF ~* [9PK ^BO)E9com/vldocking/swing/docking/DockingSelectorDialog$1.classTR@^BTtP(WR((B$)3qC9M (2ssNv8V#DRE `41UeBE6%R!O!UMw`aP,J{]Ir=e n',A L1LWQ ]k]li DT[ʠˈ9ms'cI3yy1*f5asc #ez%ǨU͒e l m4CyS:KFV% QwJ^bAC予Lay +R  p~+f'?W ..!ַWx:eyK8 -\f٫t4H`*3Qz.wV{^suOgJ-sR%e=OOHm 1\_br  $iR&% X-Z5_VqwїmejZB;W (!Ҁ hZr!q z [tS nx4v0;L "#xHtB!GI+1 @s) 7cRh͋/PK ^B.V 9com/vldocking/swing/docking/DockingSelectorDialog$2.classVoEMlg|ڄ@K qR$i6vA\\h2^OM6wH$zBšʹLġ_Px"Xξy>~{3??0v *Y)ya\6Lv\Ĵ\$0"ȅ**x]1hNf k9lџk߼0M{y' pR&] 9(_E8=9[f 93.eG%)Nm-m.J "U|ˍMaKHFr SKaZb`8A ,5Y0o8c7( d[_^v\%yRC33&EtvhyN+vIAN59 G$E o"Ppo+xG dЙlۦw>>P5k(Ahe +0jXa`ccj_(" {&,g8raxF TC " E.j=Ldنi6}dkgNO 5"MH+MĴ'5jĨ1\b* u-T'˂dUɾ,:6+p"*s$L6Y) A"?z&yx- fr La9~dViᬹ7 Cɪ+.Y>K¤7o$C7CԀ{kyhrv Oz:Jp6H 駥ngB2-Q5FsQc?~BcOfV>4jb xf IN%BOј &kU(Th{A n#HB} >њF2>SE6w1mU-o!zNQ< L1! q¨DܝzN$E2Lt?Z"W4{7tNR|́&0Ԟq{~oM PK ^B͜.&9com/vldocking/swing/docking/DockingSelectorDialog$3.classSnA}啌' 8";#!̹=n4n;. M> Q=6)CuUo r"ʖ\Z E-@]@EZM="6TLWC!g] ۾xWA}KKݑ􍊛\Bnr =b$PCl߬v K|;'㧢f|& e E2nBkɚo\gH [ָ#P@ +7x[˶0q ,ϝt0[:u[َPi6HyT\TQsbV]ᆋum7`KLzČe0SS]!+v0_/5-iUm@VZORXB'xOf)2_~nKqR.9e瓸 X;.a9m? PK ^Bu)79com/vldocking/swing/docking/DockingSelectorDialog$4.classSOA-Ԟ*ZZ1Q MQ#>/wk98vݶ2Q4>b"qv{Ę4&agggg~V<"\8b w8PqVYaXm(& cgzJ1OT1?e2lCW[ M f,ўH$ yil޹`e-H7e$w_Y<ҋTձ"bӁ w6^FQOU4/b@ޒa2z_E*ᾇ|U,zx%jRc~c-RGn30m(_sIiU[9RԇȲ ]cyGk% yrKR&t]DumGfT2m nq3uĭJjj_0\"Z$.,be#4rr F\ZS6շ 7I2*>[i]A6ƞjPK ^B Kcom/vldocking/swing/docking/DockingSelectorDialog$DockablesTableModel.classWkSW~Nv&aAn\ QU+!J4@kֶK꒵ ڻ~L?ԙЩ2)89)0e=gy>9~y `_ф\Q0G_aCWWkzfDCxs (0x*]6y9[9mʝO03 U +g;ZΙ̂YuRM-78y#77PAnZs^O#j3Ϲb^t6zֱ#a9bl+PS ršv>^܀.meM8gotȋox[]cɠr9=05.e%fvژv]st(MC$,0KX EYXUш?H*Z%-i 4rRы4IET~PA)'AQ";!a#M\%/е%쒵"hP&jHfu kcn-|7(x(cYl|*ѡb/:UA׬?vn;2eR T8(T,*n-o㶊wpt]}|@CQ𑊏놷T֢UeS)>S9Pq_2$V¥х3ײNYߖíf|TP~2D7}m3"D7E7 eP)AD`kÑ^E?$uh{Aә$UiѬ!W"z>O'_`2؏bAi"3S2u?vw?ѮOz|*/ܑؽ?Ӻ$ }Yj6j!vaۍ(b#DA4)vC!WA~> K+xo"r G<zuPK4Ou-jy{potM(ayo|v_ZhZ|vG~yIZ*K W ۋZ։,=ls,{ 8AŅ|4)&HxnQZ>W+Wig=!U̖I`]hc=8¬6PJ/m$_=&\j\84M=Ĝ[rei|!.cc1ĆH'J((9`H. LUj2EۉCE I[1,w$:F`I4!׻gpVi|7(21:I 1A#X/ZD~ >#jD?ƺ~v-hPK ^BP 7com/vldocking/swing/docking/DockingSelectorDialog.classY xǒql9'aBe'Wb'%Z؊eYB ZzM)Rh (m)gz@ەlYb̼fF^^wٍ}8,nuCˆ qp sݘ1|ׅ;y(a7u{> 7?$R؍ ?uc~x~o/\xiqlЯ\Gݨ7x;'X߹76 O4ß,+ wI_cxx /s7WyEkn4xu>xӍ_F+Äoqvn#p"YHܸ$'^+:mCZD@nF5.bZL1ݚ ]Me:=3ը[ h?B@kkڴȚfմ54;l>[նȎp6٫ZD QO&+\I*CZ*GfMMM ꏨDaDCzt0M=*0":&:9FZ$Ikiœ-:(|j.A5JDsR:&+1$\ $pwX4͵0iQٻpwT5 bȤ:fdKaeJ|ju=j0* ong%oGց.ciփ!DĠ \MRLb-ՇEڧYd;E>J&g#hHrIjf?9(F,#,6!RQ'`mf֥"7cuֻ:т"b)Pvl9$/@;(.>\bm[q .~%_s'S9L{91Pȉr2y39q9QKNP"vR΢M)`F&^r]y_VW\\B\J\F\>+'rBi"^Blűd K.81, nE(7;\XNJ#8)L]99/OY>z/b 8Vq@ִ0IEkǰ.0iFo 8I(6gq-V8WyNwn[p:\!-cOczTKaNߒKg\Omu܍SK5459G8%Ȯ5ű}"E\$@-.W|50#**7bpt>9p 8i?Kzwm%d-Jq^[iHbQBt$96{Z~E4Pc%ʏP5D `SvL& |oYs[vfq4^O|4JǢǟxV$sPK ^Bzx[862com/vldocking/swing/docking/DockingUtilities.classZ |Tչr% B0`2P"@$L\Zdnd&LֺbREV`mъRkbk[Z-H߽wfn&Hxsιs{O|.⟻(Ɠy OUӸDR(gHs4e̔f4JSpqQTk|v.}ųyN69xplrr4([۾U/՚ýQ1 A`SB$uသr+냾(|o>$"^GUi2{eo8vg+fj Dvth=[&z;s8Xc0u;`QĪ4m h"ؑuġΞx2!"ϒ:k%<ʹ wk_:KΑHhs@`-ӝ;H/3&?ÎCtDߧ$(m Dԝ++tўpTk (fhS+ĿEDP]Dvt3Jץk% 0:3ԅ.kzQ,D|;Q .y)3vLF-X,l~չjZ#htth }>$6:`jRqgq贂H+X1y"6m 3i0bw11) DuLU!ShOSWELVluxd9-)-٠k}9 #j ԏ '$'=qjWα,LbBfٰ ϏlW/ұenc.)Gj F:h jZK}0,?wTU·|'t9gY5¡F?qW4U~pxG*J}?^c7FϪQy/cA_P%%S5vQl5aߗU U}kEjE/|QDpS$*@Ԥ\#iUy?M*PY#](U( ۇ2c*][8Na|X<[{C1m^%BB/tQ>~{pT&?"&v]H4Q1zaA&Ui"U>ͩ*]K5hU'O*?!%8ELW;}W{t '.k!3EH9a=Qf&0uk*.?ʀ/RM~\M*pm3P/I*%1k*Wi#3;ShoT~4ja&ψ25#ZPI/&(2Jѱ$RmbyEt2BȼJ,Bn -ݒa$S[yFp6 01Ԛr㎦ab/o<f_4g*W[;Jᓓg/Q ٖ&Y>As eȅXXv(a]RLlY/Iy< |ƴn@"LuȬ1W-BMʛRoRaL3cac1|ĺx$P-*Hpi)+H 2̳p_Jԋ_i.KfʰI#}P$m 1)S* 5t/ɋ3{~ UT>eЛt^D47- SΕk׬ZtlhZ|}c˥pQw(CkĴ]=wxC ,S9ējL!en;#_ǩ ){ldo8VD`TENqTCi6\*it1]@:3>~ҍt ܌l;O- 0Jb`\Ku0.z`\ R`l+]t񠉱.=ƙƉ:<<; G+ Zp%Zėq+ڀx=_ @!o?͡.Z@ j z&)@*8nČ=AR*&>@v[aTR M%c4Nzd{ bٸj֔1W):oNNg2- lo1.}@:m7R (LJ:*UU,p:lno_ oh sDnm]t/N,ݭ T]ct{xb^ПÓ ?FZ;~>]IU)*gRim߳0~Ӳ>vf,R SaU*<Ôd%q Tƃ$PI}y :^ҟ Ł`} {pT4lL?Ϙ0U>BAܛXr>GyyKL9A>t/&3faH6+=eBlf|{=ݤz'ЄAL^]?xKB{h[[^g7 @q&1"A,`+ٔʶ{0}Ghj-ُSQ=dQv^r:Vj/ ~rhQ* A*} z"z&җ1KQZDӾv #b!X(xkEv bQM[U*(^)5Cӏ+sܧ= v} ̓wIҟn@# dS02]H?% Uľࢯ#)M`oVz # *3 /B!z0w`*oѿa't~EV&a0»HAa^_>G(p*Qf:EBs6BX#QlomK*Ӭ4i)ӾdCN*|;M9Hlb8sh6[<3Qla3~tg"\NQ,Ih`BG[jHrF!I`s _:b*q1,Ē7$5(?n<`h`wA?-@9/!E_ɕŃX,0-zH{ö/2Xi$}C.GΤX.\IBih;ӿ1+mp10@^8]:-uA$A<= $@`5O]:kҟ 8$ěo5&F1Y2q7\/so0HMkTS=zn1_hQ2H'W2yxS.$8j%%]7=?K vEry2ُ(5AZďe#?N΃Q|vt{Iz?OI:hy"~37"]g3ιϚ'=$"I KN8sHŵ g8jpf4[Mc4*;T*JC^<IQWnϾm(9T ~?*b΅oPZ8]d;I. 8sNJ{ @^_+cDLDϚ$"nSs dr&6H݃:zYƿߢt{&禍B96?xs,@lExEbTz&{!)׷j'r͐1ЎtNǨGucTkNn= IdSVT>MPyl=Ivg$t[,B/{`Ϸ{YPK ^B /com/vldocking/swing/docking/DragControler.classQ=O0<+(6&d!H:Bk+M?x!d|wN#" ,@;I9UriH IҙoYe<+6y'pήH C`d"<>fd&>{a.J;'evMuƶrD 3;@`T5_+R^' UTln7%tߞk[4@OnGCk`X[sma PK ^B6com/vldocking/swing/docking/DragControlerFactory.classS[oQ zjmZ5V6P5`a9nfӟ@}H⫉?8gҒmgo~Xê :bQÒ(uQL!{4<`Hڎ/c 5=0km2/Jx6\GznGx[ܔwΐxf;|- EP7GMEfk;u1g WMOp):04J3ԛoKp|ij5,cx8Mf{ ҖG|Rb O/= C^q ѰA e^5ړB1E,ׇ!QFPrHQz$sߡAvdhFc۬Pr4MOOLJǢe_14ffИJ=6#ѱH9>f; EU5.]2~tgV0TP ,ј.\&ݟLv 6RɔQ[yo40 GcS$Rt7~KrćXVD`o2qл Jyg8sA3s%΀Hzbu<Po| !S@`mȠ9 (ip Q)Ё#nd O$q*Bt{%}%=x vC- 6{ ̤gG>##I#ɚ}%aq[JsHշ*Ht$CHf -a5˺ t| x:GS> T>D?>>S\g;|u|H'qPͣ]Ts(qF4s]#p|*q!Y~G/M'ȋ20˞/a]MI8)}pi~p-!PK ^B^8com/vldocking/swing/docking/DragControlerGlassPane.classXW60TXEHP`aQʰ;ag,[Rޜ{HV(N{sr򽷳 t{wy'p;Y}x@CΨxPC!l=,ZDq^ \^!WxP3PG4v^꒝7*T7-xix;Qx(ޥxTZ+ ćĔ|ćj>>OFYB >|чDqKyч%*U\RP=4e>cܴH5 `4jƻ-qLGT9ffEOH1#a({׷iYecEהwѶԜԭ9 Ҭ>eo3ƻIu35[NT4K̰QV-L͸ [&Nއu,䄍#/yZdsS;֡ƭFcԦR2DFqꥣ"o 8"Nu77<)(ϲ:6~ s)[}lضmE crӲIi]O#5T);:|BYy<\_fB(=o hp/wWXNo^}ȫ{5d}ԫ߫L k^,(/fYQ±2Px%KP#o5!_2J(-T#X*خ[FKPدceN!%1{"tn`!8@7$Cfb ΃cPNЪ> Kv}SSlC7LpKv2 kt>z|ǪYm5- .aW@(&Ж~D'6rI-DAr)i)ri\:r.2I)!ir[l^.Gr\:ph%.8y\X $<\N{\"9\5T0GI.r1Df?ހ%R"$Jey/d@D:d_PK ^BS 2com/vldocking/swing/docking/FloatingDialog$1.classTn@=I)-J/qK@y!^VU\^. QYUTDĖwΜٙ??xg\Ų VLŪF#6CYicXo@¸=v#G^q^2$CҖ Ci#z[<:I׹d"يx 4'[oQUR`Wa+0,c.(WE܏ʎY"X03|Dl/vCXىH$~-ԑ 4,8X`bʂ:[h5YhE%\$S%٨$ E[TWRS v#;9}_ldms#@$l"K=2TRJ K jgB7Bj.YF8MhzY|G X&Bc30Cΰ|;CQO?P:Õ<"Μ$-Ȍx~hktq waEBt)Ѩ."%,a6˒ѩe_PK ^Bth3?com/vldocking/swing/docking/FloatingDialog$ResizeListener.classX tTfow L$ $04L e<&ŖR֟VږV[JT[RZ[sj[zl=֞jO[@{oӜsܙ;}c$-> V KBȇ}(ȝ?& Tqw)≵Q# ۶hZ=Qc4<ֻn6@wψڂp(jDzkᨖ`^VĈ&BMD6Vt>͈{:'+SۢA-ܥ E\0C7mF}*!vQ$/《>#T|]V7T<'T=iKsWxs=;sA>-ZNbZgLp~f/cS ]aL4hlJ̭hr;Ͻ/;eZpEiILy"i@ZqRYD즎;-kιsx#cΏ9ـc/1W"'Oϰ?>_1//1_g k[d*~78rǟh:NJ*U/Ԉ2F:o i+A1I-/}=Si:3,ަx^W$N9)tfw5{Xc[HE إCor,khF {Nb9ps…|Jܸ.;DQЪ`(hSNѲt^J־:Uj|| 'Ey捋,=IXE|G)%5*jx3ګt`fFp9xcƯĜQlk,f)6>4$/ Wm"TGg`:F'F]!*-4{R%*+!]]g#]k&yxa \eG/PK ^Bw 8com/vldocking/swing/docking/FloatingDialog$Resizer.classTRP.]PŝEʦ( @.#BziIMRpk3:r<7M&'gwι7|`(b8)*HH1<Ȫ°Fd`T1黠ࢂqqm/C{ζ\Oeݬv.*M1  0K.rݔrך5m#%Ovy]V/3sv3to׫ܹ9X Sd7AIAYx`Yər >!.,/gWk-!*>7eVeeĨKnkM]w >+{A qC̋*ddBeLj 4\u ӘQӐ 0y )paPŒ ZHɺCBAiGywh)C^u9ԊtCDӆ'6bzwѩ/9۴;#$~fs,`„)s(y`*&< 5.&Ls*=?#Ag GG'hP0i'6_xo#@(M" 1B@D/{^kFt'&H#Xstf[5-L n=Z2kϚ Pc1>;R;>ʝ$=g|gq*bC;OPK ^BӟB ;com/vldocking/swing/docking/FloatingDialog$TitlePanel.classVoevvZJK/)--`Z RJtvtfxGb%xyDĄho^7˂E"N9ss~LZ,ŠeW>'~)H1$A8RH4j8*JC6+?(ͦQ -T42Ęy*lBC |t؞{@ u=Δ!A['aMfgMn>HY y˱޷vIaaQ[`|΅㼽3 ,n,Scc~6g%ξ_X<aRņp&yNsUiM5 (Ɏ1LEf!7[ϖj٫eHmXLptLᡠ)|)pMhS:11B!3= <ɥ򄯞D4&n%aN|VIgpR)Z->4 H!4 V LNc=AzGX"W_BH/43*ޣ3^çӛ@o;z?Y\s.~A=SXh1%ϣ<+Z< ~k-6`#sb>&lFY^%pg[y^]%Սmvf%>p`{/|>;K@*#nJ Dr/W&YF}X oPK ^Bj8 *0com/vldocking/swing/docking/FloatingDialog.classXyX\]1CHH4F KBVIyIyt摭ֶjw]Rڨ`R5vj7k}[s{3fȀ{;9Op ͸r//r?/A^C|؇<Ļ(8xG`8`I SpJi>}D}‹'}(FbMy/S>TX 3>T><1 %FW|_e? /f,~g|Gw|gsaǏxB?gl^‹_z+ocj[4ǚ"Z<|a3wkQ="PdqefXXckk;5ѸE]ZdLwJsO㶁ޮnk˷h˄<* =m۶KKPRvvu0I!ɮmC&4f̈4<+i߯Cfl&+=a-dkA3|PoFMr. G%T!Q>Y4ҵuCPݠYˢ[Iv4#FT$(uAc`$d0řZ#fҦe U'iwɠa5CH0Q56[&MѰXJeos.Q$962zAn4$mCzTè̟_1mDnd6"_燹#f=h4./cfQ^U=}lVU2V}6NTCJ$y6ϾJ.(JycWPj6FI"c*Y0Tb+szCA3%'2QS:T*RQ)*64r2|O'O xe}}@^d)kH#/TZ'c:k-aq3 ȅlCiJBꍌʟvc_w5kU1T\/Va^aH /Q*.m*~ߪx%.#Cû:˟JRPL+) ['0TPV`kQQyj]8J,TQ'n/0Gyta*IOc3?*^ ž}XQVTh*`q< fk8g.UG^AC_jgaUFPE(U T5֙ѧĉ=J1A-SNm}mZTb2ViXA3I_dU:ވI<$êL3_gy3o"LP?W8uR]ư,}-z;c1=F`QLgHf2JMnHR[3JCg9K] y YN®=L/ Gٯ ^V5+;b[#QR:a]Sꛅk*Rمq1 v׺\&dGJ"f~ڧSCd.rO#ԣ>'R;شy_qN: !t[vby=Emygw[q `Fʑ⤱bjI6WP6Q']2'< wB~OV܄ߋeVrj77ᛳ {r%;7[ r=p~nwdMά"a~\wM L 56A~s%PK ^B\$\;com/vldocking/swing/docking/FloatingDockableContainer.class;o>c^vnvF̼Ĝ̼tF} \~q9\RK 5SK<2K2$&22h6l"€Ĥs~^Ibf^j#~p_Z r[N~b jLYS3#H~N"PRVjr ##0020300iV60adL \PK ^BYjQcom/vldocking/swing/docking/HeavyWeightDragControler$HWShapePainterStrategy.classWkt\UNfI6 -#MRZZJ4iڊm2dnwR@,@R@D ɄR(.p-..+3I3mʏ}9uߗXWhMA>7 B !}BBkj"ᤄs@Ae6($# `?d!GHVp1(n SBn 0"C > /q_;Dpw bsrD6 wi[= Iߜ6g1`H:i%2ΨªV&k[iӞڠ[d J}1bvkpʘ,JT_jB%$QE#{5 0*Yݙi Q8e\=f ;^+4^H9+ \ʤ*l bK" v+Ϗ2>m\FװS3r Ʈ=vLִ{5SexguemDz|a9ad-9jLcfg2fCbLHf /p$3D[a>(Jn>YvtY.$y-1( K0}#e~ (]]g^L5|W43IAO3%[z.șt\t\n+/xE^kpΞNUZAepuYJb~‡ut[W5_:rcxX7GqTq|23>:okxLxBwa)3Egu|iआuq :r"Nx 5QVB[i; ulʣ?3(X$k3#}_7*c~s#%o ^pA5jvd gK)gqb)saҊ'ݦ_C1ff{/KNc.k;vm|s|Mxx1q 5 {vgg{Ǫ#J2o$7ƍ>3phn,}@#"};W˅uY(T#G񷚬UOA_~b|mN=RHvmL4gZT)ɏ %b%ߋgQqL.iʗMH/;lP!/?+sGsȧ|ZyUHzW4M@E'Q= 8$U&ɬJfh1ϗC򡽱I>k'"Hz'"~/6h.nl=d#x 7LnQSi͟]SVLPáڛϡhƽQ>4~_4J^u>@PYԭB]0;#D}ˢυpvLj8Q(m ΣHQʡC1dƸ_"|F#}K1rj6o5Ls)fI莧[Z.PkjVu +IFܶFm#uaREIG|7evݐ}lzumhn$Sn%) ױM3,mX~{b 1[u]6eBvxԈMZ{J?ɐ1[7ԨeNd@Xr)$ S T{L=ֵnN0FҲX>kH\p 6Wh2jH*W\>~,{De =qEdFrpv@g1Rn cӄN +%0# >˦ H=\q*8+ ˥GAR IeRt t:;Q2R-*Va5hRqKU,RYU,crpkX歄nl-}a&U\eWpUx8kGw/Q&PSENI]B{W{*=CnVS*>*> >S9|+7,en(7&nU wXdpWO缌$YѬ!x91):[hJh D|ox4(hI>ű @&u7;j}Tװrg:6# Ks3o }<'}$OU=YE P<-NBx,69b՛] > yTzwIbpSE,gͲ; p6O=|) dx9@O:AP|'-9^Pz{赹K_0hfʝcsZ Ca Ԡht%y˽_oK#F|ڻkI~ZH]Enw=:q8.@'/!IVP0>.nTV kD?ȮCQ؀F4y0!(a4"T2#+N_):0-CHEd(EH}%(%[Yuc5̾)㯤D(y%$X%Z abv w\jauXs':LLk˱v`OBk[#T.Ɯ * uePDjnc>]̮rL#t-u@2,G 1q'֧%PH`mC;q[0vO{A ߈)K}xK/̻{܏z)5PZ*<^QUt=  ö9Rf{d62r@b82q2eeb qU"~x/s_d6a,β gxy8)' z)~b=69~ 3"*~ߪ؍=tT= Ϋ#D0Vg"oSwMX)SſQ,S<^H?&xTx5nSНBj)`ha-s|OW1{3l_zVZӾv,qOCnZI_`7Ì M;&]`qv~/&?|_J>ac.ދQmf86\jiCryÕJ,MdTE?JO^˥ۓn!-"3I[^ [!WsE.RkGgdf-Tǝq-3TGZra*>Hdh7^RԂɮfM&/Y(;TKTLVHp 4dqb.*Iu~1~ʬ$(*e>JrLσ)~MS@[hLE 01Dڑ 8a{SYSs/:dY Rf}#hWb߸$~>tYD;qDt؆ E7=ҟ+,O , DUw@ tHD$฀6 (#,Ȧ7!oĦ=<i$x-\xkDߌL< qoNS_Hl܍-ԯ~; PK ^B frI :com/vldocking/swing/docking/HeavyWeightDragControler.classVSUNHɲ$-`*.EZB/i n6۰v3٥_|J8X&`Z.cq&{;ϗchFFE F#2(" r]rC2&܌r%*'Q0`ZE3zbN ԫ`mLϙE-kf9S]ty zh:nI{faM$)#T(;+v~ΛѲ^mlH' g9w%.UnVQ]P@0y16o,=W$%>zqZ/[J z  ?߫*,x̌c{eh|j71ݷ|Y.9i{wwrlQU/-`xE6YK t_N>lc*-,>Y E{ȇ $LnM> nqǒ@Q6SY<0n{HSWb 'C]In2y0$U0L8'0pp[CJ0/[Ҋ{Ю+z}P(R=|Ųޝ# G y03w5GA, Xک }pJ.'p tԎP0a)jXp_Ajs.o4^׉S&I|Xʎ^* yġnS5Ef7=[dZKʁbҚZ@KrYi˵*1J5:꜡^(Eklݣզ6Om}3 YvXB|ض:GS]OH~F'I =GPSy󭹢+bQ֟!4`P])zŮ"JBBtwJ"u&lkBF6p2P~֖>AC]nG[8:ID#l&M)G{DmX|wbVy5LG@Qte )Yt&q0UהsDG=Ra]<)a=Kw^yc.b (H{\FQ;K~B/W/_^ 2M"I<뽚;V$ɁRźROp9 6kX)|ZE ~֗PNWC?f>Q2M@+ct-RrsPK ^B×-_ Qcom/vldocking/swing/docking/LightWeightDragControler$LWShapePainterStrategy.classVmSU~nYBҔZ-֐ AKThx 7n]::~H:3~rqp#&|Ğ, 67L_?f3fm69 3D1y ?Ր {E Km%GoUKVdMqMPpֶ<Ǯ^ֈnWJP5%3rd퍪mGQF-YPXQ-\R.Jk3].% VMg@کdsfy[2MQ2q ]f͙1Q0:좬,J3]tjK '93iSe8YAq3g"F*vqmG)=ٝOs[rF9Yu.G > z@ۛNP j-0`oKuEn35O.'M#Nb?ﶎ*Hx/~H8sYxE%5txu\U:f3f0׊sӓ /pO}|C@P)+vYCQ(ܹšQ8@c3$R9tY%z\;ODj{wn!=w!F(p/7\aYFn/B !Xs`'iD=I&y;:XByW&$ `*z@74-~xSbT4^*SK2aY>!cN5nϛHQD'S%3 q5z fI kW)hVhWG| cŘ%'aG1c$wc!IG1\"yF'h|J떙pOD#:xcm:;q~k8Cx>NIpXJOMaM8Њ1 1.H3ĵB۠<)!!6U~7{:zwI dE}@V[F2qto?SnGKciOj!ӪI$DZ W4?tTn&U(a(hLm8R,H-X_PK ^Bf:com/vldocking/swing/docking/LightWeightDragControler.classn@u\@i(c IJUR*HA8Kbx#{[ H <bI9H֮׳3?Y7(9pܵqAml2lzF;DJ s%_(q5I"Ej-z'aGGAuOjgM$GJ*&Y8TD^6 0l̋d`iiPXPWtJih! i]r>ցY± 29O_ OFdYA;!lLn- [Ņ=}/dͳ|w*Qgwp;o …ʈBJ?PK ^B^<com/vldocking/swing/docking/MaximizedComponentReplacer.classN@D&~ )H DcD(x+Xw#?B_Q!Q| t4l13:;W_ᡍ5^!s%H2@CB'4(.#V9QZnDBHBwo8?21 .gAQl`&&~R>(kqb2"d.$̏ ލXnotQL%xM#l%Ň/ZB^`aׂ/g.s4@ :M8@՟XA)57PK ^Bfeu3com/vldocking/swing/docking/MaximizedDockView.classRAdY\AP78 \ )LvR@V^CYL1t%<,⥇WXr2a< #/{Fu"kіޫ@ BrQw3#V8nȭbuIUU c~6{p%sfo*"sT?dTSl0\JX8d+Ծ»ǛĖbweta3qCVBtO!"xGrWM5ߍSY M+XuQȢUz"w9ݰҀWr9ȹPJ?xna B\li^ r=NvKkKO4ҳeN#ǫnԾ?dzMv}T+*A9Q{f,9^7bM"Qp Jv idbuzWǤ/Z=ӵRt=˱AqKڱ=߰Q6è ay=LR)lZ*[ߛ y#ߴlxɼvi6g˫˓%mNLPSfI(ڶKԹ,ȝg\c=픷۴}wӏ'Ơ9$Be׺VU6ey T]9f|\0!AbU}Փ*ᮛ #^Y,o 4+|V^Q=(n3uvc ζ[0X ]780+1y%‚{KG%,#/8J|j&/m,v@I aŐ*Yu[=3RT|o-5'lḖ-|;|nNHpDEEEZl0CaT<gn^8\]̭V~Om#Wt*`|LXxưr7j wUS Y Y;')rgoRw6םtOTJUnMsNsy,*5n\]9d7t슀u$S /4bL*wIi8˜e/O!IjĢۍ7ˎksO)ev^Vo[Ю/ hmrםԵOwNpDO9wDj149CF-dLy0"V Ce :n=]$IF-,+<<0I> 4 q1l3b$/ K_#qLRV<9"|ctK1 y1+?0>$)Lz񨾧 qώP8p)d=SFQS+>! ҧa)CwR;D+\5$iD:']:Kty)p",ɔ,Ui5*L{6T] MR/ud$PK ^B$ B:com/vldocking/swing/docking/RelativeDockablePosition.classWiW~0 l8klM ŀmRbBBCŰMlIY6kӤi;1qhszN?KBCO{cZqt}ۈg/*vcZE-N08YB2q ?~x@ Rpg Q*xO TqZoUϪ؄T<JzQs7O fg0x{ ޗqNBQV ; si24ǍpOO-cRs|(ja[$~wGWOOB IPv%aiڞX@Vo%9\slTIPq"nO'qti+nucxS|jrtiDO'F8)]FڰZ%{lZjSfRP%!=gQ3Og >;L5bPJ1!չZٝS5g[1zMyr?[ Sab!t(E%D׍ؖoe(JjvSH6D}/UYbמBXsƲHJttLi$>=aQ"cU,Eմt•bW"崋oNd^kwfÝFq4\&S)}8j Oҥ} 3a12'y44dN#͍͡Ѝ̓! Y asube-ȕ<Q 08(MAaQCG$'{j}șASe\>&g֠#(d|S|SsPds_0K _k4|E Ȯ5MO3àA'.{cA7[&2WޡctWvYZn1=M^>gi.pJ{;j+_)|‡,#Eii%5~ q*wb1 >||iGjiq{PB_kSy&/ZV&sC1DDyH99/o#X.PiN-)v# !MmY1V cd8#jc :H%" x8E*TGi<S:yEv[_ʌE"ky lkpMF(!~?/j, !ԽI47T/y6MSP(T~SB7<'6Rn-4KrHb6% H=M+-5whNJI6~.vΌ;=38SM8IQ dXDMd j+ցUh:4#ke87R[yxs!syr;\<⹑DTYo#uy&\< +qf@ [)5픶NZbp8h]^w PK ^Bjf(]:com/vldocking/swing/docking/RelativeDockingUtilities.class| xEpUw; $$}ȡ@"! I8tV+~Md/>É8@%n\N !!ŠIRh;Dv*a.#d1R 킑8.$3 Y':qNvD"&W³p5SΒlY-s\+{/0<wyvy-\Y\,1y< 17tsKk V&~BUqQŌryFZ U {,(*^P^9GRYFVՕ/)iߟUW^Q^W^Z;!n^yeںUuE4d ² -)QG=GM*t>nHlq5BB *K+εlSE.+-_VƸj"uWό!nV-ZX:KD%~61jq&O")d1#wJ[𪺺bi6jb#@pT|*drew!-2,fmHNVyU+KHuE &U+$@.Nm_u@TS?~NѶtV,u4WZ1qOjm1UVP+U L-;m#G=s\a3p{֓ݔMQ%Jk/"oӚi,n sjW({jlqUTUWՄs$Hҥa}K뤍s薓 3=-Fc+ML[^Y[ZS@ͧc"7hXq͕Q)U*,9TV\|޸0e V`BRK[y'PU5"GLt-,Dl'.+<*@jGFD37 _Z6V; /GL!9,1oĨgFۄ}sIS(ح :rU#kL†}b"&]jJ քbX(ZeǓ3@斂 28FVהՕ֍SNCZ /Êmy"(םR;WM^ԍ)@ca.i0*žRYbVC(j%BX(z(iw4JJkx=DXvkam\yQcDU)3U(-ˊ!XAЦE6[ȞE9uNE%%JJ"4#dőJqzd;VQ^RLJ, RK珮$v-g]m%M{ 0XrMZ\S\:\ưvݥߘ0Lja"b1.1iGH{ܓa1"x 5p C4*^je&^1 \n \sBVFR&^Wxp,Vu&^ќζ@ҽ%M o6oߚx\^L\L]jt,~/;/TBwJ»).1**pD1^hݰap[>Lm"2e̓&>Mr.A&>LG zYqpM|LZ=RO&>{M|ZB`MSGL z(O;Vhl4=f;ʪEEKK M|9`TFF&Ͻ@[}N#^"dL}Zm)BS__:tDkIp2Z@mEZiJ1A7jZ::bi7)O=QFq:#;Ĝέ̽ԨIh3EsJDΣ)|SK䌓Ǽ'{3kJ+K[!oO)זDL z㨱ǴyJG|uM䗅N_TBwy咪 ‹Rŕj'#:ApOoެl6N~ U9#GNъp^ฆG>B 79`Ef ֌eF]Hq8N6mԤG>pNb1P\SJ3Jص 崁PyHLW&"-(/QqE*Z'u<}ʄq珘D!hFuՎ*Ӳ!ZpC)Sxd"]Z.s$PABTvtuY,v}z`Zp  ?(/qA8+n-p. y!.`oCmX  jO0zLdƶk߂'<a״Zrw^w4iy, 6-Ge> 7 "h0 0Fa43j`<\H5 &Mb L,J2Mdd>O6*Yd-E ,pq \37x>EUx)\: upF؂}܏|E])P M\Iג q_RͰ ?_q$k¹ip1\BcK֤{ey /O著\z0A+JAl~$T4:\M޸!H| %HXO [:Sp \O.n\p# h6HUǀ1& pce 0Zi31莡N I@!ZI([1h#H½h(h(*H4S4i iBAҤ5Q֓Y&Wfٟ IVSXOfIƈ!'H3.D6@4 WfqL 4^\Qk ao<?DZq$ilеw\=-vAbrnuZzzA.H {=MONG w G?)L4 "e ^PA b D1Sˮ E#jdKYy-yNS<3j"AQ!tBE^nMmhڸӺlDD7%,]@fpv } \A~o?sD;+ ~nj*rwC^A|0.gc;%J"2 [BK hi.ܢ²,k9AA`3+#++1?I!hkkAy_͗rFAJ0XK KRi/@[o# ?h۫i<+e2_ҘO'-JZ EW8˽iهY>h_l=rivf(}%ĠϮ4yvmPӲim:HWK£1-Ц޲>k%%IR?Zņ-lhN&XIg#/l!ݲ՘fE8횓}`?$a>3 B_8`sp4Xc LXvwa!l`'xC| ːc9 \&"j_._x1x7^[p%>Wa=akq?ƒxx#ނ_o-㸖9p,׳T=;X/l n`gW-c[[z|m‡0ۍ^^UGٻX>]~8<p p/OA 򉸏s|>>~~?kv_[ ߎU _[o6?oEhHD]#*ęxHLŏX.jB܉_ ،_%;!~+#(~ijiA@Pv<&riLjS[\ V1Sy̧mdqV=iO,I,'d;K{>Gt}< Y^:XeYGRI7,W[Y7Q]zYO b}/X_߬XFdF6btfÌ^lя2(6ƘSxc`&s$6٨eSTc9f̦Xq/;flq6^cgsy|gs.V`sYѝ:ylc +s`l4 jv`3Cf>1GO͙3ly>,aJy\a^ieߘٿ͇s7|}ok~0dGͯ1{Okqstܓŝݞ\=빞=G|c||/u}>7OS}44>W }e,߅|r>w?۷m"~>6/}|G~ Bgj^'%Y|_还_쿞_꿙_濍_ƿ/?WWWŹ q)|| 0Gִ Zv"T袞dy' m0 t!+RAniGp CK#b_iv(8 ꠭{qa=!([[7}+̰!ܢ,%td) QI'Q$Aixx j!>OSm:E}7OPsrXLDFV#z%Ӑ;>2{N!23EpfeDswd gEnw!ڐg_ϳ~Rtϛp(y>?9 u7,#/l~_&(h\ l¥&oz^0&BDHZr$ޡE>_$!d],o$GfGaQ(K]Gt@jt# h9X`(h)Ң?B"2h =T^hJ;*Ne32'n_47BӡQ!v nq&V-(.koxFПH/X-+~ "wB]aX|=@>Qw ŃQz=0rvPԃF.-(b;]iKE]yi9-|L\)onPt|ݯ ٜ}o c + <,Ğ/ϱr$s쎲д{8~A+hOح'`b0&6brDeȷ\ !IIIIvd.Y>wT=ĂTɐirFA(&%2WZCr ȧ噁h'#3:XV;MePB_ZךoL dbiQ^)zM1YZ~j C#RՒO<1_!*EX*@\ Wz1L,-A1RşX'3Q1AD1MKӵNP.sW$qv8OsKEv)i2qQhω{R+qV,}X"q@\/kU&qFA\/Gq&7 #IHwF'$,{|qXeŽƭbl[?6G!q::z`Q(8f'%IEbfcxxޱCw<&8^t|.^tx٩ΐxY"ސY8vm,\ gRyd!μcrX&!Kgy+`ʕuc̕uɧd,av_f*o*9*B KlʆelʆeAe:4Y$O ] aUQ\2q*]Z'tuџS~ĩwelL JEڋ,SH } ~xM;r.qwmʹģCI\a'F\@,징O"'e'EZ$r-QQGq FRw S3HrQVrJVN N>=Ngks,ѥ P$a@}Ӓ8< #'\Ê]#W|OOYE y =N=7eVC^f;z8~./jt>Visz_~1DvۨH&!gn] A=5o5.ĀS3+mΝΛ ΏSERA0wAW45RE}HBzB80Z|ŧ0E|pŗp8 WL| !R';xC|o#|/~B&Ч!i\}uSM(nQIltpxʣ!UkjDܠl4"2؆pNi*˹52d22NpjƉ<hHs3AV=@}&[H[B*] ]p N"x\34PK ^Bs .com/vldocking/swing/docking/ShadowBorder.classVmsU~nl*BQX@D-Hh-"&Kdۂ/88~VZf͏39wwӴtF3s=sss7gxE@>q@ד1 6bS`3fͬ9|<{ lnL-=\m :,K(H6pe6 m•|^+Z֚͹ o m#Gc4kT[ʶ@g #5gɊSTX6U:-K@f9?zH. ;_gQD$:kO,/ikJWVyTC92]=-gklYAK6R Ѿo]j2u,4dͺbKVĶM<Lֺ\\cWVC9^bؿZ.#5}җ)*ԡʅ<'=_.Vîo^ngWkyp _Z:5BTE:̾R )E_\>g+6> P*ASɮC/&\%0X [)״ᚸ$3Ǹ6@΁>`کMtE9Df&)*1Ht&IVj&q001?0?/_1,7!ܒ049:k y!+Hq鍐HyFKHuSjAB*rRv`EojSojAX?c3Pu} 7䙢39R=~en&^ۀIB?gޡ tO/#Ia"C`2vIg-;IHhk! P*0]ľY*'ݭWxU_Lr E\*D_Ǡ^;M>/) gRc݊J@sU5<=Gs(h$rƶ<6u'or]>%, b}!Cf›LCr=niU &d-vTs&~[&r]Kgw0V(鵗kM"~t"tiĉa NblscH>v!.ԭp#mx|Gx `$oFtנc p!>QCO|RÎN|B/>S/!8bh@bt 4Ԇ t̏qPK ^B#7v6com/vldocking/swing/docking/ShapePainterStrategy.class}J@kśoP/Fѣ'A!}i mfُϷwsL ¸޸f9ypr\%NT\Z/e >0g%۵˞2OF[DʊS;6?jeapnG"> [35SM&a, BzL? @qAGoj'PK ^B:"ߛ9com/vldocking/swing/docking/SingleDockableContainer.class;o>cnvvNv.FĤTF M\Xf^~q9`*KS2Ad90i̼"IJDFc|f ҬT㟔\ȠKF1202013ی, , db`PK ^Bq(2com/vldocking/swing/docking/SplitContainer$1.classR[OA]eYr+(B(hIb"Xf?$N%2YkPy9sn|&1Vy(a,x♋ C]z cC 3/RźddV[gXmEMbIm$42\*ںRIm}{ CТq[y;!xKG<穴vX `wa6ePtN/.• p ų<1 iaST2{0IBE9 poD>Fy vȫhPK ^Bѧ$0com/vldocking/swing/docking/SplitContainer.classY |uJ#FeXOJ|Ňl%Y|XZ$ݕlI8LIƔI ЦI 6=Sr6isФ%Cof/e~7f2)<ث`:^kxoU].^'TOg]G ^^3 yM|Ƿwf~A9CӃG? TtqU[ ~į ڃZF'UUpN'p*,$[rG J< UW=bJBC(f="StZB!eGI!7׽V),2Se.ԟ:=#^>% >>1u=Ai]ߊD@gfQvCj8_r"/pBZlpD]h4B;~p4Pe}IyF;ApbA.[Z{"HYcVz53+ԋF %8QYAʞ ^xt\D EHD`Eդ;m 3,CjI#yWҰQ&4;,3dCz?=ᡈj *SGԥ$CՔa}7J>16_bSߣ ѼkSK\SVS:Qskޙo0q>&(CaGcGWf Y'XyRT&bʕrbFdH;.䫎p?5kfi0є&bVUӦ)ר&H`ؔmjH)r-k)lfJl7$2e*Cv &" 8jH)e!6:xY6 >S5s&c)ҏ>C) ֕A]ɔDMɐ~rZl_#"g"$7,߃MED>j]ay¦m?m.wr'nLK6専+G*O*},!J`BSw$Za%3l&v=ك.xcH6 +Qy2Ϯ|!bh)RZYn%+xuHxx L V1;:tﴓ7P`lʗ&Rlf" :& -[Y $?3[7ꧽM-|6miccS=z OiNwcKKNIa:Bpr1~8Ol~ C1{I"c/m'+m)$$#}Ugi%qqG~ 8..8N&_}oZFڪ ˰5] n2.ޑb0ZR"J<0MGInL?|nL㲓w&5RmҺ2\!^܉xr׻(7pw! "iE2Uc`7oܓAH=8b^|b<1 %I[;~,i#Uq=LYq:P@̎pTǜS<57y8׹5q,8^]]SFzN+q,9HEȌX|*ez{0YȬ`T.b-ealdn 짠Q::{pU)5Χl?:O3v]khj)0spK |/94.>Qu?%{ x[O`⢣#\TE\Dma!d`YgZGhfXsYJevq.i.8nMp7OG<3XEmz`y?G}=̴q,}s\+cdIbfN2C$prsa+=R=Ur|-VojܔS-98Y8Mr#,s$+u&?ßH|lj푫4z$9Mfdh,{Emhg5b,3$KFף,}l#WXs]i\OSvn`ዼ Sn6J8﹍ehg wPK ^B]V.com/vldocking/swing/docking/SplitResizer.classSKOQNgJ Y)(DHc#jtNBiѥwXX$.#Ͻ@=s9w* $EX S^?pI~)"R qWU0u/ʭG63\jMd#R[2i"u,#L.e9"%PPl8, 1asPYB' D.mj)'7$x̢v" 0svAVo9P19/˵+׭WEYaX Z3XikÝ?+SFѦ֦e=Poq@>00F50*>20H1 B&IHlrN b6[<>7ܡ`;1)v>q zHqVl;.OL\v`}6/lT. 2m5Zm]μ"W:5?Sn&P&KO Z9$]Tl㝴vfeқeMQF=mnwAj{VZU.Q䳇3#t#s p(d= |ZgrB/p%˥*%jn ?gW_PK ^B:V.com/vldocking/swing/docking/TabFactory$1.classTmOP~6m6Nj(u MF['[>u JKn/c ?e<~5i9Ϲs{9%0;q1'뮀$`NB<0/!NiZqP'+=GtND%ҼeE^)  Ca[bg"EM*i"x5=K3dgknk-nz/F>7 >!ta-#I~}9Y P W\李aH C2'a^WA(]ܭcn:FaK=uM/T4uK׶nCFS7g+M`HF_eOv[l; SUjnZnKMAb$ _ο'>#I#;:tgc0pWÔi 3 `0VGx3/?a$SehtċFuCxk|&Pѵ]Tr[8E˭vkmKg3WUmS"eng<}Dc:>< _#Y =1[+SmJK*!љaDgvsk{KnóIJTBk7pぁxĐ>6DEQbW͝cn7cɪ|ߚX'iqʹVaLŕ9 j8g{u_{oSjneܧS&: סl<os+}kId1M#7+ U U2,{dg'NL(ѝR%;}9V4),.201xBP_ЕHc ;:M5?G@L^C}8fD(c&H`9Q@ ]' nP<7 kN# @~:PK ^B12:com/vldocking/swing/docking/TabbedContainerActions$1.classT[OAW(,(^Kv),!mM ՘}tecveGH3{~;߹l clM"9PJ P)Z`2EЖQn1LUk2"({2>#C媞3<jw#Eo3$HF3TZ@8 =V HL~#蹖r_FЙ]?f 0Q=q,ҌݑZ Jf7W$I$72z]Gڑj'ejF.1U?rKԳxu@ 伒"V9jX渂 E8dx?M`X0鎇N#*=}ϰ5>'ìIe3negϪ?'=:5CfTQwMCӇd"&hM'ʠdYfd4Gf 1GO scNSd/~JW,xkt^Ffoa"1Of+%B#qw)$.ѝ}<$ړ '~PK ^Bڐ=:com/vldocking/swing/docking/TabbedContainerActions$2.classT]OA=ߔE**Q-b5`LjLоtw+]3--?xg*Fpg̹{f CTgDޘ{Y}(Q" ]el9aJ _חI ?"w:GBes*ر!z1$a㟑II=q}W?%Z@T<}2nw%, z˗^Ga+c]W7VeXRw_;6kiš*_c;&_ղ$^}CXuEH_WL{?XE Bv?臶|zVWmXo{b9/Nز`a%[a;< <&VLQ:҇E;B:5su 4Vl>m^:g &&,ۣT )bq {1ds9s|;̈k0;)uXi ")Fm,]E/Zzp@bkg *0 b͖b0Z-Mfc=ۼ&pwq5' ߮OPK ^BP @B:com/vldocking/swing/docking/TabbedContainerActions$3.classTn1=εM4 JME!EIE*5ҍZ;i~ >B7 Q}w3ǧo;4 fyC9#W H5S.[H؛_#њ!$:7K?&y,S<MbmѠ,ϐo\|'1ph6S]ܣ=x?) PK ^Bv]::com/vldocking/swing/docking/TabbedContainerActions$4.classT[OAN/E*(x.E$`LH ݑlw4G&nQ[̜5oa}Y_ xrLB1+ #7_ K~,=-ڰ>t+:T'g=AoؙI?5ƞʍ7',O0`_%VL-p8ũNK/5ƌjq` k"ɖFdtJppV<%k:_rJ" H88RI_Y ӶpP-3[ o{AI TbK2Pj5<$lOs:\jE*ғ9 v({vwzztp1ʶUGNϜzHԄ|gP2d&O#/r󾎳BXԳ6Vp|z2WN2 )F^a9H=6(-<0ja31RV}>a4~1[̔bsw.a6'$V'PK ^BC:com/vldocking/swing/docking/TabbedContainerActions$5.classT[OAݶPRAt)1i1՘}m;ҕٙ/3L@(%lه=w.;|.6&A,b)XΡPT"yej22T̓ yÙJPZc\٫O~SU{f=HЛ vLze1,:"8F Xn3Xuĩ^GD/-R8UᡥbT [a(ztĈZs \M=Prj'[c QOx ê=]j4q64.bo~Ǿgxek4C7<+VlTjFYL(b-uaw"0̙pCxtD'6dq#x{sGTbI+G*3A*k}-M:6u#C7ry$+|hzN9BL[l˜8C0g)g ҟb YBq CY\".S JfGKyG9JCQA[Dʗ˝e(e4u}A0 <|PmWtpzj578Fe0[oN=ns %HTų~#t_Fi鮯5Npy6HQ54і TiJN\UKx {.2 aq~kb B]K=ƅ@ =ُ\zVjHA3tHSaF+6ll\Ĕ"VsXG9h(Qw9fHp-5aNcQPg6Ϟ1愜ѩ'TB5BGTҦ1&h`'J!_,h}d!AeD}𓲀ITi,1pv wpWxښPK ^BʨC :com/vldocking/swing/docking/TabbedContainerActions$7.classTKo@6  h Ju)EHQJE!rන"&BjA S* >z|x} =l Yn1<C5D#"v=a(4d4uE03C=|Pk O{~}[do&M+&/aGqS׏v+7|ȝ`GGۜDx LCz$q٠ыD\[/N]#{螯5vpy£VkNi T!:X7$\DeҨ+|_;b(B$L-WHi DM= '+[3 T$=bU  bBk98q4aޤ;]#*=ΰ19'Cɍע5w{:&UƛIfC~\:aS_ $1տvP𡂏\V+2JoYFgCCQdHSX#ml/t}ԾP/9ǻ?l{Aom,B^_wKPpI bim o z C0皦4hqKȭ糇 MDXH2 &ksF#T@؎67.'[;d l)hv"Ėc>ӎ*a:uC;cեUU02P33R )a6 ̺t1Cq'F]Srƨi>{1_}Ok$4\YzoMNc"lRףODSl^KEOwd8vK6ݥa_}}g%P8ި ,uJ?&O*vGuS >&}ևע76L#;vL sJ.M&$7S,UJrND ˉon[h#lSv5nYڌFtOƵIcqUgpijYNx2h /#3UH8-C,] DZ1_JFb%vP3$1-vgNWjLUxnʳ$4~隞~6aFr_H\23%'LPIf#}=1(,5QLღ^[2 bPEot-D9諜#ŝ.z]c.vn QL=&j"%&}䠇~q zWb/ɚGp94h n!GȚ2_mma##\QN, I2YAWze"6> s!y>q=E !zO8H2M 㔸n $69Ϊu묋n~c(!j,y<_x (  ,nPa`XxD88 žN=!m7 = E(1,C8Ò <~4P9XT`'OSNHwM\H2A(a;O|ןHG@,'h?5{q*gObl S*A<2`[hñB5 x` MԨ삡G>|=<䁤dBL%;\46~:TRELlvGRZ$_=gSEo>AIsnЀ\TTi-"tVWt>91A\&[9Zzme[A-gW14`(a-_}Ab^4odm^WNVIo+l sE Ji@ T4zOPK ^B60com/vldocking/swing/docking/TabbedDockView.classVmSF~ d9!m I[bC6mZٺ$t3|ot't: 왻ݻӛX1{Q|d| &1'& 遌 c$dDQӋX_H((KH2A)& 8arFێn"{+X㪦Pc 9 dem庆f6usvD{Wϧ ႥqeV+bal(JH uMl\Q:3 h Ef>};M[(V70uA Aļ/I+4@{W6+ǥTv6!r- f7Ԯ ¸ X|ۘP Y k w `t=J|X{~sӘaH)k]w%qj&ֹ[>?*PѤ `ӂM |-Yg)$f%UL,2N2uf2!JΏ =Rb ,k +3δn.ߘuC(X[VԎ)\6ߠkI()V4ʸ6A pE\{>VKT~dYW+ɲ0*՚¥>w:Cpwwͮ\=i4v*zF븊kԏGZ8ԾG#I^JgB`zFS+{÷n4ꛑG%E9{CWҿNPҙ>"0Cask]21d{P)Mb$ C{$YpN3X,J=0G+$ARf<ɒF~b2BFD>b7v1:|wq/ =KqB.a1q)Ai V8Mzg $ ^I05?/PK ^BzvH t9com/vldocking/swing/docking/TabbedDockableContainer.classRN0mKS8HCPR$;RXJq("wh+ N:8rpL/T9WK\QF"zTY½4_'S]=y|ь\p'%-0^=tU#W&ߜ5t+^VR[vG0<{G@ӟMO9jK檸XJ&B% 9$̢%Ἁ/.pp]8{ص؇kq繇YpPK ^BXg:com/vldocking/swing/docking/animation/AnimationEvent.classR]KA=&&F۪U>$~#b d.vt3SIS}P>Q;/޹{=;wX,l| ycXL+CΫWwFu~t 0VVMtgۭQ\o0^j]~ݲjQ2z&vMԆBo1LVMdYSi&dP[A[!!ya0.jWm+L{n RJce#'>Y"E)c!'ilFK9xqVޢaHdRn RHӲF8,yG"tiQnyn6+](]i0/Ld+xOB܆hyf <3(A4Ǹt]#y*"B'.x dŧ!͉W͛C碪PK ^BSm=com/vldocking/swing/docking/animation/AnimationListener.class;o>cNvvvFļĒ%yEzYe $ 2@?'?)+5YX@,V PK ^B,5?com/vldocking/swing/docking/animation/ComponentAnimator$1.classMAZĞmAEH1aſ9%ztu*]]xhpLyb 3θ|TӖ}vKyIkNݲ>!L vgo@pdS7IU ?ؗ4UP]AM! _PK ^B^W Ucom/vldocking/swing/docking/animation/ComponentAnimator$AnimationActionListener.classVSUݰv bZTi * Eڂ(.ݸ3o>ܙ]C_t$$tɹs9w?> + 0XGbH!Qp*xț@iXe(da|i= ,X\`ߋ g1!cRA3.rK,.+´dxY -nG@BӱT֗Mk!殲,Ze5ϴXNgl˰ae;dȴLP(g4eLds3ͥӔu-59&ĩ ,c/U[߬@7hNH $-z1cγWY9;k%)ˆiBʠE{r/4S/kM2^j;SuۺuI@nw`NrT<*k2^UqWe\SxQDV1*t$Uͳb%*RH0+p85[Eop OME)pdWWG5EnPش@uOKT-\]]{x( Hiom2H}9^l5y5@pLzt."5XD2gy{rm{)kl#G}]RfRݢbz ~+#CAf>.l969#7nyLCkE[sTPVqkxpEeg"dQޔޜEEڗ-aY8?H C!S/pIߪw]~7 4져愜 xqG\p,0E EbgV=Abʽ8+VÕ9bVC=Ը~l?a8ەbRlWJ+×C-9Y3P?a1u*  aBLWFiZ Qň8qf#x^(c q 6=wʤ_CP9DA Q]?LE2GWc4Y6 [[.O mjt6vV5m'.;ֱ6ˡWG~u[%0iGd齇vz%zE=6rxGI DPz9Xwe߹JjȦ9ZT|ȉ@@*@Nʁ,r$JQNEpA<\  u 2~6ޞeAB~Z (ǥԩqz@7[K&xPK ^B5=*com/vldocking/swing/docking/attach16v2.png sb``p  $?ORlI. Ap品" 0kPו*'3g+B<]C*n%'Hd8q gi;9,6{5,/#/]]ݯ<@`jj+fMgsHI-/'~~JYHNӸ1Jʓ< 6uI+.``{ -E'Kdq\Q1l@-x]mٲ労%ƪXFC}}yK -'&xwn`X*u@_1xsJhPK ^BȯPQ1com/vldocking/swing/docking/attach16v2pressed.png sb``p  $?ORlI. Ap品" 0kPו*'3gj~=Oǐ[S bd;͚ܺm7G"L-ˬ=*[xn|DNG<=95fUGԵKHp# ze9v+_tX>`ޓ .0ab_# ]gLBFP֍p!U缲dٽ9Nmep¾yNn:3KGl6&f~b4ɲ]+Ч ~.PK ^BTMN2com/vldocking/swing/docking/attach16v2rollover.png sb``p  $?ORlI. Ap品" 0kPו*'3$ӛGB=]C*n j6}Y};u X?\HjcH{ %3&)^s/|!Ov A滪/W{ʜvJ7L|}t)jv22x|w&y1;$e&24w۾2CþvjA0ۗbl5(v*z0S~h!@o2xsJhPK ^B%c]P'com/vldocking/swing/docking/close16.gifstL``---? F?Yt@9'8t9d<6,8!aΩ7APpnF]2PK ^Bمrd.com/vldocking/swing/docking/close16pressed.gifstL``---? F?Yt@9'89d<6,8!RQйW^GPhӌBen:Ή*':ՌWT:=@?lM PK ^B*ird/com/vldocking/swing/docking/close16rollover.gifstL``---? F?Yt@9'89d<6,8!RQйW^G0хAX2iˉcrVK,= R92UXM PK ^B6'G *com/vldocking/swing/docking/close16tab.png sb``p  $W)WRlI. Ap品"@U 0kPו*'3@ӁB=]C*n͝hu@e~kԬ^%-'Kx9q8Z,lOǐ[w6q?L9ukۧ]М|ffԤO8qkS\]-pBD9KvJssM$6湧oƉw9\u_qcUo9 v[ Y<~qI?/YgNCliGĜk:eSBPK ^BM 2com/vldocking/swing/docking/close16tabRollover.png sb``p  $W)WRlI. Ap品"@U 0kPו*'3{@zOǐ[s'<\/gf'_ ]}<;A}*3!5 z z \݆kwz>cnӕri& V3ݫrjhK-jկ&~ t :&PK ^Bq=")com/vldocking/swing/docking/close16v2.png sb``p  $?ORlI. Ap品" 0kPו*'{8Tܺ;ɖOU5ɪ/teeG |검馧\M?Z;W=zg̰{YgكΈ]<`0#y۶[rLfWn1)Ӟ\2j2[ljE晶uV0com/vldocking/swing/docking/close16v2pressed.png sb``p  $?ORlI. Ap品" 0kPו*'weOǐ[GQ)]t覰{qݢK1>uQ{.q°cu2NRdBl6g l'͝|@ â,uY;=sbdϕOl IМ3)`Cߟ&;Y@CIMZ&֤77W\|:?آeSBPK ^BGh 1com/vldocking/swing/docking/close16v2rollover.png sb``p  $?ORlI. Ap品" 0kPו*' ÁEB=]C*n] >)xXAL+tn׍T_2b?#'nT@ #[\vO  ,͢ ˺(NpeQ!v^qʜ?ߞdꤲBݳw&ZӜyƳ#"KL\?_ظrpn t&:&PK ^B[R}&com/vldocking/swing/docking/close8.png sb``p  $RlI. Ap品" 0kPו*3|9@9%yż). <]C*n%'H0؜R[(sO\Ͳz܎iM )M-d/>&#F9L;NMatsYPK ^B/com/vldocking/swing/docking/closeAllOther16.png sb``p  $?ORlI. Ap品" 0kPו*tE=lkDs~nnj^ s~AeQfzFBOp~NiIf~^1omB=Oǐ[ &O=rm\zCΞhْg)4:f^) PK ^BszN{OzQ{L|MtkǝÞġʜf©ȧģƨŤǺfʯd̫ͯȳӴʹμӾչ]]ԾϺѽ׻ZҽڿXPN)JMGxxtRNS@fbKGDH pHYs  tIME  $iIDATxڅ0 IRh>y~>89dڹ$" |-gÂ&̐!xI5l_ YrPhL0WvN%] ۋVa8gpWten`Eyg0/GZMPwa-y pS8I:?wx]= !"IENDB`PK ^BHFaS&com/vldocking/swing/docking/dock16.gifstL``---? F?Yt@9'8 9d<6,8!a3eńG I6+6>:cb1q*L PK ^Bwf-com/vldocking/swing/docking/dock16pressed.gifstL``ϵ|Q0 FP̠ y2Z<?eE$&010rb3:eSBPK ^B_0com/vldocking/swing/docking/dock16v2rollover.png sb``p  $?ORlI. Ap品" 0kPו*'>p_PcHŭ?o:pAq ~k-]?kF xwq`ώ^ut۝& 5x2냏yx8p@aaoɻ·>?g?M̗u1n zTy' eSBPK ^B\Q*com/vldocking/swing/docking/dragcursor.gifstLT`P`---? F?Yt@9'89d<6,8!sb^s<6.:- `c}RN, rrIJ8Ӽ:,V9?XȆmr[4/rJPYwOm]}}=335PK ^BI֫bg5com/vldocking/swing/docking/event/DockDragEvent.classS]oQ=*oXZWck4R 51>nwoʮB_q b̝;9sf_3 .g1+l*GQ#⅀ʮlۑCY7ֆH=-{;T.Jak[mnl~'?s#r({rzuU@{軤z`kMϙ@jߓmx}ݸiڥ9U#7m]`Fi8u ^Q:+Ti8HJVd;;Ha%R+c<\(7*ǡX#OM]gf 8d &5&jPٸ@>CB)L^өC0CP2k _ .Rlҟۄ\$ø91%@y(/{GpqR#p'5c~FjgT&Kڈjz#\f{H}Qpӊ7U4gpv&>M&jq.?ln6oj<. $ xIW׊*M~4 +8OI(G( +I]"]ߣ/?җ6'L/PK ^Bsq 5com/vldocking/swing/docking/event/DockDropEvent.classVmSU~.Y}h@HRR&B Z&{ nlRw/_ș㹻e2s{y9ϽO?EC9\Y)4dtUҵ>ĂX d*|"bXS n* %cC&Tl2n ickɛHձY\u l!|0 gIp^|*Eiy6v7Lj6IʢsS9kZ۷C,gf_0slʒm=WnÍI3`w!FIANB 7Ķ@~ 'ENPBYk"(ZPmw(XB~PtC=:-P1WU T"¶7T|2P%1Xz'Et4 %[E 7MǨ}a g7MכFUH25͚fjuM\{*8CE abU5&,u_fȜ 𵓁!\+}2H)_.ʇ!B: BT7=^|R/nl`u +hASb5pF1dzTD=$gJp,oL⿊1):u㿧 anzr"r`+Wut{6~'xTe۶lZK qZ27 c􄟣g~\:`}݅D? J&q!!#CO%R^+ ̕1AT:H.ӎ 6B>b⫞/R %=4F?M'OX 1!_1zsop^r5ۈ}P"uة6N 6^j#vqҿ#ψCnsDFAMuR$6i6nrqmӃ=|K˜tb?E5MTG#3DMtxkvtc gd\~ŧ=#_9F.]&C\KwbǸk?PK ^B3+1com/vldocking/swing/docking/event/DockEvent.classSn@=8M6R.@&NR#.T>PE⍍ n]N*U !Qٵ`Fffsv ܑ%)9X9T0upvk΁wHN1TO̊#>sEo^(^I Dn3lNeI 2bxn4KNbJ&2hӀ/vz-ݓ K^w]yNz jyj!ݎÍ0aT:l?n>|!+8_(Ȱuǔ؞L%Kc5ڕ[aCNDUy̛89& &Paԁڗnk_8ʔM}oN%PeSr)MH %D'`Veͪj_ɯdI>GĽILɿeZ1) ʺ@yd%d ^ĥ$MZFeoпR\Qq@Bp)$M* R$x/|RITu'm0䤳abXF35pv'T[PK ^B\`>v>com/vldocking/swing/docking/event/DockableSelectionEvent.classQN@s@;\ @4@* ~ǖH $ >B] EzgovfW&tꨠm`'<*x|EAp=/FnT?8GsC\`pZAb2iz"7Qmˢ \H<+Ž3K ZHd,Ә/?mg=~6#owaP t,TQc8t&o!=1Tl.NC2h҃2r+z57+g1)6ا~V ulXXT&U} 4g@i!WSC%cM 3_6PK ^BfnAcom/vldocking/swing/docking/event/DockableSelectionListener.class;o>cNvvvFԜ<ļF[ \̼tr 㥖yI90 ak0FҢT̜TF9 >%yEzYe d3|!9@'ee@b`L lPK ^Be_vq+@com/vldocking/swing/docking/event/DockableStateChangeEvent.classR[KAU˚f"7]b$B: ~@?*:3`X`,ۜ朝Ϸw'؊!(XfMǺ c} 㵭~9­[݁%y! W 9(hVFZɢpy׮Νl`H=nU쎐ːSOK[WfLչ;Lv5ʼn4T:ۿ)4m Ma"? M")Uj;T2 vA#)E1qO`fn74CaHPeg< H0I),e,,d 4!"4F cB3Op~&xIu-PK ^BH" Ccom/vldocking/swing/docking/event/DockableStateChangeListener.class;o>cNvvvFĤĒTļF{ \tf^~q9RRJ]0$5KS2sR(,.IK-J,Kdd%>!  csIY%l L b1I&6PK ^B~Dcom/vldocking/swing/docking/event/DockableStateWillChangeEvent.classR]OA=ʲPC[Y}D%OUL xN2lS>HBc?e3;w9g7u=A 5ϳL$j_EJ0xzFd [)FX rgd#B;fpD-C.28մA楚L.0YKyF^Q'^Ѧ[}q\=ї4{)Tow塶7N ("f+z2BZR?|ߣNvǬ"aaa2Lh0JW?\LȥenYDX}/өNut,X ^v`NΕagl&"kL &1&i_f2lQ>Ey/ 57)7~'d پKHla^B݁7G-F;_?3]sPK ^BOGcom/vldocking/swing/docking/event/DockableStateWillChangeListener.class;o>cNvvvFĤĒ̜ļTFg \̼tr 㥖` cd /-JNuCOfqIj^j^VbY"## bdOJM.acd`d`bFFfH21PK ^B/eEcom/vldocking/swing/docking/event/DockingActionAddDockableEvent.classT[OAf]lE^-&m&$ 1}؝²KDc?7^@ ->22;wfogQatY7` OD$q$yas=n07([&Nq~;佞1w~с;Ukamgr[d|XѢKXu=n1T<}Sh{< ;u> "ZC;`-/zvrxbXUgbXc:oËѾt#"A^d7e2tSKv7'x- ; avhx||wYcd 3KcXI+n&Y}IV+k5] ֬_}"IZ' 4`[XY[ jUܦJB*mwSlHSM5aPd \ i4?Cx^:ݴa^j2t7h)jxAҦ ,~UPK ^B=?com/vldocking/swing/docking/event/DockingActionCloseEvent.classTMO@}q@GoH*J@B!q],/7ߴTBr&9Շ}o?~x!8-^0yB~W|rH(xFꁈcmxTx^Z۝5Rߐ7bY {C50rZ儐$</g2:HB‚);sB1ɶ Mg߶:6^#8aXVa7U%0T覉Bبx-4ʈbSFu塀 'G|C{/*='^_,lyv{wOP2?˶;eh3b1s%;*ev1Id9:Nm-g-OBkIa7)`(Y_G,7PK ^BSQ/iCcom/vldocking/swing/docking/event/DockingActionCreateTabEvent.classՔn@ Bh) &DRi"k#{xޅ <bvPTU!q,?kmK0p}E,KbjbՄà3T;d1ۍ썴y&C1I26ơoc:Ia38i+g ߜ&nNVD|yT׿cmwl% 9 clor,E[~q>!i`|c1Q_VJ9HI6 1ԦSͲΟE[qⱺ^Nz,t,tEJ(+7",!nPnH 0a٘Aaq p:İ>%?B&j թɝU+CmUuFݞ%{FhI~[+̫Q}hxl@`RT \984<89@ET@Tth*@"YVQE0E\j9'>,P5u=ܐp GWsj9Z SKfɇPK ^B~ Bcom/vldocking/swing/docking/event/DockingActionDockableEvent.classT]OA=lweJE([>(oFB1i}Npd%ݡ?gh12ޙ|PZe޻{ܙzdXr2ÝnH0T;arG:"F^m1829;IȕLbǢ4)EzmD%g[)k_q%*^7´C{7,S7Gw 5Cޓσz+i}wBk`O"qn8O=ɣˁld4X|PUЙ̴3{Tw2ǻ{s{?/}nO=]1bXCE-{yL⾊**2hԛa5[&30noP0L'? a D\_MfꭜHEh,4W^U0QY>BrJeF9BWiP A۔AKdY{2V("+ӄ\2r%R^gI6U?[ fK$cʨX n)2"ax_OF+2ԁKkwO^!)$S$\Nh' !H"GFj@Ӡ1nԾĻD|w?PK ^B T=com/vldocking/swing/docking/event/DockingActionListener.class;o>cnvNv.FԂ̼t=k5))*Y^&; Ӭ۬U*ZgjkM"x:'vYL/膶ut^ Qt:"we:NI_8g#ԗ!M7e2 ӝސ@W+k(. }$y!%y_7h'C\x&(e<fѮXeE%sJ7zQu.v2"D&܈ ҏ[ c0lĐ2HS.|Nf=M8nKEJ}NҢ]#GH&l, }Sb|ʈ܀_*1Dz@Bf0$1C8!qN!{O c[t/ ԃd%apHOOH跤)3"B4o4xCg .1I)hzϙ?qF@CCaQÒdկZ]r<.*iftM`Nu:k+pnkZ^Kvb[@ٷGQl/':kx@r+O-;8 ڹw)%DBTvvzUԫ2Ѽ<>ڷoXkpuhL忖FCFk"J*d$Xnw'A~vYRYәl'|Wm PF#x&KnlSGB]^QK%uLbJFu$qQ8&^!l$0 句G}ΚA_jn>d9kWcPcȕ W2*e >~9c!WAiVD15~W(^R@`&XD KtYIӓ-B::nP9np6KY\f,K We2cp-٤T+;(% m w0VzO"wq/~G#VތǐZ(.ԣVqYPK ^Ba: Gcom/vldocking/swing/docking/event/DockingActionSplitDockableEvent.classUNA=Sn)`E Z-*_ʧ@EX .]]PW0DMxx, ]b៹w̽3?}?ЏtExaH |x0ۑ:b&Q,KZUȦLò5ö"NnO(x,8Q7fe;ծ2R"rp\s5jlRcuC.n .(b5-ouN\8' :pKdgyd .H{b%ֵ܉Ϊ+! >lH{ڑ|4s+%͔&#7R\(m<- 4QMmOK4(DiG0m3rN#TD/Pq OT\FH4@Ky]=y=OAQ U<O& @Q=k@{`EY c~c e@5I_|L;†"Ak>%VLAodo9pdzuɯi7!!o8@0Tǁǁz R9)">Cn ZPCd7PK ^B]dHI)com/vldocking/swing/docking/float16v2.png sb``p  $?ORlI. Ap品" 0kPו*'3ɥB<]C*n : P{ ߏ]^a}$~`Nג/B.JoQRdm+㳓jW3,X5!qk1V\!v9rb+DFpn}q`Ib6zH빇7z\"=Ķ+j82C<_* zޙcrqo7u o$94u,]m鄝Mg?tV5|+R4v}) PK ^B .RR0com/vldocking/swing/docking/float16v2pressed.png sb``p  $?ORlI. Ap品" 0kPו*'3A@.!NVj6q1)_F:>d?gѮM_V6Wy]eŸߙmc`^jwkrq6yZ# ]; =3+n<\仭V#Zx;oxM7bLYj}{yrv%Խ?IZƳ~~Dx) PK ^B軄DF1com/vldocking/swing/docking/float16v2rollover.png sb``p  $?ORlI. Ap品" 0kPו*'3JG[eOǐ[s+|*bq) YpDŎ=s¢g79798;ABcmm7 po{'=*7}Uvtz,@1xsJhPK ^B!TbT&com/vldocking/swing/docking/hide16.gifstL``---? F?Yt@9'8 9d<6,8!s cΊYՓd6\|pOҴIBhl, PK ^Bawg-com/vldocking/swing/docking/hide16pressed.gifstL``ϵ|Q0 FP̠ fon_J0s0ݓ^me O^ZǂQ_̇媰)mûڳICfiY/r0>)xa/ k^:eSBPK ^BHiZ*com/vldocking/swing/docking/maximize16.gifstL``---? F?Yt@9'89d<6,8!,s`anEF}#+6,>'dveᢓ"ش`5PK ^B{A~1com/vldocking/swing/docking/maximize16pressed.gifstL``\{;`ş, : @  2`YQ`ipXQ!pX}y9v^ZpzA΢D~B %'xѭh̀ePK ^BI)ou2com/vldocking/swing/docking/maximize16rollover.gifstL``---Q0OF&PN  V 8|V040 0X8,:&fQ@OeᒣbR1'7-=ݦeEB(d$s2\f^xzPK ^BN;<,com/vldocking/swing/docking/maximize16v2.png sb``p  $?ORlI. Ap品" 0kPו*'5y@.!VsM[DpfZ7R^0[\Q]gXM˓hΥe$|s*)9~iZDbɽuL<]վAohYb~qtbwcNK[Edne#ţ[ڵG%]>zEğx˫F ofi׵uoOzeSBPK ^Blo@B3com/vldocking/swing/docking/maximize16v2pressed.png sb``p  $?ORlI. Ap品" 0kPו*',tyOǐ[K (HtrXԂ{70[xwپf{,>(jk{.]\oyՙ+Osz(L,Hq >W=U­.5~]aa]&23I+ GGZEYذxiZNB^M?'6j``PK ^B+-~0com/vldocking/swing/docking/restore16pressed.gifstL``\{;`ş, : @  2802T8b`dqQ8@2ǃ LXxt*Ok(TJ>5g&5e-7h7^tbNMޓ600XPK ^Brr1com/vldocking/swing/docking/restore16rollover.gifstL``(#(dad``daP`g`ذGȥ"Q`6qqNrmk:<;WT~J ޷",Iݢ7?.<=<\tQ5PK ^B::CC+com/vldocking/swing/docking/restore16v2.png sb``p  $?ORlI. Ap品" 0kPו*''⺃@ .![5.}ʷ&fBNER92etHMnT1V_r7gXǘ7se:u Dcy־#.;wλϢJ&xcU+7OtNة9w Ŗ$W˟^J+c7ޜy甛`@ yE׎(滷KmQs7*)]Na8!Li<]\9%4PK ^BףYY2com/vldocking/swing/docking/restore16v2pressed.png sb``p  $?ORlI. Ap品" 0kPו*'@g.!mUpuc۷=?]a\Aӏy%K3ʠ8VNZ~E{<[1CCJf+s[&esb&; lHO.Z˭G%E*m߉;I 3_g7|} ş){iG9RӢ`OMz_sxҷH\Cyq R~󟤕0C #YoeSBPK ^Bx+563com/vldocking/swing/docking/restore16v2rollover.png sb``p  $?ORlI. Ap品" 0kPו*'eY@Þ.!m6(4MpO[42L9Mˏiv[W>2!w7zL?կMF:7sT,fԞJ9e#Y,ABL7--ifnplϻ^|exݔ+={ď}_y-}f駲oE=4/;Y{7^E _̎ɳLG>Vm|tTh[PzeSBPK ^B \>E&com/vldocking/swing/docking/shadow.png sb``p  $MRz%%E%y ! Yz f )/ L MLM *>kd/ue#gsd&gGd1Af< dIwud`'ȟRqd_>V#xeONLUW='iZO{&]tss>ZV.Rۆ5eN2N(]c5[6zTuqi!Yk+~^z-;წlrmEl;3FT&fTJN6u=%=]) PK ^BU5.com/vldocking/swing/docking/stopdragcursor.gifstLT`P`---? F?Yt@9'8 9d<6,8!sb^s<6.:`G`qCy æ% ބ/JUdf~Z9A'Z38qcح}74L;5ǭ3UBﹺV+k;Ѕ!3#Jf<`ܻqk$yn 7we^׷HJGM(uwc^|PK ^Bant:com/vldocking/swing/docking/ui/AutoHideButtonPanelUI.classUSW] dYFB(eK&ZI@Pmnf3TL3N?}}{.ᶌq,8D+aY=Ĭ@F %|+V!'!/ aUcD/űd O ph85Ȫ8ӮjuMsVi#Kun9]|?O N]uK/}X#E[Zz"Ju8Df0L03m{0? ll0$|g-KXzBBQgH6pw wFG|l'ŏ +'=sm;#F Ie-$TBϢ?"O#(tGCx*B!BW^7@c2[4VՔ[ fHPS^QScA7Gȣu| |E=)[u&3wؼ۶yȐd2)( 44IW ( b;~Z4/JPK ^Bl j5com/vldocking/swing/docking/ui/AutoHideButtonUI.classWyx%yu D8L ,JHCPRDdCB˻BZِzMz$!)hM~J|7c |XA1Z5~\u~q7(&~p`Տp x/N%Fw{Ƚ^۽xyq@,=(xGaA#gѫMsQ[c)112 bc<>.' O <n-Hj &f_?2- zl}2)mCLcg| CZЭu ] f4MK^rjWV 3fv9]̝Eգ B23ΰ*د;ihfyF6vʛ d34O+MlE@QȒC]4& ByLbLi{KMY7eC`T`͙Y-g]G56XKK`q6/FBX`RZ!~3~ CCsxĽ95ۣ'k& gVO 5iԏ_JkfUǮMrB?iѓ!ҨR<>q_ hRjL D_؁Ǘe9g9GEuN1,eQ̪FΩN3M|a$\ `,cIK tc/6^^.} ?ď8~P9r p%~kxw=G:u?, 7a8G1K&)U֥dl KMbфfҮ*0src>ʨ/Bj*5.Wč$'[H}%6PB,;W*ֵ_Kn>KMaf8q#R\P}yt嘽+i}f6QLެ)Ui]23|V(:KIݟFp .-RqILz`#S:9`D+Ne1EWNãEDezl|[4Qܭg2Qڏ Ę")`Nu\D]1Q|o Y9Jv̙\p[l>yQU,VN:Se'eS9uT.b=+׀a-^Gt=be4A 6(*}fGj%B֍B_&.[GiswucdEx"$|Mg6ŒikShIuIK h$ 426 ah@F\.5Fg2Q$[CRN.lԼtL#e:A+bZDb>ƠIv]nb-YFtP0q;jQ-"xu4A@ +,mm/asqn]M\7QzӔƶAꟐ%L5u3%`4 -y$x=}b]X$z(OSzR,輲;;9xy2S D)P=+#ջ=#ab{ig"]PˆE_T3x"3XڢZ^VDXd/DZ466c3l]23P!Y$B? Yq y K}V}$}>$py2B"Vҷ zpDh"rp80Inw|iUy[c2SP履t_Gz:REDuu3-ƭȐd@.xqK?>zj#l6fpk£l7+q1EYB]L6"<[YPMRW0?ed23ܔU ^'Dit*e zF#Q5J,C9K%s30{PQЧk. r W ,O6mܲ˂z0Z`O:|W-._PK ^Bͺ:com/vldocking/swing/docking/ui/AutoHideExpandPanelUI.classR]o@K8v @[B! !Vh( $h>^GϢ  $3? w1I ^vnvg+h۰0cĬL\a&m1q&4't~佑K7}*<J_ߏy?Vk2:C`lF>kte(H^@f7xiddJ01̜eF{Nڱʿ&%Fqv&n reL]q4;4YLF)_sJ\U+vQ8r&ȬʻIxO"H|`Iw69t oPK ^Bv~9com/vldocking/swing/docking/ui/DockViewTitleBarUI$1.classSmOA~-=z VmkBmhLѐ(nnrWn1qv9*Xdfvyvfg Zẋ2nT0.b(-3,qwBn#L|gC/ɛGXH0r3ֵYM1f?`?\ l&.GC} l >l/,k;^QA(H+j.A9 :2,݃ Y^r .}<]hS `L~ѱz=cHL<n .`!/Y N`t`9}ңLvrbLQ^- W<#\m$YWaj [jr4k/vIБa\vb);APv# E$RFNMB4:*QeD?!B~sXX4-؁A9E+q:gqbzǨ4FstC}O0xS v0x3ٳ9>`^/:%| ^kLo8_o9; e|#?v|g?W tB#~RNE7|:Wo;|T'?B1ک*bws}RQ K9-$Y8PPBiBst}d:E_3, rH%Eq)K4@`. a00#bP`4" J2(cP@ce0xT1VD&LrE"&senԧ28ӸTɃ;EyZT1[5d T1G2Kj1A=y8\%[#7.B7q*9bYcXcUKM,YnUxTѢehUWǩb*|hS_UxUUREXXXZ6Y-+l kj8]ᰫ\X%6o16a汍35FMhi/&Tϭ^lhg64ϏI\TSW$ZwVW6ʪQ!aǴVgUl IhcP[p8 \yn9lڈd3h{{Cu 7Gɯё UѣyZ]}Yms|M8Yh~dRZo($ ?\^ٍFLc ULhk]M>M[ zn6í^*CԂShWسaRa 4ɣ:hu[ʭN izM]>Kл)v4dz`Uku9QL\U^"No X^jE r>ɬ2 [!KNiIɴʚYu5y|tUVֳ}MFIe@fmK;et鶎hK8Oģ%vRikي$plF'&9\eC? $=hëZɃ`liyK蝹ڀC߳2EҰQEOa05r0^r5bx?j3&y+5-M q"ow e?j'&Y/E4J#0` ~bp.ʥ]T 4Go3I3.-pO$80$ T 21-1>6-&l6 %Id6-B6lSmiKSlfKgMmhݧf˰I6 jócfcN97ʚXeRl:NlY 0Iī6`L%-Ok<~dJj2#6P lCx4 4P0ZaY,ߓXܞc͍cn;aH޲0B~5ax}qNd ׃|I61WKBNO.Us{A ˜}S2ܾWƒbsgLcjPX{T5)R=q{7I,=6GFЕiPK4S*( L͠X ioV{~:HG>&};U5)HmotxD.aFcOݟHHO3|tQ¾WdκDsdniꂚ:ߵй63"*{o:dMaޟ?E_a 0R)3reLm~;yp 7ެb^^7IfEL?V-p4y|-]ᦰp9́:F8#2WuC3:|hSVnt%Rd ϬLIqw~A >::sy5^8mdz{Ni{I--16|l0N!5$3p6i} ˼J*&NH6,`+K^iXODҟ`Nx>Z(Zpnyhlgo$毰J^U\P^mr쎅#TA%?(9Y/vrfƿ=׷]>Q{!e鑢|fJ`3|i 8ˏr-;BJDWɁ6KK+ÐQ-s|2WϽ%N"\JHk2Yrl`XD^Njjjs 2dZƍ]3c̹AA0>H߁̴yHAJoίRh,@Yw\P/Ϫ}cqV _K,,ܱ@ձSjkFtH_N}[RD7!Úo`h5 {o{|M{?-˺2>W$z2_2#'L^8i#WŽyYs?Zro+pz>nn:'!9Bg_r0R͆DľrɓX^wW{:<.#NJm6,+ɷњRG&wX)P7MxDűҘiYJi Pldw[kg>ć'$ Ac 7N=bin9&A2'VzU.xn*>mIXPFӊ̿q58mP7Fka_WPN~N |/&?b_M7Na]&m=&L(1Xfb&N1bbĩ'K58}L)_w%Mel8y&g|7C9Upvm,E{"]HOg& Z. EzY,}~**b X<ŋIX! C`JVC p 4¥X@Թb8G(#hS`m,.[!o%5E]!ia1ao2&?I+;aQVWTmqȶmu\(@ b\o P  [DhQ##0& }^XCƸ`=A9\Oks&8 np B tB!gWdZ+'U8˰V0(q KiEq ' @'~m!#2(:œ05G]PE ʦ q/Vl`L⸱q j&آU@A{! 6pR`3[`D` l/ty=62*x4θ6l4A8`a6`EeF2`*bv0^)1JqZ'hAF0!= 5dY9Gnzeh:ܪZ.ZWLuh&J#P;i/ӗhi_E}^x#NJ* 8Tʀ<<P;j)q0%k6wfL>9_;Po`8DKO/Dež)ޝAsR֓CV_wQ캏VY"W{FFd½XE%AZ݆3d#ݮřTWb5"˝Ge6)pSi}n!Tg^jjO|ȍ:|+;ʼn%zd n.5 7bm}Zc_LXTdyŝ ȢN1D_oG|[GYKD?BrX',я_Onx.?#=y$dA͖sqӉVO1=pe"YRԗuAÍJ޵lĉIOlDU" cK㤄tiH\6nˍ@\A[3fL bN(PJXJ*()IᔄE *JNtRAD&w}?X;X})JrD} #9kq.)DN~ y Dq#ܻq*>HOѱ}tT?CŸp@8G Z1p,/A D+.HK9xq + ]b;6Kq\('(d''UsY5b=͓moRFR󹍂I'Q[l[c}SDE*.DC#E!\Leƣ`n(Pp Eǝ0T +`οPc0w'2MU &(oB3:MahR6A{i/l  9㔝~<~ZȧA8(.B 2$d8a8kJw0mj Wp;w@|JfZHOT2MY y9:bNn55?Aa)"Kjtf"׉~P N&ٛZPFJr+|T)rj4B.ƂZKm\EF5k+4 3)`9fi-'g,l规+@aLhWx\'$؀Mx:93( ,x×x|ox1K\yx9đx 5z֑KYOd밁b6N<odzN<Kp#D=m1Kz arJ⛸s|qħq7>+lHE|Ab8,1_i$;(;|V(r3N%x4x6e ^ťCh e1CB"Bc IY˨2`+RhJt$ߟMTSp>[::v8ʮC@A0GxHN (03se.)|H棸+Mui(LwgI$kH>ϐ|!mq66)x*Ś1xFft)p|gR*)D JgQFYbӡ5'xWhlRwCXspğp0e:Oox4M]=G %q3$}3ܪ?)S֟g7és?/ C%>_I %HEW%TM%\WoH|/ߔ-oKVGoߓZ.`3(G_,%^"ur~n3%!) FL `̆iPCp̃ZXuꡕjp8݇h\X(np; )肣a; ШEw%7|Z;XA+YUXNwO3N闆= I 7ҕkTt@nyPK ^B)-Dcom/vldocking/swing/docking/ui/DockViewUI$ViewAncestorListener.classT[SPN[ ` "*Պ᪂@8&4/}?'A@ o$~`6#BCZEYc*bW0BǤ)bF9Z-QKN2de-){SIv]{DaD crx^|}Rd+ kpcLc+v<͋m2hk6=sQqZ<#&7Q7,^綧7I/* M F1:hS U}dc{x=S0~h Fe5W-ju͎gBfpq C䱘QuJv7 w6mcL_N1ˠڮ2Csٮ3t%㕈.Y.s`γL`Vl.*Zn|=p+{kVͭ0Z+\Qߔ0dh<,gg3m}Cy:\]ԾUJm*dg\,ʔF-^a"/56-llvP,':홷Y-$wi^Ib? JFq  0{X1q0I-YEPGA6d& >1].u>\ !d8fJ͟U5d W͈lt n7Z1q-_FNthJ%BLp}"$C&TC &Hiz>y AK2C,xC@?gIaD"ŹY)_k3bQ tƮwȘLm7"A "J%\5F ]$\1r˧@oyIש:'Z/HJi__t̟n?ږ"M;䫸T׸!зmEgy{B.i1RFv ?PK ^BF+ Ocom/vldocking/swing/docking/ui/DockingSplitPaneUI$DockingSplitPaneDivider.classVse}et[JKZ( Dl+%B,(IBM M(""":<:vq||?7߷%ʀ;|~?7V ͏s+A`(W얛=hD"&A\l N(H1e+#d;-AFn_dX lJKZ_ZF싴 MmiӲ5R9݃#vҰ5 茥éx:0akD‰]=awkYk Ӱ {am8k& e­3 q]`Va[rCQ=۫ESTucX܏#/;F\ Գm)Ͳt2nl$g߳{fL_M9FpGV$x_X.N\.OCZN?=\P>:T\\R"[ 4SNWMO@=-TWVM~*'K++(M8m+f(RKǭIJTJ:C>#Jb1u .euͦbӊ.likJ+L+>;sgO/>.77zauX6tw%SԄL> ' sw+sAd0q4sE!@SUR;SkΗ/^+#Xܰ2iKw׏:m%G:ŕp`s5U.~C44 i aC;N,P0;3'dcV g y[|%yx]kU(l-Z Pݟ71kW~*W)70{ x(ZJk9AOt먞Wt3QtK <8%lŷsICOcx~T<|Eqbn;Ai:yA˥s8rn>Eȇ *{IAo)+xKto%64Nfd2bw3+ jXTx 4# 0Ѕ)&a3%)a95F3/CrCE 2u8.8~Vh)ыb$syqY\Cq9w ji<Zi Ǻ-sPh[4J=sӆ=xg=XPԷ~\+vjE#ϲcj`6@AD`s[SХ`KDZ$FA dtKw7`SA Q=3Y#={gs ~뀁LH2)MqKmSxOJJr't$̌(8JruLcFV踋{1:zQHY ˥!P9 1g͹=̌"j:<'D{ FqM>ly]sLA:ڮw,f6}H0KV~PUS8AJ9㶨.bW}[W-^v=:i+ÞI!%4xI9ª+l-2 cy4s_,Ph6*ahKdf ᗫ"nH CIr AYP#˭Ri^ҕ]U =<5U$RQJ19>q dqZMP2 CGneu8КYۜNSFk#mMTw[z؋ Rێ 9>mVRQ3ԟT&" +=&i#`"EJk;&iY3 Q>筭IfDnQ>V=볉tb` #m #} ǩ& pb>5p7g !ptE3Ed͕ 1s0%F q_1-co%k=^%ʁ@M )~o iL4MM:0~f޽ם 廛kLWzSMB_3dS\_2K M&Arke.]rd^6vO릧7M cl[ Fs=޳v$8];USN?K҃>#qmn:tJM3@ 6""x^tR\=DOԨxC{uB b}"XØNz@;TaQ)v, C==q{ ꖶ(UV41LP&!OmOXBr{hԝR+0C:G(9 C'g ;;R`'{.͓⪈;C XpҥSdqWau~׈__ڑyº5S-+_@+o .G=h i;[ZVf+)P+0K` (Eh'0_`A4>X(H`-8D`8\G ZZ `a@@@D(Q@\Sh@R %%J`+;Nx7'(pR'K"pj!NԎ38Kg #py \ p.XK.\ +Zk^ 7 Qf[nMv;KnW`&[$pVxP!xT1xR`SO<+/ xQxIx*ro)+7 |$'⟅\ |*oB.>B H, Z,-UxH:ZN+R=n.kR)n$J#IW'5EV+jPIQUTum<OTA{=ʿ5X٤3"Hj?P^Š@m-+Ĭy]Vba9>.'"T{$ *jRuV̫wS*ܲ!ܩu%Jur>E1kuZKAآ:^pʒ~<3hǬĜh8ĄeAhfDJVd tDZGZ8bNsgpFR01oF4uF#x,Ei>;jLX+"k⪀y:MsyeZ6OZzY(u-w Z$[v5_$Ux4_e%l`-HXɤjBC2,u>Y>՚e/tDш2GTk )v2k}RNXQ+ffy70qaj\!߉+29.&yYGkQJ9Q_vCd_BhtRJXs"r/ڜU2RBuƳL%Q;/M!zijf}'-)֜Y:mz3DЫw5cP&BKY|%e,\ $bYȢT2I]!l!x:*-e;9R;pNgAJ 3+drf/T^R^rz]l~~҂pRs.ir\utc.Cl*Km,wFvgR'n0 >$Gthѡ9&\ś]\fe e\Af7o+U:T?{ ;qkβdB!Nޙ2fi#E9dd-{UXjElWD&ZkXvH9ppayQY ;8}9~:sawҨ!/b s@sX3G,́v:༐|{y#fasIAY`u Qys+ܜ=Ȋ=>}RF@O7g 5*"/ ~1;&26qhuw'7hBhdl krm,KM}iK֮*Mᄺut_U-4Gf՟?'0'ҕcn_&[Rx,d1У(joɹayzXL+ڲb!D՞M9z@{>v(4nW]-iꌵPm{&ЗlgB%ܖB=F]=L}w+$lI8cLVN0S{ ߕuLѩsڮU.Cfuitb2-3˖sٌ*gL*s ~"Yi6}كHNJh0O햛--ޭ- C[|7\6a/tYi˺rON=gGqڮV2WL+F1m#\oea}1Ξh_C\χΞ̾{+S1 {viu\S낧 ${5$'UM+T$ub'Xvu-ϼEzh`.euuxWL=kbNI䧨pʶ@?JD#he;Yp4Oɪr ^vG2^NHL} S&IÝK{HgޕMbXs8פ9}(J|/6}[с>mgLo!PYΌ4$Bp~Qjf<.kٔJiLEgh-jn V~ KX<]iu/S\_=r󜭬6)cѷݰrW>ݝZgđj9].v9\CzI4vk*g\y< XE9x,Q췑 b|95MupE$+𚢈 , _)"~'f5T)/%Iry"M 3T~^hj'R-] J'u{ylX|%[b1OwpEfиL#~cͼIMhr6,eXJ5fEֶTD/Q/ #׆¨tK $^ 'Dc*7*6QimFUiFQ^yA:**kȤki0]O>sBR2>ln[hf Cܿ߇򸼙GJ6{yV1}UMZӫӶ6m<([ djk*%J>]%?+_? _y%;X̓ds =+ Ci=zc4qM'疜mvc9J78UWՎ+l6tKK6t՝aS_;sӬ5g9U5PuyyW1iw Ni4;9'OvC&7>Tb:YJSQ'Z ygc]t Fҝq]v}30UhcӶ,AǶUPc;7̪!R>?4 qXz!O/z!8 ofl@~+8_&S_L!J'i/؛( Vro1;õƙ )dmmYnCŘKCqEm\} xo?ݶڗrGm):l< \J\SzNMw)GkJХ$4E.M)r)4%RVkJoFSRRєru)iRהRM)3Oϡ'OvHE=Os{g UY^\o= U}==H症T}Ѓ]yoU_T^KT}Iy_U_ZnRU_^^+I^ JvVw޵ZuZzE7ҿ.Zg7jMvzh3]ǛcoT4^h:,eXDXB'KiXFpS,q$H` Z1 G[t`%NAgsq :Gcx)|.|k"5Jq1p1'Sp1'888888 g epq&5.e7"\ll%xor+\alU*Klg'5Tf|L1+崵ȭ'neu38|-:8-ANBXp6it.[!zgv|jgF>ٿ"ȭ|xm=X-=T~_Gv*#?ԉD\_>Dw0ח$Tܠធ}opKRN;)u<ڍ|@Lp+4e&7_-jk^7fy57mj-2Ong&ڪ]C~.?QXi2׊p7`=_6&jy,Sq?='y #,SX&/cP j'-30vI2x /s4h๥;pB_uKH-]i6}֘OOQJ.Lϩpz/^/^fה *x=3!UsD,[d&lsm$&l4/Dg<ʼExBxwûޣxَ8?8i!eS7ضPn!2~ y%Z:T́aL/ ?PK ^Bk0com/vldocking/swing/docking/ws/WSDesktop$1.classPPJ5,,B#Ob! m^,<k3sr2'uwrֱVaT6-uRLjcUD.z4ԑ)?B[M ь2/VYBPC-;&J`ȼ>'-vm.SyPK ^B%9`ACcom/vldocking/swing/docking/ws/WSDesktop$CompoundDockableNode.classSN@=΃(ЖG   A@(T6L;8 >BbQ;NhUeg{t<=?<D>!|֡b&arN E55,2ܯ8\0 ]r^e%q-յ(h^''e5E+C!2Uۮ1"tRߔWN`%4.ugm9d^rN,ߖuK cnS*ɛ^JcyO +-~-Am04Q#SP{c׽tt_ZW I)M,0аl3#8Ov=p2:݀!9z7*-Jdd@}RCNPBP\G6 NĐCFP(Ɓ4!61;(R:BW5i1B?Oi&0摈khGpdB:$<>־9`Q6clLt Ma1%u6\!Y Jx*\(RUw-kkΦ[QYVh3+SD#h.+'wmn1P;$ |#egz@{{S8bnT2ԉ2}ϣa]vSǫrlLjigkMO9F8j.3| Rz"/kmQQTImt_c]Eԡm||7y'S__ vBG-<$jSJ3@?Na?~zi\ :nf-%°koξmZg0zv˃2$j؁&σx":dH|& ynasS32laXXj[i֧ 6$$m8Mo L0gby cM tFmK 0:ol-Tp/b%+PL@oKrVXUV"e"y)&5-`N4Eʕ Vy*/Ьb C(b3d"ȩj%5ŠP9 J<y>+e6Cw01(|#X,E\ȓ \Z.n cpYP}4%HF\@V" ZI?K^'_TSPK ^Bc$vR3com/vldocking/swing/docking/ws/WSDesktop$Node.classRMO@}V j%~Z4^ &&DR6Z,-i[ ?8'尳of;ٯO'3a-Gf6tlftݘ=:jq* y\ $ S3Z쇏N"85`إw(̙ERn[=q0̢83W8= 37νA^DYkqG!ZcvѠ-G=l[MԛFa$q_ %o}ͻUf*t@sP\ؚ&|.S4fS!Kts!Z@eD^= PK ^BRM8com/vldocking/swing/docking/ws/WSDesktop$SplitNode.classmOPwu1QYQ8b0EuTJ_JM$$ގBp%=yOQXG\OB&s鉌)Oǒ3^Xޚ35Bn-cXs݁SxR՝nf}!2Kv]s b`U΢2>ۖt!nNȠvBa4p.%8'VMNzk oFyp J4\4ck[] {Q[·BYu]YeFK)7gJm *7CTjZ =Ȥp})\%.)$ѝ3-9 JxtB5.]*t5nLZ1 }bi2 /RjCvvhOjgG~Wii\vLqSPov@ڜz "M &") TpBP#t ]<z7L/ Z#sDo|>mh$~G뙆=ՐyX>ka0y66ĵ"]ǑfB0"FDX!?\_V6tDz !eeTD+q^&XGDhk7M$PK ^B;6com/vldocking/swing/docking/ws/WSDesktop$TabNode.classOPƟU8dt P|EN'~@!| #xDXnT"Ĕ@s~ý_0wQ$7SjEcQ <33FP %WmU.:hr9XfZyDz!gC77ݝzmf-۪ Z-\-TblT yk1zyjMgjI&'[eiFkU5rMTa48",b '*\ ˛'ՙ4wM{QܫeӳiQKl^0𼇎rLdJvrttnp_CGc/fR1!]&:y4*uI%qh*XV"0s *^ᵊިx@C58nvzc.0=E\bT }_6 De%C5u:6Ie}:$-\JAzcPG hɴFʪfː^=}IOwm6 @9=F9L!u*( r"_$N/>GA 9E4㯱x>8Hz}v&n\qQiqikhANe=@e(C( 1s'4 TD*jTmmD˜@?Cy>ZPA1á?PK ^Bn/u;com/vldocking/swing/docking/ws/WSDesktop$TopLevelNode.classSMo@}'qԴE+mS-iK*RK nq*qB̬Cggvߛ}3{5p ѬY1c*y-ulc? 0߅{$2;w9y}'4RIk[Me+?[΀d칾#G# ns<,8*0XY/7dW3jοɎOb͎,T :=էkO>cDs&Lbaj:lgM:G,=tFn,T&^Q~*,."ttEU s+h62}<#';o ˓o 9jؗ(IQ }AI CR-ei(,F7&I۹f)(w XGX :i.*PK ^B'[.com/vldocking/swing/docking/ws/WSDesktop.class\ |T?^&! a& !,IæP@܆d@d殨uw+뎅D.V-jZ[޼g޻{=,s}>'h˓BGoNwɛ ~Gt(ϿwJ%A./2yJ &jL~Gx(,D"vZoWu&)\1]{2}7|G\>')X=?QL. eB \/Ppk&?}Tl*e*^(7&*\h4U}rI4ST{S˽tTLBUg2MTASuŎT*TMe#XSegu\rLG/^->:J}MO!S*T/S U M5PH 2ض:FS 6yja)*KJ>T#>RFvFjƦuԇ8WOUT5I+ 5Yd4Pe>ZM4TSMǛjfҭjf:A(YfvN2\ywNSitSM/|\U*"S-4r0yk UËbSUj4 Fݪvr?C.r3ULZ*eZnbB;LT+M`xwI3M:Se}uL>P\` MJ]$Kwkۯ u.3LT][q|U4^PqffrdizMT[)3j*cV蒚h}uEi|qx^UHNcfx uK-EkKdEႪpZ(f2+핇L..)XZUxYPLeufZz%"jƬ8.L}`bnpMlrAu8V_Qrk <XܘB&=6bre] C'i30Ò%+#NB .RhcՉ6#镐&>k-iWbZҗV"7ܺ!2Z0 cdDQ1'ahV|I~VX}v(#vZ1&rHެr:5Z[ Ou5ۆUv5X$o;\C#:PLYc{UZ Hg8Qn:7_9!)mA:\>HSk#5UXa*s9+&f Aͳ O o)S۰fs`;E hVB}|!ɏ%hy6 "C"MGL?XTϳ@”+ϨjjN<5+J5c9LZM$ ~PW 5nKd081 j쳢ebrZR0*@UKkQZ ?Ѯ^+#;GD+PW-/ԈˉctP?PI1J-ϲʊ<ӻ0R`!XrEP\khzv0-\? X;P׃DѰulE"CjKs]E \\Z 88x1?j,wB]jqU1QW>2nt')\ ם\g,\Y-I$ZQ؋*2߲qVgcbIFW|)_ï>W?l~j5|r ˔_߆;};_}:G 3Q$fx+LDDvRP^^0ch 4 k?|3;y>d/`NfPw{ JK5~G:PD{j~AY`9ק[Cr lG.d8fpRR@R #IJ[0\hiN؃1 uF}Pv4Qɬˁm= "pՖ)ۿ HArD0Y IA;7X+,i=I~FAC:-34W]0գW'Gn[j~O jf$9>\%?̕"W/G܊ǢIfu,@₉ڼ.2I~'YY]q֍Y13b'wM%&Fiv!*0^md0R=~huxY&N*-W&䩣gN*9`2kK. :vDd#ing91C/_oR߿lg7ҷ~cB?PMڠ}wEZ~k46C.CMm%Ϝ7whn%sNl"ȷRCxK iDC)uY3V)nwaϥԁRw:zQ 4TJ54ΠqGuz٘?1 ȗYّ> s F-%MسL/nߍčUC@6R`^ruJDgR:ޟ΁~Υ":OKv.w]sBju)|V|F긃ҶR9&m9&HGȕh"pt $+sd[NUm;i:k`ŶkiYWkz^N+MkM/"m)W$j~bE7bm۲nEޠw'!rJamY#Vn#EP[)Gg z7R7h4QFs\c1di߲%<-ߣFH}kk Yos[-i#͵ކA{3NTX:x]t5G= @WУt-F1 qBVEhF-zJ}"Ct-wiu@K閟ZJosGXsHp&w!CS{({h]Bݸlb9AOk0HOQC7S"OГ$d+׊P qAwE=CZh G;]h= S DAVeGX+W!?#jY|lr9<$yiKaY۠eܓ{[KG.-}kc{(**Ɗ[P{@|{IpٮzszH]y>fjԏQP~&u9<η} )714hT铦j@V:'8HEXP13?;ÝM {ybH{\/ @YKΝrA|}dod󛨤-@LbՒr;=#mpvcx6l\Cy$\6~{dzKܛ=%Nlo-0]ALlÇK0Ř<٥`L3q''p H#spuV݄Fn8vT*%pMd!>'c%bu$;{#Btorn` % I=zJŜFcMDY-ޝk9HwpW ^7z܃9җ#㰒 MQ <ţ ,>ZL{}#P獠"F6$)Y+9vʁӔ5P\?6@OQZ]tekZbGsoԇ:ۻp? /s-,0:YͲb\Pl.NL%@n`O^\ӡ O#D_#dC!ʼnyb0h̒F^`v3Y .08>SCo:Bn `#{Sұt(b&${_cx@(/0G,rDv6ܬF+B^ ܌_cpj/#+ ~Pv6C$K" )eTh~'ó%%:\_. 7+"i/U^buH݃n #h-8L4!p2q1vT qF* knC6r--5I&&-z֭5='ꐛJ,ɿwi P>J[.%]{)H.lu`m8z#Z@[O~f(g5T^"m ]ɅӝɃZL>qV08Nb5֙jS kA,#E`\[@{] Agnz* _#]|܋o\ 6$|#a|+y=_}xs??j[_ MW̥Oa|Ǣu2ލB$*.h}A]p<2> '|;=ukѲਔ2PÈ>BGJE@MKTw H;@:ibPo˷Le[PYZZ 5L"O⪛hn͒9꺝)55^9ҲASOFѬ}oi]V'=+限Nt$qlăCA > ܀yksu:Z*gig$tލ| MToM߆ۼCs]*(r!]ѥ1)]ß}>>] * Ęk]DDn0?xig68y)4H/q kFָiPc%X5u:aKH \ngVeY9Zyl! 4KE0$D:Q-%?GsݥvYg9u3wߛgRb foryORl:>|>%"ģ)y[i;+ýem鬺n>2@5S1e+NVj*DkeK ۮr䡐B .E ;QV,侃{nTXKCFu`z3<u5d=7ѝE>ly݊6=y[A z,bF7Ð wd5)Do49yeR{Bz(?ҨHp?^)-RtDkq]uU&mV]YW!'*I⮪7g>Gv, A@/zBZnZF}[/LN%8W@&W{O L}s? =NGkWt}vr2ϳxS>0jSW|.mrvQ.~N~Y@v47k⦌LqS5-#7Q*sy;uSyPc>TZ威&t&<-]g]9'9E9!)ڛM\euww9RB3lk ~DL!vw 1N 53zah*5F4Yj4P*J5PNMt lVRp龜@ߍ\TI>p$w6֭| VȓzsV3q̷)^7;[xR{+S۵m+Sҧ,=MvvzT7; [@Z?Xi[ȜGM*nj*d64T͠1j&uUh:ّD[)9XG$ٰvqn4v4oҳ#\ۍfoy'.`'b#"N|,i~I-oB ڷoh!0jR(VA*TұjMShb9|.I}GHlZ'kw6Ub66HK :,dҢ,eB' #{(=bL6{x-'_6g-3qw )PdJ%0Ow֠Y7M|t6]S2RAKM2R,>r;5\KA#H!`U)PCA#aP_Ց_ŀ`PR ePJxDgϡչh:.TЕBNEtZM5PȕjJH$!;AIk Oo|"G0 ~ m7}׸aЉ#Eaj՝@^*S\.Fw&4V^+teAdy߷}|,81|G-s f HWl:ERdgW9hwWC#x 4z dI]s5k^K:$8u\g-V7Q%vohd0jx8{KK֋"6:<~@-t9K)- ?d PӚb<){a;I^ -P=H4I)ZY&̗- Wgbd?ʿS(DЦQ9\.1͖ZlJҋbR &I5Z5̔ՙՙZ5~&-sL-&*2?-_kc F^qې3`.RL iyw-~ HQQG8!<yNU۩J=MgR,Q;P7ڦ^e2^k hQMQl(Q!k}TEi"ߩӥD?!*M0ot,GnD8cjgU}[Q$^I#r`v/֧ds+_͂ޖ%hV;k'57?{ueSu4 Ɇ7a!AҖ"3+ԔvZk{Jɾ!"7B6ޡ^]ah>MRPr֏h&EէN1y$TS E~\4i/?~ܨK^% 8kMph_y@`0 O[¿쏒wO>$cA 0/e;VzN^?\_fşsXJS?Bbw],brQ<Y,kaxqKȏ0eIH|fOV~-q|9)wɄxwPx7SECqýq7?#4ۑ _׏ j APK ^B2?Wc~.com/vldocking/swing/docking/ws/WSDockKey.classS]OA=CnK XPeׂ J"P&&>LIO?F_Q;ӡB Mfޝs{g~'a&CDAEkk]teosͽ]k,0x'b6D`C\ ֪`P s߲"q?zڝ}/3GF Sjtز/x٪;]+cGMe'_W5K=a2;&]lnTTo 'ZȽa`z_ Ո;uN 6"Z՟œfx@rNSԉ0|TF]3$~'pĊ+uz,IPY g.ࢅ$R 531P>tթ&OBJLzGC="4kq'(ZQ;dXC4)h,F %hJ͡?4b`8C{tJݠijpB"7'zxƿՆ2_@Z~"؆_C*g/ӳ%\&+ Ŧiyx>ysl  Mcƿ%UB>;Fώ({KancTΐ #PK ^BoO4< .com/vldocking/swing/docking/ws/Workspace.classXy|~f[ &!ɂZ, ;-kֶ!Y쬻@<*miVTh5GmV{yl/f}so9 \;G-!x;{u{d6Y>#ge|>/vw0AXD|)/+A|U .y['7>[~PdBFsx"!"A|SB8a·ˆA<,Հ (rDPBsT15f~mejڶƷǣ;mTCUg' 9SêJ4V_t{:i%2=YO;Ѯε-Xʤ ޺M|k$%OlKe̎B_NsJӛ⹔<>7E[Nmg iœI MuZԓES.1ҭvX^O[ŖD?I;5hR$']#w$LKvaBOlkgdl_C\\Xih)KUSg΄SV71?@C?‹:^2c< /1b!j`fogs5/OS"p٦6)i^4?5ˢ% Bl|0dE"0p%rEF K<"ҠWc -~x g 4'ȬB^̵I U!Eip_8 0i [5ˍޜiͥlP+Toui8TQyċԕnIrq1̇"Gd\uiّh.NH_$SW12^N^!CF0 egN4 'c;6,zV*,eJq8NR G5Բ\>}/V$a*Uݩy䯻|M8It!Kc}&o3Fױqj2IȐ KWvͷZ>mZ]̦0%N&J dUK(BZvCmffH}LR  *y.Vw1[8o;RɃ {Ks f5 Bkg 0|C)0b^Ƶ>1sb)frw9w G ZB]YR!,(2%> Ue2%ڕB FZHY**)SJWܭZe:R8iSՃ%iAE{]=1qd)iҎFεw&ʭ]>=ه9r79h@0n˚Uf̡Fi<\LѴ. eb/WbE4 juC.}ioBD $/٫Hwڇ0qs &u4UO@uS\}5?rWs#~4eT]#L8i1qoA?wr~̍cf,0͑ f?t 3^w֏zgwJ0$d2|)~PoE#i+a,$MQM~^ݫRr w ο]Iu5]xתg1#(c6Rd1rw'[J^b&S٘&}Q|Iboako` ![GԑaBӱe-9+Hi^ јZREh%uI Y͖vHj$p,L߄vihf53n`D >j1C[Is ˶wu c\F45*6^Ul|bn7*/)Ex _'CgFxʷE\O[ FF-%諢u^"F|>9TdAIt6CeGaJ}@zbY-E!p( xi.於lKuJ2xr7EF%(ӗMUgq)è㈮W-lJ]C, H.؏K休b=8& 5zMpD5a4{T=:h, U/'cxϪEjc^L^\SUo S|VZ΀/ Ys#.&5L٬kho|]G?-ߌ0O.߭:>zAxvvP=ao-n3H0T0H0Ⱥ/4E2y"=x <ٻGԫgx yV6rV޳]X?:o8;"(؞o1jgH~:?={Ɂy7Pk3c?߱Nk2os'E8Cw6% zy:N(}TU&˥F/ڒX<1Y/Yv|K>%{7ͻOVSr[n1oCXsdN7p@VVC+u{H4T3ZL2P/d@1t] @O Z_*0jJ(?>PK ^Bցq?7com/vldocking/swing/docking/ws/WorkspaceException.class]/Aӯ[}W%6Ⓒ)JUcMjV-W~%lڈx9ϼgf?^`-$rF,YXB2pWvY:!9a| ? )hDH[;(lOu_?ܮEu# eחƵ TY9|xI&[Wʎj؏ލrdѯ]KW*‘O|!jHE=bBvgL&ܗ[A(n ,]Qgh=Ә2FV 0BϜ@FkH<4!,^x0{Qs.kzjXQvys4ۮ&')L3ðfbufm `e9fuX%* 䦭o}ì1eNOPK ^Br8com/vldocking/swing/docking/ws/WorkspaceMenuItem$1.classSMo@}q븍U |4@ p8P *fn۲7IE+A8QUB7ofw .:K(n]gᾍ6-<𐡬NŰ؟X轟4q:.d_F%O)Y9Óf Ci?Jj/d<1b<KZ,(~ȳL;{cWPA8!FwƧ3˩¸tm9 hJǨ3,).F}x 2QcGt#Ku-4,vPAˁvn:p'w\ShL Ű{A$&V< Ŧ$߿ID48%u"Ѐ!t=:kڟ/(\ZlJcl.@?ū6gh/z.Q~ &‚aaB=R&GN>3in-Vxe&\32q9jx0PK ^B;6com/vldocking/swing/docking/ws/WorkspaceMenuItem.classTiOQ=tu% .e(ʢXD1P -3MgXW$Q^R bdrsλ/cx $`"aRၲMa:&0G0]WV%/ˊcVdw<⼀x.p6~`Uڔ1T!*eK`{٭Rѳ?9zVnϮN @ĐL@ :ge?T-pڲv[ sv\'%az`E Vp\&+-- >8Lh[b 7H|!]V*uJ+PgQ|G 9&F[vBEs(W(,˥ϫI=ٱeY%O`5_ALz43CC惕.i(Hd! JJꕷY傣ju*8mTcp@jۧ~q@.&r#g՗=,T+ƛ/bu1bq៼O t;K'WWwte>)3sι>,+ܽ`$o<\6 ̟eQwľЫ; 8"(p U*h͠O FLF"ju7xC=`fff'Q'f PV!jD=!ZmF&:)=OVHp{߽_S֨+؂G#c2 d c,x\>c2?eDSa|2x WΟb.N(>/d _ C_WhWeZsazo|S^[K9^k?^WQ'~ $?b^?Sa3%g/QlrKYJ1^6B ejz$%GmPSQCVA{҃C\3VfI{&A}vȤ2v::Ϋՙ\2_qco2wX&K,P@va+Od-wlm2_E+l( U\&;fƙTD'w'1RW$v:I'(A!3;Z$kد%d n21M] Z;cesC8Hwoɥ,Y{a@pK|'9( p!mz)8[sYIH'jfP?䲴r-9Ly#V-rswsJMxuQmRvյNniXwd^"i^'Ãn.,ueY1.nJJg1R KJ[-W0‚SN"yf+͵Hbnߒ;AD~(,nRQh)CFb\;hW:ebL&2E8liѾ,'wYt_P_49L@52fMNџ!\ ~^6&Yi{AbQ >cXҫ4Ţ̖ie[c] 4Qq,4bDbZư3[GmFx \c1H!~1_'s]CpD\NL; )"#.y u?L}drdT~aGJm,DeŰN>Ѐb| YYsЍ/2\ WNFh <(ɯ=| /x+WwU ;NMwE1=} r_(\g +*Y1 (xo3)kxFJ-\D S*f4U2z}/#XMDj֥8%~mF?y;:+aՂIϱ~tqliΪ.Ս >ޫzrG̡1?"S%id ͋LWX#i7H8e){i }x.]{e-:G} E哸PN^fYK^{#{郰N1ˑ0rIuN ҸbcSNhgϺ;$ Yʇ a +TktJ~pV!/DBjv^F4YTvbI~qslj>1qޅ,,P]HЬWѥ`anM{7-4Yj6#[fB4.hl"&`(b3s=0^:q>%CR38H{g]9@Wn Ducu)8/q]bM!tZ7U*V)&- _R bu*AN%ѠRX,64QGE:",eFN:8nmL޷z [|.|wyax &߰iR6Z2|Q9*F |YPK ^B4 @com/vldocking/swing/tabbedpane/JTabbedPaneSmartIconManager.classW tTL^BXVqI "lVKDDVdH03 (Z) .T.JjSzZd;w{o.&iHF4-p+e*+djJi:?*iVp4Ks4k87ql Y[&nX'& ]"nYĽB#r̬o( ?`fiH>lj1@:pavN$U/DO-ƗUe(5%T&WX^hPY"{m W :W6Fi!#Å Tߘh0^Nc ½b*%>xƅ$74p_y&0/ؙtc)"E!1ќ΍6D#Da q|dYz|%O AzcuDƆZ^mJǴUTBa9)9T1=7Z&exӛر* =tfIEI[C ul&ӚqUvp.ݡvqtQOm1ͱ_̈́ 6;FOGu4xy@}j5K813,pE9!bC-B⍄XStxmM<TBfOGs̆X*ɚy1`騱0 gf'xxB>gY؎&cbkXhEunhlJ.Ss<`צ$oKr=?ٙҘasu9`ͯiqE6(M(PSC b9榪dNTնX|d'Y4եlǷ9"(,Vg9 LF"^fX8 _.^owOwŒ%bٵ1raC~IتD*<'2Z(ܹYHCJ6)L50\ړ"iFҌ@W}i 𗵖WACeiտS4=΃b:w8* cLq\Ҹks$PS@I)g^s<0 RE`rm-xw»׌iY%cei/ o7Xϟ~};W~7_pN\C6 Z!µd' ohmgX»+1.iDMy)>èQ:Tc6I=\ ܀ u.{^R-2Zdpg9q)s5Jp>ĖkZ9S)kbJU&.m%0KI^R ;Z/\e~RNgx^K.huvs+=ĥp[OSB1F;L\f"UJg;Ѹ;uX dTl 'oF~!C!,uIތF袲qh 3-G3Ffm%AQ8m'I9w~]A#} K/f c7޶ڭdl6Cww2ױNߣ|\ӂ",>E{ 1C-ARj:2iMq- jR&ݳߑExH~BGpSG*y*[MI>3G-iq0ߋ!glJWe$3ζx;t(d]0[ dc$:=k{;LzWLr|kaI[ٶ|n^6y B8yC:ŷ@S4|З  ]rgzzW<;A'16̄h+lQR#xX7Cpbuxy=\,WOnlFw)>Yi/ʝ7/AxEbī^S ԝ|ރx[= :aoc(>0LJF~oGOiQO6_؁/ 5؇/qoc5ᐫ_&kt5]5hw- drZu*xq#-QmTXNy*]ɤU)Sՙ}Լԙ;JM룎3s:Ǽyld\52rMHm&h znjJSx\M ٧ߕrN>N+NW:= $F!9GoFO!M#z hd]i _gZCʹ޷:{fp}=>, ;;ސW{zȑ|/PUB~#` ""^ ]j(P4}} ڒXٷ}:j-pX3>hZ;Վ`| 8n(x (.}WO8܃Il*+V9bEQX$΢(,PK ^BFf5com/vldocking/swing/tabbedpane/SmartIconJButton.classWktTWnfIf. IxRBC2KHm H0-df$`+kZMUJkIKRjBҥҥ??V} ,V=g}w_y Mx'0/j|C8?Qta<*OI{DGyLǥy"b >D >S2EiBJt__ 8.פzA<(ŷwBПR|;hIR/pJCX}ưq0 JNC(jCL{D DF=f %Sf:mFFo,; eXJ2fpAL Zm2+ÆTq=VhVUuoKDYaͮ^3PU1R?3`5$ñh"_lԌkFF w)2@tU03^YU^ ΂V%ّ~@P6삠JByȯa R rN;kX%4f{ac$nK &q3Y7-3e$Hz]{"sYp_<C;iӝ1";dvG#)ȘK, s~8EO-7):ZUw[̀Zkg.`Jk Y)ssɋ9U99Y*42^|%%{Ow埜l¸Ύ$Cj3C$Sj\F<Q0;Mg~TKɰt'Rs%[T>8Iױ72F]꼖D*LGRVҎ\u܆h:# {q3E[]&Z0| 3$X6ktXäY52{bWv=2lV^!Z*űPϖ37#ʋ 9o4ەFΖ9Vͬ~7n[FlQ @RK%gb;xE'i3*ԝsl1]I ;T_"5(Uo4ى.cPnjKJrhe8)QXr ɬ0\A~ڠ7;[Η"9|;V]}l7p|Z@kl@QcSo "GJ8 8 5'llBHcћ0 #|wM;ʰ ס$.rَ6j^ ՓUpkhiA%f|vaJj'+@qiA(= F=|6^H'r7^O"D*Di3p"]D*DbD{&r6IdȰ'c "ut6BDN8X,X]XA7CzxVXUnG,X-vIWyӸmzOcmLI,II,o.rxɅm5Bl/뼅&S"I_bym 2ylxED%6Danqsؙu¸WԖQa'cqmʺr;<_X+rº5ٷ;9yKW]oyWD7RSLK7k[W[E΋n,tGߓH'3: }t^9tCt]{ v]σ>AUAI Q`ܗ?< x݆en"Ϳf)i>qhckĊ$VD i'5W5\?]J  r45+Km 9x`1AR.rJfqjk9QPK ^B#m4com/vldocking/swing/toolbars/BackgroundPainter.classeͿ 0Wug n "(i4mLJ[Fo8=_z] ٫I6%R6K{ɭ?{+֎g%H RZF?jd!U^X+~qo+_0|Ӽ>ũC 4Z&ZaB tPK ^BRوF?/com/vldocking/swing/toolbars/RolloverIcon.classTV@iCCD &UQQH,!m44Fŵok|/ry$B>33g=wx8lnQqSC 41va wqp_8 >Ns3* :5m.;& =N(z/ mԫy|-L5dF|̩;@_jnLH^8XtܛU_2W]=t˦9r*Aidp+BUoKz:P%ߞJsG7j2n: $ ?魭{uv}|sXap 8ԪBUdB;FܐXw3$U7eO;,COsC\ctQG?kfE̪1\u\$T?%X"ѐ':X+:."%'"@ٷkRK "Ww#;ݸTzW1#7H'˷rHd#΅0 Q2H"rDDF,rDhy֢3e>BM~\FK",#s?pK婴z80%;F} )mtӯgtI"RG 10;juR0B4JU cm,`\2 YU"2uTI5KD.wCSit>]IB;yPK ^BÏ0com/vldocking/swing/toolbars/RoundedBorder.classSNA=nmY'HYkW?FIDMw7b٭[CCLbܹs{ϞO+xTp= )ȠC,nf[¬XUq[v0LTw>7x'4*2T͠-Ð=|5=_;n0 K; ϲƫkll5)z&op( zg7-|u#z^ڮe[=߲E1'-moFZqC0u并Ob|j8fP'^0,C&Tb`4*4> XJ$PjKCl{mߴ:Rt(l QSHac 熾ܖG➆50u<а ٲ)ek$ڌD3zj's~0uwy]dH&y#}ӻyU U& !-I:- j p4z61!Љf$5IZmC%ӏIw!=!/>E6Gp`<0K~"Zqfi{~Xy#G<[ԿB=B8W '+Φ>a68R0²j o82]EB ]%/!y\x, |>St785# PK ^BhgNv 6com/vldocking/swing/toolbars/ToolBarButtonBorder.classVmWW~nvVBQѪjP` (ZIְdj_/x~mB?Oәizz̝ܙ3_opŰ(1ga4&7܌as+Q/0dɒ 7xC&b % *( p, z]6\M}}MnVj>|[-ew4Os0+. ݬV#o<$1buH7{A -tDa{"EPk^r;Yy5G$bε)f3 7{k6OG$jdS?q7j~zir =Jz;Tr\rƦU!{f f@dBȼCp1L~)M&":D8ďF8Fi|V lyHgI,- Nf^!=P+?@݀z^T DrBl F$[p_`tfkDZlVSD>u7$ \|b?[H-ڄTP*4pW<DKbIFPgdWePK ^B5com/vldocking/swing/toolbars/ToolBarConstraints.classRn@=⤆IJi ꘶ ^J"*ѪBB8VZxg3ޟ (Ufp^ Ȣ&CC!ӵs( d?P(OsqDS.襀f6͠ۮ::"vЕޑT.`:n0ϼ^=qv1 #UhٖaGsjqC= "E*fݗg$Otp UuҬX5e,03@%kn]/KyV6Rk5{7pSO;}㖧X7gOJSQR`dīFv"sK!Š}P K$ l>EϨ)bLʰո" Uj.)i#d.W K;ۍ&BIfMČ$$^Ⱦ=G"=F471|#]2fN݊O~PK ^B1: 3com/vldocking/swing/toolbars/ToolBarContainer.classW W6l&MNlӴ <agIK6tOҽv mzrzzhB`{m>~AGP#$΋C>+ 'ą#3!,E, [!< !|'^g^d}1@ kbbÛbJ$4USSr㪙 a 1 Wr$%cLE,~xVYPK˥G>[-T$YPL.*sAM׬%Tǻ%)U j:ZT1e2Ǖ谑 -]Y3Aô,224=_`$Sz̡"դ}ѝ= 烌}̠.aؓ9G7Mf4dU˝=t07e{>FnL {ƻKB:}*W+SS]k V l_ Y5c^+o0XJ<j2";L2bVꜱkV4δmO! aT65ށ~Wde׃h_J?Tűw#TK=N+Ugo{P2NJ5 e\rqaYƜ7M-;}:ta%e9ޓr&GN3Di5'""<}aAʸw8 ;q{0)V.KƏc?O%^P.f\-ˎ,fyc(y}VL2s>L? 2~e {WnZai*E%~%-cm'划wVq4j S> *#zܠ%rQcÎ/-?C+(68)/OƲvts1 MB Wp^tOsΫ,:JYQt%sσ>@el6*Vd.`ٱ+1h 2"#o(G&zew.RG75Nq*\46-U<8ik5DxzgsT=/ m9grǵ<]gDZ|]Ў[%H|e˯?[-p. g)&V %P5[bbbhk6]KnC=IIx n D?\YWwWrOQڏ! iAVmEI |/䣈^rI4H GR#ţTZnUFv!<@%l[F{q6,hh/`t p\!㾄bsCָ\M;JS97J蹟RHVL(_u8e2Orɏ2.cS6 W-=g=Zwq/+.6E'Y\8NJ*12fK2!MqaēyJ㸟ȼ Iqctc=`|MMMH ~!LSIt&+,;uFlgQUI]2& ϐNא1Dpq9\N7$:Vp`vFsO9s __Oy%Οee<9hnL,Uv1Ftdγc+AXb ~㋨Kϒl +VJ<_ޢR´3\p-z*A=P\74 j "|n \Gk4%ɖg(U[q֩^teٷ@[zmQ-wY-wY-wY6U1!Uױ,7/p|H?b}¦WFoǿim?eIlL#Bz<]<$%ϋK4KVVru3 "ţsvPK ^BS1com/vldocking/swing/toolbars/ToolBarGripper.classSsF}I%BB T $4$-$Li:zqDPHI̔G?@?îQvxonw۷?, 0[8nɻ69gsx].[*"~(v t|m=ƚFҋ:(+ÐkJo8 ooA`rskcsy-kyuem c{ ,:+{tM{WphI@1RԱ5dz;vВq^u}IM>=TgN(0]k/F lȹ/쀨Xm*K:Qved)meLa9a39N@6͢Y0~?+'L*C8L8/t564A>E<б>+!SyF=l=#ixO |l>#SƧY`N봭Gғ{\_uO2?EZi#l[4-LJ\0?zA 8c8A8YܾDA=Gt.x}G8ODi Er#ʞfϡHT|2Ԝ \'7l 6LVwJZ'̿,5ƭ`JAmb:|LѹDkr&PA/ć9yL#x.lP9+4\rVN$EfRJU5(dW ghIR:2PO2= 7DA" %rm8m?R"PK ^BH 3com/vldocking/swing/toolbars/ToolBarGripperUI.classVoUP- Un[* "P]\Z/( t3 ă^HoMlbL<#ƃ  /~8ѯ"BpR;)QHT gJb#؝MR\ 8/w=A.U\0ZP`iRQR,6JecsaV"݄5p%h%zl)fz=Z3ӓV0bL:D ^pƌ vEAPn)[4kQP\^n&2q8/W\mdK3OzJ 6-g"_URkFmeT9I30j*_AlTɊrϳvsïX}~)w`IzR!"VA[͓֮d]+̎WcqDTCdPbp9)@r#$mrCׂ\v,@M;HN(*2\hGGMyO[Dd|ѯwhmWE\ F6wt. ֹ. 1u%z"~xM'MTj!]E&$U "Eރ]?B=iK|¥Nubf.\bs;;D1sS&9-Kl i-ftR-O&y4T>M_`sh.I(L)r#t5h.N{ۅ=. j3Aج7PҌJ] HߓeXC7K׃Vbf'<3 -gmN'?_>'o 6| q=Ij׳EbklYw /|m?w{$>umu ~L9z [!/fl:B}ĠR*8⨊^Ër\aluX +>2ތHylZy--%uវށ4`~ NaPK ^Bto{,com/vldocking/swing/toolbars/ToolBarIO.classW |u_YI##$Ɓ'p !!F K$Cn[HvhtKk&~$G'1~:Y,u@QY|ZaKKߗt"x]` aAu;{gC OsR]-5"T72AXjH [ꈊZ:fT\y )pP1QT=KN#=HV*[jCcxL`ʹChʖЋdES]\Mf],ZFR`L&Pl447 s.lUuWךERu^督v,=-tAޕix$fs)9]v2y4Bmhafd-H lK'U׎Զ+4A֯[nJgڊ_7ny4ePfnj/$;1&cy9͐xQ4=`gب?85E b69wjW7jnZ>J$ ć'r2")=s`3Nʙ7dfpz0=]y@+WNו7=s֟r۱蠝!d6 aXѡ#CFeu*إ;v9s%_ƅS3,IajeDZ yRX6;/{k W2jЊv9U[IN= fg=YιkD&:4O"]0kb&3'~,8[ۚb.o&#h+.ǡ \s>\ 7f s8#M+Gqsb\'+WEفq{,qO Ac)nB5:}up*0B>,C ZJR|7Enꃔy9s!P.1|,޲Ϟdܸ9y;0?cHC,*Z= !O`8BeiEZ *Ti KpLt!bNF|vq[I65F#nJzihnïa'>]x1O%h"n(1G~;d?Oq=,8òMk\c=(gjOZz!^{IGHd˪ Gi̽ѿp?3 ==-iC2ETDY_@%k(7?x' 2O)I}x[!cOD]M0+l"$/!R׳vǹ)>crt45p]?20a0YhO13VPK ^BMAV4com/vldocking/swing/toolbars/ToolBarIOReadInfo.classSOP=o(PT!(؀bn{@K·B266 %{{NϹe O"bz@.Sr)b `I't -~"]'wJG0LkơOQ\ 2.}vŝ`x'x:|=φo:"+| ڐtreÓuk}7qmqc'zE*^p}8:pM3H1gH$='D}gHMьw4%=v]$rNPK ^B$/com/vldocking/swing/toolbars/ToolBarPanel.classWWN12Ic!RJfHR$`N6c2Igg/QTj[]XJ}|{f'ɲܹssܻ_܅` &+;BxTI4GKI'"e ߌ`!&e)OGPIDų<'3RqRNUx^"hd9^#x/I4g"^J#{Dq149'Oǫ:g*^S0mئ7iަ@٩J=ɌB`eFJS[:)ǰՓ:&V␙Hֱn;:ġʤ{;6*o2SYA گ e  n1SؐaՇR{AgL+h9^v:uWOI"c݂ғOpwV}xXAC>\ Ӡ%7XGn lQ먾-DQLvL?hє)hY#+z`>9ap 56c7-2#܊NS :5<ψud3ٱն3P,Bq+e~NG [Û% aT/S$hcljKdxKqQx~5\BVr }ƸnԚ __N +FZZ;4iZԩϱ3c&%mVi>7ϱGph\Hf {*.kxWdw*~bUGIae/Sw ?5\owxYxÛ+":r O!"@5-V|eA#Bɴc6]KH>&>>nx5*euS6A+( e1^wrcƌ7(wԬ_7sO%/,%`_^WO xX_w ^0ʮ’pS W|.+璷GMsXobjrB!3Sly y A噒×e9K|y^ZL򫨒O@Q7H7ٿE|:nqqaa|q5>ܹq+8)x7{a>\Y.XvK51d&O{PK ^BI 5com/vldocking/swing/toolbars/ToolBarPanelBorder.classURUnn "!"U m(?P۲Ia۰9+L303>oየ(0n{w={_:vTt" !ɘS!aX"}$cYAZ PтU.Tdu2ʤW]K1$CmUr3GHg2chYM.,6 QNR깾'.wvȫ;Z4Ž4TM D+[KeW阶E3e:uiӖ)2vF9gt^\&{옴d*gy;´ mzϐ+|ㄈ␢I_뚣^,%fh3+Ugȶ%ݴwa<8۬[-rBY/혹t>Q(Wbh-R1t^7 (1>raXA=5{3MNiyj #"a=|nKpGUx+7rskrRwgUqw6}]^퍠fztp8F; :YA,4u+Y ~KaIW=O퇱#)VAQGq*ԍ0]F0"XVʶ5Okӊï( ‡fCH\'l[<ƏD+8wEuHOhSD_h7I6MZ@h3Ejdb>rp2&dz&@>GPy"Tg-:Zh;E{!1Bɵc("|6](]QB8PK ^B`yFCcom/vldocking/swing/toolbars/ToolBarPanelLayout$ComponentInfo.classSNAfR[VZJ X%pinغ >7&/> ^и=9;Y,G5Z3ȡOZb:;yJnҶPnvĎnhɡC:`Ȩb8a q-:t~J:ʩ [rO6 0`P0PD wljhOɴGg|/ͤg4-s>4+~#/x(c/9BN/;;tï[WuzG~,^ /^)[Nh+BߓKGU|([GLKg|.͟BKZbfXil4۱TE5<Gp:s6Z1fHbTa^0Vd4lDNXPEBt=qrX\!e k0xluMXǨp]AZD ѝq?߂Dk!zbLRCm6TAAhAJ3EZ|\]OIVbc?>ClSM4[ne:V l'(Qb s%{To-l,b49.K[Ykв)` pԄ:I :9;ERZk)7_d#v\;kک8HHfgFv/^\,>q(”h}",< '9ș{z,G$#¾ pfax`i+0Qy2IhX{D1̜@4g!KU:3iξ1JG5985Y4Qm3 vgdaiM/B2Aio&!K"}JZ"UET>K wRߎnҖgI3li-RKB"YEtsC;' X fGQXI WCrԑUvM_ЊtzI,Ct),ڍx!r2LäWIG&TJwi~MķsL+sB(A:O"vUeSvGt ߇Pf:msl#{3+YM)Jƙ&I m΃NC υsAe[`[e;w@Z>Ia1xIgMg%\t4:|P*ևvӠN|#NaZȐ'%NDi 44vuwofO'wҰj#^čg:'&,Ն g)*`߁'N\J[i9 'I4ќgS 5\Xo-kYJ|8l:2 d'ڥV{4BSbj9TMFVd};IS^_4!,SչhO<!ʯR# cOKlACWG_YZ:zOn FSt+kk>%ϴl΅tqM~>SW6h3SmZ t1 ~ AaK>A@:,Xq l ehXtקǹE%{ x9"8rSNWQL3ouJabtPTkF~ECssuYHhî,]mW8ފKUp7ۡ8Y9=ҁ5a 'Eh 70n8$<{6ӳ2\  (O6|G8ן0/ Ey@'2O34'ϑGb8-Ns gȼ黈;~h7(.>y!{R;}O+cѽ4QC 1k $yG{Fu(72 {}p=N9 ? G7)D w?C#z8NxY/MD`?rs'hv X,xt\@[t<,W tHHV8bC6$+t ޑ<4kG6Gca.UV[UTl־7Paƒ/C:&]./BY+^ _4ЖLQe~|0A5h0c NC5dq]'!PS 8Un$ëK\)ٯ\ݫ4S ?y4Wc.CY_9T+=\-sݼp-m 8aWDŬOn)K9"U0U{:wx5b3 }c NKnpI?vB̸yh(#p8`⧔&47˨)IPYN-Q9]\ýLR!n?R Cm׵dKUű.긊rc`ŭYBCl۳lԚ|5}<VncJn^ۺ iT+=W䬯-'^u1LBi4މh|>}[Bncl!G$Fu|p'L,>|7W߄Z2,[Ֆ{TK4*;jS5Z"neIthd%WkuagzdEpS߹blN'|Q U5E6>-s%.FOAKiO Xp4JsP~Ou|<:Oп<h. #, x".\KI|yx6 r*Iq1lDw;m0ۗ1m~gX/||>_ 0ke݀䮻^'Baց ==ۗ\>7+2k@jr]Zވ[Ơޞ\V֡zG7Pݫ8r,AaE3HiXa?$X/&'~E.rTQ P3ʁd J~Kw92˂~NT}i1ͻԥy^UrMC uG6$;Z6 lg04xlsYUŤ w괃QCKPk u_Q&nv~+ܘ.̷^q6nݽ&]7H4uÍ$n^~ y1 p[U5w?77o7o7o77777n>n>n7777777n |pw?}~pODsrHe Mn^uZ|7LqDk~|z *vs|T dV@Z!QIv >,mzXP%GޱP;G窇$נj2>7-U)Ћ(X37a8ҊHӊVUPm0!4cam"\CCqg;XCQeFUg# 2i=j&8kF:8pQr]~CT*ȢMT(N:iNumNXlEHI|dZFj!UPVI16Sm_/GRͅe,fG{pzUM'3*sX'LSw-SNi#/ﱺ >X S)ø 4LHI4ϓ CIy* }4ƺ4FFM';0r`>Hд)uOS# flPK ^B05com/vldocking/swing/toolbars/ToolBarPersistence.classW{~G=z mecmr6Gq1&еyW]i4=6-m!NmzSH%ε73|o;4`\0QO-%NQW3QV^~y7X-QvwX{'Ż،G 5><ވ >K|U$>. ]j0>FSjOK|FX56<=p,;1|pL%y:e%3 3[~ ƭlhHN`eH$SlT6N:Vm)cY^"w e\XMläyq_`cZ>dz)1l'e5d*:a׈s\ 囹lS+C)㖗Qb$䎚؞f)?k~K YnrYu.'u'KZ5YZؔ,RTm**b;:9h崝$ 4+%u%2k+<؞Ũq}_M 8|Y 3RSl+=wɸ:_mHzB~!m$mL:,y/H|QKƝs);H}/K|E ^WVA;̲K)JvsY3y֙|Pic{){oFb0Q #&^[nVk&^]&s0M~@w,m:6CJ%?ďCHij +O)+[Κ)~ƪW:V6sBe62&~_&~&~ğL}yeb`D` 7WĿjJE`TXqXX:kNEUT`T\WU!*EWXO\bngPĈ3y25OCvvhU"i;(5Ί׋ܦ+XRk8AVUkZU4e5/[ir[rQV'Peq\R=y-(g{Y:m-3jUn G;\AFyIRU_ ;3ˇg}|_hDы[LDdbb*=;$'I^Ff$wOr+Hr_nߏ9Qtt⡊EYY<↾'^:o[Ouӛh'V]1:fݘ*β^(.eZSW3]Dlow]4մDR϶bnJB ݬ3x3{ިe7>?vݨ{Y06kx.@)j\<+k.yuKGKe/șJǶ,{pk[װgTXlU8)Np9%O/o q,X}X Dml̘͖I2Ww^U (v)>Ě4<>SI>t4PPaU 56$لd5lϻ^&ӝ bP5\?"|Kk9Ij2]'_[;b/^H:SAiX&NΕ,YFTς#UEqFvN8PK ^BJɊ.com/vldocking/swing/toolbars/VLToolBar$1.classTkOA=n,KA|XJ[ LHZ5TE3aa%S Q4~0~7m~Sٻwfsi OCǔ.\1k;c9 UVPu  IS%l[U Uyk JyH{9#0;4ScH`8xث`]wkTmr0w<:MQ11i&RX1j TMcS5x45s 1Ӳ»$ٴ)C B6L$W:Ib]!R8;TenY"rkkGǞ¸ D Ӿly~GI< -tti5 i.I!M_W#94)XqZ3"ËQě'q=m<_:>O`:CTqts 5fb;2g%Ѓ. -YH6 mSHj'PK ^Bcf&;;com/vldocking/swing/toolbars/VLToolBar$GripperHandler.classYSP7tm( )jҎȦ.lnC$aZ(:>P9i7sov?`+ 3)Zf\X{w,Će&(IC)~C fC!uu qexfT'bJQq Pt'U~$](ن 0S8C R9j$ʥPHhl9~JvMCԜMS"Donlm(\8O溌<ݸ`|\h50 ů X#$0EWEд.GJ-[OPK ^Bϝ:/,com/vldocking/swing/toolbars/VLToolBar.classY |TdL^B IBªA!$J:Id`2LXZ+jn-XڴjIbW}m_h7K&_~}w9OX$uc.0Ggp.ߡ\=$*gsߵo݋P%]ϛ"도i*e$oD(Ro >'XX<,xmL?aFZAhO2+0-  U3O7893J"h`s)@nSLFbcr0 4j,4\YCvg2-' X lI!ب5C`|h= %;Ȳ1O;a(qBs,I-3ZeYR 9n`\1w?%cEQ66^ #l-ǹP5 c@DO(@`xW0Y,$ ~k< (ZUs0wh7@"f AvhwZ7E(>Eڡ^Đ;Ym:CWok/67{QKNXGIw˦w $)Mj,٣=Moy[Jjy:eƲʲ;!ЂHۤx$H!r?OC6TyQ֠7mn[-1`OB&ah1]R+3nXMy]FpNV%VDNg's$d'}=YW\^(J_]]X쌺:+ό3K_PX ,Ap7A+!YBD4IwRźp@z%͑hWNUD1_8MșY~Vp?u8~ pu85.]%oK݊ᣂk%\}*e>{Lܫ}n)Ƚ'[Ꮫ|qȐO|ʔA|d5ȠPU,ԋ ) W&S_)M)PM9GLڙ؄PU>Wqq|7k_ Qף}&4NV} t=[X~h-"Hg5cmv+Tp{ܘOhދ ow;%nB:2>4ѳ,/4l0l9 v~ ODt1缬M'Y2Ea]d'154+Mb*8f1g-MpǁDN4<-1lLP߄؇|?֜y<`XO ֓dcc=Y[{'PxiWu7}2G,Opt Bvħdav7Ba;FP4"jΊuVץ+;!qQsCtR+w0Z 4 c:&qZj:C1(aVpssNETH] PTl c3jыskч6/`;Ý"kx}Tuw=>0$[Dti||6 #R.Zo0&%0y5U1:w^,׺|q09MMEN[ҢjhMKiGhEӎiC,aA2ZE@VsaG )_rwW5'5'Ҩ's)˼:xO[uK:Ftgqy6MaW9^8e)(C%54s4:7+ Uqnf. b$$g:tU4UT jr~%9id*d*dg2+ǑWU9Ukw --%CW31y8|a䅬g0B׳3R#MqvFnwFVF3)71T1Ud22vFMWߡ͍e$'ïdvFrk}8zI9tʕ-a:֚a>5zDGޥky kj7|OO69L!F aZqCkX:<#x'!] c3Ix2|*1-Icx]Cʷ:G }1 bڈy!t8g>;6.o#ElSM塛u gRI^ϓ6[ZRVKV5kz;]s&ME0bLK0Cޅ3R̗P'X$]4n6vtHz;%^ T4uxz㵓*KbT59oTp%2XԬ)2G?C:1qBlmQlwy\ϱ͔E | (](ݨ=^!J#\mj̠컌.v7?xbZKgYR9Z4wiO=oi »89JVk]Z˕~4 #ȓ(@RD4þшV8NdR7H|S&f̑[hb܆rNl;SJ(20݇{~|BC{DĐ &-Bڅtc bWɽ[ǘN60l5xK7ȲN^a8:_h#c۟!FhIl jےAs^CY,}cJwmz(8F+9N| C\PԒ^;f҉qU&bwKs5sV3_񯽬ob#9p}t}il᫮̠G0va\aWjj](Oc1=&2sl%GD]]qk凖\.{ϥF\VCI>MQ1&,t29o)r_Rmc*ӉpY 0ckآ87:^}WU,W_n]tTZ[ugy ]>Rgy.u:->AUg''=:уHM/w|îbS˔x3˯(A;/߱xi-WKƋyщ[ՑXosH!tC`}s68mgڦt#oFm8Y/tM2 ܂D=e?e=_蓝k3k7(c;3)Shs֦2QpEÙqWʤ,2'˔1ugǞvZ 58ן*#?_Zx6 R ZK\w7TM--j[F (gtF:L3u9ケYÞ9=9'o]pF %p+[$8wDdE䌵T92::@g!td1 b08(C"[x(r<,8=*H᫢8!xB7ěoxRTJ(3 гeSHtsY'[+Zكv@4

lGʧҘSa3n.8Kn@mkTeCN7Hauv=@Hѣl3$.?0;<:'( 0`wjiLyN_nЙnŔscѸn= NHɾ aVVHSݼ7lޑko[T6m>j.~֣2<']lxf&@Z^ЪMt PXDw<25RQ![xwtuM8p}'ݩe 6ўͮ|Bmˑ$Jm-!eIb9jC=S3ٸ!qD$N%y$o/$^d1fx$^é$NII  ^O 2lI "Ήhú$&[Od/zߴѹsBӮ8&+#ڌˊlaG; آb̓eY=Eg`󎱴;̀6)1ebͦs6dMڂeѭ5U2,>gzS}wcJOz􀛖2{ffj˓o,Nkc)+6Vy=B!P#!<.ESnM:|+G^lnl dtТӒ?,V(TD_%RozdqP۹ZIM%5F22T14DcVySA4YCgJ z 82Jj y5F`5?Q02Uؤm-QB[s[28p9|>*ŷHi\oj\p^YY;|@kчVBBźb"Z+w&J1Eh-g8}!ip\\.f\Dt%$wL&u03/+'K<ׁY؅:Ihi#%)ZZ_/`n1~7}kw5[Dߣ |"~'ofH[&Bܰ5/'Bn18[ g&Lj ~4:έDXӶEHc4/5d7U%,@됡%v3@O=Xj.p㷟0}$L~<$ ^?38_a\#pY1b1g[OBƟOhAZ Q25%ia]:-VLhpĂ7{#/*֚5 &P[3pDA(yN#vt ? QJc%,>F3e[Xgī2RX2I?/|  YEHi$AGB(2F+8jcX:9f,6Xltx/xB; ,h1*b2ewh8+'V$c)^()s"`UOL=wu5CkH4%HU1m]ƀX@9uFۋ|gO]1WȻW8?IIkѾ=2ح5Q2JW!T#$gMae81*@ŕ%ӷ>>"Jo$(=:AtKR®Q:RT?.vPC69^r$=Z-ZD$T=uciV|RwPK ^B51=.com/vldocking/swing/toolbars/grip_expand_h.png sb``p  $RlI. `yw=,,f`aFYs$%טDx2egdK\#JssSJ *23J|sJK2yS\nx8Tܪ=g z SREV_HըOdvªgN<Eiݬ*Dd[3%ߙ.;k<%%OV_[h&@tsYPK ^B^.com/vldocking/swing/toolbars/grip_expand_v.png sb``p  $RlI. `yw=,,f`aFYs$%טDxuZEdK\#JssSJ *23J|sJK2yS\nz8TZ{v+=4.!Lk ÷|~졼m:3eqF|Ovn1_eSBPK ^Bٕ(com/vldocking/swing/toolbars/gripper.png sb``p  $4RlI. Ap品" 0kPו*''@!׈Լʢ0Ғb@J.!X22(0(?'M)ŌUSrʻT) PK ^B(4com/vldocking/swing/toolbars/toolbarbuttonborder.png sb``p  $MR rApfH0Pו*'; .!Sc32:pY™8rG%<1Z)*˭i coB1:>qR +C([Z[@s<]\9%4PK ^Bk1[<com/vldocking/swing/toolbars/toolbarbuttonborder_pressed.png sb``p  $MRlI. Ap品" rApfH0Pו_=]C*n%80=:(n*t8]υ4GLԝ0J}ƞ !'\왣^"H2׹43xsJhPK ^Bq3com/vldocking/swing/toolbars/toolbarpanelborder.png sb``p  $MR rApfH0Pו*'DfdcHŭqG؀MxCcIAFI\BJ}Rn3,3}Ak*gV}9/Ԡs%p{_%etsYPK ^B AMETA-INF/PK ^BZXc+META-INF/MANIFEST.MFPK ^BAcom/PK ^BAcom/vldocking/PK ^BAcom/vldocking/swing/PK ^BA5com/vldocking/swing/docking/PK ^B&Aocom/vldocking/swing/docking/animation/PK ^B"Acom/vldocking/swing/docking/event/PK ^BAcom/vldocking/swing/docking/ui/PK ^BA0com/vldocking/swing/docking/ws/PK ^BAmcom/vldocking/swing/tabbedpane/PK ^BAcom/vldocking/swing/toolbars/PK ^B\b;M$Ccom/vldocking/swing/docking/AbstractDragControler$DragProcess.classPK ^B[,GCecom/vldocking/swing/docking/AbstractDragControler$DropProcess.classPK ^BkXiFPcom/vldocking/swing/docking/AbstractDragControler$UnderMouseInfo.classPK ^B|=21>7com/vldocking/swing/docking/AbstractDragControler.classPK ^B%}v38com/vldocking/swing/docking/AnchorConstraints.classPK ^B \+ 1r:com/vldocking/swing/docking/AnchorManager$1.classPK ^B[y !/=com/vldocking/swing/docking/AnchorManager.classPK ^BWb6Jcom/vldocking/swing/docking/AutoHideBorderLayout.classPK ^BqXy4Rcom/vldocking/swing/docking/AutoHideButton$1$1.classPK ^B-I2Ucom/vldocking/swing/docking/AutoHideButton$1.classPK ^B/Yz08Zcom/vldocking/swing/docking/AutoHideButton.classPK ^Bg7ccom/vldocking/swing/docking/AutoHideButtonPanel$1.classPK ^Ba Gdcom/vldocking/swing/docking/AutoHideButtonPanel$ButtonHighlighter.classPK ^BFpzb 5gcom/vldocking/swing/docking/AutoHideButtonPanel.classPK ^B̪=z7lcom/vldocking/swing/docking/AutoHideExpandPanel$1.classPK ^BC_7Iqcom/vldocking/swing/docking/AutoHideExpandPanel$2.classPK ^B*B 7rcom/vldocking/swing/docking/AutoHideExpandPanel$3.classPK ^B!*-:ne7xvcom/vldocking/swing/docking/AutoHideExpandPanel$4.classPK ^BǺ J;zcom/vldocking/swing/docking/AutoHideExpandPanel$AnimationControler$1.classPK ^B1H|com/vldocking/swing/docking/AutoHideExpandPanel$AnimationControler.classPK ^BN&;]Bcom/vldocking/swing/docking/AutoHideExpandPanel$DragListener.classPK ^B>|UGcom/vldocking/swing/docking/AutoHideExpandPanel$ExpandControler$1.classPK ^Bb(YGkcom/vldocking/swing/docking/AutoHideExpandPanel$ExpandControler$2.classPK ^BɔNEŋcom/vldocking/swing/docking/AutoHideExpandPanel$ExpandControler.classPK ^Bg+pDcom/vldocking/swing/docking/AutoHideExpandPanel$FocusCollapser.classPK ^B/v&QF5,com/vldocking/swing/docking/AutoHideExpandPanel.classPK ^B7oR;com/vldocking/swing/docking/AutoHidePolicy$ExpandMode.classPK ^BMZa0Pcom/vldocking/swing/docking/AutoHidePolicy.classPK ^BX_ 0com/vldocking/swing/docking/BorderSplitter.classPK ^Bׇ8=2 com/vldocking/swing/docking/CompoundDockable.classPK ^Bw E=>6com/vldocking/swing/docking/CompoundDockingPanel.classPK ^Bg)ZCcom/vldocking/swing/docking/DefaultDockableContainerFactory$1.classPK ^Bl ADcom/vldocking/swing/docking/DefaultDockableContainerFactory.classPK ^Bə22;com/vldocking/swing/docking/DetachedDockView.classPK ^BҬ72com/vldocking/swing/docking/DockDropReceiver.classPK ^B(~+com/vldocking/swing/docking/DockGroup.classPK ^BΖ| !!)com/vldocking/swing/docking/DockKey.classPK ^B>-f2Ccom/vldocking/swing/docking/DockTabbedPane$1.classPK ^B\43com/vldocking/swing/docking/DockTabbedPane$2$1.classPK ^B_ D 2Pcom/vldocking/swing/docking/DockTabbedPane$2.classPK ^Bl2com/vldocking/swing/docking/DockTabbedPane$3.classPK ^B:;>JA2com/vldocking/swing/docking/DockTabbedPane$4.classPK ^B7bf2:com/vldocking/swing/docking/DockTabbedPane$5.classPK ^BVn2com/vldocking/swing/docking/DockTabbedPane$6.classPK ^BH 8P2com/vldocking/swing/docking/DockTabbedPane$7.classPK ^B~2'_0( com/vldocking/swing/docking/DockTabbedPane.classPK ^B{^z,1com/vldocking/swing/docking/DockView$1.classPK ^Btջ("*4com/vldocking/swing/docking/DockView.classPK ^B#f14Ccom/vldocking/swing/docking/DockViewAsTab$1.classPK ^B1Ecom/vldocking/swing/docking/DockViewAsTab$2.classPK ^B!N$n1Gcom/vldocking/swing/docking/DockViewAsTab$3.classPK ^B|L^B$n1DJcom/vldocking/swing/docking/DockViewAsTab$4.classPK ^B^x1Lcom/vldocking/swing/docking/DockViewAsTab$5.classPK ^B-s.1~Pcom/vldocking/swing/docking/DockViewAsTab$6.classPK ^Bi1xScom/vldocking/swing/docking/DockViewAsTab$7.classPK ^BD 3$1HVcom/vldocking/swing/docking/DockViewAsTab$8.classPK ^B9&V9Xcom/vldocking/swing/docking/DockViewAsTab$TabHeader.classPK ^B6/[com/vldocking/swing/docking/DockViewAsTab.classPK ^BFx4 rcom/vldocking/swing/docking/DockViewTitleBar$1.classPK ^B 4tcom/vldocking/swing/docking/DockViewTitleBar$2.classPK ^B}O6wcom/vldocking/swing/docking/DockViewTitleBar$3$1.classPK ^B[a? 4zcom/vldocking/swing/docking/DockViewTitleBar$3.classPK ^B W4-4com/vldocking/swing/docking/DockViewTitleBar$4.classPK ^BFvW Ccom/vldocking/swing/docking/DockViewTitleBar$FocusHighlighter.classPK ^B hh92(com/vldocking/swing/docking/DockViewTitleBar.classPK ^BI^*Kcom/vldocking/swing/docking/Dockable.classPK ^BQ:7com/vldocking/swing/docking/DockableActionCustomizer.classPK ^B`R3com/vldocking/swing/docking/DockableContainer.classPK ^Bq2%tEcom/vldocking/swing/docking/DockableContainerFactory$ParentType.classPK ^B:com/vldocking/swing/docking/DockableContainerFactory.classPK ^Bc_4com/vldocking/swing/docking/DockableDragSource.classPK ^BAm/com/vldocking/swing/docking/DockablePanel.classPK ^Bҍ2com/vldocking/swing/docking/DockableResolver.classPK ^BW!f8dcom/vldocking/swing/docking/DockableState$Location.classPK ^BXy/Rcom/vldocking/swing/docking/DockableState.classPK ^B7i5com/vldocking/swing/docking/DockableStoreButton.classPK ^Bng &5com/vldocking/swing/docking/DockingBorderLayout.classPK ^Bo04qcom/vldocking/swing/docking/DockingConstants$1.classPK ^B͔U97kcom/vldocking/swing/docking/DockingConstants$Hide.classPK ^B<8Qcom/vldocking/swing/docking/DockingConstants$Split.classPK ^BQ2?com/vldocking/swing/docking/DockingConstants.classPK ^BNw 70com/vldocking/swing/docking/DockingContext.classPK ^BWM_|2com/vldocking/swing/docking/DockingDesktop$1.classPK ^BS03com/vldocking/swing/docking/DockingDesktop$10.classPK ^B|r 3com/vldocking/swing/docking/DockingDesktop$11.classPK ^Bǹܶt3com/vldocking/swing/docking/DockingDesktop$12.classPK ^BT@_jY 3com/vldocking/swing/docking/DockingDesktop$13.classPK ^B3Ucom/vldocking/swing/docking/DockingDesktop$14.classPK ^B5vg2%3com/vldocking/swing/docking/DockingDesktop$15.classPK ^B2com/vldocking/swing/docking/DockingDesktop$2.classPK ^B2hcom/vldocking/swing/docking/DockingDesktop$3.classPK ^BH62Ecom/vldocking/swing/docking/DockingDesktop$4.classPK ^B1-92Mcom/vldocking/swing/docking/DockingDesktop$5.classPK ^Bsځ:M2com/vldocking/swing/docking/DockingDesktop$6.classPK ^B\S15<2Tcom/vldocking/swing/docking/DockingDesktop$7.classPK ^B+?<;2 com/vldocking/swing/docking/DockingDesktop$8.classPK ^B72e com/vldocking/swing/docking/DockingDesktop$9.classPK ^BtPѻs =com/vldocking/swing/docking/DockingDesktop$FocusHandler.classPK ^BC0u0com/vldocking/swing/docking/DockingDesktop.classPK ^Byc v.com/vldocking/swing/docking/DockingPanel.classPK ^BZL 4ƕcom/vldocking/swing/docking/DockingPreferences.classPK ^BO)E9dcom/vldocking/swing/docking/DockingSelectorDialog$1.classPK ^B.V 9ycom/vldocking/swing/docking/DockingSelectorDialog$2.classPK ^B͜.&9com/vldocking/swing/docking/DockingSelectorDialog$3.classPK ^Bu)79Ncom/vldocking/swing/docking/DockingSelectorDialog$4.classPK ^B Kcom/vldocking/swing/docking/DockingSelectorDialog$DockablesTableModel.classPK ^BP 7com/vldocking/swing/docking/DockingSelectorDialog.classPK ^Bzx[862com/vldocking/swing/docking/DockingUtilities.classPK ^B /com/vldocking/swing/docking/DragControler.classPK ^B6.com/vldocking/swing/docking/DragControlerFactory.classPK ^BrgM:com/vldocking/swing/docking/DragControlerGlassPane$1.classPK ^B/@aR:Fcom/vldocking/swing/docking/DragControlerGlassPane$2.classPK ^BuY Jcom/vldocking/swing/docking/DragControlerGlassPane$ShapeLabelPainter.classPK ^B^8com/vldocking/swing/docking/DragControlerGlassPane.classPK ^BS 2`com/vldocking/swing/docking/FloatingDialog$1.classPK ^Bth3?com/vldocking/swing/docking/FloatingDialog$ResizeListener.classPK ^Bw 8com/vldocking/swing/docking/FloatingDialog$Resizer.classPK ^BӟB ;5com/vldocking/swing/docking/FloatingDialog$TitlePanel.classPK ^Bj8 *0com/vldocking/swing/docking/FloatingDialog.classPK ^B\$\;com/vldocking/swing/docking/FloatingDockableContainer.classPK ^BYjQcom/vldocking/swing/docking/HeavyWeightDragControler$HWShapePainterStrategy.classPK ^B;H~ Ecom/vldocking/swing/docking/HeavyWeightDragControler$HeavyLabel.classPK ^BT 7Ecom/vldocking/swing/docking/HeavyWeightDragControler$HeavyShape.classPK ^B frI : com/vldocking/swing/docking/HeavyWeightDragControler.classPK ^B×-_ Q%com/vldocking/swing/docking/LightWeightDragControler$LWShapePainterStrategy.classPK ^Bf:)com/vldocking/swing/docking/LightWeightDragControler.classPK ^B^<A,com/vldocking/swing/docking/MaximizedComponentReplacer.classPK ^Bfeu3-com/vldocking/swing/docking/MaximizedDockView.classPK ^BS. K/com/vldocking/swing/docking/MaximizedDockViewAsTab$MaximizedTabHeader.classPK ^B3RR 84com/vldocking/swing/docking/MaximizedDockViewAsTab.classPK ^B$ B:8com/vldocking/swing/docking/RelativeDockablePosition.classPK ^Bjf(]:@com/vldocking/swing/docking/RelativeDockingUtilities.classPK ^Bs .icom/vldocking/swing/docking/ShadowBorder.classPK ^B95Aocom/vldocking/swing/docking/ShapeOutlinePainter.classPK ^B#7v6=rcom/vldocking/swing/docking/ShapePainterStrategy.classPK ^B:"ߛ9sscom/vldocking/swing/docking/SingleDockableContainer.classPK ^Bq(2etcom/vldocking/swing/docking/SplitContainer$1.classPK ^Bѧ$0qvcom/vldocking/swing/docking/SplitContainer.classPK ^B]V.jcom/vldocking/swing/docking/SplitResizer.classPK ^B:V.com/vldocking/swing/docking/TabFactory$1.classPK ^B:F,,com/vldocking/swing/docking/TabFactory.classPK ^B12:com/vldocking/swing/docking/TabbedContainerActions$1.classPK ^Bڐ=:com/vldocking/swing/docking/TabbedContainerActions$2.classPK ^BP @B:3com/vldocking/swing/docking/TabbedContainerActions$3.classPK ^Bv]::͖com/vldocking/swing/docking/TabbedContainerActions$4.classPK ^BC:_com/vldocking/swing/docking/TabbedContainerActions$5.classPK ^BA :com/vldocking/swing/docking/TabbedContainerActions$6.classPK ^BʨC :com/vldocking/swing/docking/TabbedContainerActions$7.classPK ^By@)8.com/vldocking/swing/docking/TabbedContainerActions.classPK ^BT2com/vldocking/swing/docking/TabbedDockView$1.classPK ^B60com/vldocking/swing/docking/TabbedDockView.classPK ^BzvH t94com/vldocking/swing/docking/TabbedDockableContainer.classPK ^BXg:com/vldocking/swing/docking/animation/AnimationEvent.classPK ^BSm=com/vldocking/swing/docking/animation/AnimationListener.classPK ^B,5?com/vldocking/swing/docking/animation/ComponentAnimator$1.classPK ^B^W Ucom/vldocking/swing/docking/animation/ComponentAnimator$AnimationActionListener.classPK ^BXwQ=~com/vldocking/swing/docking/animation/ComponentAnimator.classPK ^B5=*com/vldocking/swing/docking/attach16v2.pngPK ^BȯPQ1com/vldocking/swing/docking/attach16v2pressed.pngPK ^BTMN2com/vldocking/swing/docking/attach16v2rollover.pngPK ^B%c]P'Zcom/vldocking/swing/docking/close16.gifPK ^Bمrd.com/vldocking/swing/docking/close16pressed.gifPK ^B*ird/com/vldocking/swing/docking/close16rollover.gifPK ^B6'G *ycom/vldocking/swing/docking/close16tab.pngPK ^B 1com/vldocking/swing/docking/close16tabPressed.pngPK ^BM 2*com/vldocking/swing/docking/close16tabRollover.pngPK ^Bq=")ecom/vldocking/swing/docking/close16v2.pngPK ^B]>V0com/vldocking/swing/docking/close16v2pressed.pngPK ^BGh 1+com/vldocking/swing/docking/close16v2rollover.pngPK ^B[R}&com/vldocking/swing/docking/close8.pngPK ^B`6*com/vldocking/swing/docking/closeAll16.pngPK ^B/com/vldocking/swing/docking/closeAllOther16.pngPK ^Bv>com/vldocking/swing/docking/event/DockableSelectionEvent.classPK ^BfnAcom/vldocking/swing/docking/event/DockableSelectionListener.classPK ^Be_vq+@com/vldocking/swing/docking/event/DockableStateChangeEvent.classPK ^BH" Ccom/vldocking/swing/docking/event/DockableStateChangeListener.classPK ^B~D}com/vldocking/swing/docking/event/DockableStateWillChangeEvent.classPK ^BOGcom/vldocking/swing/docking/event/DockableStateWillChangeListener.classPK ^B/eEcom/vldocking/swing/docking/event/DockingActionAddDockableEvent.classPK ^B=?com/vldocking/swing/docking/event/DockingActionCloseEvent.classPK ^BSQ/iC-com/vldocking/swing/docking/event/DockingActionCreateTabEvent.classPK ^B~ Bcom/vldocking/swing/docking/event/DockingActionDockableEvent.classPK ^BcC:com/vldocking/swing/docking/event/DockingActionEvent.classPK ^B T=com/vldocking/swing/docking/event/DockingActionListener.classPK ^B!yAuKcom/vldocking/swing/docking/event/DockingActionSimpleStateChangeEvent.classPK ^B.䧫 Hcom/vldocking/swing/docking/event/DockingActionSplitComponentEvent.classPK ^BQPcom/vldocking/swing/docking/event/DockingActionSplitDockableContainerEvent.classPK ^Ba: Gcom/vldocking/swing/docking/event/DockingActionSplitDockableEvent.classPK ^B]dHI) com/vldocking/swing/docking/float16v2.pngPK ^B .RR0I com/vldocking/swing/docking/float16v2pressed.pngPK ^B軄DF1 com/vldocking/swing/docking/float16v2rollover.pngPK ^B!TbT&|com/vldocking/swing/docking/hide16.gifPK ^Bawg-"com/vldocking/swing/docking/hide16pressed.gifPK ^BnVHlb.com/vldocking/swing/docking/hide16rollover.gifPK ^Bx(com/vldocking/swing/docking/hide16v2.pngPK ^BTb/com/vldocking/swing/docking/hide16v2pressed.pngPK ^BJL0com/vldocking/swing/docking/hide16v2rollover.pngPK ^BHiZ*8com/vldocking/swing/docking/maximize16.gifPK ^B{A~1com/vldocking/swing/docking/maximize16pressed.gifPK ^BI)ou2com/vldocking/swing/docking/maximize16rollover.gifPK ^BN;<,com/vldocking/swing/docking/maximize16v2.pngPK ^Blo@B3!com/vldocking/swing/docking/maximize16v2pressed.pngPK ^B^3(+4com/vldocking/swing/docking/maximize16v2rollover.pngPK ^B8 iZ),com/vldocking/swing/docking/restore16.gifPK ^B+-~0com/vldocking/swing/docking/restore16pressed.gifPK ^Brr1com/vldocking/swing/docking/restore16rollover.gifPK ^B::CC+com/vldocking/swing/docking/restore16v2.pngPK ^BףYY2 com/vldocking/swing/docking/restore16v2pressed.pngPK ^Bx+563!com/vldocking/swing/docking/restore16v2rollover.pngPK ^B \>E&F#com/vldocking/swing/docking/shadow.pngPK ^BU5.$com/vldocking/swing/docking/stopdragcursor.gifPK ^BQ.%com/vldocking/swing/docking/swapdragcursor.gifPK ^Bant:&com/vldocking/swing/docking/ui/AutoHideButtonPanelUI.classPK ^Bl j5 +com/vldocking/swing/docking/ui/AutoHideButtonUI.classPK ^Bͺ:4com/vldocking/swing/docking/ui/AutoHideExpandPanelUI.classPK ^B:9y7j6com/vldocking/swing/docking/ui/DetachedDockViewUI.classPK ^Bv~989com/vldocking/swing/docking/ui/DockViewTitleBarUI$1.classPK ^B߇~999;com/vldocking/swing/docking/ui/DockViewTitleBarUI$2.classPK ^B-yt7A7>com/vldocking/swing/docking/ui/DockViewTitleBarUI.classPK ^B)-D[com/vldocking/swing/docking/ui/DockViewUI$ViewAncestorListener.classPK ^B/"/_com/vldocking/swing/docking/ui/DockViewUI.classPK ^BF+ Obcom/vldocking/swing/docking/ui/DockingSplitPaneUI$DockingSplitPaneDivider.classPK ^B9( 7hcom/vldocking/swing/docking/ui/DockingSplitPaneUI.classPK ^BHio;46bncom/vldocking/swing/docking/ui/DockingUISettings.classPK ^Bk0com/vldocking/swing/docking/ws/WSDesktop$1.classPK ^B%9`ACcom/vldocking/swing/docking/ws/WSDesktop$CompoundDockableNode.classPK ^BS;C;Ѕcom/vldocking/swing/docking/ws/WSDesktop$FloatingNode.classPK ^BA@Y 9com/vldocking/swing/docking/ws/WSDesktop$HiddenNode.classPK ^Bc$vR3ccom/vldocking/swing/docking/ws/WSDesktop$Node.classPK ^BS_NA*com/vldocking/swing/docking/ws/WSDesktop$SingleDockableNode.classPK ^BRM8Tcom/vldocking/swing/docking/ws/WSDesktop$SplitNode.classPK ^B;6~com/vldocking/swing/docking/ws/WSDesktop$TabNode.classPK ^Bn/u;ӕcom/vldocking/swing/docking/ws/WSDesktop$TopLevelNode.classPK ^B'[.com/vldocking/swing/docking/ws/WSDesktop.classPK ^B2?Wc~.׿com/vldocking/swing/docking/ws/WSDockKey.classPK ^BoO4< .com/vldocking/swing/docking/ws/Workspace.classPK ^B`6com/vldocking/swing/docking/ws/WorkspaceButton$1.classPK ^B<ʃ4gcom/vldocking/swing/docking/ws/WorkspaceButton.classPK ^Bցq?7com/vldocking/swing/docking/ws/WorkspaceException.classPK ^Br8com/vldocking/swing/docking/ws/WorkspaceMenuItem$1.classPK ^B;6com/vldocking/swing/docking/ws/WorkspaceMenuItem.classPK ^BZ@9com/vldocking/swing/tabbedpane/JTabbedPaneSmartIcon.classPK ^B4 @com/vldocking/swing/tabbedpane/JTabbedPaneSmartIconManager.classPK ^BFf5Fcom/vldocking/swing/tabbedpane/SmartIconJButton.classPK ^B#m4icom/vldocking/swing/toolbars/BackgroundPainter.classPK ^BRوF?/gcom/vldocking/swing/toolbars/RolloverIcon.classPK ^BÏ0com/vldocking/swing/toolbars/RoundedBorder.classPK ^BhgNv 6com/vldocking/swing/toolbars/ToolBarButtonBorder.classPK ^B5 com/vldocking/swing/toolbars/ToolBarConstraints.classPK ^B1: 3 com/vldocking/swing/toolbars/ToolBarContainer.classPK ^BS1Qcom/vldocking/swing/toolbars/ToolBarGripper.classPK ^BH 3com/vldocking/swing/toolbars/ToolBarGripperUI.classPK ^Bto{,com/vldocking/swing/toolbars/ToolBarIO.classPK ^BMAV4Q.com/vldocking/swing/toolbars/ToolBarIOReadInfo.classPK ^B$/o1com/vldocking/swing/toolbars/ToolBarPanel.classPK ^BI 5U:com/vldocking/swing/toolbars/ToolBarPanelBorder.classPK ^B`yFCc?com/vldocking/swing/toolbars/ToolBarPanelLayout$ComponentInfo.classPK ^Bs-5=Bcom/vldocking/swing/toolbars/ToolBarPanelLayout.classPK ^B05Xcom/vldocking/swing/toolbars/ToolBarPersistence.classPK ^Bţ'-`com/vldocking/swing/toolbars/VLButtonUI.classPK ^BJɊ.dcom/vldocking/swing/toolbars/VLToolBar$1.classPK ^BԆV.gcom/vldocking/swing/toolbars/VLToolBar$2.classPK ^Bcf&;;jcom/vldocking/swing/toolbars/VLToolBar$GripperHandler.classPK ^Bϝ:/,ncom/vldocking/swing/toolbars/VLToolBar.classPK ^B^"G 2 com/vldocking/swing/toolbars/VLToolBarLayout.classPK ^B51=.com/vldocking/swing/toolbars/grip_expand_h.pngPK ^B^.ۍcom/vldocking/swing/toolbars/grip_expand_v.pngPK ^Bٕ(com/vldocking/swing/toolbars/gripper.pngPK ^B(4com/vldocking/swing/toolbars/toolbarbuttonborder.pngPK ^Bk1[<com/vldocking/swing/toolbars/toolbarbuttonborder_pressed.pngPK ^Bq3 com/vldocking/swing/toolbars/toolbarpanelborder.pngPK&& 4.0.0 org.sonatype.oss oss-parent 7 dk.navicon vldocking 3.0.5 jar https://github.com/cmadsen/vldocking vldocking GNU Lesser General Public License Version 3.0 http://www.gnu.org/licenses/lgpl-3.0.txt lilian Lilian Chamontin owner rotexdev RotexDev comitter cmadsen Carsten Madsen comitter scm:git:git@github.com:cmadsen/vldocking.git scm:git:git@github.com:cmadsen/vldocking.git scm:git:git@github.com:cmadsen/vldocking.git 1.0.13 1.7.5 4.8 true org.apache.maven.plugins maven-eclipse-plugin 2.9 true true org.apache.maven.plugins maven-compiler-plugin 3.1 1.6 1.6 org.apache.maven.plugins maven-deploy-plugin 2.8.1 org.apache.maven.plugins maven-gpg-plugin 1.4 org.apache.maven.plugins maven-jar-plugin 2.4 org.apache.maven.plugins maven-javadoc-plugin 2.9.1 -Xdoclint:none org.apache.maven.plugins maven-source-plugin 2.2.1 org.apache.maven.plugins maven-source-plugin true attach-sources jar test-jar org.apache.maven.plugins maven-jar-plugin test-jar ${project.basedir}/src/main/resources **/doc-files/** org.slf4j slf4j-api ${slf4j.version} ch.qos.logback logback-classic ${logback.version} test junit junit ${junit.version} test release-sign-artifacts performRelease true org.apache.maven.plugins maven-javadoc-plugin attach-javadocs jar org.apache.maven.plugins maven-gpg-plugin ${gpg.passphrase} ${gpg.useagent} sign-artifacts verify sign vldocking-vldocking-3.0.5/src/000077500000000000000000000000001243334202400162415ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/000077500000000000000000000000001243334202400171655ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/000077500000000000000000000000001243334202400201065ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/000077500000000000000000000000001243334202400206645ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/000077500000000000000000000000001243334202400232655ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/000077500000000000000000000000001243334202400244145ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/000077500000000000000000000000001243334202400260325ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/AbstractDragControler.java000066400000000000000000001106151243334202400331320ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.docking.event.DockDragEvent; import com.vlsolutions.swing.docking.event.DockDropEvent; import com.vlsolutions.swing.docking.event.DockableStateChangeEvent; import com.vlsolutions.swing.docking.event.DockableStateWillChangeEvent; import com.vlsolutions.swing.docking.event.DockingActionDockableEvent; import com.vlsolutions.swing.docking.event.DockingActionEvent; import com.vlsolutions.swing.docking.event.DockingActionSimpleStateChangeEvent; import com.vlsolutions.swing.docking.event.DockingActionSplitDockableContainerEvent; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; import java.awt.Window; import java.awt.event.MouseEvent; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.SwingUtilities; import javax.swing.UIManager; /** Abstract drag controler : provides common behaviour for LW and HW controlers *

(should only be used by VLDocking core framework and extensions) * * @author Lilian Chamontin, VLSolutions * @since 3.0 */ @SuppressWarnings({"rawtypes", "unchecked", "unused"}) abstract class AbstractDragControler implements DragControler { /* This class is not public : it relies so heavily on vldocking internals that I'm reluctant * to give extenders an access to it. */ protected Shape dropShape; protected boolean isFloatingShape = false; // true during floating Dnd protected boolean startDrag; protected Point dragPoint; // !=null means that drag is occuring protected Point startDragPoint; // for offset drawing protected boolean ignoreDrag; // flag to ignore a drag operation protected DockableDragSource dockableDragSource; protected DockDropReceiver dropReceiver; // the component receiving the drop protected boolean paintFloatingDragShape = UIManager.getBoolean("FloatingContainer.paintDragShape"); protected DockingDesktop desktop; protected DockingContext dockingContext; protected ShapePainterStrategy currentShapePainterStrategy; private HashMap shapePainters = new HashMap(); public AbstractDragControler(DockingDesktop desktop) { this.desktop = desktop; this.dockingContext = desktop.getContext(); } /** process mouse clicks on DockableDragSource */ public void mouseClicked(MouseEvent e) {} /** process mouse entered on DockableDragSource (nothing yet) */ public void mouseEntered(MouseEvent e) {} /** process mouse exit on DockableDragSource (nothing yet) */ public void mouseExited(MouseEvent e) {} public void mouseMoved(MouseEvent e) {} /** process mouse pressed on DockableDragSource : prepares a drag operation */ public void mousePressed(MouseEvent e) { if(SwingUtilities.isLeftMouseButton(e)) { startDrag = true; ignoreDrag = false; } else { if(dragPoint != null) { // we were dragging cancelDrag(); } else { ignoreDrag = true; // ignore drag gesture with other than left button 2008/04/15 } } } private boolean isDragAndDropEnabled() { return UIManager.getBoolean("DragControler.isDragAndDropEnabled"); } public Dockable getDockable() { if(dockableDragSource != null) { return dockableDragSource.getDockable(); } else { return null; } } public DockDropReceiver getDropReceiver() { return dropReceiver; } public Shape getDropShape() { return dropShape; } public boolean isFloatingShape() { return isFloatingShape; } protected abstract ShapePainterStrategy createShapePainterStrategy(Window w); /** searches the best shapePainter */ protected ShapePainterStrategy getShapePainter(Component comp, DockableDragSource source) { if(comp == null) { comp = desktop; } Window w = SwingUtilities.getWindowAncestor(comp); ShapePainterStrategy newStrategy = shapePainters.get(w); if(newStrategy == null) { newStrategy = createShapePainterStrategy(w); shapePainters.put(w, newStrategy); if(currentShapePainterStrategy != null) { currentShapePainterStrategy.endDrag(); } currentShapePainterStrategy = newStrategy; newStrategy.startDrag(source); return newStrategy; } else if(newStrategy == currentShapePainterStrategy) { return newStrategy; } else { // newstrategy not null and != currentStategy currentShapePainterStrategy.endDrag(); currentShapePainterStrategy = newStrategy; newStrategy.startDrag(source); return newStrategy; } } /** This method cancels the current drag gesture. *

* It can be used for example by a key listener reacting to the escape key * *@since 2.0.1 */ /** * This method cancels the current drag gesture. *

* It can be used for example by a key listener reacting to the escape key * * @since 2.0.1 */ public void cancelDrag() { this.ignoreDrag = true; this.dropShape = null; this.dockableDragSource = null; this.startDrag = true; this.dragPoint = null; if(currentShapePainterStrategy != null) { currentShapePainterStrategy.endDrag(); } clearStrategies(); desktop.repaint(); } /** * clears the shape painters cache to avoid keeping references of old windows */ private void clearStrategies() { Window w = SwingUtilities.getWindowAncestor(desktop); Window[] owned = w.getOwnedWindows(); for(int i = 0; i < owned.length; i++) { shapePainters.remove(w); } } /** * process mouse released on DockableDragSource */ public void mouseReleased(MouseEvent e) { if(! SwingUtilities.isLeftMouseButton(e)) { if(dragPoint != null) { notifyDragSourceDragComplete(false); cancelDrag(); } } else { // left button // are we above an insertion point ? if(ignoreDrag) { return; } try { boolean dropped = false; if(dragPoint != null && dockableDragSource != null) { dropped = processMouseReleased(e); } notifyDragSourceDragComplete(dropped); } finally { // clean up state variables notifyDragSourceDragComplete(false); cancelDrag(); } } } private void notifyDragSourceDragComplete(boolean isDropped) { if(dockableDragSource != null) { dockableDragSource.endDragComponent(isDropped); } } public void mouseDragged(MouseEvent e) { if(! isDragAndDropEnabled()) { // disable dnd right now ignoreDrag = true; } if(ignoreDrag) { return; } else if(startDrag) { startDrag = false; processDragGestureStart(e); } else { processMouseDragged(e); } } /** invoked only when a drag gesture has beed done * @return true if the dockable has been dropped. */ private boolean processMouseReleased(MouseEvent e) { // 2007/01/08 updated to return a boolean //Component underMouse = findComponentAt(desktop, dragPoint.x, dragPoint.y); DockableDragSource dragSource = ((DockableDragSource) e.getSource()); this.dragPoint = SwingUtilities.convertPoint((Component) e.getSource(), e.getPoint(), desktop); UnderMouseInfo umInfo = findComponentUnderMouse(e); Component underMouse = umInfo.underMouse; Component underMouseNullDesktop = null; DockingDesktop targetDesktop = umInfo.desktop; //findNearestNestedDesktop(underMouse);//umInfo.desktop if(targetDesktop == null) { underMouseNullDesktop = findDropReceiverOutsideDesktop(underMouseNullDesktop, e); } ShapePainterStrategy shapePainterStrategy = getShapePainter(underMouse, dragSource); int dx = dragPoint.x - startDragPoint.x; int dy = dragPoint.y - startDragPoint.y; if(Math.abs(dx) < 20 && Math.abs(dy) < 10) { // deny drag gesture when too near from start point 2005/11/15 return false; } if(targetDesktop == null) { // deny drag gesture when desktops aren't compatible if(underMouseNullDesktop != null) { // we've found a dock drop receiver // we send a really simple event DockDropEvent event = new DockDropEvent(desktop, dragSource, e); ((DockDropReceiver) underMouseNullDesktop).processDockableDrop(event); // this event will be ignored } return false; } else if(targetDesktop.getContext() != desktop.getContext()) { //2006/09/11 // contexts not compatible, stop here return false; } // 2005/11/08 support for full height/width docking DockingPanel dp = targetDesktop.getDockingPanel(); Insets i = targetDesktop.getDockingPanelInsets(); Rectangle deskBounds = new Rectangle(i.left, i.top, targetDesktop.getWidth() - i.left - i.right, targetDesktop.getHeight() - i.top - i.bottom); Rectangle innerBounds = new Rectangle(deskBounds); innerBounds.x += 5; innerBounds.y += 5; innerBounds.width -= 10; innerBounds.height -= 10; if(deskBounds.contains(dragPoint) && ! innerBounds.contains(dragPoint)) { // at less than 5 pixels from a order, promote DockingPanel as the receiver underMouse = dp; } // move up hierarchy till we find a drop receiver while(underMouse != null && underMouse != targetDesktop && ! (underMouse instanceof DockDropReceiver)) { underMouse = underMouse.getParent(); } umInfo.underMouse = underMouse; // resync if(underMouse == null) { // || isAncestorOf(dockableDragSource.getDockableContainer(), underMouse)){ 2007/01/08 moved to implementations // it's not possible to drop a parent on one of its children if(underMouse instanceof DockDropReceiver) { // but we still have to use the reference on drop receiver to disaplay a floating drag shape this.dropReceiver = (DockDropReceiver) underMouse; } DropProcess dropProcess = new DropProcess(e, dockableDragSource, umInfo); if(dropProcess.canDockableBeDetached() && dropProcess.checkDockableWillBeDetached()) { Point location = new Point(e.getPoint()); SwingUtilities.convertPointToScreen(location, e.getComponent()); dropProcess.setFloating(location); return true; } else { // refused (vetoed) return false; } } else if(underMouse instanceof DockDropReceiver && e.isControlDown()) { //2005/11/08 HOT SWAP FUNCTION processHotSwap(underMouse, e.getComponent(), null, true); return true; } else if(underMouse instanceof DockDropReceiver) { // MouseEvent convertMouse; DropProcess process = new DropProcess(e, dockableDragSource, umInfo); DockDragEvent event = process.findAcceptableEvent(e); if(event.isDragAccepted() && process.isDockingActionAccepted()) {// triggers vetoable listeners return process.dropIfPossible(); } else if(process.canDockableBeDetached() // Not accepted on the desktop //2005/10/07 && process.checkDockableWillBeDetached()) { Point location = new Point(e.getPoint()); SwingUtilities.convertPointToScreen(location, e.getComponent()); process.setFloating(location); return true; } else { // vetoed, nothing can be be done return false; } } else { /*if (underMouse == null){ */// not under a droppable zone DropProcess process = new DropProcess(e, dockableDragSource, umInfo); if(process.canDockableBeDetached() && process.checkDockableWillBeDetached()) { Point location = new Point(e.getPoint()); SwingUtilities.convertPointToScreen(location, e.getComponent()); process.setFloating(location); return true; } else { return false; } } } /** Allow hot swappping of two top level dockable containers (during drag) */ protected void processHotSwap(Component underMouse, Component dragged, ShapePainterStrategy shapePainterStrategy, boolean drop) { //2005/11/08 /* This whole method should be reworked to allow hooking a DockingActionEvent subclass * to process hotswapping. * This also means we have to get rid of these "Component" and rely on DockableContainers * instead (which will allow us to properly track dockable state changes) */ // --------------------- // shortcut : if the underMouse component doesn't belong to a DockingPanel, we // just cancel the hot swap operation // explanation : hotswap between DOCKED and FLOATING whould otherwise mean // swapping dockable states, and this will not be allowed until a further release Component topLevel = underMouse; while(topLevel != null && ! (topLevel instanceof DockingPanel)) { topLevel = topLevel.getParent(); } if(topLevel == null) { // doesn't belong to a docking panel == not DOCKED if(! drop) { shapePainterStrategy.showStopDragCursor(); setDropShape(null, shapePainterStrategy); } return; } // --------------------- // to implement the "hot swap" we need to find a top level dockable container // (whose parent should be SplitContainer). while(underMouse != null && ! (underMouse.getParent() instanceof SplitContainer)) { underMouse = underMouse.getParent(); } if(underMouse != null) { Component splitChild = dragged; while(splitChild != null && ! (splitChild.getParent() instanceof SplitContainer)) { splitChild = splitChild.getParent(); } if(splitChild != null && splitChild != underMouse && underMouse instanceof DockDropReceiver) {// this one should always be true (although as it depends on implementation details, I prefer to keep it safe) // ok we've found a suitable swap pattern if(drop) { DockingUtilities.updateResizeWeights(desktop.getDockingPanel()); DockingUtilities.swapComponents(splitChild, underMouse); DockingUtilities.updateResizeWeights(desktop.getDockingPanel()); } else { shapePainterStrategy.showSwapDragCursor(); Rectangle bounds = underMouse.getBounds(); Rectangle2D shape = new Rectangle2D.Float(0, 0, bounds.width, bounds.height); this.dropReceiver = (DockDropReceiver) underMouse; setDropShape(shape, shapePainterStrategy); } } else { // couldn't find a suitable component if(! drop) { shapePainterStrategy.showStopDragCursor(); setDropShape(null, shapePainterStrategy); } } } else { // couldn't find a suitable component if(! drop) { shapePainterStrategy.showStopDragCursor(); setDropShape(null, shapePainterStrategy); } } } private void processDragGestureStart(MouseEvent e) { DockableDragSource dragSource = ((DockableDragSource) e.getSource()); this.dragPoint = SwingUtilities.convertPoint((Component) e.getSource(), e.getPoint(), desktop); this.dropShape = null; this.dockableDragSource = null; this.startDragPoint = e.getPoint(); if(dragSource.startDragComponent(startDragPoint)) { this.dockableDragSource = dragSource; getShapePainter(e.getComponent(), dragSource).startDrag(dragSource); this.startDragPoint = new Point(dragPoint); // same coordinate system for future use processMouseDragged(e); // forward the event to the actual processing } else { // drag rejected this.ignoreDrag = true; } } /** Returns information about the component right under the mouse (including other owned windows)*/ protected UnderMouseInfo findComponentUnderMouse(MouseEvent e) { // are we above an insertion point ? Point p = new Point(e.getPoint()); SwingUtilities.convertPointToScreen(p, e.getComponent()); UnderMouseInfo umInfo = new UnderMouseInfo(); //Component underMouse = null; // iterate through the owned windows (might be floatables) Window w = SwingUtilities.getWindowAncestor(desktop); Window[] children = w.getOwnedWindows(); for(int i = 0; i < children.length; i++) { if(children[i] instanceof FloatingDockableContainer && children[i].isVisible()) { Window wChild = (Window) children[i]; // assumed by the FloatingDockableContainer interface Rectangle bounds = wChild.getBounds(); if(bounds.contains(p)) { // an owned window is on top of the desktop, at current mouse position // we have to try and find a dockable into this window Point p2 = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), wChild); Container contentPane = (wChild instanceof JDialog) ? ((JDialog) wChild).getContentPane() : ((JFrame) wChild).getContentPane(); umInfo.underMouse = findComponentAt(contentPane, p2.x, p2.y); // bypass the glasspane umInfo.desktop = desktop; } } } if(umInfo.underMouse == null && desktop.getContext().getDesktopList().size() > 1) { // now look for other desktops sharing the same context // and select the top most window at current mouse location DockingContext ctx = desktop.getContext(); ArrayList desktops = ctx.getDesktopList(); // create a list of unique windows ArrayList windows = new ArrayList(); for(int i = 0; i < desktops.size(); i++) { DockingDesktop desk = (DockingDesktop) desktops.get(i); Window deskWin = SwingUtilities.getWindowAncestor(desk); if(deskWin != null && ! windows.contains(deskWin)) { // intersection with mouse ? if(deskWin.getBounds().contains(p)) { windows.add(deskWin); } } } // now we have an unordered list of windows all intersecting our point : find which one // is above Window topWindow = null; Iterator it = ctx.getOwnedWindowActionOrder().iterator(); while(it.hasNext()) { Window win = (Window) it.next(); if(windows.contains(win)) { topWindow = win; break; } } if(topWindow != null) { Point p2 = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), topWindow); Container contentPane = (topWindow instanceof JDialog) ? ((JDialog) topWindow).getContentPane() : ((JFrame) topWindow).getContentPane(); umInfo.underMouse = findComponentAt(contentPane, p2.x, p2.y); // bypass the glasspane // now find the desktop associated to the component (there might be more than 1 desktop / window) // we have to walk up the hierarchy Component c = umInfo.underMouse; while(c != null) { if(c instanceof DockingDesktop) { umInfo.desktop = (DockingDesktop) c; break; } else { c = c.getParent(); } } } // @todo : also check for floating windows belonging to these other desktops } if(umInfo.underMouse == null) { umInfo.underMouse = findComponentAt(desktop, dragPoint.x, dragPoint.y); umInfo.desktop = desktop; } return umInfo; } /** find the top most component of this container */ protected abstract Component findComponentAt(Container container, int x, int y); /** searches for a dockDropReceiver when mouse is outside a docking desktop */ protected Component findDropReceiverOutsideDesktop(Component underMouse, MouseEvent e) { // there's a side case we have to manage : when a DockDropReceiver has been // installed *outside* a desktop (this is desired when you want to // listen to drag and drop events (e.g. for a workspace switcher) // note : the event will be sent to the DockDropReceiver, but just for Drag // (ignored as a drop) // go up the hierarchy until we find a component that can receive a drop // currently this works only for the desktop's own window Container base = null; Window w = SwingUtilities.getWindowAncestor(desktop); if(w instanceof JFrame) { base = ((JFrame) w).getContentPane(); } else if(w instanceof JDialog) { base = ((JDialog) w).getContentPane(); } if(base != null) { Point pw = SwingUtilities.convertPoint((Component) e.getSource(), e.getPoint(), base); underMouse = findComponentAt(base, pw.x, pw.y); while(underMouse != null && ! (underMouse instanceof DockDropReceiver)) { underMouse = underMouse.getParent(); } } return underMouse; } protected void processMouseDragged(MouseEvent e) { Component dragged = (Component) e.getSource(); DockableDragSource dragSource = ((DockableDragSource) e.getSource()); this.dragPoint = SwingUtilities.convertPoint((Component) e.getSource(), e.getPoint(), desktop); // continue drag UnderMouseInfo umInfo = findComponentUnderMouse(e); Component underMouse = umInfo.underMouse; Component underMouseNullDesktop = null; DockingDesktop targetDesktop = umInfo.desktop;//findNearestNestedDesktop(umInfo.underMouse); if(targetDesktop == null) { underMouseNullDesktop = findDropReceiverOutsideDesktop(underMouseNullDesktop, e); } ShapePainterStrategy shapePainterStrategy = getShapePainter(underMouse, dragSource); if(dragPoint == null || startDragPoint == null) { // 2006/03/16 // safety net again : a bug has been submitted reagrding a NPE and I can't reproduce it ignoreDrag = true; return; } if(targetDesktop == null) { //2006/09/11 // deny drag gesture when desktops aren't compatible if(underMouseNullDesktop != null) { // we've found a dock drop receiver // we send a really simple event DockDragEvent event = new DockDragEvent(desktop, dragSource, e); ((DockDropReceiver) underMouseNullDesktop).processDockableDrag(event); } // finished shapePainterStrategy.showStopDragCursor(); setDropShape(null, shapePainterStrategy); return; } else if(targetDesktop.getContext() != desktop.getContext()) { //2006/09/11 // deny drag gesture when desktops aren't compatible shapePainterStrategy.showStopDragCursor(); setDropShape(null, shapePainterStrategy); return; } int dx = dragPoint.x - startDragPoint.x; int dy = dragPoint.y - startDragPoint.y; if(Math.abs(dx) < 20 && Math.abs(dy) < 10) { // deny drag gesture when too near from start point 2005/11/15 shapePainterStrategy.showStopDragCursor(); setDropShape(null, shapePainterStrategy); return; } // 2005/11/08 support for full height/width docking DockingPanel dp = targetDesktop.getDockingPanel(); Insets i = targetDesktop.getDockingPanelInsets(); Rectangle deskBounds = new Rectangle(i.left, i.top, targetDesktop.getWidth() - i.left - i.right, targetDesktop.getHeight() - i.top - i.bottom); Rectangle innerBounds = new Rectangle(deskBounds); innerBounds.x += 5; innerBounds.y += 5; innerBounds.width -= 10; innerBounds.height -= 10; if(deskBounds.contains(dragPoint) && ! innerBounds.contains(dragPoint) && underMouse != null && targetDesktop.isAncestorOf(underMouse)) { // at less than 5 pixels from a border, promote DockingPanel as the receiver underMouse = dp; } // go up the hierarchy until we find a component that can receive a drop while(underMouse != null && underMouse != targetDesktop && ! (underMouse instanceof DockDropReceiver)) { underMouse = underMouse.getParent(); } umInfo.underMouse = underMouse; // resync if(underMouse == null) {// || isAncestorOf(dockableDragSource.getDockableContainer(), underMouse)){ // it's not possible to drop a parent on one of its children // so we're goind to try and detach it if(underMouse instanceof DockDropReceiver) { // but we still have to use the reference on drop receiver to display a floating drag shape this.dropReceiver = (DockDropReceiver) underMouse; } DragProcess process = new DragProcess(dockableDragSource, umInfo); if(process.canDockableBeDetached() && process.checkAndDetachDockable(shapePainterStrategy)) { // this method manages the detachement } else { // refused (vetoed) shapePainterStrategy.showStopDragCursor(); setDropShape(null, shapePainterStrategy); } } else if(underMouse instanceof DockDropReceiver && e.isControlDown()) { //2005/11/08 HOT SWAP FUNCTION processHotSwap(underMouse, dragged, shapePainterStrategy, false); } else if(underMouse instanceof DockDropReceiver) { // loop if it returns null DragProcess process = new DragProcess(dockableDragSource, umInfo); DockDragEvent event = process.findAcceptableEvent(e); // will it cause a state change ? // a state change occur when switching between CLOSED, HIDDEN, and DOCKED // in this context, the drag event can only be generated by a hidden dockable // (if there is a way to drag its button) or an already docked dockable (no state change) if(event.isDragAccepted() && process.isDockingActionAccepted()) { shapePainterStrategy.showDragCursor(); setDropShape(event.getDropShape(), shapePainterStrategy); } else if(process.canDockableBeDetached() && process.checkAndDetachDockable(shapePainterStrategy)) { // detach done by the "if" } else { event.rejectDrag(); // vetoed by listeners shapePainterStrategy.showStopDragCursor(); setDropShape(null, shapePainterStrategy); } } else {// not above a drop receiver, might be detachable DragProcess process = new DragProcess(dockableDragSource, umInfo); if(process.canDockableBeDetached() && process.checkAndDetachDockable(shapePainterStrategy)) { // this method manages the detachement } else { // refused (vetoed) shapePainterStrategy.showStopDragCursor(); setDropShape(null, shapePainterStrategy); } } } protected void setDropShape(Shape shape, ShapePainterStrategy shapePainterStrategy) { setDropShape(shape, shapePainterStrategy, false); } protected void setDropShape(Shape shape, ShapePainterStrategy shapePainterStrategy, boolean floating) { if(dropShape == null) { if(shape != null) { this.dropShape = shape; this.isFloatingShape = floating; shapePainterStrategy.repaint(); } } else { if(shape != null) { if(! dropShape.equals(shape)) { this.dropShape = shape; this.isFloatingShape = floating; shapePainterStrategy.repaint(); } } else { this.dropShape = shape; this.isFloatingShape = floating; shapePainterStrategy.repaint(); } } } /** A component that encapsulates the drag process (manages vetoable events, floatability..) */ class DragProcess { DockableDragSource source; UnderMouseInfo umInfo; boolean stateChange = false; DockableState.Location futureLocation; DockingActionEvent dockingActionEvent; DragProcess(DockableDragSource source, UnderMouseInfo umInfo) { this.source = source; this.umInfo = umInfo; this.futureLocation = DockingUtilities.getDockableLocationFromHierarchy(umInfo.underMouse); } /** search until a drag event is accepted or rejected (not delegated) */ public DockDragEvent findAcceptableEvent(MouseEvent e) { DockDragEvent event; boolean loop = false; Component underMouse = umInfo.underMouse; do { dropReceiver = (DockDropReceiver) underMouse; MouseEvent convertMouse = SwingUtilities.convertMouseEvent((Component) e.getSource(), e, underMouse); DockableDragSource dragSource = ((DockableDragSource) e.getSource()); event = new DockDragEvent(umInfo.desktop, dragSource, convertMouse); dropReceiver.processDockableDrag(event); if(event.isDragAccepted()) { } else if(event.isDragDelegated()) { // find another dropper underMouse = underMouse.getParent(); while(underMouse != null && underMouse != umInfo.desktop && ! (underMouse instanceof DockDropReceiver)) { underMouse = underMouse.getParent(); } } if(event.isDragAccepted()) { loop = false; } else if(event.isDragDelegated() && underMouse instanceof DockDropReceiver) { loop = true; } else { loop = false; } } while(loop); if(event != null) { this.dockingActionEvent = event.getDockingAction(); umInfo.underMouse = underMouse; // 2007/01/06 } return event; } /** verifies if the dockable(s) movement will not be vetoed by listeners * */ public boolean isDockingActionAccepted() { if(source.getDockableContainer() instanceof TabbedDockableContainer) { // here we're dragging a whole tabbed pane TabbedDockableContainer tdc = (TabbedDockableContainer) source.getDockableContainer(); for(int i = 0; i < tdc.getTabCount(); i++) { Dockable d = tdc.getDockableAt(i); if(! isSingleDockingActionAccepted(d)) { return false; } } return true; } else { return isSingleDockingActionAccepted(source.getDockable()); } } /** internal method for a single dockable */ private boolean isSingleDockingActionAccepted(Dockable dockable) { DockableState currentState = umInfo.desktop.getDockableState(dockable); // will it cause a state change ? // a state change occur when switching between CLOSED, HIDDEN, and DOCKED // in this context, the drag event can only be generated by a hidden dockable // (if there is a way to drag its button) or an already docked dockable (no state change) if(currentState.getLocation() != futureLocation) { // state cannot be null this.stateChange = true; DockableState newState = new DockableState(umInfo.desktop, dockable, futureLocation); DockableStateWillChangeEvent dscwEvent = new DockableStateWillChangeEvent(currentState, newState); if(! desktop.getContext().fireDockableStateWillChange(dscwEvent)) { return false; } } if(dockingActionEvent instanceof DockingActionDockableEvent) { DockingActionDockableEvent dde = (DockingActionDockableEvent) dockingActionEvent; // also check for DockingActionEvents if(dde.getDockable() == dockable) { return desktop.getContext().fireAcceptDockingAction(dockingActionEvent); } else { // multiple dockable moved at the same time (tabs) : we create copies // of the original DockingActionEvent // @todo : see if we couldn't create a new type of action instead DockingActionDockableEvent dae = (DockingActionDockableEvent) dde.clone(); dae.setDockable(dockable); return desktop.getContext().fireAcceptDockingAction(dae); } } else if(dockingActionEvent instanceof DockingActionSplitDockableContainerEvent) { // we're dragging a full tab dockable around : accept it always @todo check this return true; } else { throw new RuntimeException("unmanaged docking action " + dockingActionEvent); } } /** check if a dockable can be detached from the desktop */ public boolean canDockableBeDetached() { if(source.getDockableContainer() instanceof TabbedDockableContainer) { // here we're dragging a whole tabbed pane TabbedDockableContainer tdc = (TabbedDockableContainer) source.getDockableContainer(); for(int i = 0; i < tdc.getTabCount(); i++) { Dockable d = tdc.getDockableAt(i); if(! canSingleDockableBeDetached(d)) { return false; } } // last check : the tab container must not be itself already detached Dockable any = tdc.getDockableAt(0); if(any.getDockKey().getLocation() == DockableState.Location.FLOATING) { //already detached, refuse another detaching return false; } else { return true; } } else { return canSingleDockableBeDetached(source.getDockable()); } } private boolean canSingleDockableBeDetached(Dockable dockable) { /* must not be already detached + floatingenabled + not maximized */ DockKey key = dockable.getDockKey(); if(key.getLocation() == DockableState.Location.FLOATING) { if(DockingUtilities.findTabbedDockableContainer(dockable) != null) { return true; } else { return false;// already detached and single } } if(key.isFloatEnabled()) { if(key.getLocation() != DockableState.Location.MAXIMIZED) { /* int dx = dragPoint.x - startDragPoint.x; int dy = dragPoint.y - startDragPoint.y; if (Math.abs(dx) < 20 && Math.abs(dy) < 10){ // deny detach when too near from start point 2005/11/01 return false; } else { return true; }*/ return true; // the test above has been moved up to filter more drag events } else { return false; } } else { return false; } } /** trigers dockableStageWillChangeEvent to allow vetoing the floating */ public boolean checkDockableWillBeDetached() { if(source.getDockableContainer() instanceof TabbedDockableContainer) { // here we're dragging a whole tabbed pane TabbedDockableContainer tdc = (TabbedDockableContainer) source.getDockableContainer(); for(int i = 0; i < tdc.getTabCount(); i++) { Dockable d = tdc.getDockableAt(i); if(! checkSingleDockableWillBeDetached(d)) { return false; } } return true; } else { return checkSingleDockableWillBeDetached(source.getDockable()); } } private boolean checkSingleDockableWillBeDetached(Dockable dockable) { DockableState newState = new DockableState(desktop, dockable, DockableState.Location.FLOATING); DockableState currentState = desktop.getDockableState(dockable); if(currentState == null) { return false; // safety check as is shouldn't be the case } DockableStateWillChangeEvent dscwEvent = new DockableStateWillChangeEvent(currentState, newState); // if(! desktop.getContext().fireDockableStateWillChange(dscwEvent)) { return false; } else { // also trigger DockingAction DockingActionEvent dae = new DockingActionSimpleStateChangeEvent(desktop, dockable, currentState.getLocation(), DockableState.Location.FLOATING); return desktop.getContext().fireAcceptDockingAction(dae); } } public boolean checkAndDetachDockable(ShapePainterStrategy shapePainterStrategy) { if(checkDockableWillBeDetached()) { if(DockingPreferences.isLightWeightUsageEnabled() && paintFloatingDragShape) { Point shapePoint = new Point(dragPoint); SwingUtilities.convertPointToScreen(shapePoint, desktop); if(dropReceiver != null) { // we are above a drop receiver and we can show something SwingUtilities.convertPointFromScreen(shapePoint, (Component) dropReceiver); Dimension dragSize = dockableDragSource.getDockableContainer().getSize(); setDropShape(new Rectangle2D.Float(shapePoint.x, shapePoint.y, dragSize.width, dragSize.height), shapePainterStrategy, true); } else { setDropShape(null, shapePainterStrategy); } } else { setDropShape(null, shapePainterStrategy); } shapePainterStrategy.showFloatCursor(); return true; } else { return false; } } } class DropProcess extends DragProcess { MouseEvent event; DropProcess(MouseEvent event, DockableDragSource source, UnderMouseInfo umInfo) { super(source, umInfo); this.event = event; } public boolean dropIfPossible() { MouseEvent convertMouse = SwingUtilities.convertMouseEvent((Component) event.getSource(), event, umInfo.underMouse); DockDropEvent dropEvent = new DockDropEvent(umInfo.desktop, source, convertMouse); dropReceiver.processDockableDrop(dropEvent); Component underMouse = umInfo.underMouse; if(dropEvent.isDropAccepted()) { if(underMouse instanceof JComponent) { ((JComponent) underMouse).revalidate(); } else if(underMouse instanceof Component) { underMouse.validate(); underMouse.repaint(); } fireDockingActionEvent(); return true; } else { return false; } } public void fireDockingActionEvent() { if(source.getDockableContainer() instanceof TabbedDockableContainer) { TabbedDockableContainer tdc = (TabbedDockableContainer) source.getDockableContainer(); for(int i = 0; i < tdc.getTabCount(); i++) { Dockable d = tdc.getDockableAt(i); fireSingleDockingActionEvent(tdc.getDockableAt(i)); } } else { fireSingleDockingActionEvent(source.getDockable()); } } private void fireSingleDockingActionEvent(Dockable dockable) { if(stateChange) { DockableState currentState = desktop.getDockableState(dockable); dockable.getDockKey().setLocation(futureLocation); dockingContext.fireDockableStateChange(new DockableStateChangeEvent(currentState, new DockableState(desktop, dockable, futureLocation))); } if(dockingActionEvent instanceof DockingActionDockableEvent) { DockingActionDockableEvent dde = (DockingActionDockableEvent) dockingActionEvent; if(dde.getDockable() == dockable) { dockingContext.fireDockingActionPerformed(dockingActionEvent); } else { DockingActionDockableEvent dae = (DockingActionDockableEvent) dde.clone(); dae.setDockable(dockable); dockingContext.fireDockingActionPerformed(dae); } } else if(dockingActionEvent instanceof DockingActionSplitDockableContainerEvent) { // we're dropping a whole container (currently it is only possible with // a tabbeddockablecontainer // @todo : missing event to fire here } else { throw new RuntimeException("Unmanaged docking action"); } } public void setFloating(Point location) { if(source.getDockableContainer() instanceof TabbedDockableContainer) { desktop.setFloating((TabbedDockableContainer) source.getDockableContainer(), location); } else { Dockable dockable = source.getDockable(); desktop.setFloating(source.getDockable(), true, location); } } } class UnderMouseInfo { DockingDesktop desktop; Component underMouse; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/AnchorConstraints.java000066400000000000000000000033241243334202400323410ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; /** A constraint used to specify how a dockable is tied (anchored) to its containing parent . * * @author Lilian Chamontin, VLSolutions * @since 2.1 */ public class AnchorConstraints { /** Field describing a dockable anchored to the TOP border of its ancestor container */ public static final int ANCHOR_TOP = 1; /** Field describing a dockable anchored to the LEFT border of its ancestor container */ public static final int ANCHOR_LEFT = 2; /** Field describing a dockable anchored to the BOTTOM border of its ancestor container */ public static final int ANCHOR_BOTTOM = 4; /** Field describing a dockable anchored to the RIGHT border of its ancestor container */ public static final int ANCHOR_RIGHT = 8; private int anchor; /** Constructor for an immutable contraints * *@param anchor value expressed as a bitwise OR between ANCHOR_ fields (for example ANCHOR_TOP|ANCHOR_LEFT) * */ public AnchorConstraints(int anchor) { this.anchor = anchor; } /** Returns the anchor value of this contraints object. *

* Anchor is expressed as a bitwise OR between ANCHOR_ fields (for example ANCHOR_TOP|ANCHOR_LEFT) */ public int getAnchor() { return anchor; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/AnchorManager.java000066400000000000000000000313541243334202400314100ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.docking.event.DockingActionAddDockableEvent; import com.vlsolutions.swing.docking.event.DockingActionCreateTabEvent; import com.vlsolutions.swing.docking.event.DockingActionEvent; import com.vlsolutions.swing.docking.event.DockingActionListener; import com.vlsolutions.swing.docking.event.DockingActionSplitComponentEvent; import com.vlsolutions.swing.docking.event.DockingActionSplitDockableContainerEvent; import com.vlsolutions.swing.docking.event.DockingActionSplitDockableEvent; import java.awt.Component; import java.awt.Container; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; /** A helper class used to specify and enforce constraints within a container * (DockingPanel or CompoundDockingPanel). *

* Constraints are currently defined as anchors (AnchorConstraints objects associated to Dockables). * * @author Lilian Chamontin, VLSolutions * @see AnchorConstraints * @since 2.1 */ @SuppressWarnings({"rawtypes", "unchecked", "unused"}) public class AnchorManager { /** Top most ancestor container */ private Container container; /** Map of AnchorConstraints (value) associated to Dockables (key) */ private HashMap constraintsByDockable = new HashMap(); /** Context where docking action events are listened to */ private DockingContext context; /** Appropriate reaction upon docking actions (vetoing the ones that would break constraints) */ private DockingActionListener actionListener = new DockingActionListener() { public boolean acceptDockingAction(DockingActionEvent event) { switch(event.getActionType()) { case DockingActionEvent.ACTION_ADD_DOCKABLE: { DockingActionAddDockableEvent e = (DockingActionAddDockableEvent) event; return acceptAddDockable(e); } case DockingActionEvent.ACTION_CREATE_TAB: { DockingActionCreateTabEvent e = (DockingActionCreateTabEvent) event; return acceptCreateTab(e); } case DockingActionEvent.ACTION_SPLIT_COMPONENT: { DockingActionSplitComponentEvent e = (DockingActionSplitComponentEvent) event; return acceptSplitComponent(e); } case DockingActionEvent.ACTION_SPLIT_DOCKABLE: { DockingActionSplitDockableEvent e = (DockingActionSplitDockableEvent) event; return acceptSplitDockable(e); } case DockingActionEvent.ACTION_SPLIT_DOCKABLE_CONTAINER: { DockingActionSplitDockableContainerEvent e = (DockingActionSplitDockableContainerEvent) event; return acceptSplitDockableContainer(e); } default: return true; // accepting everything else } } public void dockingActionPerformed(DockingActionEvent event) {} }; /** Constructs a new AnchorManager responsible for a container (desktop or compound) * * @param context the context (can be taken from DockingDesktop.getDockingContext() used by this manager * @param container the "top level" container managed (usually a DockingDesktop or a CompoundDockingPanel) */ public AnchorManager(DockingContext context, Container container) { this.context = context; this.container = container; context.addDockingActionListener(actionListener); } /** Cleanup for this manager : removes references and listeners */ public void clear() { context.removeDockingActionListener(actionListener); constraintsByDockable.clear(); } /** Associates an anchor constraints to a given dockable * @param dockable the dockable to anchor * @param constraints associated anchor constraints */ public void putDockableContraints(Dockable dockable, AnchorConstraints constraints) { constraintsByDockable.put(dockable, constraints); } /** Returns the anchor constraints associated to a given dockable * @param dockable the dockable to anchor * @return the constraints for this dockable, or null if no constraints is associated */ public AnchorConstraints getDockableConstraints(Dockable dockable) { return constraintsByDockable.get(dockable); } /** Removes an anchor constraints to a given dockable * @param dockable the dockable whose anchor is to be removed */ public AnchorConstraints removeDockableConstraints(Dockable dockable) { return constraintsByDockable.remove(dockable); } /** Look up the spilt hierarchy to find which borders a dockable is touching. * */ private int getContactBorders(Dockable dockable) { return RelativeDockingUtilities.findAnchors(dockable.getComponent(), container); } /** Returns a list of all dockables contained into base */ private ArrayList findDockables(Container base) { ArrayList dockables = new ArrayList(10); Iterator it = constraintsByDockable.keySet().iterator(); while(it.hasNext()) { Dockable d = it.next(); if(base.isAncestorOf(d.getComponent())) { dockables.add(d); } } return dockables; } private boolean acceptSplitComponent(DockingActionSplitComponentEvent event) { Component base = event.getBase(); ArrayList baseDockables = findDockables((Container) base); // we suppose that dockables in "base" are ok (respecting their own set of constraints before the split) // we still have to check is splitting will break a constraint or not int contactBorders = RelativeDockingUtilities.findAnchors(base, container); switch(event.getSplitPosition().value()) { case DockingConstants.INT_SPLIT_TOP: // as we won't be touching TOP anymore, check if this // constraint is not set in contained dockables if(isConstraintSet(AnchorConstraints.ANCHOR_TOP, baseDockables)) { return false; } contactBorders = contactBorders & ~ AnchorConstraints.ANCHOR_BOTTOM; break; case DockingConstants.INT_SPLIT_LEFT: if(isConstraintSet(AnchorConstraints.ANCHOR_LEFT, baseDockables)) { return false; } contactBorders = contactBorders & ~ AnchorConstraints.ANCHOR_RIGHT; break; case DockingConstants.INT_SPLIT_BOTTOM: if(isConstraintSet(AnchorConstraints.ANCHOR_BOTTOM, baseDockables)) { return false; } contactBorders = contactBorders & ~ AnchorConstraints.ANCHOR_TOP; break; case DockingConstants.INT_SPLIT_RIGHT: if(isConstraintSet(AnchorConstraints.ANCHOR_RIGHT, baseDockables)) { return false; } contactBorders = contactBorders & ~ AnchorConstraints.ANCHOR_LEFT; break; } // now, we're sure we won't break a 'base' constraint // we have to check if the moved dockable will respect its own constraints AnchorConstraints acDockable = getDockableConstraints(event.getDockable()); if(acDockable != null) { int anchor = acDockable.getAnchor(); if((anchor & contactBorders) != anchor) { // anchor is not respected return false; } } return true; } private boolean acceptSplitDockable(DockingActionSplitDockableEvent event) { // two rules to enforce : // the added component must respect its own set of constraints // the base dockable, once the new component added, must also respect its own set of constraints Dockable base = event.getBase(); AnchorConstraints acBase = getDockableConstraints(base); int contactBorders = getContactBorders(base); switch(event.getSplitPosition().value()) { case DockingConstants.INT_SPLIT_TOP: // as we won't be touching TOP anymore, check if this // constraint is not set in contained dockables if(isConstraintSet(AnchorConstraints.ANCHOR_TOP, base)) { return false; } contactBorders = contactBorders & ~ AnchorConstraints.ANCHOR_BOTTOM; break; case DockingConstants.INT_SPLIT_LEFT: if(isConstraintSet(AnchorConstraints.ANCHOR_LEFT, base)) { return false; } contactBorders = contactBorders & ~ AnchorConstraints.ANCHOR_RIGHT; break; case DockingConstants.INT_SPLIT_BOTTOM: if(isConstraintSet(AnchorConstraints.ANCHOR_BOTTOM, base)) { return false; } contactBorders = contactBorders & ~ AnchorConstraints.ANCHOR_TOP; break; case DockingConstants.INT_SPLIT_RIGHT: if(isConstraintSet(AnchorConstraints.ANCHOR_RIGHT, base)) { return false; } contactBorders = contactBorders & ~ AnchorConstraints.ANCHOR_LEFT; break; } // now, we're sure we won't break a 'base' constraint // we have to check if the moved dockable will respect its own constraints AnchorConstraints acDockable = getDockableConstraints(event.getDockable()); if(acDockable != null) { int anchor = acDockable.getAnchor(); if((anchor & contactBorders) != anchor) { // anchor is not respected return false; } } return true; } private boolean acceptSplitDockableContainer(DockingActionSplitDockableContainerEvent event) { Component base = event.getBase(); ArrayList baseDockables = findDockables((Container) base); // we suppose that dockables in "base" are ok (respecting their own set of constraints before the split) // we still have to check is splitting will break a constraint or not int contactBorders = RelativeDockingUtilities.findAnchors(base, container); switch(event.getSplitPosition().value()) { case DockingConstants.INT_SPLIT_TOP: // as we won't be touching TOP anymore, check if this // constraint is not set in contained dockables if(isConstraintSet(AnchorConstraints.ANCHOR_TOP, baseDockables)) { return false; } contactBorders = contactBorders & ~ AnchorConstraints.ANCHOR_BOTTOM; break; case DockingConstants.INT_SPLIT_LEFT: if(isConstraintSet(AnchorConstraints.ANCHOR_LEFT, baseDockables)) { return false; } contactBorders = contactBorders & ~ AnchorConstraints.ANCHOR_RIGHT; break; case DockingConstants.INT_SPLIT_BOTTOM: if(isConstraintSet(AnchorConstraints.ANCHOR_BOTTOM, baseDockables)) { return false; } contactBorders = contactBorders & ~ AnchorConstraints.ANCHOR_TOP; break; case DockingConstants.INT_SPLIT_RIGHT: if(isConstraintSet(AnchorConstraints.ANCHOR_RIGHT, baseDockables)) { return false; } contactBorders = contactBorders & ~ AnchorConstraints.ANCHOR_LEFT; break; } // now, we're sure we won't break a 'base' constraint // we have to check if the moved dockable container will respect its own constraints if(event.getDockableContainer() instanceof TabbedDockableContainer) { // the only one managed currently (drag gesture : move a whole tabbed pane around) ArrayList containersDockables = findDockables(event.getDockableContainer()); // check if these dockable have constraints for(int i = 0; i < containersDockables.size(); i++) { Dockable d = (Dockable) containersDockables.get(i); AnchorConstraints acDockable = getDockableConstraints(d); if(acDockable != null) { int anchor = acDockable.getAnchor(); if((anchor & contactBorders) != anchor) { // anchor is not respected return false; } } } } return true; } private boolean acceptAddDockable(DockingActionAddDockableEvent event) { Container parent = event.getParentContainer(); int contactBorders = RelativeDockingUtilities.findAnchors(parent, container); Dockable d = event.getDockable(); AnchorConstraints acDockable = getDockableConstraints(d); if(acDockable != null) { int anchor = acDockable.getAnchor(); if((anchor & contactBorders) != anchor) { // anchor is not respected return false; } } return true; } private boolean acceptCreateTab(DockingActionCreateTabEvent event) { int contactBorders = getContactBorders(event.getBase()); Dockable d = event.getDockable(); AnchorConstraints acDockable = getDockableConstraints(d); if(acDockable != null) { int anchor = acDockable.getAnchor(); if((anchor & contactBorders) != anchor) { // anchor is not respected return false; } } return true; } /** checks if a given anchor is set into one of the given dockables*/ private boolean isConstraintSet(int anchor, ArrayList baseDockables) { for(int i = 0; i < baseDockables.size(); i++) { AnchorConstraints ac = constraintsByDockable.get(baseDockables.get(i)); if(ac != null) { // 2007/01/08 if((ac.getAnchor() & anchor) > 0) { return true; } } } return false; } /** checks if a given anchor is set for a dockable*/ private boolean isConstraintSet(int anchor, Dockable dockable) { AnchorConstraints ac = constraintsByDockable.get(dockable); if(ac == null) { //2007/01/08 return false; } if((ac.getAnchor() & anchor) > 0) { return true; } return false; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/AutoHideBorderLayout.java000066400000000000000000000076631243334202400327470ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.util.*; import java.awt.*; /** A Layout Manager for auto-hide borders. * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ @SuppressWarnings({"rawtypes", "unchecked"}) public class AutoHideBorderLayout implements LayoutManager2 { private ArrayList components = new ArrayList(); private boolean isHorizontal; private int gap; // gap in pixels between components /** Constructs a new Layout. * * @param isHorizontal indicates if the layout will be horizontal or vertical. * * */ public AutoHideBorderLayout(boolean isHorizontal) { this(isHorizontal, AutoHidePolicy.getPolicy().getDefaultGap()); /** @todo we do not yet listen to gap property change */ } /** Constructs a new Layout. * @param isHorizontal indicates if the layout will be horizontal or vertical. * @param gap gap in pixels between components * */ public AutoHideBorderLayout(boolean isHorizontal, int gap) { this.isHorizontal = isHorizontal; this.gap = gap; } public float getLayoutAlignmentX(Container target) { return 0.5F; } public float getLayoutAlignmentY(Container target) { return 0.5F; } public void invalidateLayout(Container target) {} public Dimension maximumLayoutSize(Container target) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } public void addLayoutComponent(Component comp, Object constraints) { if(constraints == null) { components.add(comp); } else { Integer i = (Integer) constraints; components.add(i.intValue(), comp); } } public void removeLayoutComponent(Component comp) { components.remove(comp); } public void addLayoutComponent(String name, Component comp) {} public Dimension minimumLayoutSize(Container parent) { synchronized(parent.getTreeLock()) { Dimension dim = new Dimension(0, 0); int visible = 0; for(int i = 0; i < components.size(); i++) { Component comp = (Component) components.get(i); Dimension d = comp.getPreferredSize(); if(comp.isVisible()) { visible++; if(isHorizontal) { dim.width += d.width; dim.height = Math.max(dim.height, d.height); } else { dim.width = Math.max(dim.width, d.width); dim.height += d.height; } } } // add the gap between components if(isHorizontal) { dim.width += (visible - 1) * gap; } else { dim.height += (visible - 1) * gap; } Insets insets = parent.getInsets(); dim.width += insets.left + insets.right; dim.height += insets.top + insets.bottom; return dim; } } public Dimension preferredLayoutSize(Container parent) { return minimumLayoutSize(parent); } /** overridden to adjust position (x(top) = width(left), y(left) = height(top) */ public void layoutContainer(Container target) { synchronized(target.getTreeLock()) { Insets insets = target.getInsets(); int top = insets.top; int left = insets.left; if(isHorizontal) { for(int i = 0; i < components.size(); i++) { Component comp = (Component) components.get(i); if(comp.isVisible()) { Dimension d = comp.getPreferredSize(); comp.setBounds(left, top, d.width, d.height); left += d.width + gap; } } } else { for(int i = 0; i < components.size(); i++) { Component comp = (Component) components.get(i); if(comp.isVisible()) { Dimension d = comp.getPreferredSize(); comp.setBounds(left, top, d.width, d.height); top += d.height + gap; } } } } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/AutoHideButton.java000066400000000000000000000131301243334202400315710ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.Insets; import java.awt.Dimension; import java.beans.*; /** The button used to show Dockables in auto-hide borders. *

* This component displays the label, tooltip and icon properties of a * Dockable's DockKey, with a custom look and feel. * * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public class AutoHideButton extends JLabel { private static final long serialVersionUID = 1L; /** property name associated to the "zone" (border) property */ public static final String PROPERTY_ZONE = "autohide.zone"; public static final String uiClassID = "AutoHideButtonUI"; private boolean selected = false; private DockKey key; private Dockable dockable; private int zone; // the border used private boolean isNotification = false; private Timer notificationTimer; // blinking timer private int blinkCount = 0; private int MAX_BLINKS = UIManager.getInt("DockingDesktop.notificationBlinkCount"); private PropertyChangeListener keyListener = new PropertyChangeListener() { // this is a DockKey listener, not a KeyEvent listener... public void propertyChange(PropertyChangeEvent e) { if(e.getPropertyName().equals(DockKey.PROPERTY_NAME)) { setText((String) e.getNewValue()); } else if(e.getPropertyName().equals(DockKey.PROPERTY_TOOLTIP)) { setToolTipText((String) e.getNewValue()); } else if(e.getPropertyName().equals(DockKey.PROPERTY_ICON)) { setIcon((Icon) e.getNewValue()); } else if(e.getPropertyName().equals(DockKey.PROPERTY_NOTIFICATION)) { boolean isOn = ((Boolean) e.getNewValue()).booleanValue(); if(isOn) { if(notificationTimer == null) { notificationTimer = new Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { setNotification(! isNotification); if(! isNotification) { blinkCount++; if(blinkCount >= MAX_BLINKS) { blinkCount = 0; notificationTimer.stop(); // enough blinking } } repaint(); } }); } setNotification(true); notificationTimer.restart(); } else { if(notificationTimer != null) { notificationTimer.stop(); blinkCount = 0; } setNotification(false); } } } }; public AutoHideButton() {} /** Sets the background color according to the notification boolean */ private void setNotification(boolean notification) { this.isNotification = notification; if(notification) { setBackground(UIManager.getColor("DockingDesktop.notificationColor")); setOpaque(true); } else { setOpaque(false); } repaint(); } /** Returns the dockable this button is for */ public Dockable getDockable() { return dockable; } /** Returns the key of the dockable */ public DockKey getKey() { return key; } /** Initialize the button for a Dockable and a border zone */ public void init(Dockable dockable, int zone) { DockKey key = dockable.getDockKey(); this.dockable = dockable; this.key = key; int oldZone = this.zone; this.zone = zone; firePropertyChange("autohide.zone", oldZone, zone); key.addPropertyChangeListener(keyListener); setText(key.getName()); setToolTipText(key.getTooltip()); if(key.getIcon() != null) { setIcon(key.getIcon()); } setFocusable(true); setOpaque(false); setIconTextGap(4); setAlignmentY(1); } public Dimension getPreferredSize() { if(zone == DockingConstants.INT_HIDE_TOP || zone == DockingConstants.INT_HIDE_BOTTOM) { return super.getPreferredSize(); } else { Dimension d = super.getPreferredSize(); Insets i = getInsets(); return new Dimension(d.height - i.top - i.bottom + i.left + i.right, d.width - i.left - i.right + i.top + i.bottom); // rotate the shape } } public Dimension getMaximumSize() { if(zone == DockingConstants.INT_HIDE_TOP || zone == DockingConstants.INT_HIDE_BOTTOM) { return super.getMaximumSize(); } else { Insets i = getInsets(); Dimension d = super.getMaximumSize(); return new Dimension(d.height - i.top - i.bottom + i.left + i.right, d.width - i.left - i.right + i.top + i.bottom); // rotate the shape } } public Dimension getMinimumSize() { if(zone == DockingConstants.INT_HIDE_TOP || zone == DockingConstants.INT_HIDE_BOTTOM) { return super.getMinimumSize(); } else { Insets i = getInsets(); Dimension d = super.getMinimumSize(); return new Dimension(d.height - i.top - i.bottom + i.left + i.right, d.width - i.left - i.right + i.top + i.bottom); // rotate the shape } } /** Returns the border zone of this button*/ public int getZone() { return zone; } /** True when the button is currently selected. */ public boolean isSelected() { return selected; } /** Selects or unselects the button */ public void setSelected(boolean selected) { this.selected = selected; setOpaque(selected); repaint(); if(selected) { key.setNotification(false); // in case we were in notification mode } } public String getUIClassID() { return uiClassID; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/AutoHideButtonPanel.java000066400000000000000000000065521243334202400325630ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import javax.swing.*; import java.awt.*; import java.awt.event.*; /** A Swing panel used as a toolbar for autohide buttons. * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public class AutoHideButtonPanel extends JPanel { private static final long serialVersionUID = 1L; /** The property name associated with the "border" property */ public static final String PROPERTY_BORDERZONE = "borderzone"; public static final String uiClassID = "AutoHideButtonPanelUI"; /** <=> Zone */ private int border; /** highlight effect (rollover) on the contained buttons */ private ButtonHighlighter buttonHighlighter = new ButtonHighlighter(); /** expansion management */ private AutoHideExpandPanel expandPanel; /** Constructs a new AutoHideButtonPanel, with a shared expandPanel, and for * a specified border zone. * * @param border constant taken from AutoHideButtonPanel.TOP, AutoHideButtonPanel.LEFT, * AutoHideButtonPanel.BOTTOM, AutoHideButtonPanel.RIGHT * */ public AutoHideButtonPanel(AutoHideExpandPanel expandPanel, int border) { this.border = border; this.expandPanel = expandPanel; boolean isHorizontal = (border == DockingConstants.INT_HIDE_TOP) || (border == DockingConstants.INT_HIDE_BOTTOM); setLayout(new AutoHideBorderLayout(isHorizontal)); firePropertyChange("borderzone", - 1, border); } /** Returns the number of buttons currently displayed by this panel. */ public int getVisibleButtonCount() { Component[] comps = getComponents(); int count = 0; for(int i = 0; i < comps.length; i++) { if(comps[i].isVisible()) { count++; } } return count; } /** Returns the border this panel is for. *

* Values are : AutoHideButtonPanel.TOP, AutoHideButtonPanel.LEFT, * AutoHideButtonPanel.BOTTOM, AutoHideButtonPanel.RIGHT */ public int getBorderZone() { return border; } /** Adds a new AutoHideButton. * */ public void add(AutoHideButton btn) { add((Component) btn); btn.addMouseListener(buttonHighlighter); btn.addMouseListener(expandPanel.getControler()); } /** Removes an AutoHideButton */ public void remove(AutoHideButton btn) { super.remove(btn); btn.removeMouseListener(buttonHighlighter); } private class ButtonHighlighter extends MouseAdapter { Color highlight = UIManager.getColor("VLDocking.highlight"); public void mouseEntered(MouseEvent e) { AutoHideButton btn = (AutoHideButton) e.getSource(); if(! btn.isSelected()) { // selected buttons have their own pain style btn.setBackground(highlight); btn.setOpaque(true); btn.repaint(); } } public void mouseExited(MouseEvent e) { AutoHideButton btn = (AutoHideButton) e.getSource(); if(! btn.isSelected()) { // selected buttons have their own pain style btn.setOpaque(false); btn.repaint(); } } } public String getUIClassID() { return uiClassID; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/AutoHideExpandPanel.java000066400000000000000000001012611243334202400325200ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.beans.*; import java.awt.event.*; import javax.swing.*; import java.awt.*; import java.util.HashMap; import com.vlsolutions.swing.docking.animation.*; import java.lang.reflect.Method; import javax.swing.border.*; import javax.swing.event.AncestorEvent; import javax.swing.event.AncestorListener; /** A component used to show the currently expanded view. *

* Auto-Hide / Auto-Expand feature is a means to save space of screen replacing * a Dockable by a Button on one of the Desktop borders. *

When the user clicks on the button or his mouse rolls over it, the component * is shown (with an expansion animation) as if it was coming from behind the button's * border. * * @author Lilian Chamontin, vlsolutions. * @version 2.0 * @update 2005/10/06 Lilian Chamontin : protected access to the exansion timer that might be * null when AutoHidePolicy is EXPAND_ON_CLICK * @update 2005/11/01 Lilian Chamontin : enhanced timer management to auto-collaspe the panel * when mouse out of bounds * @update 2005/12/08 Lilian Chamontin : updated the order of component insertion for JDIC support. * @update 2006/12/19 Lilian Chamontin : fixed a memory leak issue. * @update 2007/01/08 Lilian Chamontin : updated to use the new titlebar factory method * */ @SuppressWarnings({"rawtypes", "unchecked"}) public class AutoHideExpandPanel extends JPanel implements SingleDockableContainer { private static final long serialVersionUID = 1L; public static final String uiClassID = "AutoHideExpandPanelUI"; /** Constant for the Expanded property (a bound property) */ public static final String PROPERTY_EXPANDED = "AutoHideExpanded"; private Timer expansionTimer; private boolean isRolloverTimer = false; private boolean isExpanding = false; // true during animation phase, will be used to avoid concurrent animations (@todo) private HashMap savedDimensions = new HashMap(); // Component/Dimension ExpandControler controler = new ExpandControler(); // hide event listener private AutoHideButton selectedButton; private Component expandedComponent; // current component DockingDesktop desk; private JPanel topDragger = getTopDragger(); // indirection because those components are used by the ui delegate private JPanel leftDragger = getLeftDragger(); private JPanel bottomDragger = getBottomDragger(); private JPanel rightDragger = getRightDragger(); private JPanel lastDragger; // last used dragger private JPanel content = new JPanel(new BorderLayout()); // content displayed (user component) private Panel heavyPanel; // used only when mixing lightweight and heavyweight components private DockViewTitleBar titleBar = createTitleBar(); private AnimationControler animationControler = new AnimationControler(); private Border expandFromTopBorder, expandFromLeftBorder, expandFromBottomBorder, expandFromRightBorder; /** this boolean is used to disable auto-hiding temporarily, especially during * drag operation (where mouse can leave the component) */ private boolean shouldCollapse = true; /** flag used when heavywieght usage + single heavyweight component */ private boolean isHeavyPanelInstalled = false; /** Used by the collapse timer*/ private long lastTimeMouseWasIn = 0; private boolean canUseMouseInfo = DockingUtilities.canUseMouseInfo(); private FocusCollapser collapser = new FocusCollapser(); // 2006/12/19 /** Timer used to collapse the expand panel (when mouse is out of bounds). * (only for java > 1.5) */ private javax.swing.Timer collapseTimer // 2005/11/01 = new javax.swing.Timer(250, new ActionListener() { // timer used to hide the expanded panel when mouse is out too long public void actionPerformed(ActionEvent actionEvent) { // all this mess to allow compilation from java 1.4 Point mouseLocation = DockingUtilities.getMouseLocation(); if(mouseLocation == null) { return; } Point p = new Point(); SwingUtilities.convertPointToScreen(p, AutoHideExpandPanel.this); Rectangle expandPanelBounds = new Rectangle(p.x, p.y, getWidth(), getHeight()); if(expandPanelBounds.contains(mouseLocation)) { // we're inside the expand panel lastTimeMouseWasIn = System.currentTimeMillis(); } else { // not inside the component : check also into its associated button Point btnPoint = new Point();//selectedButton.getX(),selectedButton.getY()); SwingUtilities.convertPointToScreen(btnPoint, selectedButton); Rectangle btnRect = new Rectangle(btnPoint.x, btnPoint.y, selectedButton.getWidth(), selectedButton.getHeight()); if(btnRect.contains(mouseLocation)) { lastTimeMouseWasIn = System.currentTimeMillis(); } else { if(System.currentTimeMillis() - lastTimeMouseWasIn > 1000) { // it's time to collapse if(! isActive() && shouldCollapse()) { // do not hide it if it has got the focus // or if a non-collapsible operation is occuring if(selectedButton != null) { collapse(); } } } } } } }); public AutoHideExpandPanel() { super(new BorderLayout()); if(! DockingPreferences.isLightWeightUsageEnabled()) { this.heavyPanel = new Panel(new BorderLayout()); } if(AutoHidePolicy.getPolicy().getExpandMode() == AutoHidePolicy.ExpandMode.EXPAND_ON_ROLLOVER) { expansionTimer = new Timer(AutoHidePolicy.getPolicy().getRolloverTriggerDelay(), controler); expansionTimer.setRepeats(false); isRolloverTimer = true; } initBorders(); setFocusCycleRoot(true); // keep keyboard focus //requiered to trap mouse events under the panel (so they don't go to the mousegrabber) addMouseListener(new MouseAdapter() {}); if(DockingPreferences.isLightWeightUsageEnabled()) { // for Swing only : direct usage of the content jpanel add(content, BorderLayout.CENTER); } else { if(! DockingPreferences.isSingleHeavyWeightComponent()) { // when mixing heavyweight and lightweight component, we have // to ensure our content will not be covered by an underlying heavy component. // to do this, we add an intermediary heavyweight panel. // note : if there is only one heavyweight dockable, // we delay and delegate this operation to installHeavyWeightIfNeeded heavyPanel.add(content, BorderLayout.CENTER); // jdk1.5 only, but we compile with 1.4 source level try { // this.setComponentZOrder(heavyPanel, 0); // top most Method m = Container.class.getMethod("setComponentZOrder", new Class[] {Component.class, int.class}); m.invoke(this, new Object[] {heavyPanel, new Integer(0)}); } catch(Exception ignore) { } add(heavyPanel, BorderLayout.CENTER); } else { // (heavy + single) will be dynamically changed depending on the expanded dockable add(content, BorderLayout.CENTER); add(topDragger, BorderLayout.NORTH); add(bottomDragger, BorderLayout.SOUTH); add(leftDragger, BorderLayout.WEST); add(rightDragger, BorderLayout.EAST); } } addAncestorListener(new AncestorListener() { //2006/12/19 : reworked to avoid GC leak public void ancestorAdded(AncestorEvent event) { AutoHidePolicy.getPolicy().addPropertyChangeListener(controler); if(DockingPreferences.isLightWeightUsageEnabled()) { KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("focusOwner", collapser); } } public void ancestorMoved(AncestorEvent event) {} public void ancestorRemoved(AncestorEvent event) { AutoHidePolicy.getPolicy().removePropertyChangeListener(controler); if(DockingPreferences.isLightWeightUsageEnabled()) { KeyboardFocusManager.getCurrentKeyboardFocusManager().removePropertyChangeListener("focusOwner", collapser); } } }); content.add(titleBar, BorderLayout.NORTH); // initDockingFunctions(); } private void installHeavyWeightParentIfNeeded(Dockable target) { if(DockingPreferences.isLightWeightUsageEnabled()) { return; // not needed as we are in pure lightweight } if(! DockingPreferences.isSingleHeavyWeightComponent()) { return; // not possible as there are multiple heavyweight } if(DockingUtilities.isHeavyWeightComponent(target.getComponent())) { // no need to install the heavypanel if(isHeavyPanelInstalled) { // we even have to remove it this.removeAll(); this.add(content, BorderLayout.CENTER); add(topDragger, BorderLayout.NORTH); add(bottomDragger, BorderLayout.SOUTH); add(leftDragger, BorderLayout.WEST); add(rightDragger, BorderLayout.EAST); revalidate(); isHeavyPanelInstalled = false; } } else { if(isHeavyPanelInstalled) { // nothing more to do, content is already inside heavypanel } else { this.removeAll(); this.add(heavyPanel, BorderLayout.CENTER); heavyPanel.add(content, BorderLayout.CENTER); heavyPanel.add(topDragger, BorderLayout.NORTH); heavyPanel.add(bottomDragger, BorderLayout.SOUTH); heavyPanel.add(leftDragger, BorderLayout.WEST); heavyPanel.add(rightDragger, BorderLayout.EAST); isHeavyPanelInstalled = true; revalidate(); // jdk1.5 only, but we compile with 1.4 source level try { // this.setComponentZOrder(heavyPanel, 0); // top most Method m = Container.class.getMethod("setComponentZOrder", new Class[] {Component.class, int.class}); m.invoke(this, new Object[] {heavyPanel, new Integer(0)}); } catch(Exception ignore) { } } } } public boolean isOptimizedDrawingEnabled() { return DockingPreferences.isLightWeightUsageEnabled(); // only when lightweight components (to ensure correct zorder for AWT) } /** Returns true if this panel is the ancestor of the focused component */ public boolean isActive() { if(titleBar.isActive()) { return true; } else { // since 2.1 : the autohide component can contain a nested set of dockables, so the // titlebar's activity isn't always usable : we have to verify if the focus is still // inside Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); if(focusOwner == null) { return false; } else { return isAncestorOf(focusOwner); } } //return titleBar.isActive(); } /** Returns true if this panel agrees to beeing hidden. *

* During drag operations (resizing), some mouseEnter/mouseExit events * can be lost. In that case, the desktop relies on this method to * request collaping or not. * */ public boolean shouldCollapse() { return shouldCollapse; } /** Returns the component used to modify the expand panel size when expanded from the bottom */ public JPanel getTopDragger() { /* This method is used by the UI to install proper borders */ if(topDragger == null) { topDragger = new JPanel(); } return topDragger; } /** Returns the component used to modify the expand panel size when expanded from the right */ public JPanel getLeftDragger() { /* This method is used by the UI to install proper borders */ if(leftDragger == null) { leftDragger = new JPanel(); } return leftDragger; } /** Returns the component used to modify the expand panel size when expanded from the top */ public JPanel getBottomDragger() { /* This method is used by the UI to install proper borders */ if(bottomDragger == null) { bottomDragger = new JPanel(); } return bottomDragger; } /** Returns the component used to modify the expand panel size when expanded from the right */ public JPanel getRightDragger() { /* This method is used by the UI to install proper borders */ if(rightDragger == null) { rightDragger = new JPanel(); } return rightDragger; } /** creates the shared title bar for all expanded panels */ protected DockViewTitleBar createTitleBar() { return DockableContainerFactory.getFactory().createTitleBar(); //2007/01/08 //return new DockViewTitleBar(); } public DockViewTitleBar getTitleBar() { return this.titleBar; } /** Creates the default borders for the expand panel */ public void resetBorders() { Color shadow = UIManager.getColor("VLDocking.shadow"); Color highlight = UIManager.getColor("VLDocking.highlight"); if(highlight == null) { highlight = shadow.brighter(); } getTopDragger().setBorder(BorderFactory.createMatteBorder(1, 1, 0, 1, shadow)); getLeftDragger().setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, shadow)); getBottomDragger().setBorder(BorderFactory.createMatteBorder(0, 1, 1, 1, shadow)); getRightDragger().setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, shadow)); expandFromTopBorder = BorderFactory.createCompoundBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(1, 1, 0, 1, shadow), BorderFactory.createMatteBorder(1, 1, 1, 0, highlight)), BorderFactory.createEmptyBorder(2, 2, 2, 2)); expandFromLeftBorder = BorderFactory.createCompoundBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, shadow), BorderFactory.createMatteBorder(1, 1, 1, 1, highlight)), BorderFactory.createEmptyBorder(2, 2, 2, 2)); expandFromBottomBorder = BorderFactory.createCompoundBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 1, 1, 1, shadow), BorderFactory.createMatteBorder(1, 1, 1, 1, highlight)), BorderFactory.createEmptyBorder(2, 2, 2, 2)); expandFromRightBorder = BorderFactory.createCompoundBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, shadow), BorderFactory.createMatteBorder(1, 1, 1, 1, highlight)), BorderFactory.createEmptyBorder(2, 2, 2, 2)); } /** Installs borders used to drag the expand panel around */ protected void initBorders() { Dimension min = new Dimension(4, 4); topDragger.setVisible(false); topDragger.setPreferredSize(min); topDragger.setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)); DragListener topListener = new DragListener(DockingConstants.INT_HIDE_BOTTOM); topDragger.addMouseMotionListener(topListener); topDragger.addMouseListener(topListener); leftDragger.setVisible(false); leftDragger.setPreferredSize(min); leftDragger.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); DragListener leftListener = new DragListener(DockingConstants.INT_HIDE_RIGHT); leftDragger.addMouseMotionListener(leftListener); leftDragger.addMouseListener(leftListener); bottomDragger.setVisible(false); bottomDragger.setPreferredSize(min); bottomDragger.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)); DragListener bottomListener = new DragListener(DockingConstants.INT_HIDE_TOP); bottomDragger.addMouseMotionListener(bottomListener); bottomDragger.addMouseListener(bottomListener); rightDragger.setVisible(false); rightDragger.setPreferredSize(min); rightDragger.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)); DragListener rightListener = new DragListener(DockingConstants.INT_HIDE_LEFT); rightDragger.addMouseMotionListener(rightListener); rightDragger.addMouseListener(rightListener); if(DockingPreferences.isLightWeightUsageEnabled()) { add(topDragger, BorderLayout.NORTH); add(bottomDragger, BorderLayout.SOUTH); add(leftDragger, BorderLayout.WEST); add(rightDragger, BorderLayout.EAST); } else { if(! DockingPreferences.isSingleHeavyWeightComponent()) { heavyPanel.add(topDragger, BorderLayout.NORTH); heavyPanel.add(bottomDragger, BorderLayout.SOUTH); heavyPanel.add(leftDragger, BorderLayout.WEST); heavyPanel.add(rightDragger, BorderLayout.EAST); } } } private void initDockingFunctions() { PropertyChangeListener listener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { if(e.getPropertyName().equals(DockViewTitleBar.PROPERTY_AUTOHIDE)) { // from autohide to dock // remember values after autohide Dockable d = selectedButton.getDockable(); desk.setAutoHide(d, false); } else if(e.getPropertyName().equals(DockViewTitleBar.PROPERTY_CLOSED)) { Dockable d = selectedButton.getDockable(); collapse(); desk.close(d); } else if(e.getPropertyName().equals(DockViewTitleBar.PROPERTY_DRAGGED)) { // the user is starting a drag gesture : we must collapse ! collapse(); } else if(e.getPropertyName().equals(DockViewTitleBar.PROPERTY_FLOAT)) { Dockable d = selectedButton.getDockable(); collapse(); desk.setFloating(d, true); } } }; titleBar.addPropertyChangeListener(DockViewTitleBar.PROPERTY_AUTOHIDE, listener); titleBar.addPropertyChangeListener(DockViewTitleBar.PROPERTY_CLOSED, listener); titleBar.addPropertyChangeListener(DockViewTitleBar.PROPERTY_DRAGGED, listener); titleBar.addPropertyChangeListener(DockViewTitleBar.PROPERTY_FLOAT, listener); titleBar.installDocking(desk); desk.installDockableDragSource(titleBar); } /** Returns the component responsible for managing auto-expansion. * */ /* package protected */ExpandControler getControler() { return controler; } /** Selects a button (may collapse a prevoiusly selected button) */ public void select(AutoHideButton btn) { if(selectedButton != null && selectedButton != btn) { collapse(); } selectedButton = btn; btn.setSelected(true); } private void restartCollapseTimer() { // if (!DockingPreferences.isLightWeightUsageEnabled()){ if(canUseMouseInfo) { // not for 1.4 this.lastTimeMouseWasIn = System.currentTimeMillis(); collapseTimer.restart(); } } private void stopCollapseTimer() { // if (!DockingPreferences.isLightWeightUsageEnabled()){ if(canUseMouseInfo) { // not for 1.4 collapseTimer.stop(); } } /** Expands the currently selected button */ public void expand() { if(selectedButton == null) { return;//2007/01/10 //throw new IllegalStateException("No button selected for expansion"); } installComponent(); restartCollapseTimer(); setVisible(true); Rectangle bounds = desk.getBounds(); AutoHidePolicy policy = AutoHidePolicy.getPolicy(); int model = policy.getInitialExpansionModel(); Dimension bestDimension = null; if(model == AutoHidePolicy.INITIAL_EXPAND_COMPONENT_SIZE) { bestDimension = savedDimensions.get(selectedButton); if(bestDimension == null) { bestDimension = selectedButton.getDockable().getComponent().getPreferredSize(); switch(selectedButton.getZone()) { case DockingConstants.INT_HIDE_TOP: case DockingConstants.INT_HIDE_BOTTOM: if(bestDimension.height > bounds.height / 2) { bestDimension.height = bounds.height / 2; } break; case DockingConstants.INT_HIDE_LEFT: case DockingConstants.INT_HIDE_RIGHT: if(bestDimension.width > bounds.width / 2) { bestDimension.width = bounds.width / 2; } break; } } } else if(model == AutoHidePolicy.INITIAL_EXPAND_CUSTOM_SIZE) { bestDimension = new Dimension(); switch(selectedButton.getZone()) { case DockingConstants.INT_HIDE_TOP: case DockingConstants.INT_HIDE_BOTTOM: bestDimension.height = policy.getInitialExpansionHeight(); if(bestDimension.height > bounds.height / 2) { bestDimension.height = bounds.height / 2; } break; case DockingConstants.INT_HIDE_LEFT: case DockingConstants.INT_HIDE_RIGHT: bestDimension.width = policy.getInitialExpansionWidth(); if(bestDimension.width > bounds.width / 2) { bestDimension.width = bounds.width / 2; } break; } } else { throw new RuntimeException("invalid Initial Expansion model : " + model); } // outer insets (including autohide borders) Insets i = desk.getDockingPanelInsets(); // inner insets (of expandPanel : mouse grabbers etc..) Insets i2 = getComponentInsets(); switch(selectedButton.getZone()) { case DockingConstants.INT_HIDE_TOP: new ComponentAnimator(this, new Rectangle(i.left, i.top, bounds.width - i.left - i.right, 0), new Rectangle(i.left, i.top, bounds.width - i.left - i.right, bestDimension.height + i2.top + i2.bottom), AutoHidePolicy.getPolicy().getExpansionDuration() / 1000f, animationControler); break; case DockingConstants.INT_HIDE_BOTTOM: new ComponentAnimator(this, new Rectangle(i.left, bounds.height - i.bottom, bounds.width - i.left - i.right, 0), new Rectangle(i.left, bounds.height - bestDimension.height - i.bottom - i2.top - i2.bottom, bounds.width - i.left - i.right, bestDimension.height + i2.top + i2.bottom), AutoHidePolicy.getPolicy().getExpansionDuration() / 1000f, animationControler); break; case DockingConstants.INT_HIDE_LEFT: new ComponentAnimator(this, new Rectangle(i.left, i.top, 0, bounds.height - i.top - i.bottom), new Rectangle(i.left, i.top, bestDimension.width + i2.left + i2.right, bounds.height - i.top - i.bottom), AutoHidePolicy.getPolicy().getExpansionDuration() / 1000f, animationControler); break; case DockingConstants.INT_HIDE_RIGHT: new ComponentAnimator(this, new Rectangle(bounds.width - i.right, i.top, 0, bounds.height - i.top - i.bottom), new Rectangle(bounds.width - bestDimension.width - i.right - i2.left - i2.right, i.top, bestDimension.width + i2.left + i2.right, bounds.height - i.top - i.bottom), AutoHidePolicy.getPolicy().getExpansionDuration() / 1000f, animationControler); break; default: assert false; } firePropertyChange(PROPERTY_EXPANDED, false, true); } /** Removes a dockable (if it was the currently expanded one) */ public void remove(Dockable dockable) { Component comp = dockable.getComponent(); if(expandedComponent != null && expandedComponent == comp) { content.remove(expandedComponent); expandedComponent = null; } } private void installComponent() { final Component comp = selectedButton.getDockable().getComponent(); if(expandedComponent != null) { if(expandedComponent != comp) { content.remove(expandedComponent); content.add(comp, BorderLayout.CENTER); //2005/12/08 back again in this order (JDIC workaround) installHeavyWeightParentIfNeeded(selectedButton.getDockable()); expandedComponent = comp; } } else { content.add(comp, BorderLayout.CENTER); installHeavyWeightParentIfNeeded(selectedButton.getDockable()); expandedComponent = comp; } /* // the workaround isn't needed anymore : we use the heavyweightTimer instead if (!DockingPreferences.isLightWeightUsageEnabled()){ // this is a workaround : mouse listener doesn't work properly // on AWT components (they grab the event even if they are 'under' // our mouse grabber. SwingUtilities.invokeLater(new Runnable(){ public void run(){ // heavyPanel.requestFocus(); comp.requestFocus(); } // by requesting focus, we can rely on the safer focusOwner property // and use it to collapse thi panel (see FocusCollapser code below) }); }*/ titleBar.setDockable(selectedButton.getDockable()); desk.installDockableDragSource(titleBar); switch(selectedButton.getZone()) { case DockingConstants.INT_HIDE_TOP: content.setBorder(expandFromTopBorder); bottomDragger.setVisible(true); // remove previous border if(lastDragger != null && lastDragger != bottomDragger) { lastDragger.setVisible(false); } lastDragger = bottomDragger; break; case DockingConstants.INT_HIDE_BOTTOM: content.setBorder(expandFromBottomBorder); topDragger.setVisible(true); if(lastDragger != null && lastDragger != topDragger) { lastDragger.setVisible(false); } lastDragger = topDragger; break; case DockingConstants.INT_HIDE_LEFT: content.setBorder(expandFromLeftBorder); rightDragger.setVisible(true); if(lastDragger != null && lastDragger != rightDragger) { lastDragger.setVisible(false); } lastDragger = rightDragger; break; case DockingConstants.INT_HIDE_RIGHT: content.setBorder(expandFromRightBorder); leftDragger.setVisible(true); if(lastDragger != null && lastDragger != leftDragger) { lastDragger.setVisible(false); } lastDragger = leftDragger; break; default: assert false; } revalidate(); repaint(); } /** Calculates the insets needed around the center component. * This is the sum of border sizes and bordercomponents sizes. * */ private Insets getComponentInsets() { Insets i = getInsets(); // borders Insets i2 = content.getInsets(); i.top += i2.top; i.left += i2.left; i.bottom += i2.bottom; i.right += i2.right; if(topDragger.isVisible()) { i.top += topDragger.getHeight(); } i.top += titleBar.getHeight(); if(leftDragger.isVisible()) { i.left += leftDragger.getWidth(); } if(bottomDragger.isVisible()) { i.bottom += bottomDragger.getHeight(); } if(rightDragger.isVisible()) { i.right += rightDragger.getWidth(); } return i; } /** Collapse the expand panel (making it unvisible) */ public void collapse() { if(selectedButton != null) { savedDimensions.put(selectedButton, selectedButton.getDockable().getComponent().getSize()); selectedButton.setSelected(false); firePropertyChange(PROPERTY_EXPANDED, true, false); } selectedButton = null; setVisible(false); titleBar.closePopUp(); stopCollapseTimer(); if(! DockingPreferences.isLightWeightUsageEnabled()) { // we'd better repaint (ugly traces on linux) desk.repaint(); } } public void uninstallDocking(DockingDesktop desktop) { titleBar.uninstallDocking(desk); } public void installDocking(DockingDesktop desktop) { this.desk = desktop; initDockingFunctions(); } public Dockable getDockable() { if(selectedButton != null) { return selectedButton.getDockable(); } else { return null; } } public String getUIClassID() { return uiClassID; } /** Clears the state of this expand panel. *

* This is useful when re-installing a desktop from readXml (for example, * it resets dockable expand sizes) */ public void clear() { // clear savedDimensions.clear(); } /** inner class that follows animations of expansion */ private class AnimationControler implements AnimationListener { public void animation(AnimationEvent e) { isExpanding = e.getState() != AnimationEvent.ANIMATION_END; if(e.getState() == AnimationEvent.ANIMATION_END) { SwingUtilities.invokeLater(new Runnable() { public void run() { content.repaint(); } }); } } } /** This class hides expansion implementation from API */ private class ExpandControler implements MouseListener, ActionListener, PropertyChangeListener { /* temporary button : the next to be selected after a mouseEntered event and * triggered timer delay. */ private AutoHideButton mouseEnteredButton; /** used to avoid bad interactions between focus listeners and expand controler */ private boolean isUnderControl = false; public void mouseClicked(MouseEvent e) { // don't do anything during animation phase if(! isExpanding) { if(expansionTimer != null) { //2005/10/06 expansionTimer.stop(); } AutoHideButton clicked = (AutoHideButton) e.getSource(); if(selectedButton != clicked) { // we need to tell the focus listener not to manage focus while // this operation is occuring isUnderControl = true; select(clicked); // will trigger a focus change is DockingPreferences.isHeavuWeight SwingUtilities.invokeLater(new Runnable() { public void run() { expand(); isUnderControl = false; } }); } else { collapse(); } } } public void mouseEntered(MouseEvent e) { if(! isRolloverTimer) { return; } AutoHideButton btn = (AutoHideButton) e.getSource(); if(! btn.isSelected()) { // nothing more to do if selected if(expansionTimer != null) { expansionTimer.restart(); // 2005/10/06 } mouseEnteredButton = btn; } } public void mouseExited(MouseEvent e) { if(! isRolloverTimer) { return; } AutoHideButton btn = (AutoHideButton) e.getSource(); if(! btn.isSelected()) { // nothing more to do if selected expansionTimer.stop(); mouseEnteredButton = null; } } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void propertyChange(PropertyChangeEvent e) { /* triggered by autohide policy change*/ if(e.getPropertyName().equals(AutoHidePolicy.PROPERTY_EXPAND_MODE)) { if(AutoHidePolicy.getPolicy().getExpandMode() == AutoHidePolicy.ExpandMode.EXPAND_ON_ROLLOVER) { expansionTimer = new Timer(AutoHidePolicy.getPolicy().getRolloverTriggerDelay(), this); isRolloverTimer = true; } else { expansionTimer.stop(); expansionTimer = null; isRolloverTimer = false; } } else if(e.getPropertyName().equals(AutoHidePolicy.PROPERTY_ROLLOVER_TRIGGER_DELAY)) { if(AutoHidePolicy.getPolicy().getExpandMode() == AutoHidePolicy.ExpandMode.EXPAND_ON_ROLLOVER) { expansionTimer.setDelay(AutoHidePolicy.getPolicy().getRolloverTriggerDelay()); } } } public void actionPerformed(ActionEvent e) { // timer event : there is a button to expand assert mouseEnteredButton != null; isUnderControl = true; select(mouseEnteredButton); // will collapse the previous button SwingUtilities.invokeLater(new Runnable() { public void run() { expand(); isUnderControl = false; } }); } } private class DragListener implements MouseListener, MouseMotionListener { /* inner class of expand panel*/ int zone; DragListener(int zone) { this.zone = zone; } public void mouseDragged(MouseEvent e) { /* implement the drag effect on expand panel : a single border * can be dragged (the one not overlapping the borders of the panel */ // new height/width (including borders) int newHeight, newWidth; // where are we on the desk ? Point p = SwingUtilities.convertPoint((Component) e.getSource(), e.getPoint(), desk); Insets insets = getInsets(); Insets idesk = desk.getDockingPanelInsets(); switch(zone) { case DockingConstants.INT_HIDE_TOP: // drag from top to bottom : change the height of the panel newHeight = p.y - idesk.top + bottomDragger.getHeight() / 2 + insets.bottom + insets.top; newHeight = Math.max(10, Math.min(newHeight, desk.getHeight())); // clip setSize(getWidth(), newHeight); invalidate(); validate(); repaint(); break; case DockingConstants.INT_HIDE_BOTTOM: newHeight = desk.getHeight() - idesk.bottom - p.y + topDragger.getHeight() / 2 + insets.top + insets.bottom; int maxHeight = desk.getHeight() - topDragger.getHeight(); if(newHeight > maxHeight) { newHeight = maxHeight; } else if(newHeight < 10) { newHeight = 10; } Rectangle bounds = getBounds(); bounds.y = desk.getHeight() - idesk.bottom - newHeight; bounds.height = newHeight; setBounds(bounds); invalidate(); validate(); repaint(); break; case DockingConstants.INT_HIDE_LEFT: newWidth = p.x + rightDragger.getWidth() / 2 - idesk.left + insets.right + insets.left; int maxWidth = desk.getWidth() - rightDragger.getWidth(); if(newWidth > maxWidth) { newWidth = maxWidth; } else if(newWidth < 10) { newWidth = 10; } setSize(newWidth, getHeight()); invalidate(); validate(); repaint(); break; case DockingConstants.INT_HIDE_RIGHT: newWidth = desk.getWidth() - idesk.right - p.x + leftDragger.getWidth() / 2 + insets.left + insets.right; maxWidth = desk.getWidth() - leftDragger.getWidth(); if(newWidth > maxWidth) { newWidth = maxWidth; } else if(newWidth < 10) { newWidth = 10; } bounds = getBounds(); bounds.x = desk.getWidth() - idesk.right - newWidth; bounds.width = newWidth; setBounds(bounds); invalidate(); validate(); repaint(); break; } desk.repaint(); } public void mouseMoved(MouseEvent e) {} public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) { shouldCollapse = false; // begining or drag } public void mouseReleased(MouseEvent e) { shouldCollapse = true; // end of drag } } private class FocusCollapser implements PropertyChangeListener { // focusOwner public void propertyChange(PropertyChangeEvent e) { if(! controler.isUnderControl) { // this is not a focus lost due to the expand controler Component c = (Component) e.getNewValue(); if(c != null && ! AutoHideExpandPanel.this.isAncestorOf(c)) { // avoid collapsing when focus is given to a component which isn't a dockable if(DockingUtilities.findSingleDockableContainerAncestor(c) != null) { collapse(); } } } } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/AutoHidePolicy.java000066400000000000000000000164001243334202400315600ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.beans.*; /** This class holds preferences on default autohiding behaviour. * * @see AutoHideButtonPanel * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public class AutoHidePolicy { /** A set of constants for expanding a button on rollover, or on click */ public enum ExpandMode { /** Expand on rollover */ EXPAND_ON_ROLLOVER, /** Expand after click */ EXPAND_ON_CLICK; } /** A constant for initial expantion : based on preferred size of component * @see AutoHidePolicy#setInitialExpansionModel(int) */ public static final int INITIAL_EXPAND_COMPONENT_SIZE = 0; /** A constant for initial expantion : based on custom widths and heights * @see AutoHidePolicy#setInitialExpansionWidth(int) * @see AutoHidePolicy#setInitialExpansionHeight(int) * @see AutoHidePolicy#setInitialExpansionModel(int) */ public static final int INITIAL_EXPAND_CUSTOM_SIZE = 1; /** a constant designing the bound property DEFAULT_HIDE_BORDER */ public static final String PROPERTY_DEFAULT_HIDE_BORDER = "defaultHideBorder"; /** a constant designing the bound property DEFAULT_GAP */ public static final String PROPERTY_DEFAULT_GAP = "defaultGap"; /** a constant designing the bound property EXPAND_MODE (enum type) */ public static final String PROPERTY_EXPAND_MODE = "expandMode"; /** a constant designing the bound property ROLLOVER_TRIGGER_DELAY */ public static final String PROPERTY_ROLLOVER_TRIGGER_DELAY = "rolloverTriggerDelay"; /** a constant designing the bound property EXPANSION_DURATION */ public static final String PROPERTY_EXPANSION_DURATION = "expansionDuration"; private static AutoHidePolicy policy = new AutoHidePolicy(); /** where do we put the button at startup */ private DockingConstants.Hide defaultHideBorder = DockingConstants.HIDE_LEFT; /** pixels between two buttons */ private int defaultGap = 4; private ExpandMode expandMode; // rollover / click private int rolloverTriggerDelay = 500; // wait before expansion (only for expandMode==ROLLOVER) private int expansionDuration = 300; // millis private int initialExpansionModel = 0; private int initialExpansionWidth = 200; private int initialExpansionHeight = 200; private PropertyChangeSupport propertySupport = new PropertyChangeSupport(this); private AutoHidePolicy() {} /** Updates the default hide border. *

* Default is AutoHideExpandPanel.LEFT; * * @param defaultHideBorder values taken from DockingConstants.HIDE_TOP, HIDE_LEFT, HIDE_BOTTOM, HIDE_RIGHT * */ public void setDefaultHideBorder(DockingConstants.Hide defaultHideBorder) { DockingConstants.Hide old = this.defaultHideBorder; this.defaultHideBorder = defaultHideBorder; propertySupport.firePropertyChange(PROPERTY_DEFAULT_HIDE_BORDER, old, defaultHideBorder); } /** Returns the default hide border (used when not specified in a DockKey)*/ public DockingConstants.Hide getDefaultHideBorder() { return defaultHideBorder; } /** Returns the default gap between border components */ public int getDefaultGap() { return defaultGap; } /** Updates the gap (in pixels) between auto-hide buttons*/ public void setDefaultGap(int gap) { int old = this.defaultGap; this.defaultGap = gap; propertySupport.firePropertyChange(PROPERTY_DEFAULT_GAP, old, gap); } /** Returns the singleton instance of this class */ public static AutoHidePolicy getPolicy() { return policy; } /** Returns the expand mode in use. * @return EXPAND_ON_ROLLOVER or EXPAND_ON_CLICK * */ public ExpandMode getExpandMode() { return expandMode; } /** Updates the expand mode. * @param expandMode legal values are EXPAND_ON_ROLLOVER or EXPAND_ON_CLICK * */ public void setExpandMode(ExpandMode expandMode) { ExpandMode old = this.expandMode; this.expandMode = expandMode; propertySupport.firePropertyChange(PROPERTY_EXPAND_MODE, old, expandMode); } /** Returns the rollover trigger delay (in millis) * * */ public int getRolloverTriggerDelay() { return rolloverTriggerDelay; } /** Updates the rollover trigger delay * @param delay delay in millis before expanding a Dockable */ public void setRolloverTriggerDelay(int delay) { int old = this.rolloverTriggerDelay; this.rolloverTriggerDelay = delay; propertySupport.firePropertyChange(PROPERTY_ROLLOVER_TRIGGER_DELAY, old, delay); } /** Returns the expansion duration (in millis) */ public int getExpansionDuration() { return expansionDuration; } /** Updates the expansion duration (time in millis) */ public void setExpansionDuration(int millis) { int old = expansionDuration; this.expansionDuration = millis; propertySupport.firePropertyChange(PROPERTY_EXPANSION_DURATION, old, millis); } /** Hook for property change notification */ public void addPropertyChangeListener(PropertyChangeListener listener) { propertySupport.addPropertyChangeListener(listener); } /** Hook for property change notification */ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertySupport.addPropertyChangeListener(propertyName, listener); } /** Remove a property change notification */ public void removePropertyChangeListener(PropertyChangeListener listener) { propertySupport.removePropertyChangeListener(listener); } /** Remove a property change notification */ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertySupport.removePropertyChangeListener(propertyName, listener); } /** returns the expansion model (computation size of first expansion) * * @return the useComponentPreferredSize */ public int getInitialExpansionModel() { return initialExpansionModel; } /** * @param model the model to set, values are INITIAL_EXPAND_CUSTOM_SIZE * and INITIAL_EXPAND_COMPONENT_SIZE */ public void setInitialExpansionModel(int model) { this.initialExpansionModel = model; } /** * @return the initialExpansionWidth */ public int getInitialExpansionWidth() { return initialExpansionWidth; } /** sets the first expansion width (only used with INITIAL_EXPAND_CUSTOM_SIZE model) * @param initialExpansionWidth the with to set for first expansion * @see AutoHidePolicy#setInitialExpansionModel(int) */ public void setInitialExpansionWidth(int initialExpansionWidth) { this.initialExpansionWidth = initialExpansionWidth; } /** * @return the initialExpansionHeight */ public int getInitialExpansionHeight() { return initialExpansionHeight; } /** sets the first expansion height (only used with INITIAL_EXPAND_CUSTOM_SIZE model) * * @param initialExpansionHeight the initialExpansionHeight to set * @see AutoHidePolicy#setInitialExpansionModel(int) */ public void setInitialExpansionHeight(int initialExpansionHeight) { this.initialExpansionHeight = initialExpansionHeight; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/BorderSplitter.java000066400000000000000000000205671243334202400316530ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.geom.Rectangle2D; import java.awt.*; import com.vlsolutions.swing.docking.event.*; /** An utility class used to delegate the border drag/drop scanning for docking ( * since the same code is used in many DockDropReceivers). *

* This class is only meant for API Extenders. *

* Taking a DockDragEvent or DockDropEvent, check if mouse is near of one border. * If so, accepts the drag or drop operation. * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * @update 2005/10/21 Lilian Chamontin : updated the shape to show real size of drop (and not 20 pixeles width/height) * @update 2005/11/14 Lilian Chamontin : added support for drag and drop of a whole tabbed container * @update 2005/12/08 Lilian Chamontin : fixed a bug when dropping into itself */ public class BorderSplitter { Component delegator; public BorderSplitter(Component delegator) { this.delegator = delegator; } public void processDockableDrag(DockDragEvent e) { scanDrop(e, false); } public void processDockableDrop(DockDropEvent e) { scanDrop(e, true); } /** This method should be overriden if the delegator doesn't belong to the * docking containment hierarchy after drop acceptance. *

Here is a case : *

* *

* Then, tabpane will be replaced by a simple DockableContainer on drop acceptance * (because only one tab left). *

* And DockingDesktop.splitContainer(Component base, Split position) cannot be * called with tabpane as "base" (instead, it should be called with the replacer of * tabpane, or use the other split method which takes a dockable as base. * * * */ public void split(DockDropEvent event, Container draggedContainer, DockingConstants.Split position) { /* standard splitting */ // event.getDesktop().splitComponent(delegator, event.getDragSource().getDockable(), // position); event.getDesktop().splitComponent(delegator, draggedContainer, position); //2005/11/14 } private void acceptSplit(DockDropEvent event, DockingConstants.Split position) { Container container = event.getDragSource().getDockableContainer(); Dockable dockable = event.getDragSource().getDockable();//2005/12/08 TabbedDockableContainer tabAncestor = DockingUtilities.findTabbedDockableContainer(dockable); Dockable remainingDockable = null; if(tabAncestor != null && tabAncestor.getTabCount() == 2 && tabAncestor == delegator) {//2007//11/15 // drop onto itself : one of the two remanining dockable is dropped // find which dockable is dropped, and which remains remainingDockable = tabAncestor.getDockableAt(0); if(remainingDockable == dockable) { //oops ! remainingDockable = tabAncestor.getDockableAt(1); } } ((DockDropEvent) event).acceptDrop(); if(container instanceof TabbedDockableContainer) { split(event, container, position); } else { //if (tabAncestor != null && tabAncestor.getTabCount() == 1 && tabAncestor == delegator){//2007//11/15 if(tabAncestor != null && tabAncestor.getTabCount() == 0 && tabAncestor == delegator) {//2007//11/15 // we have detected a dropping onto itself : // the drop gesture comes from the tabAncestor (as it's given by the drag source) // and translates into a border split // if only one tab remains, that means the tabAncestor is no longer useful and // so we now need to remove that tab and replace it by a standard singledockable // which is done by the standard desktop "split" public method. //Dockable remainingDockable = tabAncestor.getDockableAt(0); event.getDesktop().split(remainingDockable, // the only remaining dockable dockable, position); } else { // standard dropping, just use the internal API to relayout the desktop. event.getDesktop().splitComponent(delegator, dockable, position); } } } /** Accept the drag gesture and setup the docking action event associated to it */ private void acceptDragSplit(DockDragEvent event, DockingConstants.Split position, Shape shape) { Container container = event.getDragSource().getDockableContainer(); Dockable dockable = event.getDragSource().getDockable();//2005/12/08 TabbedDockableContainer tabAncestor = DockingUtilities.findTabbedDockableContainer(dockable); DockableState.Location initialLocation = dockable.getDockKey().getLocation(); DockableState.Location borderSpliterLocation = DockingUtilities.getDockableLocationFromHierarchy(delegator); if(container instanceof TabbedDockableContainer) { event.setDockingAction(new DockingActionSplitComponentEvent(event.getDesktop(), dockable, initialLocation, borderSpliterLocation, container, position, 0.5f)); } else { if(tabAncestor != null && tabAncestor.getTabCount() == 1 && tabAncestor == delegator) { // we have detected a dropping onto itself : // the drop gesture comes from the tabAncestor (as it's given by the drag source) // and translates into a border split // if only one tab remains, that means the tabAncestor is no longer useful and // so we now need to remove that tab and replace it by a standard singledockable // which is done by the standard desktop "split" public method. Dockable remainingDockable = tabAncestor.getDockableAt(0); event.setDockingAction(new DockingActionSplitDockableEvent(event.getDesktop(), dockable, initialLocation, borderSpliterLocation, remainingDockable, position, 0.5f)); } else { // standard dropping, just use the internal API to relayout the desktop. event.setDockingAction(new DockingActionSplitComponentEvent(event.getDesktop(), dockable, initialLocation, borderSpliterLocation, delegator, position, 0.5f)); } } event.acceptDrag(shape); } private void scanDrop(DockEvent event, boolean drop) { Point p = event.getMouseEvent().getPoint(); Dimension size = delegator.getSize(); int distTop = p.y; int distLeft = p.x; int min = Math.min(distTop, distLeft); int distRight = size.width - p.x; min = Math.min(min, distRight); int distBottom = size.height - p.y; min = Math.min(min, distBottom); Dimension draggedSize = null; DockableDragSource source = event.getDragSource(); // the drag size is the one of the parent dockable container //draggedSize = dragged.getComponent().getParent().getSize(); draggedSize = source.getDockableContainer().getSize(); int bestHeight = (int) Math.min(draggedSize.height, size.height * 0.5); int bestWidth = (int) Math.min(draggedSize.width, size.width * 0.5); if(min == distTop && min < delegator.getHeight() / 4) { // dock on top if(drop) { acceptSplit((DockDropEvent) event, DockingConstants.SPLIT_TOP); } else { Rectangle2D r2d = new Rectangle2D.Float(0, 0, size.width, bestHeight); acceptDragSplit((DockDragEvent) event, DockingConstants.SPLIT_TOP, r2d); } } else if(min == distLeft && min < delegator.getWidth() / 4) { if(drop) { acceptSplit((DockDropEvent) event, DockingConstants.SPLIT_LEFT); } else { Rectangle2D r2d = new Rectangle2D.Float(0, 0, bestWidth, size.height); acceptDragSplit((DockDragEvent) event, DockingConstants.SPLIT_LEFT, r2d); } } else if(min == distBottom && min < delegator.getHeight() / 4) { if(drop) { acceptSplit((DockDropEvent) event, DockingConstants.SPLIT_BOTTOM); } else { Rectangle2D r2d = new Rectangle2D.Float(0, size.height - bestHeight, //20, size.width, bestHeight); acceptDragSplit((DockDragEvent) event, DockingConstants.SPLIT_BOTTOM, r2d); } } else if(min == distRight && min < delegator.getWidth() / 4) { // right if(drop) { acceptSplit((DockDropEvent) event, DockingConstants.SPLIT_RIGHT); } else { Rectangle2D r2d = new Rectangle2D.Float(size.width - bestWidth, 0, bestWidth, size.height); acceptDragSplit((DockDragEvent) event, DockingConstants.SPLIT_RIGHT, r2d); } } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/CompoundDockable.java000066400000000000000000000044621243334202400321140ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.Component; /** Describes a Dockable that can contain sub-dockables. *

* This class allows dockable nesting, with full support for workspace save and restore. *

* Currently this class is associated to a CompoundDockingPanel component : you * insert dockables into it with an initial addDockable(CompoundDockable) invocation from DockingDesktop, * and further dockables with split/createTab calls. *

* Example : *

 *   DockingDesktop desk = ...
 *   desk.addDockable(dockable1);
 *   desk.split(dockable1, dockable2, DockingConstants.SPLIT_RIGHT);
 *   // now let's add a compound dockable
 *   CompoundDockable compound = new CompoundDockable(new DockKey("Compound!"));
 *   desk.split(dockable1, compound);
 *   // and add a tab into it
 *   desk.addDockable(compound, dockable3); // initial nesting : new API call
 *   desk.createTab(dockable3, dockable4, 1); // a tab, using standard API
 * 
*

* CompoundDockables are displayed as SingleDockableContainers (with a title bar). Don't * forget to properly initialize the DockKey of this dockable to have it well presented on * screen (name, tooltip, icon). * * @author Lilian Chamontin, VLSolutions * @since 2.1 */ public class CompoundDockable implements Dockable { private CompoundDockingPanel panel = new CompoundDockingPanel(this); private DockKey key; /** Constructs a new CompoundDockable with a given key */ public CompoundDockable(DockKey key) { this.key = key; } /** Returns the key used to describe this dockable */ public DockKey getDockKey() { return key; } /** Returns the component used by this dockable. * *

* Implementation note : this method always returns a CompoundDockingPanel. * */ public final Component getComponent() { return panel; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/CompoundDockingPanel.java000066400000000000000000000067621243334202400327530ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.docking.event.DockDragEvent; import com.vlsolutions.swing.docking.event.DockDropEvent; import com.vlsolutions.swing.docking.event.DockEvent; import com.vlsolutions.swing.docking.event.DockingActionAddDockableEvent; import java.awt.BorderLayout; import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JPanel; /** A specialized container used to nest dockables inside that sub-part of the * desktop. *

* This component is used by the API (as the associate component of a CompoundDockable) * and shouldn't be used outside this context. * * @author Lilian Chamontin, VLSolutions * @since 2.1 * @see CompoundDockable */ public class CompoundDockingPanel extends JPanel implements DockDropReceiver { private static final long serialVersionUID = 1L; private CompoundDockable dockable; /** Constructs a new CompoundDockingPanel, for a given dockable */ public CompoundDockingPanel(CompoundDockable dockable) { setLayout(new BorderLayout()); this.dockable = dockable; } /** act the same as a splitContainer : allow drop on the borders*/ public void processDockableDrag(DockDragEvent event) { scanContainer(event, false); } public void processDockableDrop(DockDropEvent event) { scanContainer(event, true); } private void acceptDrop(DockEvent event) { ((DockDropEvent) event).acceptDrop(); Dockable d = event.getDragSource().getDockable(); DockableContainer dockableContainer = DockableContainerFactory.getFactory().createDockableContainer(d, DockableContainerFactory.ParentType.PARENT_DESKTOP); dockableContainer.installDocking(event.getDesktop()); add((JComponent) dockableContainer, BorderLayout.CENTER); } private void scanContainer(DockEvent event, boolean drop) { // reject operation if the source is an ancestor of this component if(event.getDragSource().getDockableContainer().isAncestorOf(this)) { // this is possible for compound containers (as they contain sub-dockables) // in that case, you cannnot drop a compound into one of its children // 2007/01/08 if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).delegateDrag(); } return; } @SuppressWarnings("unused") Point p = event.getMouseEvent().getPoint(); Rectangle compBounds = getBounds(); Dockable dragged = event.getDragSource().getDockable(); DockableState.Location initialLocation = dragged.getDockKey().getLocation(); DockableState.Location nextLocation = dockable.getDockKey().getLocation(); event.setDockingAction(new DockingActionAddDockableEvent(event.getDesktop(), dragged, initialLocation, nextLocation, this)); if(drop) { acceptDrop(event); } else { Rectangle2D r2d = new Rectangle2D.Float(0, 0, compBounds.width, compBounds.height); ((DockDragEvent) event).acceptDrag(r2d); } } /** Returns the compound dockable this container is for */ public CompoundDockable getDockable() { return dockable; } } DefaultDockableContainerFactory.java000066400000000000000000000057701243334202400350330ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.Dialog; import java.awt.Frame; import java.awt.Window; /** * Default implementation of the DockableContainerFactory. *

* Uses DockView as a SingleDockableContainer, and * DockTabbedPane as a TabbedDockableContainer *

* Note : the API has changed between VLDocking 1.1 and 2.0 : the * createDockableContainer now uses a second parameter to specify the context of * the container creation. * * @author Lilian Chamontin, vlsolutions. * @version 2.0 */ public class DefaultDockableContainerFactory extends DockableContainerFactory { public DefaultDockableContainerFactory() { } /** * Returns the component used to modify the expand panel size when expanded * from the top. This implementation uses the following components : *

    *
  • DockView for standard dockables *
  • TabbedDockView for dockable contained in a tabContainer *
  • MaximizedDockView for maximized dockables *
  • DetachedDockView for floating dockables. *
* * @see DockView * @see TabbedDockView * @see MaximizedDockView * @see DetachedDockView */ public SingleDockableContainer createDockableContainer(Dockable dockable, ParentType parentType) { switch (parentType) { case PARENT_TABBED_CONTAINER: return new TabbedDockView(dockable); case PARENT_DESKTOP: return new MaximizedDockView(dockable); case PARENT_SPLIT_CONTAINER: return new DockView(dockable); case PARENT_DETACHED_WINDOW: return new DetachedDockView(dockable); default: throw new RuntimeException("Wrong dockable container type"); } } /** * Returns the container used for tabbed docking. *

* Current implementation uses the DockTabbedPane class. * * @see DockTabbedPane */ public TabbedDockableContainer createTabbedDockableContainer() { return new DockTabbedPane(); } /** * This method is called when a dockable is detached from the DockingDesktop * and put in the FLOATING state. *

* The floating container must be an instanceof Dialog or Window. */ public FloatingDockableContainer createFloatingDockableContainer( Window owner) { if (owner instanceof Dialog) { return new FloatingDialog((Dialog) owner); } else { return new FloatingDialog((Frame) owner); } } /** * This implementation of the factory method return a default * DockViewTitleBar object. * * @since 2.1.3 */ public DockViewTitleBar createTitleBar() { return new DockViewTitleBar(); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DetachedDockView.java000066400000000000000000000077361243334202400320470ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.docking.event.DockDragEvent; import com.vlsolutions.swing.docking.event.DockDropEvent; import com.vlsolutions.swing.docking.event.DockEvent; import com.vlsolutions.swing.docking.event.DockingActionCreateTabEvent; import java.awt.Rectangle; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; /** A DockView suitable for detached dockables (in their own window). * * @see DockView * * @author Lilian Chamontin, VLSolutions * @since 2.0 */ public class DetachedDockView extends DockView { private static final long serialVersionUID = 1L; private static final String uiClassID = "DetachedDockViewUI"; public DetachedDockView(Dockable dockable) { super(dockable); } /** {@inheritDoc} * @since 2.0 */ public String getUIClassID() { return uiClassID; } /* common method for drag && drop, overriden from DockView to only allow tabbed drops */ protected void scanDrop(DockEvent event, boolean drop) { if(getParent() instanceof TabbedDockableContainer) { // cannot nest DockTabbedPanes if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).delegateDrag(); } return; } if(event.getDragSource().getDockable() == dockable) { // cannot drop onto itself if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } // The dockview isn't contained inside a tabbedpane, // there is only one possible option : to create an tab if(event.getDragSource().getDockableContainer() instanceof TabbedDockableContainer) { // but you cannot drop a whole tab container into a detached view if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } Rectangle bounds = getBounds(); // not on the borders : we should create a new tab // reject if key groups aren't compatible DockGroup thisGroup = dockable.getDockKey().getDockGroup(); DockGroup dragGroup = event.getDragSource().getDockable().getDockKey().getDockGroup(); if(! DockGroup.areGroupsCompatible(thisGroup, dragGroup)) { if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } Dockable d = event.getDragSource().getDockable(); DockableState.Location dockableLocation = d.getDockKey().getLocation(); DockableState.Location viewLocation = dockable.getDockKey().getLocation(); if(drop) { event.setDockingAction(new DockingActionCreateTabEvent(event.getDesktop(), d, dockableLocation, viewLocation, dockable, 0)); ((DockDropEvent) event).acceptDrop(false); // don't remove the floatable : we have to find it's current position desktop.createTab(dockable, event.getDragSource().getDockable(), 0, true); } else { Rectangle2D r2d = new Rectangle2D.Float(bounds.x, bounds.y, bounds.width, bounds.height); event.setDockingAction(new DockingActionCreateTabEvent(event.getDesktop(), d, dockableLocation, viewLocation, dockable, 0)); if(r2d.equals(lastDropShape)) { // optimized shape caching ((DockDragEvent) event).acceptDrag(lastDropGeneralPath); } else { // draw a 'tabbed pane shape' GeneralPath path = buildPathForTab(bounds);; lastDropShape = r2d; lastDropGeneralPath = path; ((DockDragEvent) event).acceptDrag(lastDropGeneralPath); } } } /** {@inheritDoc} */ public String toString() { return "DetachedDockView of " + dockable.getDockKey(); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockDropReceiver.java000066400000000000000000000047071243334202400320770ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.docking.event.*; /** An interface implemented by components that can accept docking action with mouse drag and drop. *

* This interface is used by API Extenders to create new kind of drop receivers. *

* The DockDropReceiver is responsible for the Drag and Drop gesture recognition of * a docking movement. When a user starts a drag gesture over a {@link DockableDragSource}, * the DockingDesktop scans its containment hierarchy (under the mouse pointer), looking * for DockDropReceivers. If one is found, it is asked for drag or drop processing. *

* The receiver can reject a drag, or display a shape explaining to the user how a * drop of the component would affect the global layout. * * * @see DockableDragSource * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public interface DockDropReceiver { /** The component is notified of a drag operation. * *

* This method is used to give a visual clue of dropping capability * (for example, mouse cursor change, painting a shadow of future component position) * * *

* These clues are transmitted via the event's methods. * * @see DockDragEvent * @see DockDropEvent * * */ public void processDockableDrag(DockDragEvent event); /** The component is requested to perform a docking drop action. *

* This method is called only after a successful {@link #processDockableDrag(DockDragEvent)} *

* The parameters provided for the drop are the same than those of the last drag * (in order to avoid an allowed last drag followed by a rejected drop). *

* On event acceptation ( {@link DockDropEvent#acceptDrop() } , the source component * will be removed from its container, so the DropReceiver must add the * component to its own hierarchy otherwise * the component would be lost (from a user's point of view). * */ public void processDockableDrop(DockDropEvent event); } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockGroup.java000066400000000000000000000100771243334202400305770ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; /** This class describes a logical group of Dockables. *

* When a dockable is associated to a DockGroup (via its DockKey) drag and drop operations * are limited to dockables of the same group (or new location) or compatible group (a group with * a common ancestor see {@link #isCompatibleGroup(DockGroup)} ). *

* It becomes easy to develop, for example, and MDI program : all documents are given the same * DockGroup, and other dockable are given another group so they don't mess with each other. *

* The DockGroups can be nested to allow some mixing (for example, an editor application can consist of * 4 groups : "Formaters" and "Files" the parent of "TextFiles" and "HTMLfile". In that case, * Textfiles and Htmlfiles can be part of tha same tabbed container whereas Formaters are kept outside. * * * @see DockKey#setDockGroup(DockGroup) * @author Lilian Chamontin, VLSolutions * @since 2.0 */ public class DockGroup { /** The optional parent of this group */ private DockGroup parent; /** internal name for comparisons */ private String name; /** Constructs a new dockgroup with a given name. *

Note that names must be unique (this feature is not controlled by the framework) * through all DockGroups. */ public DockGroup(String name) { this.name = name; } /** Constructs a new dockgroup with a given name and a parent group. *

Note that names must be unique (this feature is not controlled by the framework) * through all DockGroups. */ public DockGroup(String name, DockGroup parent) { this.name = name; this.parent = parent; } /** returns the parent of this group (may be null) */ public DockGroup getParent() { return parent; } /** Updates the parent of this group */ public void setParent(DockGroup parent) { this.parent = parent; } /** returns the name of this group (which is used as an internal key) */ public String getName() { return name; } /** overriden for storage/comparisons with the "name" property */ public boolean equals(Object o) { return o != null && o instanceof DockGroup && ((DockGroup) o).name.equals(name); } /** overriden for storage/comparisons with the "name" property */ public int hashCode() { return name.hashCode(); } /** returns true if this group is the ancestor of group g. * To be an ancestor, this group must be either equel to g, or to one of g's parents chain. */ public boolean isAncestorOf(DockGroup g) { if(this.equals(g)) { return true; } else { DockGroup parent = g.parent; while(parent != null) { if(this.equals(parent)) { return true; } else { parent = parent.parent; } } } return false; } /** returns true is this group is compatible with the given parameter. *

* two groups are compatible if they share the same ancestor or if one is the * ancestor of the other. *

* When compatibility is found, dockables of those groups can be docked in * the same tab container. */ public boolean isCompatibleGroup(DockGroup g) { if(g == null) return false; if(this.equals(g)) { return true; } else if(this.isAncestorOf(g)) { return true; } else if(g.isAncestorOf(this)) { return true; } else if(parent != null) { return parent.isCompatibleGroup(g.parent); } else { return false; } } /** convenience method to check compatibility between groups */ public static boolean areGroupsCompatible(DockGroup g1, DockGroup g2) { if(g1 == null) { return g2 == null; } else if(g2 == null) { return g1 == null; } else { return g1.isCompatibleGroup(g2); } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockKey.java000066400000000000000000000340441243334202400302330ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import javax.swing.*; import java.beans.*; import java.util.HashMap; /** * Provides a unique identification for a Dockable and runtime properties, like icon, name, * tooltip, preferred audohide-zone... * * *

* As it is the object which identifies uniquely a user Dockable component, * it should be associated with one and only one Dockable. *

* The unique key used for equals() comparison is the dockKey property, * other properties can be shared by a set of DockKey (for example, * you can share an icon, or even a display name between * dockable Components). * *

* Another usage is the decoration of a dockable container, providing informations * such as its name, tooltip or icon. *

* Properties of a DockKey are listened to by the docking framework, so a change * of name or icon is reflected on the GUI without further programming. * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * * @update 2006/12/01 Lilian Chamontin : added client property support * */ @SuppressWarnings({"rawtypes", "unchecked"}) public class DockKey { /** Key identifying a change in the tooltip property */ public static final String PROPERTY_TOOLTIP = "tooltip"; /** Key identifying a change in the name property */ public static final String PROPERTY_NAME = "name"; /** Key identifying a change in the tabname property (title used by tabbed containers) */ public static final String PROPERTY_TAB_NAME = "tabName"; /** * Key identifying a change in the dockKey property */ public static final String PROPERTY_DOCKKEY = "dockKey"; /** Key identifying a change in the icon property */ public static final String PROPERTY_ICON = "icon"; /** Key identifying a change in the autohideEnabled property */ public static final String PROPERTY_AUTOHIDEABLE = "autohide"; /** Key identifying a change in the closeEnabled property */ public static final String PROPERTY_CLOSEABLE = "close"; /** Key identifying a change in the maximizedEnabled property */ public static final String PROPERTY_MAXIMIZABLE = "maximizable"; /** Key identifying a change in the notification property */ public static final String PROPERTY_NOTIFICATION = "notification"; /** Key identifying a change in the floatableEnabled property */ public static final String PROPERTY_FLOATABLE = "floatable"; /** * Key identifying a change in the dockable dockableState */ public static final String PROPERTY_DOCKABLE_STATE = "dockablestate"; private String dockKey; private String name; /** new as 2.1 : the tab name property is used to display the dockable title when tabbed*/ private String tabName; private String tooltip; private Icon icon; private DockingConstants.Hide autoHideBorder; private boolean isAutoHideEnabled = true; private boolean isCloseEnabled = true; private boolean isMaximizeEnabled = true; private boolean isFloatEnabled = false; // for compatiblity with version 1.1 /** resize weight of the dockable, this is not a bound property and should be set * during initialization. */ private float resizeWeight = 0f; private boolean notification = false; /** additional client properties * @since 2.1.2 */ private HashMap clientProperties = null; /** * Current visibility dockableState of the dockable (DockableState.CLOSED, STATE_AUTO_HIDE, DOCKED, MAXIMIZED, * FLOATING) */ private DockableState.Location location = DockableState.Location.CLOSED; // these are not bound properties private DockGroup dockGroup; private DockableActionCustomizer actionCustomizer; private transient PropertyChangeSupport propertySupport = new PropertyChangeSupport(this); /** * JavaBeans constructor : If used, also think to set the dockKey property. */ public DockKey() {} /** * Constructs a DockKey with dockKey (unique key) and name set to the same value */ public DockKey(String dockKey) { this(dockKey, dockKey, null, null, null); } /** * Constructs a DockKey with dockKey (unique key) and a displayed name */ public DockKey(String dockKey, String name) { this(dockKey, name, null, null, null); } /** * Constructs a DockKey with dockKey (unique key), a displayed name and a tooltip */ public DockKey(String dockKey, String name, String tooltip) { this(dockKey, name, tooltip, null, null); } /** * Constructs a DockKey with dockKey (unique key), a displayed name, a tooltip and * an icon. */ public DockKey(String dockKey, String name, String tooltip, Icon icon) { this(dockKey, name, tooltip, icon, null); } /** * Constructs a DockKey with dockKey (unique key), a displayed name, a tooltip, an icon * and a default autohide border. */ public DockKey(String dockKey, String name, String tooltip, Icon icon, DockingConstants.Hide hideBorder) { this.dockKey = dockKey; this.name = name; this.tooltip = tooltip; this.icon = icon; this.autoHideBorder = hideBorder; } /** Hook for property change notification */ public void addPropertyChangeListener(PropertyChangeListener listener) { propertySupport.addPropertyChangeListener(listener); } /** Remove a property change notification */ public void removePropertyChangeListener(PropertyChangeListener listener) { propertySupport.removePropertyChangeListener(listener); } /** Returns the icon displayed in title bars */ public Icon getIcon() { return icon; } /** Returns the name (or title) displayed in title bars */ public String getName() { return name; } /** Returns the tooltip associated to the title bar */ public String getTooltip() { if(tooltip == null) { return name; } return tooltip; } /** Returns the unique id designating the user component. *

* Note : This used to be the getDockName prior version 2.0. It has been renamed * to clarify the concept (there was a naming problem between getName() and getDockName() * */ public String getKey() { return dockKey; } /** Updates the tooltip property. *

PropertyListeners are notified of that change * */ public void setTooltip(String tooltip) { String old = this.tooltip; this.tooltip = tooltip; propertySupport.firePropertyChange(PROPERTY_TOOLTIP, old, tooltip); } /** Updates the name property. * The name property is used by dockable container headers to associate a title with a dockable. *

PropertyListeners are notified of that change * */ public void setName(String name) { String old = this.name; this.name = name; propertySupport.firePropertyChange(PROPERTY_NAME, old, name); } /** Returns the tab name (or tab title) displayed when the component is contained into a tabbed container. */ public String getTabName() { return tabName; } /** Updates the tabname property. * This property is used by tabbed containers to display a shorter version of the title of this dockable. *

* Default value is null, meaning the name *

* PropertyListeners are notified of that change * *@since 2.1 * */ public void setTabName(String tabName) { String old = this.tabName; this.tabName = tabName; propertySupport.firePropertyChange(PROPERTY_TAB_NAME, old, tabName); } /** Updates the icon property. *

* PropertyListeners are notified of that change */ public void setIcon(Icon icon) { Icon old = this.icon; this.icon = icon; propertySupport.firePropertyChange(PROPERTY_ICON, old, icon); } /** * Updates the dockKey property. *

* Although PropertyListeners are notified of that change, * it is not recommended to change dynamicaly the dockKey property, as it is heavily used in * the docking framework to identify dockable components. *

* Note : This used to be the getDockName prior version 2.0. It has been renamed * to clarify the concept (there was a naming problem between getName() and getDockName() */ public void setKey(String dockKey) { String old = this.dockKey; this.dockKey = dockKey; propertySupport.firePropertyChange(PROPERTY_DOCKKEY, old, dockKey); } /** @see #getKey() * @deprecated use getKey instead */ public String getDockName() { return getKey(); } /** @see #setKey(String) * @deprecated use setKey instead */ public void setDockName(String name) { setKey(name); } /** Returns the autohide border of this dockable, or null if not set*/ public DockingConstants.Hide getAutoHideBorder() { return autoHideBorder; } /** Updates the autohide border property */ public void setAutoHideBorder(DockingConstants.Hide border) { this.autoHideBorder = border; } /** Returns try if autohiding is enabled */ public boolean isAutoHideEnabled() { return isAutoHideEnabled; } /** Updates the autohideEnabled propety. *

* PropertyListeners are notified of that change * */ public void setAutoHideEnabled(boolean enabled) { boolean old = this.isAutoHideEnabled; this.isAutoHideEnabled = enabled; propertySupport.firePropertyChange(PROPERTY_AUTOHIDEABLE, old, enabled); } /** Returns true if this dockable can be closed */ public boolean isCloseEnabled() { return isCloseEnabled; } /** Updates the closeEnabled propety. *

PropertyListeners are notified of that change * */ public void setCloseEnabled(boolean enabled) { boolean old = this.isCloseEnabled; this.isCloseEnabled = enabled; propertySupport.firePropertyChange(PROPERTY_CLOSEABLE, old, enabled); } /** Returns true if this dockable can be maximized */ public boolean isMaximizeEnabled() { return isMaximizeEnabled; } /** Updates the maximizeEnabled propety. *

PropertyListeners are notified of that change * */ public void setMaximizeEnabled(boolean enabled) { boolean old = this.isMaximizeEnabled; this.isMaximizeEnabled = enabled; propertySupport.firePropertyChange(PROPERTY_MAXIMIZABLE, old, enabled); } /** Returns true if this dockable can be detached from its desktop */ public boolean isFloatEnabled() { return isFloatEnabled; } /** Updates the floatEnabled propety. *

PropertyListeners are notified of that change * */ public void setFloatEnabled(boolean enabled) { boolean old = this.isFloatEnabled; this.isFloatEnabled = enabled; propertySupport.firePropertyChange(PROPERTY_FLOATABLE, old, enabled); } /** Returns true is a notification has been set. *

default notification is making title bars blink. * */ public boolean isNotification() { return notification; } /** Updates the notification propety. Notification results in * a visual change of the dockable in order to attract attention from the * user to this dockable. * *

PropertyListeners are notified of that change. * */ public void setNotification(boolean notification) { boolean old = this.notification; this.notification = notification; propertySupport.firePropertyChange(PROPERTY_NOTIFICATION, old, notification); } /** Overriden for Map storage needs */ public int hashCode() { return dockKey.hashCode(); } /** Overriden for Map storage needs */ public boolean equals(Object o) { return o instanceof DockKey && dockKey.equals(((DockKey) o).dockKey); } public String toString() { return "DockKey[" + name + ']'; } /** Returns the action customizer associated to this dockkey (may return null) * */ public DockableActionCustomizer getActionCustomizer() { return actionCustomizer; } /** Updates the action customizer of this dockable * */ public void setActionCustomizer(DockableActionCustomizer actionCustomizer) { this.actionCustomizer = actionCustomizer; } /** Updates the dockGroup of this dockable. */ public void setDockGroup(DockGroup group) { this.dockGroup = group; } /** returns the dockGroup of this dockable */ public DockGroup getDockGroup() { return this.dockGroup; } /** * returns the current visible location of the dockable * (see DockableState.Location for enumeration values) * @see DockableState */ public DockableState.Location getLocation() { return location; } /** updates the location property. *

* Warning : do not call this method, it is for the sole use of the DockingDesktop API. * @see DockableState */ public void setLocation(DockableState.Location location) { DockableState.Location old = this.location; this.location = location; propertySupport.firePropertyChange(PROPERTY_DOCKABLE_STATE, old, location); } public float getResizeWeight() { return this.resizeWeight; } /** updates the resize weight of this dockable. Valid values range between 0.0f and 1.0f */ public void setResizeWeight(float weight) { this.resizeWeight = weight; } /** Allows any property to be stored in a map associated with this dockkey. A property change event * is propagated to listeners (with a property name equal to "clientProperty." + name) * * * @param name the name used to lookup the property * @param value the value of the property * @since 2.1.2 */ public void putProperty(String name, Object value) { if(clientProperties == null) { clientProperties = new HashMap(); } clientProperties.put(name, value); propertySupport.firePropertyChange("clientProperty." + name, null, value); } /** returns a property associated to this name, or null if the property is undefined * @param name the name used to lookup the property * @since 2.1.2 */ public Object getProperty(String name) { if(clientProperties != null) { return clientProperties.get(name); } else { return null; } } /** returns and removes a property associated to this name, or null if the property is undefined * @param name the name used to lookup the property * @since 2.1.2 */ public Object removeProperty(String name) { if(clientProperties != null) { return clientProperties.remove(name); } else { return null; } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockTabbedPane.java000066400000000000000000001122731243334202400314710ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.*; import java.awt.geom.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.*; import com.vlsolutions.swing.docking.event.*; import com.vlsolutions.swing.tabbedpane.JTabbedPaneSmartIcon; import com.vlsolutions.swing.tabbedpane.JTabbedPaneSmartIconManager; import com.vlsolutions.swing.tabbedpane.SmartIconJButton; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.HashMap; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /** A JTabbedPane customized for integration with the docking framework. * *

* Defaults : *

    *
  • tab position is TOP (look at DockingUISettings to change that), *
  • layout policy is WRAP_TAB_LAYOUT * (due to a java bug which limits usage of MouseMotionListeners in JTabbedPanes, * it is not possible to use SCROLL_LAYOUT_POLICY) *
* *

* This tabbed pane is not meant to be used outside of DockingDesktop because of * their connected behaviour (drag/drop support, docking constraints, etc). *

* As of version 2.0 of the framework, the tabbed pane displays a close icon (other functions * are available with a right click menu). * * @see DockingDesktop * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * @update 2005/11/01 Lilian Chamontin : enhanced shape painting (tries to avoid * going outside the tab bounds) * @update 2005/11/10 Lilian Chamontin : added support for DnD multiple tabs at once. * @update 2005/12/08 Lilian Chamontin : removed a portion of code as its been refactored in BorderSplitter * @update 2007/11/04 Lilian Chamontin : fixed a memory leak when removing dockables * @update 2008/07/05 Lilian Chamontin : removed a hardcoded icon reference * */ @SuppressWarnings({"rawtypes", "unchecked", "unused"}) public class DockTabbedPane extends JTabbedPane implements DockDropReceiver, DockableDragSource, TabbedDockableContainer { /* no UI for this component, as it is look and feel dependent : we cannot extend BasicTabbedPaneUI */ private static final long serialVersionUID = 1L; /** cache for reusing the general path lastDropPath between calls to getDropShape */ private Rectangle lastDropBounds, lastDropTabBounds; private GeneralPath lastDropPath; /** set by a drag operation */ private SingleDockableContainer draggedDockable = null; /** True when the whole tabbedpane is dragged */ private boolean isMultipleDrag = false; protected DockingDesktop desktop; /** The pop-up menu used to provide fast "close" shortcuts (close all, close others) */ protected JPopupMenu popup = new JPopupMenu(); /** the tab currently associated with the pop-up */ protected int popupTab = - 1; /** The tab that was selected before the current one */ protected int previousSelectedDockable = - 1; private HashMap closeActions = new HashMap(); // DockKey , Action private JTabbedPaneSmartIconManager tabManager = new JTabbedPaneSmartIconManager(this); /* This pseudo-dockable is used during drag and drop operations of the whole tabbed pane */ static int instanceCount = 0; private Dockable selfDockable = new Dockable() { DockKey selfKey = new DockKey("dockTab" + instanceCount++); public DockKey getDockKey() { selfKey.setName(getDockableAt(0).getDockKey().getName() + "..."); return selfKey; } public Component getComponent() { return DockTabbedPane.this; } }; private PropertyChangeListener keyChangeListener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { DockKey k = (DockKey) e.getSource(); if(e.getPropertyName().equals(DockKey.PROPERTY_CLOSEABLE)) { Action closeAction = closeActions.get(k); if(closeAction != null) { closeAction.setEnabled(k.isCloseEnabled()); } } else if(e.getPropertyName().equals(DockKey.PROPERTY_ICON)) { int tab = getDockableIndex(k); if(tab >= 0) { JTabbedPaneSmartIcon tabIcon = (JTabbedPaneSmartIcon) getIconAt(tab); tabIcon.setIcon((Icon) e.getNewValue()); JTabbedPaneSmartIcon newIcon = tabIcon.copy(); // we create a copy to trigger a repaint event setIconAt(tab, newIcon); } } else if(e.getPropertyName().equals(DockKey.PROPERTY_NAME)) { int tab = getDockableIndex(k); if(tab >= 0) { JTabbedPaneSmartIcon tabIcon = (JTabbedPaneSmartIcon) getIconAt(tab); String old = tabIcon.getLabel(); String label = (String) e.getNewValue(); tabIcon.setLabel(label); JTabbedPaneSmartIcon newIcon = tabIcon.copy(); // we create a copy to trigger a repaint event setIconAt(tab, newIcon); SwingUtilities.invokeLater(new Runnable() { public void run() { // we have to revalidate/repaint to ensure the new icon size is correctly // taken into account revalidate(); repaint(); } }); } } else if(e.getPropertyName().equals(DockKey.PROPERTY_TOOLTIP)) { int tab = getDockableIndex(k); if(tab >= 0) { JTabbedPaneSmartIcon tabIcon = (JTabbedPaneSmartIcon) getIconAt(tab); tabIcon.setTooltipText((String) e.getNewValue()); setToolTipTextAt(tab, (String) e.getNewValue()); // 2008/04/15 also propagate to the tab } } } }; public DockTabbedPane() { int tabPlacement = UIManager.getInt("TabbedDockableContainer.tabPlacement"); setTabLayoutPolicy(WRAP_TAB_LAYOUT); setTabPlacement(tabPlacement); addMouseListener(new MouseAdapter() { // depending on the platform, pop-up is triggered either by mousePressed or mouseReleased public void mousePressed(MouseEvent e) { if(e.isPopupTrigger()) { // popup only when left button is not pressed checkForPopUp(e); } } public void mouseReleased(MouseEvent e) { if(e.isPopupTrigger()) { checkForPopUp(e); } } public void mouseClicked(MouseEvent e) { if(e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e)) { Dockable d = findDockableAt(e); if(d != null && d.getDockKey().isMaximizeEnabled() && d.getDockKey().getLocation() == DockableState.Location.DOCKED) { // 2005/10/10 don't maximize floatings desktop.maximize(d); } } } }); if(UIManager.getBoolean("TabbedPane.alternateTabIcons")) { //2005/11/14 // we use a different set of icons addChangeListener(new ChangeListener() { int prevTab = - 1; public void stateChanged(ChangeEvent e) { int selectedTab = getSelectedIndex(); if(selectedTab >= 0) { installTabIcons(selectedTab, true); if(prevTab != - 1) { installTabIcons(prevTab, false); } previousSelectedDockable = prevTab; prevTab = selectedTab; } } }); } } private void installTabIcons(int tab, boolean selected) { if(tab < getTabCount()) { JTabbedPaneSmartIcon icon = (JTabbedPaneSmartIcon) getIconAt(tab); if(icon != null) { SmartIconJButton closeIcon = icon.getSmartButton(0); if(selected) { closeIcon.setIcon(UIManager.getIcon("DockTabbedPane.close")); closeIcon.setPressedIcon(UIManager.getIcon("DockTabbedPane.close.pressed")); closeIcon.setRolloverIcon(UIManager.getIcon("DockTabbedPane.close.rollover")); } else { closeIcon.setIcon(UIManager.getIcon("DockTabbedPane.unselected_close")); closeIcon.setPressedIcon(UIManager.getIcon("DockTabbedPane.unselected_close.pressed")); closeIcon.setRolloverIcon(UIManager.getIcon("DockTabbedPane.unselected_close.rollover")); } icon.setSmartButton(0, closeIcon); } } } /** Returns the tab index of the dockable corresponding to the given key, or null if the dockable * doesn't belong to this tab. */ public int getDockableIndex(DockKey key) { for(int i = 0; i < getTabCount(); i++) { Dockable d = getDockableAt(i); if(d != null //2006/12/07 && d.getDockKey().equals(key)) { return i; } } return - 1; } private void checkForPopUp(MouseEvent e) { /* Tabbed dockable can be of two states : docked and floating * when floating, the only option is to attach again. */ Dockable d = findDockableAt(e); if(d != null) { DockKey key = d.getDockKey(); // first add the standard menu JPopupMenu popup = new JPopupMenu(key.getName()); int menuCount = 0; if(key.getLocation() == DockableState.Location.DOCKED) { if(key.isAutoHideEnabled()) { popup.add(new JMenuItem(TabbedContainerActions.createHideTabAction(d, desktop))); menuCount++; } if(key.isFloatEnabled()) { popup.add(new JMenuItem(TabbedContainerActions.createFloatTabAction(d, desktop))); menuCount++; } if(key.isMaximizeEnabled()) { popup.add(new JMenuItem(TabbedContainerActions.createMaximizeTabAction(d, desktop))); menuCount++; } if(key.isCloseEnabled()) { JMenuItem mItem = new JMenuItem(TabbedContainerActions.createCloseAction(d, desktop)); // 2008/07/05 removed hardcoded icon final Icon closeIcon = UIManager.getIcon("DockTabbedPane.close"); mItem.setPressedIcon(closeIcon); //mItem.setPressedIcon(new ImageIcon(getClass().getResource("close16.gif"))); popup.add(mItem); menuCount++; } } else if(key.getLocation() == DockableState.Location.FLOATING) { if(DockingUtilities.isChildOfCompoundDockable(d)) { // as of v2.1 floating dockable which is a child of compound dockable don't have "attach" menu } else { popup.add(new JMenuItem(TabbedContainerActions.createAttachTabAction(d, desktop))); menuCount++; } } else if(key.getLocation() == DockableState.Location.HIDDEN) { // a tabbed hidden dockable can only occur when the dockable is child of a compound dockable // in that case, there isn't any general popup option available } else { throw new RuntimeException("invalid state for a tabbed dockable"); } DockableActionCustomizer customizer = d.getDockKey().getActionCustomizer(); if(customizer != null && customizer.isTabSelectorPopUpCustomizer()) { if(menuCount > 0) { popup.addSeparator(); } customizer.visitTabSelectorPopUp(popup, d); } if(menuCount > 0) { popup.pack(); popup.show(this, e.getX(), e.getY()); } } } private Dockable findDockableAt(MouseEvent e) { Point p = e.getPoint(); // find the tab on which the mouse has been pressed popupTab = - 1; for(int i = 0; i < getTabCount(); i++) { Rectangle tabbounds = getBoundsAt(i); if(tabbounds != null && tabbounds.contains(p)) { // all right return getDockableAt(i); } } return null; } /** Adds a new tab respecting the presentation and constraints of the component. * * {@inheritDoc} * */ public void addDockable(Dockable dockable, int tab) { SingleDockableContainer dc = DockableContainerFactory.getFactory().createDockableContainer(dockable, DockableContainerFactory.ParentType.PARENT_TABBED_CONTAINER); dc.installDocking(desktop); addDockableContainer(dc, tab); } private void addDockableContainer(final SingleDockableContainer dc, int tab) { final DockKey key = dc.getDockable().getDockKey(); AbstractAction closeAction = new AbstractAction("Close") { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { desktop.close(dc.getDockable()); } }; closeActions.put(key, closeAction); SmartIconJButton closeIcon = new SmartIconJButton(closeAction); if(UIManager.getBoolean("TabbedPane.alternateTabIcons")) { //2005/12/09 closeIcon.setIcon(UIManager.getIcon("DockTabbedPane.unselected_close")); closeIcon.setPressedIcon(UIManager.getIcon("DockTabbedPane.unselected_close.pressed")); closeIcon.setRolloverIcon(UIManager.getIcon("DockTabbedPane.unselected_close.rollover")); } else { closeIcon.setIcon(UIManager.getIcon("DockTabbedPane.close")); closeIcon.setPressedIcon(UIManager.getIcon("DockTabbedPane.close.pressed")); closeIcon.setRolloverIcon(UIManager.getIcon("DockTabbedPane.close.rollover")); } closeAction.setEnabled(key.isCloseEnabled()); // add a tooltip closeAction.putValue(AbstractAction.SHORT_DESCRIPTION, UIManager.get("DockTabbedPane.closeButtonText")); final JTabbedPaneSmartIcon smartIcon = new JTabbedPaneSmartIcon(key.getIcon(), key.getName(), new SmartIconJButton[] {closeIcon}); smartIcon.setTooltipText(key.getTooltip()); smartIcon.setIconForTabbedPane(this); if(tab >= getTabCount()) { //addTab(key.getName(), key.getIcon(), (Component)dc, key.getTooltip()); addTab("", smartIcon, (Component) dc, key.getTooltip()); //addTab(key.getName(),smartIcon, (Component) dc, key.getTooltip()); tab = getTabCount() - 1; } else { //insertTab(key.getName(), key.getIcon(), (Component)dc, key.getTooltip(), tab); insertTab("", smartIcon, (Component) dc, key.getTooltip(), tab); //insertTab(key.getName(), smartIcon, (Component)dc, key.getTooltip(), tab); } key.addPropertyChangeListener(keyChangeListener); revalidate(); repaint(); /* SwingUtilities.invokeLater(new Runnable(){ public void run(){ setTitleAt(getDockableIndex(key), ""); // workaround for painting problems } });*/ } public void processDockableDrag(DockDragEvent e) { scanDrop(e, false); } private void scanDrop(DockEvent event, boolean drop) { // dockDropReceiver DockableDragSource dragSource = event.getDragSource(); // reject operation if the source is an ancestor of this component. if(dragSource.getDockableContainer().isAncestorOf(this)) { // this is possible for compound containers (as they contain sub-dockables) // in that case, you cannnot drop a compound into one of its children // 2007/01/08 if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).delegateDrag(); } return; } Dockable dockable = null; SingleDockableContainer dc = null; Container dragContainer = event.getDragSource().getDockableContainer(); if(dragContainer instanceof TabbedDockableContainer) { if(dragContainer == this) { // drop onto itself not possible if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } } else { // fast check to avoid processing a dockable of unknown type dockable = dragSource.getDockable(); dc = DockingUtilities.findSingleDockableContainer(dockable); if(dc == null) { if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } } Point p = event.getMouseEvent().getPoint(); Rectangle vbounds = getSelectedComponent().getBounds(); // is point inside the main tab area ? if(vbounds.contains(p)) { scanMainTabZone(event, drop, dragSource, vbounds); return; } // deny DnD coming from whole tabs if(dragSource.getDockableContainer() instanceof TabbedDockableContainer) { if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } // not in the main zone, check for tabs positions // (but reject first if groups are not compatible) DockableDragSource s = event.getDragSource(); Dockable d = s.getDockable(); DockGroup dragGroup = d.getDockKey().getDockGroup(); for(int i = 0; i < getTabCount(); i++) { DockGroup thisGroup = getDockableAt(i).getDockKey().getDockGroup(); if(! DockGroup.areGroupsCompatible(thisGroup, dragGroup)) { if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } } for(int i = 0; i < getTabCount(); i++) { Rectangle tabbounds = getBoundsAt(i); if(tabbounds != null && tabbounds.contains(p)) { // insert before this tab if allowed SingleDockableContainer tab = (SingleDockableContainer) getComponentAt(i); if(tab.getDockable() == dragSource.getDockable()) { if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } if(i > 0) { tab = (SingleDockableContainer) getComponentAt(i - 1); if(tab.getDockable() == dragSource.getDockable()) { if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } } if(vbounds.equals(lastDropBounds) && tabbounds.equals(lastDropTabBounds)) { // optimized (cached) } else { GeneralPath gp = buildPathForCurrentTab(vbounds, tabbounds); lastDropBounds = vbounds; lastDropTabBounds = tabbounds; lastDropPath = gp; } Dockable draggedDockable = dragSource.getDockable(); DockableState.Location initialLocation = draggedDockable.getDockKey().getLocation(); Dockable base = getDockableAt(0); DockableState.Location nextLocation = base.getDockKey().getLocation(); event.setDockingAction(new DockingActionCreateTabEvent(event.getDesktop(), draggedDockable, initialLocation, nextLocation, base, i)); if(drop) { if(DockingUtilities.findTabbedDockableContainer(dockable) == this) { // the dockable IS another tab of this container, so we just have to // change its tab order. ((DockDropEvent) event).acceptDrop(false); // don't remove addDockableContainer(dc, i); // simply move } else { // request the desktop to create the tab if(base.getDockKey().getLocation() == DockableState.Location.FLOATING) { //2005/12/09 if(dragSource.getDockable().getDockKey().getLocation() == DockableState.Location.FLOATING) { // this is new 2.1 feature : allowed DnD if the tab is a child of a compund dockable ((DockDropEvent) event).acceptDrop(); // remove } else { ((DockDropEvent) event).acceptDrop(false); // don't remove it yet, we need to store its previous dockable state } } else { ((DockDropEvent) event).acceptDrop(); } desktop.createTab(base, dragSource.getDockable(), i); //2005/10/08 //addDockable(dragSource.getDockable(), i); //2005/10/08 } setSelectedIndex(i); } else { ((DockDragEvent) event).acceptDrag(lastDropPath); } return; } } // not on the tabs, check if after the last int lastTab = getTabCount() - 1; Rectangle lasttabbounds = getBoundsAt(lastTab); if (lasttabbounds == null) { return; } Rectangle afterlast = new Rectangle(lasttabbounds.x + lasttabbounds.width, lasttabbounds.y, getX() + getWidth() - (lasttabbounds.x + lasttabbounds.width), lasttabbounds.height); if(afterlast.contains(p)) { SingleDockableContainer dockableContainer = (SingleDockableContainer) getComponentAt(lastTab); if(dockableContainer.getDockable() == dragSource.getDockable()) { if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } if(vbounds.equals(lastDropBounds) && afterlast.equals(lastDropTabBounds)) { } else { GeneralPath gp = buildPathAfterLastTab(vbounds, afterlast); lastDropBounds = vbounds; lastDropTabBounds = afterlast; lastDropPath = gp; } Dockable draggedDockable = dragSource.getDockable(); DockableState.Location initialLocation = draggedDockable.getDockKey().getLocation(); Dockable base = getDockableAt(0); DockableState.Location nextLocation = base.getDockKey().getLocation(); event.setDockingAction(new DockingActionCreateTabEvent(event.getDesktop(), draggedDockable, initialLocation, nextLocation, base, lastTab + 1)); if(drop) { if(DockingUtilities.findTabbedDockableContainer(dockable) == this) { // the dockable IS another tab of this container, so we just have to // change its tab order. ((DockDropEvent) event).acceptDrop(false); // don't remove addDockableContainer(dc, lastTab + 1); // simply move } else { if(base.getDockKey().getLocation() == DockableState.Location.FLOATING) { //2005/12/09 if(dragSource.getDockable().getDockKey().getLocation() == DockableState.Location.FLOATING) { // this is new 2.1 feature : allowed DnD if the tab is a child of a compund dockable ((DockDropEvent) event).acceptDrop(); // remove } else { ((DockDropEvent) event).acceptDrop(false); // don't remove it yet, we need to store its previous dockable state } } else { ((DockDropEvent) event).acceptDrop(); } desktop.createTab(base, dragSource.getDockable(), lastTab + 1); //2005/10/08 //addDockable(dragSource.getDockable(), lastTab+1); } setSelectedIndex(getTabCount() - 1); } else { ((DockDragEvent) event).acceptDrag(lastDropPath); } return; } lastDropBounds = null; lastDropTabBounds = null; lastDropPath = null; if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } } /** Creates a general path suitable for showing tab insertion before the currentTab*/ protected GeneralPath buildPathForCurrentTab(Rectangle vbounds, Rectangle tabbounds) { GeneralPath gp = new GeneralPath(); if(getTabPlacement() == SwingConstants.BOTTOM) { gp.moveTo(vbounds.x, vbounds.y); gp.lineTo(vbounds.x + vbounds.width, vbounds.y); gp.lineTo(vbounds.x + vbounds.width, vbounds.y + vbounds.height); int height = Math.min(16, tabbounds.height); if(getTabRunCount() > 1 && (tabbounds.y > vbounds.y + vbounds.height + 10)) { gp.lineTo(vbounds.x, vbounds.y + vbounds.height); gp.closePath(); gp.moveTo(tabbounds.x, tabbounds.y); gp.lineTo(tabbounds.x + 30, tabbounds.y); gp.lineTo(tabbounds.x + 25, tabbounds.y + height); gp.lineTo(tabbounds.x, tabbounds.y + height); gp.closePath(); } else { gp.lineTo(tabbounds.x + 30, vbounds.y + vbounds.height); gp.lineTo(tabbounds.x + 25, vbounds.y + vbounds.height + height); gp.lineTo(tabbounds.x, vbounds.y + vbounds.height + height); gp.lineTo(tabbounds.x, vbounds.y + vbounds.height); gp.lineTo(vbounds.x, vbounds.y + vbounds.height); gp.closePath(); } } else { // TOP int height = Math.min(16, tabbounds.height); gp.moveTo(vbounds.x, vbounds.y); if(getTabRunCount() > 1 && (tabbounds.y + tabbounds.height < vbounds.y - 10)) { gp.lineTo(vbounds.x + vbounds.width, vbounds.y); gp.lineTo(vbounds.x + vbounds.width, vbounds.y + vbounds.height); gp.lineTo(vbounds.x, vbounds.y + vbounds.height); gp.closePath(); gp.moveTo(tabbounds.x, tabbounds.y); gp.lineTo(tabbounds.x + 25, tabbounds.y); gp.lineTo(tabbounds.x + 30, tabbounds.y + height); gp.lineTo(tabbounds.x, tabbounds.y + height); gp.closePath(); } else { gp.lineTo(tabbounds.x, vbounds.y); gp.lineTo(tabbounds.x, vbounds.y - height); gp.lineTo(tabbounds.x + 25, vbounds.y - height); gp.lineTo(tabbounds.x + 30, vbounds.y); gp.lineTo(vbounds.x + vbounds.width, vbounds.y); gp.lineTo(vbounds.x + vbounds.width, vbounds.y + vbounds.height); gp.lineTo(vbounds.x, vbounds.y + vbounds.height); gp.closePath(); } } return gp; } /** Creates a general path suitable for showing tab insertion after the last tab*/ protected GeneralPath buildPathAfterLastTab(Rectangle vbounds, Rectangle afterlast) { GeneralPath gp = new GeneralPath(); if(getTabPlacement() == SwingConstants.BOTTOM) { int height = Math.min(16, afterlast.height); gp.moveTo(vbounds.x, vbounds.y); gp.lineTo(vbounds.x + vbounds.width, vbounds.y); gp.lineTo(vbounds.x + vbounds.width, vbounds.y + vbounds.height); if(getTabRunCount() > 1) { gp.lineTo(vbounds.x, vbounds.y + vbounds.height); gp.closePath(); gp.moveTo(afterlast.x, afterlast.y); gp.lineTo(afterlast.x + 30, afterlast.y); gp.lineTo(afterlast.x + 25, afterlast.y + height); gp.lineTo(afterlast.x, afterlast.y + height); gp.closePath(); } else { if(afterlast.x + 30 > vbounds.x + vbounds.width) { // we're outside the component bounds, so we go back a little bit int newX = vbounds.x + vbounds.width - 30; gp.lineTo(newX + 30, vbounds.y + vbounds.height); gp.lineTo(newX + 25, vbounds.y + vbounds.height + height); gp.lineTo(newX, vbounds.y + vbounds.height + height); gp.lineTo(newX, vbounds.y + vbounds.height); } else { gp.lineTo(afterlast.x + 30, vbounds.y + vbounds.height); gp.lineTo(afterlast.x + 25, vbounds.y + vbounds.height + height); gp.lineTo(afterlast.x, vbounds.y + vbounds.height + height); gp.lineTo(afterlast.x, vbounds.y + vbounds.height); } gp.lineTo(vbounds.x, vbounds.y + vbounds.height); gp.closePath(); } } else { // TOP int height = Math.min(16, afterlast.height); gp.moveTo(vbounds.x, vbounds.y); if(getTabRunCount() > 1) { gp.lineTo(vbounds.x + vbounds.width, vbounds.y); gp.lineTo(vbounds.x + vbounds.width, vbounds.y + vbounds.height); gp.lineTo(vbounds.x, vbounds.y + vbounds.height); gp.closePath(); gp.moveTo(afterlast.x, afterlast.y); gp.lineTo(afterlast.x + 25, afterlast.y); gp.lineTo(afterlast.x + 30, afterlast.y + height); gp.lineTo(afterlast.x, afterlast.y + height); gp.closePath(); } else { if(afterlast.x + 30 > vbounds.x + vbounds.width) {//2005/11/01 // we're outside the component bounds, so we go back a little bit int newX = vbounds.x + vbounds.width - 30; gp.lineTo(newX, vbounds.y); gp.lineTo(newX, vbounds.y - height); gp.lineTo(newX + 25, vbounds.y - height); gp.lineTo(newX + 30, vbounds.y); } else { gp.lineTo(afterlast.x, vbounds.y); gp.lineTo(afterlast.x, vbounds.y - height); gp.lineTo(afterlast.x + 25, vbounds.y - height); gp.lineTo(afterlast.x + 30, vbounds.y); } gp.lineTo(vbounds.x + vbounds.width, vbounds.y); gp.lineTo(vbounds.x + vbounds.width, vbounds.y + vbounds.height); gp.lineTo(vbounds.x, vbounds.y + vbounds.height); gp.closePath(); } } return gp; } private void scanMainTabZone(DockEvent event, boolean drop, DockableDragSource dragSource, Rectangle vbounds) { Point p = event.getMouseEvent().getPoint(); /* allow drop : * - on the current tab * - between tabs * delegate drop if mouse to near of the borders */ if(scanBorderBounds(event, drop, p)) { return; } // deny DnD coming from whole tabs if(dragSource.getDockableContainer() instanceof TabbedDockableContainer) { if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } if(scanSameComponent(event, drop, dragSource)) { return; } if(scanAdjacentTab(event, drop, dragSource)) { return; } // reject if all key groups aren't compatible DockGroup dragGroup = event.getDragSource().getDockable().getDockKey().getDockGroup(); for(int i = 0; i < getTabCount(); i++) { DockGroup thisGroup = getDockableAt(i).getDockKey().getDockGroup(); if(! DockGroup.areGroupsCompatible(thisGroup, dragGroup)) { if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } } // now we know we can insert the dragged component here int tab = getSelectedIndex(); Rectangle tabbounds = getBoundsAt(tab); if (tabbounds == null) { return; } if(vbounds.equals(lastDropBounds) && tabbounds.equals(lastDropTabBounds)) { // optimized (cached) } else { // insert before tab GeneralPath gp = buildPathForCurrentTab(vbounds, tabbounds); lastDropBounds = vbounds; lastDropTabBounds = tabbounds; lastDropPath = gp; } Dockable base = getDockableAt(0); Dockable draggedDockable = dragSource.getDockable(); DockableState.Location initialLocation = draggedDockable.getDockKey().getLocation(); DockableState.Location nextLocation = base.getDockKey().getLocation(); if(drop) { event.setDockingAction(new DockingActionCreateTabEvent(event.getDesktop(), draggedDockable, initialLocation, nextLocation, base, tab)); if(base.getDockKey().getLocation() == DockableState.Location.FLOATING) {//2005/12/09 if(dragSource.getDockable().getDockKey().getLocation() == DockableState.Location.FLOATING) { // this is new 2.1 feature : allowed DnD if the tab is a child of a compound dockable ((DockDropEvent) event).acceptDrop(); // remove } else { ((DockDropEvent) event).acceptDrop(false); // don't remove it yet, we need to store its previous dockable state } } else { ((DockDropEvent) event).acceptDrop(); } //addDockable(event.getDragSource().getDockable(), tab); //event.getDesktop().addToTabbedGroup(base, event.getDragSource().getDockable()); //2005/07/13 desktop.createTab(base, dragSource.getDockable(), tab); //2005/10/08 setSelectedIndex(tab); // dockingPanel.moveDock(dragSource.getTargetKey(), dc); } else { event.setDockingAction(new DockingActionCreateTabEvent(event.getDesktop(), draggedDockable, initialLocation, nextLocation, base, tab)); ((DockDragEvent) event).acceptDrag(lastDropPath); } return; } private boolean scanAdjacentTab(DockEvent event, boolean drop, DockableDragSource dragSource) { if(getSelectedIndex() > 0) { // check and reject a drag/drop of [tab-1] on [tab] SingleDockableContainer dockableContainer = (SingleDockableContainer) getComponentAt(getSelectedIndex() - 1); if(dockableContainer.getDockable() == dragSource.getDockable()) { if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return true; } } return false; } private boolean scanSameComponent(DockEvent event, boolean drop, DockableDragSource dragSource) { SingleDockableContainer dockableContainer = (SingleDockableContainer) getSelectedComponent(); if(dockableContainer.getDockable() == dragSource.getDockable()) { // cannot drag/drop onto itself if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return true; } return false; } private boolean scanBorderBounds(DockEvent event, boolean drop, Point p) { /** we early reject this operation if the tab is used by a floating dialog */ Dockable firstDockable = getDockableAt(0); if(firstDockable.getDockKey().getLocation() == DockableState.Location.FLOATING) { // as of v2.1 this DnD operation is allowed if the tabbed pane is a child of a compund dockable if(! DockingUtilities.isChildOfCompoundDockable(firstDockable)) { // not a nested child return false; } } Rectangle innerBounds = null; if(getTabPlacement() == SwingConstants.BOTTOM) { int yTab = getBoundsAt(0).y; // upper coordinate of tabbed selectors innerBounds = new Rectangle(20, 20, getWidth() - 20 - 20, yTab - 20 - 20); /** @todo : clamp values */ } else { // TOP Rectangle tabBounds = getBoundsAt(0); if (tabBounds == null) { return false; } int yTab = tabBounds.y + tabBounds.height; // lower coordinate of tabbed selectors innerBounds = new Rectangle(20, yTab + 20, getWidth() - 20 - 20, getHeight() - yTab - 20 - 20); } if(! innerBounds.contains(p)) { // too near of the bounds, suggest a split docking BorderSplitter splitter = new BorderSplitter(this) /* NO LONGER NEEDED : REIMPLEMENTED IN BORDER SPLITTER 2005/12/08 { // we override split in order to resolve the case where // the drop operation would remove this tabpane from the containment // hierarchy public void split(DockDropEvent event, Container draggedContainer, DockingConstants.Split position){ if (getTabCount() == 1){ // there is only one tab left, meaning // this tabbedpane has already been removed from containment hierarchy Dockable remainingDockable = getDockableAt(0); event.getDesktop().split( remainingDockable, // one of the remaining dockables event.getDragSource().getDockable(), position); } else { super.split(event, draggedContainer, position); // standard behaviour } } }*/; if(drop) { splitter.processDockableDrop((DockDropEvent) event); } else { splitter.processDockableDrag((DockDragEvent) event); } return true; } return false; } /** {@inheritDoc} */ public void processDockableDrop(DockDropEvent event) { scanDrop(event, true); } /** {@inheritDoc} */ public boolean startDragComponent(Point p) { clearDragState(); // which component is dragged ? for(int i = 0; i < getTabCount(); i++) { Rectangle tabbounds = getBoundsAt(i); if(tabbounds != null && tabbounds.contains(p)) { draggedDockable = (SingleDockableContainer) getComponentAt(i); if(i > 2 && i == getTabCount() - 1) { // workaround for a focus problem : when the JTabbedPane has focus on the last tab // and we start a drag (and drop outside the tabbedpane, there is a // nonblocking stacktrace due to a bad focusIndex in BasicTabbedPaneUI (method focusLost() of the Handler) KeyboardFocusManager.getCurrentKeyboardFocusManager().upFocusCycle(); // by putting the focus up before the drop occurs, we ensure a good focusIndex is set } return true; } } // search for whole tab drag : look after last tab and in-between tabs Rectangle header = getBoundsAt(0); if (header == null) { return false; } header.x = 0; int lastTab = getTabCount() - 1; Rectangle lasttabbounds = getBoundsAt(lastTab); if (lasttabbounds == null) { return false; } header = header.union(lasttabbounds); Rectangle afterlast = new Rectangle(lasttabbounds.x + lasttabbounds.width, lasttabbounds.y, getX() + getWidth() - (lasttabbounds.x + lasttabbounds.width), lasttabbounds.height); if(afterlast.contains(p) || header.contains(p)) { // either after the last tab or between tabs this.isMultipleDrag = true; return true; } return false; } /** {@inheritDoc} */ public Dockable getDockable() { // from DockableDragSource if(isMultipleDrag) { return selfDockable; } else { if(draggedDockable != null) { return draggedDockable.getDockable(); } return null; } } /** {@inheritDoc} */ public Dockable getSelectedDockable() { if(getSelectedIndex() < 0) { return null; // safety } Component comp = getComponentAt(getSelectedIndex()); if(comp instanceof SingleDockableContainer) { return ((SingleDockableContainer) comp).getDockable(); } else { // this may happen when the dockable is maximized : it is temporarily replaced by an // impostor (a JLabel) return null; } } /** {@inheritDoc} */ public void setSelectedDockable(Dockable dockable) { Component c = (Component) DockingUtilities.findSingleDockableContainer(dockable); if(c != null && indexOfComponent(c) >= 0) { setSelectedComponent(c); } } /** {@inheritDoc} */ public Dockable getDockableAt(int index) { Component c = getComponentAt(index); if(c instanceof SingleDockableContainer) { return ((SingleDockableContainer) c).getDockable(); } else { return null; } } /** {@inheritDoc} */ public void removeDockable(Dockable dockable) { DockableContainer dc = DockingUtilities.findSingleDockableContainer(dockable); if(dc != null) { // after a dockable is removed, we go back to the previously selected if still visible if(previousSelectedDockable != - 1 && previousSelectedDockable < getTabCount()) { final Dockable d = getDockableAt(previousSelectedDockable); SwingUtilities.invokeLater(new Runnable() { public void run() { setSelectedDockable(d); } }); } remove((Component) dc); } //2007/11/04 // clean up key / actions references / listeners closeActions.remove(dockable.getDockKey()); dockable.getDockKey().removePropertyChangeListener(keyChangeListener); } /** {@inheritDoc} */ public void removeDockable(int index) { Dockable dockable = getDockableAt(index); final int prev = this.previousSelectedDockable; SwingUtilities.invokeLater(new Runnable() { public void run() { if(prev != - 1 && prev < getTabCount()) { setSelectedIndex(prev); } } }); removeTabAt(index); // clean up key / actions references / listeners closeActions.remove(dockable.getDockKey()); dockable.getDockKey().removePropertyChangeListener(keyChangeListener); } private void clearDragState() { // reset drag variables this.draggedDockable = null; this.isMultipleDrag = false; } /** {@inheritDoc} */ public String toString() { return "DockTabbedPane [" + Integer.toHexString(hashCode()) + " - tabcount=" + getTabCount() + "]"; } /** {@inheritDoc} */ public int indexOfDockable(Dockable dockable) { DockableContainer dc = DockingUtilities.findSingleDockableContainer(dockable); if(dc != null) { return indexOfComponent((Component) dc); } else { return - 1; } } /** {@inheritDoc} */ public void installDocking(DockingDesktop desktop) { this.desktop = desktop; desktop.installDockableDragSource(this); } /** {@inheritDoc} */ public void uninstallDocking(DockingDesktop desktop) { desktop.uninstallDockableDragSource(this); } public Container getDockableContainer() { if(isMultipleDrag) { return this; } else { return ((Container) draggedDockable); } } public void endDragComponent(boolean dropped) { // nothing more to do } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockView.java000066400000000000000000000267121243334202400304200ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.beans.*; import java.awt.*; import java.awt.geom.*; import javax.swing.*; import com.vlsolutions.swing.docking.event.*; /** DefaultImplementation of the SingleDockableContainer. *

* A Dockview is the component responsible for displaying a single user * component inside a DockingPanel. *

* The DockView contains a DockViewTitleBar, used as a header to display useful information * and optional controls (close/maximize/hide/float) *

* UI : The user component is displayed with decorations provided by a * {@link com.vlsolutions.swing.docking.ui.DockViewUI} delegate. *

* Here is an example (VLDocking 1.1 "shadow" style) : *

    *
  • A gadient for the title bar and a set of icons for the buttons. *
  • A shadowed border for enhanced visibility.
    *
*

Sample DockView

* *

* Note : multiple user-components are not displayable by the dockview : * the default implementation of TabbedDockableContainer is the {@link DockTabbedPane}. * * @see DockViewTitleBar * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * @update 2005/12/09 Lilian Chamontin : added NPE safety check around uninstallDocking as sometimes * uninstalling is done twice. * @update 2007/01/08 Lilian Chamontin : delegated the creation of the titlebar to allow easy override. */ public class DockView extends JPanel implements DockDropReceiver, SingleDockableContainer { private static final long serialVersionUID = 1L; private static final String uiClassID = "DockViewUI"; protected DockViewTitleBar title = getTitleBar(); /** the desktop managing this view */ protected DockingDesktop desktop; /** the dockable managed by this view */ protected Dockable dockable; //user component /** remember the last drop position to cache the shape used for showing the drop position */ protected Shape lastDropShape, lastDropGeneralPath; /** listen to the titlebar actions */ private PropertyChangeListener listener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { if(e.getPropertyName().equals(DockViewTitleBar.PROPERTY_AUTOHIDE)) { if(e.getOldValue().equals(Boolean.TRUE)) { // from autohide to dock : not possible because DockView isn't used } else { // dock to autohide desktop.setAutoHide(dockable, true); } } else if(e.getPropertyName().equals(DockViewTitleBar.PROPERTY_CLOSED)) { desktop.close(dockable); } else if(e.getPropertyName().equals(DockViewTitleBar.PROPERTY_MAXIMIZED)) { if(e.getNewValue().equals(Boolean.TRUE)) { desktop.maximize(dockable); } else { desktop.restore(dockable); } } else if(e.getPropertyName().equals(DockViewTitleBar.PROPERTY_FLOAT)) { desktop.setFloating(dockable, ((Boolean) e.getNewValue()).booleanValue()); } } }; /** Constructs an empty DockView. *

* A {@link #setDockable(Dockable)} call is requiered for this constructor to be usefull. * */ public DockView() { super(new BorderLayout()); add(title, BorderLayout.NORTH); } /** Constructs a new DockView for the given dockable. * * @param dockable the dockable to show * */ public DockView(Dockable dockable) { this(); setDockable(dockable); } /** Constructs a new DockView for the given dockable. * * @param dockable the dockable to show * */ public DockView(Dockable dockable, boolean showTitle) { super(new BorderLayout()); add(title, BorderLayout.NORTH); if(! showTitle) { title.setVisible(false); } setDockable(dockable); } /** Returns the contained component * * {@inheritDoc} * */ public Dockable getDockable() { return dockable; } /** Adds the dockable's component to this DockView. * * * @param dockable the user dockable */ public void setDockable(Dockable dockable) { this.dockable = dockable; add(dockable.getComponent(), BorderLayout.CENTER); if(title != null) { title.setDockable(dockable); } // allow resizing of split pane beyond minimum size // could be replaced by adding a JScrollPane instead of panels setMinimumSize(new Dimension(30, 30)); } /** {@inheritDoc} */ public String toString() { return "DockView of " + dockable.getDockKey(); } /** {@inheritDoc} * @since 2.0 */ public String getUIClassID() { return uiClassID; } /** {@inheritDoc}. */ public void processDockableDrag(DockDragEvent event) { scanDrop(event, false); } /** {@inheritDoc} *

* Please note that a drag into a DockView can also lead to create a DockTabbedPane. */ public void processDockableDrop(DockDropEvent event) { scanDrop(event, true); } /* common method for drag && drop gesture support */ protected void scanDrop(DockEvent event, boolean drop) { // reject operation if the source is an ancestor of this view. if(event.getDragSource().getDockableContainer().isAncestorOf(this)) { // this is possible for compound containers (as they contain sub-dockables) // in that case, you cannnot drop a compound into one of its children // 2007/01/08 if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).delegateDrag(); } return; } if(getParent() instanceof TabbedDockableContainer) { // cannot nest DockTabbedPanes if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).delegateDrag(); } return; } if(event.getDragSource().getDockable() == dockable) { // cannot drop onto itself if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } // The dockview isn't contained inside a tabbedpane, so there are now 5 drop zones : // - center : create a tabbedpane // - top/left/bottom/right : split the view Rectangle bounds = getBounds(); BorderSplitter splitter = new BorderSplitter(this); boolean accepted; if(drop) { splitter.processDockableDrop((DockDropEvent) event); accepted = ((DockDropEvent) event).isDropAccepted(); } else { splitter.processDockableDrag((DockDragEvent) event); accepted = ((DockDragEvent) event).isDragAccepted(); } if(! accepted) { // not on the borders : we should create a new tab if(event.getDragSource().getDockableContainer() instanceof TabbedDockableContainer) { // cannot drop a whole tab container if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } // reject if key groups aren't compatible DockGroup thisGroup = dockable.getDockKey().getDockGroup(); DockGroup dragGroup = event.getDragSource().getDockable().getDockKey().getDockGroup(); if(! DockGroup.areGroupsCompatible(thisGroup, dragGroup)) { if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } return; } Dockable d = event.getDragSource().getDockable(); DockableState.Location dockableLocation = d.getDockKey().getLocation(); DockableState.Location viewLocation = dockable.getDockKey().getLocation(); if(drop) { event.setDockingAction(new DockingActionCreateTabEvent(event.getDesktop(), d, dockableLocation, viewLocation, dockable, 0)); /*if (dockable.getDockKey().getLocation() == DockableState.STATE_FLOATING){ ((DockDropEvent) event).acceptDrop(false); // don't remove a floating dockable from its hierarchy yet } else {*/ ((DockDropEvent) event).acceptDrop(); /*} */ desktop.createTab(dockable, event.getDragSource().getDockable(), 0, true); } else { event.setDockingAction(new DockingActionCreateTabEvent(event.getDesktop(), d, dockableLocation, viewLocation, dockable, 0)); Rectangle2D r2d = new Rectangle2D.Float(bounds.x, bounds.y, bounds.width, bounds.height); if(r2d.equals(lastDropShape)) { // optimized shape caching ((DockDragEvent) event).acceptDrag(lastDropGeneralPath); } else { // draw a 'tabbed pane shape' GeneralPath path = buildPathForTab(bounds);; lastDropShape = r2d; lastDropGeneralPath = path; ((DockDragEvent) event).acceptDrag(lastDropGeneralPath); } } } } /** Create a path used to display the drag shape of a tab container */ protected GeneralPath buildPathForTab(Rectangle bounds) { GeneralPath path = new GeneralPath(); int tabPlacement = UIManager.getInt("TabbedDockableContainer.tabPlacement"); if(tabPlacement == SwingConstants.BOTTOM) { Rectangle tabRect = new Rectangle(0, 0, bounds.width - 5, bounds.height - 5); path.moveTo(tabRect.x, tabRect.y); path.lineTo(tabRect.x + tabRect.width, tabRect.y); path.lineTo(tabRect.x + tabRect.width, tabRect.y + tabRect.height - 15); path.lineTo(tabRect.x + 30, tabRect.y + tabRect.height - 15); path.lineTo(tabRect.x + 25, tabRect.y + tabRect.height); path.lineTo(tabRect.x + 10, tabRect.y + tabRect.height); path.lineTo(tabRect.x + 10, tabRect.y + tabRect.height - 15); path.lineTo(tabRect.x, tabRect.y + tabRect.height - 15); path.closePath(); } else { // TOP Rectangle tabRect = new Rectangle(0, 20, bounds.width - 5, bounds.height - 20 - 5); path.moveTo(tabRect.x, tabRect.y); path.lineTo(tabRect.x + 10, tabRect.y); path.lineTo(tabRect.x + 10, tabRect.y - 15); path.lineTo(tabRect.x + 25, tabRect.y - 15); path.lineTo(tabRect.x + 30, tabRect.y); path.lineTo(tabRect.x + tabRect.width, tabRect.y); path.lineTo(tabRect.x + tabRect.width, tabRect.y + tabRect.height); path.lineTo(tabRect.x, tabRect.y + tabRect.height); path.closePath(); } return path; } /** {@inheritDoc} */ public void installDocking(DockingDesktop desktop) { this.desktop = desktop; desktop.installDockableDragSource(title); title.addPropertyChangeListener(DockViewTitleBar.PROPERTY_AUTOHIDE, listener); title.addPropertyChangeListener(DockViewTitleBar.PROPERTY_CLOSED, listener); title.addPropertyChangeListener(DockViewTitleBar.PROPERTY_MAXIMIZED, listener); title.addPropertyChangeListener(DockViewTitleBar.PROPERTY_FLOAT, listener); title.installDocking(desktop); } /** {@inheritDoc} */ public void uninstallDocking(DockingDesktop desktop) { if(title != null) { // safety check, as removing is sometimes cascaded and done once more than it should be 2005/12/09 //System.out.println("uninstallDocking VIEW on " + dockable.getDockKey()); desktop.uninstallDockableDragSource(title); title.removePropertyChangeListener(DockViewTitleBar.PROPERTY_AUTOHIDE, listener); title.removePropertyChangeListener(DockViewTitleBar.PROPERTY_CLOSED, listener); title.removePropertyChangeListener(DockViewTitleBar.PROPERTY_MAXIMIZED, listener); title.removePropertyChangeListener(DockViewTitleBar.PROPERTY_FLOAT, listener); title.uninstallDocking(desktop); } //remove(title); title = null; this.desktop = null; } /** Returns (or creates) the title bar of this dockview */ public DockViewTitleBar getTitleBar() { if(title == null) { title = DockableContainerFactory.getFactory().createTitleBar();//2007/01/08 } return title; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockViewAsTab.java000066400000000000000000000407641243334202400313360ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.tabbedpane.JTabbedPaneSmartIcon; import com.vlsolutions.swing.tabbedpane.JTabbedPaneSmartIconManager; import com.vlsolutions.swing.tabbedpane.SmartIconJButton; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import javax.swing.AbstractAction; import javax.swing.Icon; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JTabbedPane; import javax.swing.KeyStroke; import javax.swing.UIManager; /** This component is used to display single dockables like if they were in a tabbed pane. *

* Please note this component is still in its early stages and might change in future releases. *

* To use it, just install the TabFactory as DockableContainerFactory * * @author Lilian Chamontin, VLSolutions * @see TabFactory * @since 2.1.3 */ @SuppressWarnings({"rawtypes", "unchecked", "unused"}) public class DockViewAsTab extends DockView implements SingleDockableContainer { private static final long serialVersionUID = 1L; private static final String CLOSE_TEXT = UIManager.getString("DockViewTitleBar.closeButtonText"); private static final String ICONIFY_TEXT = UIManager.getString("DockViewTitleBar.minimizeButtonText"); private static final String RESTORE_TEXT = UIManager.getString("DockViewTitleBar.restoreButtonText"); private static final String MAXIMIZE_TEXT = UIManager.getString("DockViewTitleBar.maximizeButtonText"); private static final String FLOAT_TEXT = UIManager.getString("DockViewTitleBar.floatButtonText"); private static final String ATTACH_TEXT = UIManager.getString("DockViewTitleBar.attachButtonText"); private static Icon closeIcon = UIManager.getIcon("DockViewTitleBar.menu.close"); private static Icon maximizeIcon = UIManager.getIcon("DockViewTitleBar.menu.maximize"); private static Icon restoreIcon = UIManager.getIcon("DockViewTitleBar.menu.restore"); private static Icon hideIcon = UIManager.getIcon("DockViewTitleBar.menu.hide"); private static Icon dockIcon = UIManager.getIcon("DockViewTitleBar.menu.dock"); private static Icon floatIcon = UIManager.getIcon("DockViewTitleBar.menu.float"); private static Icon attachIcon = UIManager.getIcon("DockViewTitleBar.menu.attach"); /** The tab container in which the components are added */ protected TabHeader tabHeader = createTabHeader(); /** smart icon manager */ protected JTabbedPaneSmartIconManager tpManager = new JTabbedPaneSmartIconManager(tabHeader); /** smart icon used to display the title */ protected JTabbedPaneSmartIcon smartIcon = new JTabbedPaneSmartIcon(null, " ", null); protected AbstractAction closeAction = new AbstractAction("Close") { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { desktop.close(getDockable()); } }; protected SmartIconJButton closeSmartIcon = new SmartIconJButton(closeAction); protected AbstractAction maximizeAction = new AbstractAction("Maximize") { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { maximizeAction(); } }; protected SmartIconJButton maximizeSmartIcon = new SmartIconJButton(maximizeAction); protected AbstractAction hideAction = new AbstractAction("Hide") { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { desktop.setAutoHide(getDockable(), true); } }; protected SmartIconJButton hideSmartIcon = new SmartIconJButton(hideAction); protected AbstractAction floatAction = new AbstractAction("Float") { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { desktop.setFloating(getDockable(), true); } }; protected SmartIconJButton floatSmartIcon = new SmartIconJButton(floatAction); // flags to hide/show buttons in the title bar (they are always visible in the contextual menu, but might // take too much space on the titles (for example a minimum set could be hide/float/close // as maximize is accessed by double click) protected boolean isCloseButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isCloseButtonDisplayed"); protected boolean isHideButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isHideButtonDisplayed"); protected boolean isDockButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isDockButtonDisplayed"); protected boolean isMaximizeButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isMaximizeButtonDisplayed"); protected boolean isRestoreButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isRestoreButtonDisplayed"); protected boolean isFloatButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isFloatButtonDisplayed"); protected boolean isAttachButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isAttachButtonDisplayed"); /** listen to the key changes */ private PropertyChangeListener keyListener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { String pName = e.getPropertyName(); if(pName.equals(DockKey.PROPERTY_ICON)) { smartIcon.setIcon((Icon) e.getNewValue()); } else if(pName.equals(DockKey.PROPERTY_NAME)) { smartIcon.setLabel((String) e.getNewValue()); revalidate(); } else if(pName.equals(DockKey.PROPERTY_TOOLTIP)) { smartIcon.setTooltipText((String) e.getNewValue()); } else if(pName.equals(DockKey.PROPERTY_AUTOHIDEABLE)) { resetTabIcons(); } else if(pName.equals(DockKey.PROPERTY_CLOSEABLE)) { resetTabIcons(); } else if(pName.equals(DockKey.PROPERTY_FLOATABLE)) { resetTabIcons(); } else if(pName.equals(DockKey.PROPERTY_MAXIMIZABLE)) { resetTabIcons(); } } }; private JPopupMenu currentPopUp = null; /** reacts to single and double click on title bar */ private MouseListener titleMouseListener = new MouseAdapter() { public void mouseClicked(MouseEvent e) { if(e.getClickCount() == 2) { maximizeAction(); } else { getDockable().getComponent().requestFocus(); } } public void mousePressed(MouseEvent e) { if(e.isPopupTrigger()) { checkForPopUp(e); } } public void mouseReleased(MouseEvent e) { if(e.isPopupTrigger()) { checkForPopUp(e); } } }; private ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { if(e.getActionCommand().equals("dock")) { dockAction(); } else if(e.getActionCommand().equals("close")) { closeAction(); } else if(e.getActionCommand().equals("maximize")) { maximizeAction(); } else if(e.getActionCommand().equals("float")) { floatAction(); } } }; public DockViewAsTab(Dockable dockable) { super(dockable, false); add(tabHeader, BorderLayout.CENTER); tabHeader.addMouseListener(titleMouseListener); configureCloseButton(); configureHideButton(); configureMaximizeButton(); configureFloatButton(); setDockableAsTab(dockable); } private void checkForPopUp(MouseEvent e) { Dockable target = getDockable(); JPopupMenu popup = new JPopupMenu(target.getDockKey().getName()); // first add the standard menu DockKey key = target.getDockKey(); switch(key.getLocation()) { case DOCKED: initDockedPopUp(popup); break; case HIDDEN: //initAutoHidePopUp(popup); break; case MAXIMIZED: initMaximizedPopUp(popup); break; case FLOATING: initFloatingPopUp(popup); break; default: // nothing to do } DockableActionCustomizer customizer = target.getDockKey().getActionCustomizer(); if(customizer != null && customizer.isSingleDockableTitleBarPopUpCustomizer()) { if(popup.getComponentCount() > 0) { popup.addSeparator(); } customizer.visitSingleDockableTitleBarPopUp(popup, target); } if(popup.getComponentCount() > 0) { popup.show(tabHeader, e.getX(), e.getY()); this.currentPopUp = popup; } } private JMenuItem createPopUpItem(String text, Icon icon, String tooltip, String actionCommand, KeyStroke accelerator) { JMenuItem menuItem = new JMenuItem(text, icon); menuItem.setActionCommand(actionCommand); menuItem.addActionListener(actionListener); if(accelerator != null) { menuItem.setAccelerator(accelerator); } return menuItem; } /** Init the popup displayed as the title bar contextual menu */ protected void initMaximizedPopUp(JPopupMenu popup) { popup.add(createPopUpItem(RESTORE_TEXT, restoreIcon, RESTORE_TEXT, "maximize", (KeyStroke) UIManager.get("DockingDesktop.maximizeActionAccelerator"))); } protected void initAutoHidePopUp(JPopupMenu popup) { if(DockingUtilities.isChildOfCompoundDockable(getDockable())) { // restore option not allowed for children of a compound dockable } else { popup.add(createPopUpItem(RESTORE_TEXT, dockIcon, RESTORE_TEXT, "dock", (KeyStroke) UIManager.get("DockingDesktop.dockActionAccelerator"))); } if(getDockable().getDockKey().isCloseEnabled()) { popup.add(createPopUpItem(CLOSE_TEXT, closeSmartIcon, CLOSE_TEXT, "close", (KeyStroke) UIManager.get("DockingDesktop.closeActionAccelerator"))); } } protected void initDockedPopUp(JPopupMenu popup) { DockKey key = getDockable().getDockKey(); if(key.isAutoHideEnabled()) { popup.add(createPopUpItem(ICONIFY_TEXT, hideSmartIcon, ICONIFY_TEXT, "dock", (KeyStroke) UIManager.get("DockingDesktop.dockActionAccelerator"))); } if(key.isFloatEnabled()) { popup.add(createPopUpItem(FLOAT_TEXT, floatSmartIcon, FLOAT_TEXT, "float", (KeyStroke) UIManager.get("DockingDesktop.floatActionAccelerator"))); } if(key.isMaximizeEnabled()) { popup.add(createPopUpItem(MAXIMIZE_TEXT, maximizeSmartIcon, MAXIMIZE_TEXT, "maximize", (KeyStroke) UIManager.get("DockingDesktop.maximizeActionAccelerator"))); } if(key.isCloseEnabled()) { popup.add(createPopUpItem(CLOSE_TEXT, closeSmartIcon, CLOSE_TEXT, "close", (KeyStroke) UIManager.get("DockingDesktop.closeActionAccelerator"))); } } /** Init the popup displayed as the title bar contextual menu */ protected void initFloatingPopUp(JPopupMenu popup) { if(DockingUtilities.isChildOfCompoundDockable(getDockable())) { // attach option not allowed for children of a compound dockable } else { popup.add(createPopUpItem(ATTACH_TEXT, attachIcon, ATTACH_TEXT, "float", (KeyStroke) UIManager.get("DockingDesktop.floatActionAccelerator"))); } } /** This method is invoked to hide the pop-up that could still be visible * (To avoid a visible pop-up for an invisible component) */ public void closePopUp() { if(currentPopUp != null) { currentPopUp.setVisible(false); // @todo uncertain about correct gc of the pop-up in that case currentPopUp = null; } } private void dockAction() { if(isAutoHide()) { desktop.setAutoHide(getDockable(), false); } else { desktop.setAutoHide(getDockable(), true); } } protected void maximizeAction() { if(isMaximized()) { desktop.restore(getDockable()); } else { desktop.maximize(getDockable()); } } private void closeAction() { desktop.close(getDockable()); } private void floatAction() { if(getDockable().getDockKey().getLocation() == DockableState.Location.FLOATING) { desktop.setFloating(getDockable(), true); } else { desktop.setFloating(getDockable(), false); } } private boolean isAutoHide() { return getDockable().getDockKey().getLocation() == DockableState.Location.HIDDEN; } private boolean isMaximized() { return getDockable().getDockKey().getLocation() == DockableState.Location.MAXIMIZED; } protected void configureFloatButton() { if(isFloatButtonDisplayed) { floatSmartIcon.setIcon(UIManager.getIcon("DockViewTitleBar.float")); floatSmartIcon.setPressedIcon(UIManager.getIcon("DockViewTitleBar.float.pressed")); floatSmartIcon.setRolloverIcon(UIManager.getIcon("DockViewTitleBar.float.rollover")); // add a tooltip floatAction.putValue(AbstractAction.SHORT_DESCRIPTION, UIManager.get("DockViewTitleBar.floatButtonText")); } } protected void configureMaximizeButton() { if(isMaximizeButtonDisplayed) { maximizeSmartIcon.setIcon(UIManager.getIcon("DockViewTitleBar.maximize")); maximizeSmartIcon.setPressedIcon(UIManager.getIcon("DockViewTitleBar.maximize.pressed")); maximizeSmartIcon.setRolloverIcon(UIManager.getIcon("DockViewTitleBar.maximize.rollover")); // add a tooltip maximizeAction.putValue(AbstractAction.SHORT_DESCRIPTION, UIManager.get("DockViewTitleBar.maximizeButtonText")); } } protected void configureHideButton() { if(isHideButtonDisplayed) { hideSmartIcon.setIcon(UIManager.getIcon("DockViewTitleBar.hide")); hideSmartIcon.setPressedIcon(UIManager.getIcon("DockViewTitleBar.hide.pressed")); hideSmartIcon.setRolloverIcon(UIManager.getIcon("DockViewTitleBar.hide.rollover")); // add a tooltip hideAction.putValue(AbstractAction.SHORT_DESCRIPTION, UIManager.get("DockViewTitleBar.minimizeButtonText")); } } protected void configureCloseButton() { if(isCloseButtonDisplayed) { closeSmartIcon.setIcon(UIManager.getIcon("DockTabbedPane.close")); closeSmartIcon.setPressedIcon(UIManager.getIcon("DockTabbedPane.close.pressed")); closeSmartIcon.setRolloverIcon(UIManager.getIcon("DockTabbedPane.close.rollover")); // add a tooltip closeAction.putValue(AbstractAction.SHORT_DESCRIPTION, UIManager.get("DockTabbedPane.closeButtonText")); } } public void setDockable(Dockable d) { // overriden to disable DockView settings } public void setDockableAsTab(final Dockable d) { this.dockable = d; if(title != null) { // still needed as removeing it triggers Exception... we'll have to // remove it one day (when building a proper ui class) title.setDockable(dockable); } resetTabIcons(); // allow resizing of split pane beyond minimum size // could be replaced by adding a JScrollPane instead of panels setMinimumSize(new Dimension(30, 30)); } public void resetTabIcons() { ArrayList icons = new ArrayList(); DockKey k = getDockable().getDockKey(); if(k.isCloseEnabled() && isCloseButtonDisplayed) { icons.add(closeSmartIcon); } if(k.isMaximizeEnabled() && isMaximizeButtonDisplayed) { icons.add(maximizeSmartIcon); } if(k.isAutoHideEnabled() && isHideButtonDisplayed) { icons.add(hideSmartIcon); } if(k.isFloatEnabled() && isFloatButtonDisplayed) { icons.add(floatSmartIcon); } // this is an attempt to create the set of icons displayed for this dockable // currently, only "close" is managed, but other buttons could be added, as // the jTabebdPaneSmartIcon supports(simulates) many sub-buttons. if(icons.size() > 0) { SmartIconJButton[] iconsArray = (SmartIconJButton[]) icons.toArray(new SmartIconJButton[0]); smartIcon = new JTabbedPaneSmartIcon(k.getIcon(), k.getName(), iconsArray); smartIcon.setIconForTabbedPane(tabHeader); tabHeader.addTab("", smartIcon, getDockable().getComponent()); } else { tabHeader.addTab(k.getName(), k.getIcon(), getDockable().getComponent()); } } /** {@inheritDoc} */ public void installDocking(DockingDesktop desktop) { this.desktop = desktop; desktop.installDockableDragSource(tabHeader); dockable.getDockKey().addPropertyChangeListener(keyListener); } /** {@inheritDoc} */ public void uninstallDocking(DockingDesktop desktop) { desktop.uninstallDockableDragSource(tabHeader); dockable.getDockKey().removePropertyChangeListener(keyListener); } public String getUIClassID() { return "PanelUI"; // default panel UI } protected TabHeader createTabHeader() { return new TabHeader(); } protected class TabHeader extends JTabbedPane implements DockableDragSource { private static final long serialVersionUID = 1L; public boolean startDragComponent(Point p) { Rectangle bounds = getBoundsAt(0); return bounds != null && bounds.contains(p); } public Container getDockableContainer() { return DockViewAsTab.this; } public Dockable getDockable() { return dockable; } public void endDragComponent(boolean dropped) {} } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockViewTitleBar.java000066400000000000000000000555761243334202400320610ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.beans.*; import java.awt.event.MouseEvent; import java.awt.Component; import java.awt.Point; /** A title bar, associated to a DockView (container of a single user component). *

* Here is an example of a title bar : . *

* DockViewTitleBar is able to display the following properties of a DockKey : *

    *
  • Icon *
  • Name *
  • Tooltip *
  • Notification (blinking background). *
  • And some buttons if their corresponding Action contains the *
*

* This title bar supports buttons used for docking features : * * * * * * * * *
function Version 1.1Version 2.0
maximize
restore
hide
dock
close
float (detach)n/a
attachn/a
* *

* The buttons managed have no effect on the state of the dockable : they just fire * property change events, and it is the responsibility of the DockableContainer to * listen to those events and to relay the operation to the docking desktop. *

* Note : the UI Delegate of the DockViewTitleBar is the {@link com.vlsolutions.swing.docking.ui.DockViewTitleBarUI} * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public class DockViewTitleBar extends JPanel implements DockableDragSource { private static final long serialVersionUID = 1L; /** Property name designating the autohide button selection */ public static final String PROPERTY_AUTOHIDE = "DockTitle.AUTOHIDE"; /** Property name designating the close button selection */ public static final String PROPERTY_CLOSED = "DockTitle.CLOSED"; /** Property name designating a drag gesture beginning */ public static final String PROPERTY_DRAGGED = "DockTitle.DRAGGED"; /** Property name designating the maximized button selection */ public static final String PROPERTY_MAXIMIZED = "DockTitle.MAXIMIZED"; /** Property name designating the float button selection */ public static final String PROPERTY_FLOAT = "DockTitle.FLOAT"; private static final String uiClassID = "DockViewTitleBarUI"; private static final String CLOSE_TEXT = UIManager.getString("DockViewTitleBar.closeButtonText"); private static final String ICONIFY_TEXT = UIManager.getString("DockViewTitleBar.minimizeButtonText"); private static final String RESTORE_TEXT = UIManager.getString("DockViewTitleBar.restoreButtonText"); private static final String MAXIMIZE_TEXT = UIManager.getString("DockViewTitleBar.maximizeButtonText"); private static final String FLOAT_TEXT = UIManager.getString("DockViewTitleBar.floatButtonText"); private static final String ATTACH_TEXT = UIManager.getString("DockViewTitleBar.attachButtonText"); private static Icon closeIcon = UIManager.getIcon("DockViewTitleBar.menu.close"); private static Icon maximizeIcon = UIManager.getIcon("DockViewTitleBar.menu.maximize"); private static Icon restoreIcon = UIManager.getIcon("DockViewTitleBar.menu.restore"); private static Icon hideIcon = UIManager.getIcon("DockViewTitleBar.menu.hide"); private static Icon dockIcon = UIManager.getIcon("DockViewTitleBar.menu.dock"); private static Icon floatIcon = UIManager.getIcon("DockViewTitleBar.menu.float"); private static Icon attachIcon = UIManager.getIcon("DockViewTitleBar.menu.attach"); // ------------ member fields -------------- // this creation tricks to manage the UI class requiring access to the components // before they are created private JLabel titleLabel = getTitleLabel(); private JButton closeButton = getCloseButton(); private JButton dockButton = getHideOrDockButton(); private JButton maximizeButton = getMaximizeOrRestoreButton(); private JButton floatButton = getFloatButton(); private boolean active; private ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { if(e.getActionCommand().equals("dock")) { dockAction(); } else if(e.getActionCommand().equals("close")) { closeAction(); } else if(e.getActionCommand().equals("maximize")) { maximizeAction(); } else if(e.getActionCommand().equals("float")) { floatAction(); } } }; private Dockable target; // the component this title is for /** used to have a state of blinking (notification) */ private boolean isNotification = false; private JPopupMenu currentPopUp = null; /** current blinking count (the limit to the notification timer) */ private int blinkCount = 0; private int MAX_BLINKS = UIManager.getInt("DockingDesktop.notificationBlinkCount"); /** reacts to single and double click on title bar */ private MouseListener titleMouseListener = new MouseAdapter() { public void mouseClicked(MouseEvent e) { if(e.getClickCount() == 2) { maximizeAction(); } else { //requestFocus(); // replaced by a better focus behaviour for 1.2 target.getComponent().requestFocus(); } } public void mousePressed(MouseEvent e) { if(e.isPopupTrigger()) { checkForPopUp(e); } } public void mouseReleased(MouseEvent e) { if(e.isPopupTrigger()) { checkForPopUp(e); } } }; /** listen to the key changes */ private PropertyChangeListener dockKeyListener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { String pName = e.getPropertyName(); if(pName.equals(DockKey.PROPERTY_ICON)) { titleLabel.setIcon((Icon) e.getNewValue()); } else if(pName.equals(DockKey.PROPERTY_NAME)) { titleLabel.setText((String) e.getNewValue()); revalidate(); } else if(pName.equals(DockKey.PROPERTY_TOOLTIP)) { setToolTipText((String) e.getNewValue()); } else if(pName.equals(DockKey.PROPERTY_NOTIFICATION)) { // attract user attention boolean isOn = ((Boolean) e.getNewValue()).booleanValue(); if(isOn && ! isActive()) { if(notificationTimer == null) { notificationTimer = new javax.swing.Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { setNotification(! isNotification); if(! isNotification) { blinkCount++; if(blinkCount >= MAX_BLINKS) { blinkCount = 0; notificationTimer.stop(); // enough blinking } } } }); } notificationTimer.restart(); } else { if(notificationTimer != null) { notificationTimer.stop(); blinkCount = 0; } setNotification(false); } } /*else if (pName.equals(DockKey.PROPERTY_DOCKABLE_STATE)){ * int newState = ((Integer)e.getNewValue()).intValue(); int oldState = ((Integer)e.getOldValue()).intValue(); switch (newState){ case DockableState.HIDDEN : setAutoHide(true); break; case DockableState.MAXIMIZED : setMaximized(true); break; case DockableState.DOCKED : if (oldState == DockableState.HIDDEN){ setAutoHide(false); } break; default: //@todo : managed the floatable state // nothing to track here } }*/ } }; /** Timer used to trigger repaint event for notification (blinking title bar) */ private javax.swing.Timer notificationTimer; /** singleton for keyboard management */ @SuppressWarnings("unused") private static FocusHighlighter focusHighlighter = new FocusHighlighter(); //2005/11/10 private DockingDesktop desktop; /** Constructs an empty title bar (no dockable yet associated). */ public DockViewTitleBar() { this(null); } /** Constructs a title bar for the specified dockable. *

* Warning : a DockViewTitleBar can be used with multiple dockables (this is the case * for example in autohide borders, where a single titlebar is shared by all hidden dockables * (shown only when one is expanding). */ public DockViewTitleBar(Dockable dockable) { setDockable(dockable); closeButton.setText(""); dockButton.setText(""); maximizeButton.setText(""); closeButton.setActionCommand("close"); dockButton.setActionCommand("dock"); maximizeButton.setActionCommand("maximize"); floatButton.setActionCommand("float"); closeButton.addActionListener(actionListener); dockButton.addActionListener(actionListener); maximizeButton.addActionListener(actionListener); floatButton.addActionListener(actionListener); this.addMouseListener(titleMouseListener); //maximizeButton.addMouseListener(new ButtonRolloverEffect()); } /** Notification of completion of layout. *

This hook can be used to insert customized buttons without otherwise * having to fully replace the UI delegate */ public void finishLayout() { } /** Returns the desktop associated to this title bar, if one has been registered * with #installDocking(DockingDesktop), or null. */ public DockingDesktop getDesktop() { return desktop; } /** Overriden as a means to unregister internal listeners, do not call directly */ public void removeNotify() { super.removeNotify(); /* KeyboardFocusManager.getCurrentKeyboardFocusManager().removePropertyChangeListener( focusHighlighter); 2005/11/10: now it's shared between title bars*/ if(target != null) { DockKey k = target.getDockKey(); if(k != null) { k.removePropertyChangeListener(dockKeyListener);//2007/04/16 } } } /** Returns the label used to display the dockkey name. *

Shouldn't be used to update the title : the best way is to update the * DockKey (property listener ensure the labels and buttons stay in sync). * *@since 2.0 */ public JLabel getTitleLabel() { if(titleLabel == null) { titleLabel = new JLabel(); } return titleLabel; } public JButton getCloseButton() { if(closeButton == null) { closeButton = new JButton(); } return closeButton; } /** returns the button used for hiding or docking the view. *

* As hiding and docking are mutually exclusive, the same button is used for both purposes */ public JButton getHideOrDockButton() { if(dockButton == null) { dockButton = new JButton(); } return dockButton; } /** returns the button used for maximizing or restoring the view. *

* As those operations are mutually exclusive, the same button is used for both purposes */ public JButton getMaximizeOrRestoreButton() { if(maximizeButton == null) { maximizeButton = new JButton(); } return maximizeButton; } /** returns the button used for floating (detach) the view. */ public JButton getFloatButton() { if(floatButton == null) { floatButton = new JButton(); } return floatButton; } private void setNotification(boolean notification) { boolean old = this.isNotification; this.isNotification = notification; firePropertyChange("titlebar.notification", old, notification); } private boolean isAutoHide() { return target.getDockKey().getLocation() == DockableState.Location.HIDDEN; } private boolean isMaximized() { return target.getDockKey().getLocation() == DockableState.Location.MAXIMIZED; } private void dockAction() { boolean old = isAutoHide(); firePropertyChange(PROPERTY_AUTOHIDE, old, ! old); } private void maximizeAction() { // we use the visible property of the button to check if maximization // is enabled or not if(target.getDockKey().getLocation() == DockableState.Location.FLOATING) { // ignore : floating cannot be maximized return; } if(target.getDockKey().isMaximizeEnabled()) { //if (maximizeButton.isVisible()){ //2008/04/17 boolean old = isMaximized(); // we don't really change the maximized property, // which will be updated if the desktop accepts this maximization /* We do not use fireVetoableChange, to keep maximization processing outside * the title bar (everything is driven par the dockingdesktop and the * SingleDockableContainer */ firePropertyChange(PROPERTY_MAXIMIZED, old, ! old); } } private void closeAction() { firePropertyChange(PROPERTY_CLOSED, false, true); } private void floatAction() { if(target.getDockKey().getLocation() == DockableState.Location.FLOATING) { firePropertyChange(PROPERTY_FLOAT, true, false); } else { firePropertyChange(PROPERTY_FLOAT, false, true); } } /** This method is invoked to hide the pop-up that could still be visible * (To avoid a visible pop-up for an invisible component) */ public void closePopUp() { if(currentPopUp != null) { currentPopUp.setVisible(false); // @todo uncertain about correct gc of the pop-up in that case currentPopUp = null; } } /** {@inheritDoc} * @since 2.0 */ public String getUIClassID() { return uiClassID; } /** Returns true if the dockable is the currently active one. *

* There is at most one active dockable for a dekstop, and it there is one, * it is the one which contains the keybord focused component. * */ public boolean isActive() { return active; } /** Updates the active property. * A title bar is active when the dockable it is for is ancestor of * the keybord focused component. * */ public void setActive(boolean active) { boolean old = this.active; this.active = active; firePropertyChange("active", old, active); } /** Changes the dockable this title bar is for */ public void setDockable(Dockable dockable) { Dockable old = target; if(target != null && target != dockable) { target.getDockKey().removePropertyChangeListener(dockKeyListener); } if(dockable != null) { this.target = dockable; DockKey key = dockable.getDockKey(); titleLabel.setText(key.getName()); titleLabel.setIcon(key.getIcon()); setToolTipText(key.getTooltip()); revalidate(); /*dockButton.setVisible(key.isAutoHideEnabled()); this.autoHide = key.getLocation() == DockableState.HIDDEN; setDockButtonAsAutoHide(autoHide); closeButton.setVisible(key.isCloseEnabled()); maximizeButton.setVisible(key.isMaximizeEnabled() && !autoHide);*/ key.addPropertyChangeListener(dockKeyListener); } firePropertyChange("dockable", old, dockable); } /** {@inheritDoc} */ public Dockable getDockable() { return target; } /** {@inheritDoc} */ public boolean startDragComponent(Point p) { // disable DnD for some cases : // - child of a compound dockable, in hidden state // - child of a maximized compund dockable // - maximized dockable DockableState.Location targetLocation = target.getDockKey().getLocation(); if(targetLocation == DockableState.Location.HIDDEN) { if(DockingUtilities.isChildOfCompoundDockable(target)) { // nested hidden dockables cannot be drag and dropped return false; } } else if(targetLocation == DockableState.Location.DOCKED) { boolean isChildOfMaximizedContainer = false; if(desktop != null) { Dockable max = desktop.getMaximizedDockable(); if(max != null && max.getComponent().getParent().isAncestorOf(this)) { isChildOfMaximizedContainer = true; } } if(isChildOfMaximizedContainer) { return false; } } else if(targetLocation == DockableState.Location.MAXIMIZED) { return false; } // notify our listeners that drag has begun firePropertyChange(PROPERTY_DRAGGED, false, true); return true; } /** Returns a readeable String representing this title bar */ public String toString() { if(target != null) { return "DockViewTitleBar of [" + target.getDockKey() + "]"; } else { return "DockViewTitleBar"; } } private JMenuItem createPopUpItem(String text, Icon icon, String tooltip, String actionCommand, KeyStroke accelerator) { JMenuItem menuItem = new JMenuItem(text, icon); menuItem.setActionCommand(actionCommand); menuItem.addActionListener(actionListener); if(accelerator != null) { menuItem.setAccelerator(accelerator); } return menuItem; } private void checkForPopUp(MouseEvent e) { JPopupMenu popup = new JPopupMenu(target.getDockKey().getName()); // first add the standard menu DockKey key = target.getDockKey(); switch(key.getLocation()) { case DOCKED: initDockedPopUp(popup); break; case HIDDEN: initAutoHidePopUp(popup); break; case MAXIMIZED: initMaximizedPopUp(popup); break; case FLOATING: initFloatingPopUp(popup); break; default: // nothing to do } DockableActionCustomizer customizer = target.getDockKey().getActionCustomizer(); if(customizer != null && customizer.isSingleDockableTitleBarPopUpCustomizer()) { if(popup.getComponentCount() > 0) { popup.addSeparator(); } customizer.visitSingleDockableTitleBarPopUp(popup, target); } if(popup.getComponentCount() > 0) { popup.show(DockViewTitleBar.this, e.getX(), e.getY()); this.currentPopUp = popup; } } /** Init the popup displayed as the title bar contextual menu */ protected void initMaximizedPopUp(JPopupMenu popup) { popup.add(createPopUpItem(RESTORE_TEXT, restoreIcon, RESTORE_TEXT, "maximize", (KeyStroke) UIManager.get("DockingDesktop.maximizeActionAccelerator"))); } protected void initAutoHidePopUp(JPopupMenu popup) { if(DockingUtilities.isChildOfCompoundDockable(target)) { // restore option not allowed for children of a compound dockable } else { popup.add(createPopUpItem(RESTORE_TEXT, dockIcon, RESTORE_TEXT, "dock", (KeyStroke) UIManager.get("DockingDesktop.dockActionAccelerator"))); } if(target.getDockKey().isCloseEnabled()) { popup.add(createPopUpItem(CLOSE_TEXT, closeIcon, CLOSE_TEXT, "close", (KeyStroke) UIManager.get("DockingDesktop.closeActionAccelerator"))); } } protected void initDockedPopUp(JPopupMenu popup) { DockKey key = target.getDockKey(); if(key.isAutoHideEnabled()) { popup.add(createPopUpItem(ICONIFY_TEXT, hideIcon, ICONIFY_TEXT, "dock", (KeyStroke) UIManager.get("DockingDesktop.dockActionAccelerator"))); } if(key.isFloatEnabled()) { popup.add(createPopUpItem(FLOAT_TEXT, floatIcon, FLOAT_TEXT, "float", (KeyStroke) UIManager.get("DockingDesktop.floatActionAccelerator"))); } if(key.isMaximizeEnabled()) { popup.add(createPopUpItem(MAXIMIZE_TEXT, maximizeIcon, MAXIMIZE_TEXT, "maximize", (KeyStroke) UIManager.get("DockingDesktop.maximizeActionAccelerator"))); } if(key.isCloseEnabled()) { popup.add(createPopUpItem(CLOSE_TEXT, closeIcon, CLOSE_TEXT, "close", (KeyStroke) UIManager.get("DockingDesktop.closeActionAccelerator"))); } } /** Init the popup displayed as the title bar contextual menu */ protected void initFloatingPopUp(JPopupMenu popup) { if(DockingUtilities.isChildOfCompoundDockable(target)) { // attach option not allowed for children of a compound dockable } else { popup.add(createPopUpItem(ATTACH_TEXT, attachIcon, ATTACH_TEXT, "float", (KeyStroke) UIManager.get("DockingDesktop.floatActionAccelerator"))); } } /** Returns the container of the dockable's component */ public Container getDockableContainer() { // easy return getParent(); } public void installDocking(DockingDesktop desktop) { this.desktop = desktop; } public void uninstallDocking(DockingDesktop desktop) { //System.out.println("uninstallDocking TITLE on " + target.getDockKey()); this.desktop = null; setUI(null); //2007/11/14 } /** notifies the source when the drag operation has ended (by a drop or cancelled) * @since 2.1.3 */ public void endDragComponent(boolean dropped) { // nothing more to do } /* used to highlight the title bar when its parent is ancestor of the * focused component */ private static class FocusHighlighter implements PropertyChangeListener { private DockViewTitleBar activeTitleBar; FocusHighlighter() { // this is a singleton so we register here for keyboard focus events properties KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("focusOwner", this); } // focusOwner public void propertyChange(PropertyChangeEvent e) { Component c = (Component) e.getNewValue(); Component ancestor = c; // is the focus contained in a single dockable container while(ancestor != null && ! (ancestor instanceof SingleDockableContainer)) { ancestor = ancestor.getParent(); } if(ancestor != null) { if(ancestor instanceof DockView) { DockView view = (DockView) ancestor; DockViewTitleBar tb = view.getTitleBar(); if(tb == activeTitleBar) { // no view change in focus } else if(tb != null) { if(activeTitleBar != null) { activeTitleBar.setActive(false); } tb.setActive(true); // reset notification (blinking) Dockable target = tb.target; if(target != null && target.getDockKey() != null) { //2007/02/27 fixed NPE target.getDockKey().setNotification(false); } } else { // tb == null && tb != activeTitleBar activeTitleBar.setActive(false); } activeTitleBar = tb; } else if(ancestor instanceof AutoHideExpandPanel) { DockViewTitleBar tb = ((AutoHideExpandPanel) ancestor).getTitleBar(); if(tb == activeTitleBar) { // no view change in focus } else if(tb != null) { if(activeTitleBar != null) { activeTitleBar.setActive(false); } tb.setActive(true); // reset notification (blinking) tb.target.getDockKey().setNotification(false); } else { // tb == null && tb != activeTitleBar activeTitleBar.setActive(false); } activeTitleBar = tb; } else { if(activeTitleBar != null) { activeTitleBar.setActive(false); } activeTitleBar = null; } } else { if(activeTitleBar != null) { activeTitleBar.setActive(false); } activeTitleBar = null; } /* // try to find if the component taking the focus is the ancestor if (activeTitleBar != null){ Container parent = activeTitleBar.getParent(); if (parent != null && c != null && parent.isAncestorOf(c)) { if (!active) { setActive(true); } // reset notification (blinking) target.getDockKey().setNotification(false); } else if (active) { setActive(false); } */ } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/Dockable.java000066400000000000000000000035751243334202400304130ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.*; /** Interface describing a component (AWT/Swing) that can be managed by the * DockingDesktop. * *

* Objects implementing this interface are usually wrappers around user components, * or user components themselves. *

    *
  • a wrapper example : the {@link DockablePanel} is a Dockable, and is used to display a * single user Component. *
  • a direct implementation example : *
     * class MyComponent extends  JPanel implements Dockable {
     *     // unique key for the docking desktop
     *     DockKey key = new DockKey("MyComponent");
     *
     *     public MyComponent(){
     *         // build your user component here
     *         add(new JButton("Button"));
     *         add(new JTextField("Field"));
     *
     *         // initialize docking properties
     *         key.setName("My Component");
     *         key.setIcon(...);
     *         key.setCloseEnabled(false);
     *     }
     *     public DockKey getDockKey(){
     *         return key;
     *     }
     *     public Component getComponent(){
     *         // this component is the dockable
     *         return this;
     *     }
     * }
     * 
    *
* * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public interface Dockable { /** returns the unique key identifying the docked element */ public DockKey getDockKey(); /** returns the component wrapped. * * */ public Component getComponent(); } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockableActionCustomizer.java000066400000000000000000000100611243334202400336220ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import javax.swing.JPopupMenu; /** An objet that can provide actions relative to a dockable. *

* It can be used, for example, to add a set of menu items to the contextual menu * associated with any dockable. *

Example : *

 *   DockableActionCustomizer customizer = new DockableActionCustomizer(){
 *     public void visitSingleDockableTitleBarPopUp(JPopupMenu popUpMenu, Dockable dockable){
 *        popUpMenu.add(new JMenuItem("test")); // a menu for SingleDockableContainers
 *     }
 *     public void visitTabSelectorPopUp(JPopupMenu popUpMenu, Dockable dockable){
 *          popUpMenu.add(new JMenuItem(closeAllInTab)); // two menus when contained in a tabbed container
 *          popUpMenu.add(new JMenuItem(closeAllOtherInTab));
 *     }
 *   };
 *   customizer.setSingleDockableTitleBarPopUpCustomizer(true); // enable single
 *   customizer.setTabSelectorPopUpCustomizer(true); // enable tabbed
 *   DockKey key = ...
 *   key.setActioncustomizer(customizer); // assoiate it with one or more DockKeys
 * 
*

* Implementation Note : the customizer is invoked every time a pop-up is triggered * from the associated dockable container. It is a good practice to keep object creation * and listener attachments outside the visit..() methods. * * @author Lilian Chamontin, VLSolutions */ public class DockableActionCustomizer { private boolean isSingleDockableTitleBarPopUpCustomizer = false; private boolean isTabSelectorPopUpCustomizer = false; /** Default constructor */ public DockableActionCustomizer() {} /** Override this method to add contextual items at the end of the pop-up menu * which can be triggered on a tab selector. *

* It is recommended to add menu items at the end to the pop-up menu as other * items may have been installed by other visitors (DockGroup for example) *

* implementation note : This method can be called multiple times as pop-up menus are built during * the contextual event dispatch (not stored for the life of the dockable). * */ public void visitTabSelectorPopUp(JPopupMenu popUpMenu, Dockable tabbedDockable) {} /** Override this method to add contextual items at the end of the pop-up menu * which can be triggered on the title bar of a single dockable. *

* It is recommended to add menu items at the end to the pop-up menu as other * items may have been installed by other visitors (DockGroup for example) *

* implementation note : This method can be called multiple times as pop-up menus are built during * the contextual event dispatch (not stored for the life of the dockable). * */ public void visitSingleDockableTitleBarPopUp(JPopupMenu popUpMenu, Dockable dockable) { } /** Returns wether this customizer is used in the context of a SingleDockableContainer */ public boolean isSingleDockableTitleBarPopUpCustomizer() { return this.isSingleDockableTitleBarPopUpCustomizer; } /** Updates the singleDockableTitleBar property. * @see #isSingleDockableTitleBarPopUpCustomizer() */ public void setSingleDockableTitleBarPopUpCustomizer(boolean isCustomizer) { this.isSingleDockableTitleBarPopUpCustomizer = isCustomizer; } /** Returns wether this customizer is used in the context of a TabbedDockableContainer */ public boolean isTabSelectorPopUpCustomizer() { return this.isTabSelectorPopUpCustomizer; } /** Updates the tabSelectorDockableTitleBar property * @see #isTabSelectorPopUpCustomizer() */ public void setTabSelectorPopUpCustomizer(boolean isCustomizer) { this.isTabSelectorPopUpCustomizer = isCustomizer; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockableContainer.java000066400000000000000000000036501243334202400322500ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; /** A DockableContainer is the base interface of GUI components used to * display Dockable components. *

* The components are usually displayed with decorations * (a title bar, docking state management buttons, a drop shadow, ...) *

* This interface is meant for API extenders that would like to create new kind of * containers (via the sub-interfaces {@link SingleDockableContainer} * and {@link TabbedDockableContainer} and the {@link DockableContainerFactory}). *

* Usually, a DockableContainer also contains (or implements) one ore more * DockableDragSources * in order to achieve drag and drop operations. *

* * @see DockableDragSource * @see DockableContainerFactory * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public interface DockableContainer { /** Invoked once after creation, in order to let this component register * its DockableDragSources to the DockingDesktop, and have a reference of this * Desktop. * *

basic implementation use a single DragSource, and thus calls * desk.installDockableDragSource(dragSource). * * * */ public void installDocking(DockingDesktop desktop); /** Called once, when the dockablecontainer is no longer used by the desktop, * in order to releases resources and listeners taken on installDocking(). * */ public void uninstallDocking(DockingDesktop desktop); } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockableContainerFactory.java000066400000000000000000000100551243334202400335750ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.Window; /** An abstract factory used by the DockingDesktop to create instance * of Dockable containers. *

* This factory enables API Extenders to change part of the behaviour on the DockingDesktop * (mostly about look and feel issues) without modifying the code of that central class. * * @see DockableContainer * @see DefaultDockableContainerFactory : the default implementation * * @author Lilian Chamontin, vlsolutions. * @version 1.1 * @update 2007/01/08 Lilian Chamontin : updated to declare a new titlebar factory method * */ public abstract class DockableContainerFactory { private static DockableContainerFactory factory; public enum ParentType { /** Constant used to describe the type of usage a SingleDockableContainer is for*/ PARENT_DESKTOP, /** Constant used to describe the type of usage a SingleDockableContainer is for*/ PARENT_TABBED_CONTAINER, /** Constant used to describe the type of usage a SingleDockableContainer is for*/ PARENT_SPLIT_CONTAINER, /** Constant used to describe the type of usage a SingleDockableContainer is for*/ PARENT_DETACHED_WINDOW } /** Constant used to describe the type of usage a SingleDockableContainer is for*/ //public static final int PARENT_DESKTOP = 0; /** Constant used to describe the type of usage a SingleDockableContainer is for*/ //public static final int PARENT_TABBED_CONTAINER = 1; /** Constant used to describe the type of usage a SingleDockableContainer is for*/ //public static final int PARENT_SPLIT_CONTAINER = 2; /** Constant used to describe the type of usage a SingleDockableContainer is for*/ //public static final int PARENT_DETACHED_WINDOW = 3; /** This method is called by the DockingDesktop whenever a dockable is inserted * in its containment hierachy. * */ public abstract SingleDockableContainer createDockableContainer(Dockable dockable, ParentType parentType); /** @deprecated use the other createDockableContainer method ({@link #createDockableContainer(Dockable, int)} */ public SingleDockableContainer createDockableContainer(Dockable dockable, boolean c) { return createDockableContainer(dockable, ParentType.PARENT_SPLIT_CONTAINER); } /** This method is called when a tab insertion is requested by the DockingDesktop. */ public abstract TabbedDockableContainer createTabbedDockableContainer(); /** This method is called when a dockable is detached from the DockingDesktop and put * in the FLOATING state. *

* The floating container must be an instanceof Dialog or Window. */ public abstract FloatingDockableContainer createFloatingDockableContainer(Window owner); /** This method is invoked when a dockable container needs to install a title bar. *

* This method is used by the standard implementation of Docking (DockView, etc) but is optional * for other implementations, as currently the titlebar isn't specified as a core component of * the docking framework (i.e. it is not an interface). *@since 2.1.3 */ public abstract DockViewTitleBar createTitleBar(); /** Returns the current factory. *

it no factory has been provided, it will * fall back on DefaultDockableContainerFactory */ public static DockableContainerFactory getFactory() { if(factory == null) { factory = new DefaultDockableContainerFactory(); } return factory; } /** Changes the factory to be used by DockingDesktop. *

* Note that this change is not propagated to already docked components. * */ public static void setFactory(DockableContainerFactory f) { factory = f; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockableDragSource.java000066400000000000000000000042501243334202400323610ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.*; /** An interface implemented by visual components used for drag and drop operations * on a DockableContainer. *

* This interface is used by API Extenders to create new kind of drag sources. *

* A "Drag Source" is a component, linked to a Dockable, responsible * for drag gesture recognition. There can be more than one DockableDragSource per * Dockable. *

* For example, the title bar of a docked component is usually the drag source of * this component (meaning : when a user drags the title bar, he expects the dockable * to be dragged around). *

* These draggable components must be able to give informations about their * target (the component known to the user, which is actually dragged). * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public interface DockableDragSource { /** Notifies this source that a drag operation has begun. *

The source may reject the drag according to internal conditions (in that case * this method shall return false) or to wrong mouse position . * * @return true if drag operation is accepted (i.e the zone pointed by p refers to * a draggable component), false otherwise. * */ public boolean startDragComponent(Point p); /** Returns the Dockable component this source is for */ public Dockable getDockable(); /** returns the DockableContainer responsible for displaying the associated dockable */ public Container getDockableContainer(); /** notifies the source when the drag operation has ended (by a drop or cancelled) * @since 2.1.3 */ public void endDragComponent(boolean dropped); } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockablePanel.java000066400000000000000000000033021243334202400313570ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import javax.swing.*; import java.awt.*; /** A basic implementation of Dockable. *

* It's a JPanel with a BorderLayout, and it can display a single Dockable. *

* This class is provided as an intermediary between a User Component and the docking * desktop (for example, for application that don't want to be too tied with the * DockingFramework). * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public class DockablePanel extends JPanel implements Dockable { private static final long serialVersionUID = 1L; private DockKey key; public DockablePanel() { setLayout(new BorderLayout()); } public DockablePanel(Component contained, DockKey key) { setLayout(new BorderLayout()); add(contained, BorderLayout.CENTER); this.key = key; } public DockKey getDockKey() { return key; } public void setDockKey(DockKey key) { this.key = key; } public Component getComponent() { return this; } /** Removes all contained components (normally no more than one), and * put this comp on the center area of the BorderLayout. * */ public void setComponent(Component comp) { removeAll(); add(comp, BorderLayout.CENTER); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockableResolver.java000066400000000000000000000020211243334202400321160ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; /** An interface used to find a dockable (when read from an input stream like XML) * when the only information given is its DockKey id. * *

This is mainly to allow auto-registration of new dockables when loading a new workspace. * * @author Lilian Chamontin, VLSolutions * @since 2.1.2 */ public interface DockableResolver { /** Returns the dockable which should be associated to this DockKey identifier, or null if * not found. */ public Dockable resolveDockable(String keyName); } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockableState.java000066400000000000000000000123411243334202400314030ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; /** General information about the current state of a dockable component. *

* This class is a simple record of a dockable and its current display state. *

It is used together with DockableStateChangeEvents (and listeners) to * track changes of Dockable visibility. * * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * * @update 2005/10/07 Lilian Chamontin : added getStateName(int state) method */ @SuppressWarnings("rawtypes") public class DockableState implements Comparable { private Dockable dockable; //private static final String [] stateNames = {"CLOSED", "DOCKED", "HIDDEN", "MAXIMIZED", "FLOATING"}; /** Possible locations of a dockable */ public enum Location { /** A constant describing a Dockable that is not visible. * */ CLOSED, /** A constant describing a Dockable that is visible (displayed in a DockableContainer) */ DOCKED, /** A constant describing a Dockable that is in auto-hide mode (reduced to a button) */ HIDDEN, /** A constant describing a Dockable that is currently maximized */ MAXIMIZED, /** A constant describing a Dockable that is currently floating (detached from the desktop) */ FLOATING } private Location location; /** Relative position for hidden/closed dockable show-again */ private RelativeDockablePosition position; /** Desktop currently using this dockable */ private DockingDesktop desktop; public DockableState() { position = new RelativeDockablePosition(); } public DockableState(DockingDesktop desktop, Dockable dockable, Location location) { this.desktop = desktop; this.dockable = dockable; this.location = location; position = new RelativeDockablePosition(); } public DockableState(DockingDesktop desktop, Dockable dockable, Location location, RelativeDockablePosition position) { this.desktop = desktop; this.dockable = dockable; this.location = location; this.position = position; } /** Creates a dockable state based on an existing state, with another relative positionning */ public DockableState(DockableState copy, RelativeDockablePosition position) { this.desktop = copy.desktop; this.dockable = copy.dockable; this.location = copy.location; this.position = position; } /** Comparable interface, used to sort components by name order. * */ public int compareTo(Object object) { if(object instanceof DockableState) { return dockable.getDockKey().getName().compareTo(((DockableState) object).dockable.getDockKey().getName()); } else { return - 1; } } /** Returns the dockable this state is for */ public Dockable getDockable() { return dockable; } /** Convenience method returning wether the dockable is in the DOCKED state */ public boolean isDocked() { return location == Location.DOCKED; } /** Convenience method returning wether the dockable is in the HIDDEN state */ public boolean isHidden() { return location == Location.HIDDEN; } /** Convenience method returning wether the dockable is in the CLOSED state */ public boolean isClosed() { return location == Location.CLOSED; } /** Convenience method returning wether the dockable is in the FLOATING state */ public boolean isFloating() { return location == Location.FLOATING; } /** Convenience method returning wether the dockable is in the MAXIMIZED state */ public boolean isMaximized() { return location == Location.MAXIMIZED; } /** Returns the current location of the dockable (CLOSED, DOCKED, HIDDEN...). */ public Location getLocation() { return location; } /** Returns the relative restore position of the dockable when it is not shown (auto-hide * or closed). *

* Please note that this position is meaningless for visible components * (as it is not automatically calculated at every move / resize of the dockable ). * * */ public RelativeDockablePosition getPosition() { return position; } public String toString() { return "DockableState [" + dockable.getDockKey() + ", state=" + location.name() + ", position=" + position; } /** Returns the desktop currently using this dockable, or null if none * * @since 2.1 */ public DockingDesktop getDesktop() { return desktop; } /** Updates the desktop field (desktop using this dockable) * @since 2.1 */ public void setDesktop(DockingDesktop desktop) { this.desktop = desktop; } /** Utility (compatibility) method used to associate an int to the Location enumeration * (opposite to location.ordinal() */ public static Location getLocationFromInt(int state) { switch(state) { case 0: return Location.CLOSED; case 1: return Location.DOCKED; case 2: return Location.HIDDEN; case 3: return Location.MAXIMIZED; case 4: return Location.FLOATING; default: return null; } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockableStoreButton.java000066400000000000000000000114501243334202400326130ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.docking.event.DockDragEvent; import com.vlsolutions.swing.docking.event.DockDropEvent; import java.awt.Container; import java.awt.Point; import javax.swing.Icon; import javax.swing.JButton; /** A Button that can be used to store a dockable (for example to allow moving a dockable * between two workspaces). * *

* The button is able to display the Icon, text and toolip of a dockable key, and can be used as a drag * source (to initiate a drop into a desktop). * * @author Lilian Chamontin, VLSolutions */ public class DockableStoreButton extends JButton implements DockDropReceiver, DockableDragSource { private static final long serialVersionUID = 1L; private Dockable dockable; private String emptyText = "Nothing stored"; private String emptyTooltip = "Move and drop a view of your application above this button to store it"; private Icon emptyIcon = null; private String fullText = "View &1 stored"; private String fullTooltip = "Drag this button to move the view &1 to a new position"; public DockableStoreButton(String emptyText) { super(emptyText); this.emptyText = emptyText; updateButtonText(); } public DockableStoreButton() { updateButtonText(); } /** when a dockable is dragged above this button, the button stores it as its new * target dockable. * @see #getDockable() */ public void processDockableDrag(DockDragEvent event) { event.rejectDrag(); } /** Rejects the drop as this action isn't possible on this component */ public void processDockableDrop(DockDropEvent event) { setDockable(event.getDragSource().getDockable()); event.rejectDrop(); } public void setDockable(Dockable dockable) { this.dockable = dockable; updateButtonText(); } /** Override this method if you want to change the display (text and icon) of this button and * the default settings don't suit your needs. */ public void updateButtonText() { if(dockable == null) { setText(emptyText); setToolTipText(emptyTooltip); setIcon(null); } else { String text = fullText.replaceAll("&1", dockable.getDockKey().getName()); setText(text); String tttext = fullTooltip.replaceAll("&1", dockable.getDockKey().getName()); setToolTipText(tttext); setIcon(dockable.getDockKey().getIcon()); } } public boolean startDragComponent(Point p) { return dockable != null; } /** Return the dockable currently stored (may be null) */ public Dockable getDockable() { return dockable; } public Container getDockableContainer() { return (Container) DockingUtilities.findDockableContainer(dockable); } public void endDragComponent(boolean dropped) { if(dropped) { dockable = null; updateButtonText(); } } /** Returns the text used for this button when no dockable is stored*/ public String getEmptyText() { return emptyText; } /** updates the text used for this button when no dockable is stored*/ public void setEmptyText(String emptyText) { this.emptyText = emptyText; } /** Returns the text used as tooltip for this button when no dockable is stored*/ public String getEmptyTooltip() { return emptyTooltip; } /** Updates the text used as tooltip for this button when no dockable is stored*/ public void setEmptyTooltip(String emptyTooltip) { this.emptyTooltip = emptyTooltip; } /** Returns the Icon used with this button when no dockable is selected */ public Icon getEmptyIcon() { return emptyIcon; } /** Updates the icon used for this button when no dockable is stored*/ public void setEmptyIcon(Icon emptyIcon) { this.emptyIcon = emptyIcon; } /** Returns the text used for this button when a dockable is stored*/ public String getFullText() { return fullText; } /** Returns the text used for this button when a dockable is stored*/ public void setFullText(String fullText) { this.fullText = fullText; } /** Returns the text used for as tooltip this button when a dockable is stored*/ public String getFullTooltip() { return fullTooltip; } /** Updates the text used as tooltip for this button when no dockable is stored. * The special value '&1' will be replaced by the name of this dockable. *

* For example "&1 stored" could be replaced by "MyDockable stored" */ public void setFullTooltip(String fullTooltip) { this.fullTooltip = fullTooltip; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockingBorderLayout.java000066400000000000000000000143001243334202400326050ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.*; /** A layout adapted to autohide panels. *

* This layout is like a BorderLayout but corners are always empty * (for example, the TOP component starts with an x coordinate equal to the * width of the LEFT component). * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public class DockingBorderLayout implements LayoutManager2 { Component topComp, leftComp, bottomComp, rightComp, centerComp; public DockingBorderLayout() {} public float getLayoutAlignmentX(Container target) { return 0.5F; } public float getLayoutAlignmentY(Container target) { return 0.5F; } public void invalidateLayout(Container target) {} public Dimension maximumLayoutSize(Container target) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } public void addLayoutComponent(Component comp, Object constraints) { addLayoutComponent((String) constraints, comp); } public void removeLayoutComponent(Component comp) {} public void addLayoutComponent(String name, Component comp) { if(name.equals(BorderLayout.NORTH)) { topComp = comp; } else if(name.equals(BorderLayout.EAST)) { rightComp = comp; } else if(name.equals(BorderLayout.SOUTH)) { bottomComp = comp; } else if(name.equals(BorderLayout.WEST)) { leftComp = comp; } else if(name.equals(BorderLayout.CENTER)) { centerComp = comp; } else { throw new IllegalArgumentException("wrong constraint"); } } public Dimension minimumLayoutSize(Container parent) { synchronized(parent.getTreeLock()) { Dimension dim = new Dimension(0, 0); if(leftComp != null && leftComp.isVisible()) { Dimension d = leftComp.getMinimumSize(); dim.width += d.width; dim.height = Math.max(d.height, dim.height); } if(rightComp != null && rightComp.isVisible()) { Dimension d = rightComp.getMinimumSize(); dim.width += d.width; dim.height = Math.max(d.height, dim.height); } if(centerComp != null && centerComp.isVisible()) { Dimension d = centerComp.getMinimumSize(); dim.width += d.width; dim.height = Math.max(d.height, dim.height); } if(topComp != null && topComp.isVisible()) { Dimension d = topComp.getMinimumSize(); dim.width = Math.max(d.width, dim.width); dim.height += d.height; } if(bottomComp != null && bottomComp.isVisible()) { Dimension d = bottomComp.getMinimumSize(); dim.width = Math.max(d.width, dim.width); dim.height += d.height; } Insets insets = parent.getInsets(); dim.width += insets.left + insets.right; dim.height += insets.top + insets.bottom; return dim; } } public Dimension preferredLayoutSize(Container parent) { synchronized(parent.getTreeLock()) { Dimension dim = new Dimension(0, 0); if(leftComp != null && leftComp.isVisible()) { Dimension d = leftComp.getPreferredSize(); dim.width += d.width; dim.height = Math.max(d.height, dim.height); } if(rightComp != null && rightComp.isVisible()) { Dimension d = rightComp.getPreferredSize(); dim.width += d.width; dim.height = Math.max(d.height, dim.height); } if(centerComp != null && centerComp.isVisible()) { Dimension d = centerComp.getPreferredSize(); dim.width += d.width; dim.height = Math.max(d.height, dim.height); } if(topComp != null && topComp.isVisible()) { Dimension d = topComp.getPreferredSize(); dim.width = Math.max(d.width, dim.width); dim.height += d.height; } if(bottomComp != null && bottomComp.isVisible()) { Dimension d = bottomComp.getPreferredSize(); dim.width = Math.max(d.width, dim.width); dim.height += d.height; } Insets insets = parent.getInsets(); dim.width += insets.left + insets.right; dim.height += insets.top + insets.bottom; return dim; } } private int getSideWidth(Component comp) { if(comp == null) return 0; if(comp.isVisible()) return comp.getPreferredSize().width; return 0; } private int getSideHeight(Component comp) { if(comp == null) return 0; if(comp.isVisible()) return comp.getPreferredSize().height; return 0; } /** overridden to adjust position (x(top) = width(left), y(left) = height(top) */ public void layoutContainer(Container target) { synchronized(target.getTreeLock()) { Insets insets = target.getInsets(); int top = insets.top; int bottom = target.getHeight() - insets.bottom; int left = insets.left; int right = target.getWidth() - insets.right; int lw = getSideWidth(leftComp); int rw = getSideWidth(rightComp); int th = getSideHeight(topComp); int bh = getSideHeight(bottomComp); if(topComp != null && topComp.isVisible()) { topComp.setSize(right - left - lw - rw, topComp.getHeight()); Dimension d = topComp.getPreferredSize(); topComp.setBounds(left + lw, top, right - left - lw - rw, d.height); } if(bottomComp != null && bottomComp.isVisible()) { bottomComp.setSize(right - left - lw - rw, bottomComp.getHeight()); Dimension d = bottomComp.getPreferredSize(); bottomComp.setBounds(left + lw, bottom - d.height, right - left - lw - rw, d.height); } if(rightComp != null && rightComp.isVisible()) { rightComp.setSize(rightComp.getWidth(), bottom - top - th - bh); Dimension d = rightComp.getPreferredSize(); rightComp.setBounds(right - d.width, top + th, d.width, bottom - top - th - bh); } if(leftComp != null && leftComp.isVisible()) { leftComp.setSize(leftComp.getWidth(), bottom - top); Dimension d = leftComp.getPreferredSize(); leftComp.setBounds(left, top + th, d.width, bottom - top - th - bh); } if(centerComp != null && centerComp.isVisible()) { centerComp.setBounds(left + lw, top + th, right - left - lw - rw, bottom - top - th - bh); } } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockingConstants.java000066400000000000000000000060761243334202400321610ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; /** Constants used by the DockingDesktop to position Dockables. *

* API Users will use these constants to interact with the DockingDesktop. *

* These constants are defined as enumerations of Hide and Split classes, in order * to avoid runtime errors. * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public class DockingConstants { public static final int INT_SPLIT_TOP = 0; public static final int INT_SPLIT_LEFT = 1; public static final int INT_SPLIT_BOTTOM = 2; public static final int INT_SPLIT_RIGHT = 3; /** A constant describing a VERTICAL splitting operation where the new component * goes on the TOP part */ public static final Split SPLIT_TOP = new Split(INT_SPLIT_TOP); /** A constant describing an HORIZONTAL splitting operation where the new component * goes on the LEFT part */ public static final Split SPLIT_LEFT = new Split(INT_SPLIT_LEFT); /** A constant describing a VERTICAL splitting operation where the new component * goes on the BOTTOM part */ public static final Split SPLIT_BOTTOM = new Split(INT_SPLIT_BOTTOM); /** A constant describing an HORIZONTAL splitting operation where the new component * goes on the RIGHT part */ public static final Split SPLIT_RIGHT = new Split(INT_SPLIT_RIGHT); public static final int INT_HIDE_TOP = 0; public static final int INT_HIDE_LEFT = 1; public static final int INT_HIDE_BOTTOM = 2; public static final int INT_HIDE_RIGHT = 3; /** A constant describing an auto-hide operation where the component * goes on the TOP border */ public static final Hide HIDE_TOP = new Hide(INT_HIDE_TOP); /** A constant describing an auto-hide operation where the component * goes on the LEFT border */ public static final Hide HIDE_LEFT = new Hide(INT_HIDE_LEFT); /** A constant describing an auto-hide operation where the component * goes on the BOTTOM border */ public static final Hide HIDE_BOTTOM = new Hide(INT_HIDE_BOTTOM); /** A constant describing an auto-hide operation where the component * goes on the RIGHT border */ public static final Hide HIDE_RIGHT = new Hide(INT_HIDE_RIGHT); /** Typesafe enumeration describing a split operation on the DockingDesktop.*/ public static class Split { private int value; private Split(int value) { this.value = value; } public int value() { return value; } } /** Typesafe enumeration describing an auto-hide operation on the DockingDesktop.*/ public static class Hide { private int value; private Hide(int value) { this.value = value; } public int value() { return value; } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockingContext.java000066400000000000000000000417411243334202400316270ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.docking.event.DockableSelectionEvent; import com.vlsolutions.swing.docking.event.DockableSelectionListener; import com.vlsolutions.swing.docking.event.DockableStateChangeEvent; import com.vlsolutions.swing.docking.event.DockableStateChangeListener; import com.vlsolutions.swing.docking.event.DockableStateWillChangeEvent; import com.vlsolutions.swing.docking.event.DockableStateWillChangeListener; import com.vlsolutions.swing.docking.event.DockingActionEvent; import com.vlsolutions.swing.docking.event.DockingActionListener; import java.awt.Window; import java.awt.event.WindowEvent; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** A context that can be shared by multiple docking desktops. *

* Keeps track of registered dockables and manages import export. *

* A DockingContext can be seen as the top-most grouping element of docking * (as DockingDesktop can be contained is a context), and as such, all * methods related to workspace management have been promoted to this class. * * * @author Lilian Chamontin, VLSolutions * @since 2.1 * @update 2007/01/08 Lilian Chamontin : updated registerDockable to * put the dockable in the CLOSED state if not previously registered (was null before v2.1.3) */ @SuppressWarnings({"rawtypes", "unchecked"}) public class DockingContext { /** All dockables must be registered (even if not shown) in order to be processed * by the XML Parser or to be displayed in the DockingSelectorDialog */ protected ArrayList registeredDockables = new ArrayList(); /** inner state of the dockables */ protected HashMap dockableStates = new HashMap(); // key : Dockable / value : /* DockableState change listeners */ // before state change : private ArrayList dockableStateWillChangeListeners = new ArrayList(); // after state change : private ArrayList dockableStateChangeListeners = new ArrayList(); /** selection change */ private ArrayList dockableSelectionListeners = new ArrayList(); /** Docking action listener (preferred way to track docking changes) */ private ArrayList dockingActionListeners = new ArrayList(); private ArrayList desktops = new ArrayList(); /** An always ordered list of window (used to keep track of which one is above which one, to resolve some * DnD issues) */ private LinkedList ownedWindowActivationOrder = new LinkedList(); /** Finds new Dockables given a key name (useful when processing an XML stream if the dockable * hasn't been registered yet. */ private DockableResolver dockableResolver = null; /** Constructs a new DockingContext */ public DockingContext() {} /** Adds a desktop to this context */ public void addDesktop(DockingDesktop desktop) { if(! desktops.contains((desktop))) { desktops.add(desktop); } } /** Removes a desktop from this context */ public void removeDesktop(DockingDesktop desktop) { desktops.remove(desktop); // time to check if some windows should be removed as not ancestors of remaining desktops Iterator it = ownedWindowActivationOrder.iterator(); while(it.hasNext()) { Window w = (Window) it.next(); boolean ancestor = false; for(int i = 0; i < desktops.size(); i++) { DockingDesktop desk = (DockingDesktop) desktops.get(i); if(w.isAncestorOf(desk)) { ancestor = true; break; } } if(! ancestor) { // this window isn't an ancestor of any managed desktops : we drop it it.remove(); } } } /** Every dockable must be registered in order to be managed by a DockingDesktop. *

* if this method is invoked and the dockable is already registered, nothing happens. * if the dockable is still unknown, it is added to the dockables set and (since 2.1.3) * its state is set to CLOSED (prior 2.1.3, the state was null). * * */ public void registerDockable(Dockable dockable) { if(! registeredDockables.contains(dockable)) { registeredDockables.add(dockable); } if(getDockableState(dockable) == null) { // should be always the case here // 2007/01/08 setDockableState(dockable, new DockableState(null, dockable, DockableState.Location.CLOSED)); } } /** Unregisters the dockable, which can be garbage collected (no longer used * by docking desktops. * */ public void unregisterDockable(Dockable dockable) { close(dockable); // in case it was still visible registeredDockables.remove(dockable); dockableStates.remove(dockable); // 2005/11/09 } /** Close this dockable */ public void close(Dockable dockable) { DockableState state = dockableStates.get(dockable); DockingDesktop desk = state.getDesktop(); if(desk != null) { desk.close(dockable); } } /** Returns the current state of a dockable (CLOSED, HIDDEN, DOCKED, MAXIMIZED, FLOATING) */ public DockableState getDockableState(Dockable dockable) { return dockableStates.get(dockable); } /** Updates the current state of a dockable */ public void setDockableState(Dockable dockable, DockableState state) { dockableStates.put(dockable, state); } /** Adds a new DockableStateChangeListener to this desktop. *

* DockableStateChange Events are triggered after the state change. * *

As of version 2.0 of the framework, this method can also be replaced by * adding a propertychangeListener on the DockKey object (and react to its DockableState * property). * * */ public void addDockableStateChangeListener(DockableStateChangeListener listener) { if(! dockableStateChangeListeners.contains(listener)) { dockableStateChangeListeners.add(listener); } } /** Removes a DockableStateChangeListener from this desktop. * */ public void removeDockableStateChangeListener(DockableStateChangeListener listener) { dockableStateChangeListeners.remove(listener); } /** Adds a new DockableStateWillChangeListener to this desktop. *

* DockableStateWillChange Events are triggered before the state change, and * are vetoable. * */ public void addDockableStateWillChangeListener(DockableStateWillChangeListener listener) { if(! dockableStateWillChangeListeners.contains(listener)) { dockableStateWillChangeListeners.add(listener); } } /** Removes a DockableStateWillChangeListener from this desktop. * */ public void removeDockableStateWillChangeListener(DockableStateWillChangeListener listener) { dockableStateWillChangeListeners.remove(listener); } /** Creates and returns an array of all registered dockable with their current * state. *

* Visibility states are [DockableState.CLOSED, DOCKED, HIDDEN] * @return an array of DockableState */ public DockableState[] getDockables() { DockableState[] states = new DockableState[registeredDockables.size()]; for(int i = 0; i < states.length; i++) { Dockable d = registeredDockables.get(i); states[i] = dockableStates.get(d); if(states[i] == null) { DockableState closed = new DockableState(null, d, DockableState.Location.CLOSED); states[i] = closed; } } return states; } /** Saves the current desktop configuration into an XML stream. *

* The workspace is composed of every desktop layouts associated * with this context (desktops are identified by their 'desktopName' property). * *

* The stream is not closed at the end of the operation. * * @see #readXML(InputStream) * */ public void writeXML(OutputStream stream) throws IOException { PrintWriter out = new PrintWriter(stream); out.println(""); out.println(""); for(int i = 0; i < desktops.size(); i++) { DockingDesktop desktop = (DockingDesktop) desktops.get(i); desktop.writeDesktopNode(out); } out.println(""); out.flush(); } /** Reads an XML encoded stream as the new desktop configuration. *

* When the method returns, the desktops associated to this context are totally * reconfigured with posiibly different dockables at different positions. *

* Note : The DockKeys of the stream must be registered with * the {@link #registerDockable(Dockable) registerDockable} method, * prior readXML.
* * This is the case if the desktop is already open and dockables * laid out, but might not be the case if this method is used at application startup * to populate an empty desktop. *

* Note : altenatively (since 2.1.2) if a DockableResolver has been set, it will * be use to auto-register the new dockables encountered along the stream.
*

* Dismisses all visible dockables (docked and auto-hidden), and clear their DockableState. *

* The stream is not closed at the end of the operation. *

* Note : When multiple desktops are loaded from the stream, the context uses their "desktopName" * property (desk.getDesktopName()) to identify them. * * @see #writeXML(OutputStream) * @see #registerDockable(Dockable) * @see #setDockableResolver(DockableResolver) * */ public void readXML(InputStream in) throws ParserConfigurationException, IOException, SAXException { // remove all dockable states for(int i = 0; i < desktops.size(); i++) { DockingDesktop desk = (DockingDesktop) desktops.get(i); desk.clear(); } dockableStates.clear(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(in); Element root = doc.getDocumentElement(); if(root.getNodeName().equals("DockingDesktop")) { // this is an old desktop file, missing the VLDocking root node (VLDocking 2.0 format) // so we noly have a single desktop DockingDesktop desk = getDesktopByName(null); // only one desk.readDesktopNode(root); } else { NodeList desktopChildren = root.getChildNodes(); for(int i = 0, len = desktopChildren.getLength(); i < len; i++) { Node node = desktopChildren.item(i); if(node instanceof Element) { Element deskChild = (Element) node; DockingDesktop desk = getDesktopByName(deskChild.getAttribute("name")); desk.readDesktopNode(deskChild); } } } } private DockingDesktop getDesktopByName(String name) { if(desktops.size() == 1) { // always found if only one desktop DockingDesktop desktop = desktops.get(0); return desktop; } for(int i = 0; i < desktops.size(); i++) { DockingDesktop desktop = desktops.get(i); if(desktop.getDesktopName().equals(name)) { return desktop; } } throw new RuntimeException("No desktop found with name : " + name); } /** constructs and returns the list of dockables corresponding to a desktop, at a specific state*/ public ArrayList getDockablesByState(DockingDesktop desktop, DockableState.Location state) { ArrayList list = new ArrayList(); for(int i = 0; i < registeredDockables.size(); i++) { Dockable d = registeredDockables.get(i); DockableState dState = dockableStates.get(d); if(dState != null && dState.getDesktop() == desktop && dState.getLocation() == state) { list.add(d); } } return list; } /** Returns the (registered) dockable corresponding to the given key id, * or null if not found *

* Note : since VLDocking 2.1.2, this method also tries to use its DockableResolver * if null would have been returned. * @see DockableResolver */ public Dockable getDockableByKey(String dockKey) { for(int i = 0; i < registeredDockables.size(); i++) { Dockable d = registeredDockables.get(i); if(d.getDockKey().getKey().equals(dockKey)) { return d; } } // not found if(dockableResolver != null) { Dockable d = dockableResolver.resolveDockable(dockKey); if(d != null) { registerDockable(d); // a new one } return d; // might be null } return null; } /*package protected */void fireDockableStateChange(DockableStateChangeEvent e) { for(int i = 0; i < dockableStateChangeListeners.size(); i++) { DockableStateChangeListener listener = dockableStateChangeListeners.get(i); listener.dockableStateChanged(e); } } /*package protected */boolean fireDockableStateWillChange(DockableStateWillChangeEvent e) { DockingDesktop desk = e.getFutureState().getDesktop(); if(desk.getMaximizedDockable() != null) { // veto events coming from autohide and floating components if a component is maximized // @todo : this could be improved by disabling the dock and attach properties of // the remaining visible dockables to avoid having the user don't understand // why a button doesn't react. if(desk.getMaximizedDockable() != e.getCurrentState().getDockable()) { if(e.getFutureState().isDocked()) { if(e.getCurrentState().isHidden()) { return false; // refused } else if(e.getCurrentState().isFloating()) { return false; } } } } // dispatch events and listen to vetoes for(int i = 0; i < dockableStateWillChangeListeners.size(); i++) { DockableStateWillChangeListener listener = dockableStateWillChangeListeners.get(i); listener.dockableStateWillChange(e); if(! e.isAccepted()) { // stop as soon as the operation is cancelled return false; } } return true; } /** Adds a new DockableSelectionListener to this desktop. *

* DockableSelection Events are triggered when a dockable takes the focus. * */ public void addDockableSelectionListener(DockableSelectionListener listener) { if(! dockableSelectionListeners.contains(listener)) { dockableSelectionListeners.add(listener); } } /** Removes a DockableSelectionListener from this desktop. * */ public void removeDockableSelectionListener(DockableSelectionListener listener) { dockableSelectionListeners.remove(listener); } /*package protected */void fireDockableSelectionChange(DockableSelectionEvent e) { for(int i = 0; i < dockableSelectionListeners.size(); i++) { DockableSelectionListener listener = dockableSelectionListeners.get(i); listener.selectionChanged(e); } } public void addDockingActionListener(DockingActionListener listener) { if(! dockingActionListeners.contains(listener)) { dockingActionListeners.add(listener); } } public void removeDockingActionListener(DockingActionListener listener) { dockingActionListeners.remove(listener); } /** returns false if the docking action is rejected, or true if accepted by all listeners*/ boolean fireAcceptDockingAction(DockingActionEvent e) { /*package protected */ for(int i = 0; i < dockingActionListeners.size(); i++) { DockingActionListener listener = dockingActionListeners.get(i); if(! listener.acceptDockingAction(e)) { return false; } } return true; } /*package protected */void fireDockingActionPerformed(DockingActionEvent e) { for(int i = 0; i < dockingActionListeners.size(); i++) { DockingActionListener listener = dockingActionListeners.get(i); listener.dockingActionPerformed(e); } } /** Returns a list of the desktops sharing this context */ public ArrayList getDesktopList() { return desktops; } /** used to track window activation (to have an up to date z ordered list of window) */ void windowActivated(WindowEvent e) { /* package protected */ /* these events are forwarded by docking desktops */ Window w = e.getWindow(); if(ownedWindowActivationOrder.size() > 0 && ownedWindowActivationOrder.getFirst() != w) { ownedWindowActivationOrder.remove(w); ownedWindowActivationOrder.addFirst(w); } } /** Returns a list of owned windows, ordered by window z-order */ LinkedList getOwnedWindowActionOrder() { /* package protected */ return ownedWindowActivationOrder; } /** Registers a new window */ void registerWindow(Window w) { /* package protected */ ownedWindowActivationOrder.addLast(w); } /** Returns the dockable resolver used by this context (or null if none defined) * @since 2.1.2 */ public DockableResolver getDockableResolver() { return dockableResolver; } /** Updates the dockable resolver used by this context (can be set to null) * @since 2.1.2 */ public void setDockableResolver(DockableResolver dockableResolver) { this.dockableResolver = dockableResolver; } }vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockingDesktop.java000066400000000000000000004531551243334202400316220ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Insets; import java.awt.KeyboardFocusManager; import java.awt.Panel; import java.awt.Point; import java.awt.Rectangle; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import javax.swing.AbstractAction; import javax.swing.JComponent; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.AncestorEvent; import javax.swing.event.AncestorListener; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.xml.parsers.ParserConfigurationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import com.vlsolutions.swing.docking.event.DockableSelectionEvent; import com.vlsolutions.swing.docking.event.DockableSelectionListener; import com.vlsolutions.swing.docking.event.DockableStateChangeEvent; import com.vlsolutions.swing.docking.event.DockableStateChangeListener; import com.vlsolutions.swing.docking.event.DockableStateWillChangeEvent; import com.vlsolutions.swing.docking.event.DockableStateWillChangeListener; import com.vlsolutions.swing.docking.event.DockingActionAddDockableEvent; import com.vlsolutions.swing.docking.event.DockingActionCloseEvent; import com.vlsolutions.swing.docking.event.DockingActionCreateTabEvent; import com.vlsolutions.swing.docking.event.DockingActionEvent; import com.vlsolutions.swing.docking.event.DockingActionListener; import com.vlsolutions.swing.docking.event.DockingActionSimpleStateChangeEvent; import com.vlsolutions.swing.docking.event.DockingActionSplitComponentEvent; import com.vlsolutions.swing.docking.event.DockingActionSplitDockableEvent; import com.vlsolutions.swing.docking.ui.DockingUISettings; /** * The DockingDesktop is the main class of the VLDocking Framework. *

* It is the equivalent of what is JDesktopPane for JInternalWindow : a * JLayeredPane customized to include : *

    *
  • Four auto-hide borders used to show Dockable iconified as buttons. *
  • A nested containment hierarchy (made of JSplitPanes) with drag and drop * (dock) capabilities. *
  • An extensive API to programmatically change its contents. *
  • An XML encoder/decoder to create / save / reload workspaces (sets of * dockable components) *
  • An abstraction of the Dockable notion, with factories to allow different * implementations or customization of the Dockable containers. *
  • An event model to track changes and react to them. *
* * @author Lilian Chamontin, VLSolutions. * @version 2.0 * * @update 2005/10/06 Lilian Chamontin : added support for dnd to floatables * @update 2005/10/07 Lilian Chamontin : cancel drag operation with ESCAPE key * @update 2005/11/08 Lilian Chamontin : added support for global width/height * drop (in split method) * @update 2005/11/14 Lilian Chamontin : reworked setFloating methods. * @update 2005/12/08 Lilian Chamontin : fixed a bug related to multiple desktop * usage (when moving a window after the desktop has been removed from * hierarchy, the listeners were still invoked and caused a NPE in * moveFloatingWindows). * * @update 2006/12/01 Lilian Chamontin : fixed a NPE when closing a window with * some floating children remaining * @update 2006/12/19 Lilian Chamontin : fixed a memory leak issue due to * keyboard focus manager handling * @update 2007/03/19 reformulate addHiddenDockable tests to support closed * dockables. * @update 2007/08/11 added safety check to avoid creating tabs on a maximized * component * @update 2008/07/05 fixed a NPE occuring when saving workspace and a tabbed * component was still maximized */ @SuppressWarnings({ "rawtypes", "unchecked", "unused" }) public class DockingDesktop extends JLayeredPane { private static final long serialVersionUID = 1L; private static final String CURRENT_VERSION_NUMBER = "2.1.5"; private static final String BUILD_DATE = "2008/07/05"; private static final Logger log = LoggerFactory .getLogger(DockingDesktop.class); static { // install UI settings if not already done DockingUISettings.getInstance().installUI(); } /** contextual data that can be shared by multiple desktops */ private DockingContext context; /** panel containing autohidepanels on borders and dockingpanel at center */ private JPanel contentPane = new JPanel(new DockingBorderLayout()); /** main central container for dockables */ protected DockingPanel dockingPanel = new DockingPanel(); /** container responsible for auto-hidden components expansion */ protected AutoHideExpandPanel expandPanel = createAutoHideExpandPanel(); /** panel used to display autohide buttons */ protected AutoHideButtonPanel topBorderPane = new AutoHideButtonPanel( expandPanel, DockingConstants.INT_HIDE_TOP); /** panel used to display autohide buttons */ protected AutoHideButtonPanel leftBorderPane = new AutoHideButtonPanel( expandPanel, DockingConstants.INT_HIDE_LEFT); /** panel used to display autohide buttons */ protected AutoHideButtonPanel bottomBorderPane = new AutoHideButtonPanel( expandPanel, DockingConstants.INT_HIDE_BOTTOM); /** panel used to display autohide buttons */ protected AutoHideButtonPanel rightBorderPane = new AutoHideButtonPanel( expandPanel, DockingConstants.INT_HIDE_RIGHT); /** array containing the border panes */ protected AutoHideButtonPanel[] borderPanes = { topBorderPane, leftBorderPane, bottomBorderPane, rightBorderPane }; private HashMap autoHideButtons = new HashMap(); // key // : // DockKey // / // value // : // AutoHideButton private DragControler dragControler; /** a component used to track position of the current maximized component */ private MaximizedComponentReplacer dummyMaximedReplacer = new MaximizedComponentReplacer();// 2007/01/18 // new JLabel(); /** the current maximized component */ private Component maximizedComponent; /** * a flag set when adding a maximized component : true is this one is * heavyweight Only used with heavyweight support AND * singleHeavyWeightComponent */ private boolean currentMaximizedComponentIsHeavyWeight = false; private JComponent mouseMotionGrabber = new JComponent() { private static final long serialVersionUID = 1L; // component used to grab mouse events under the expansion panel // only visible (and active) when expansion panel is visible }; /** * this timer is only used when the java version is < 1.5 (version>=1.5 uses * the MouseInfo component) */ private javax.swing.Timer mouseOutOfExpandedPanelTimer = new javax.swing.Timer( 1000, new ActionListener() { // timer used to hide the expanded panel when mouse is out too // long public void actionPerformed(ActionEvent actionEvent) { if (!expandPanel.isActive() && expandPanel.shouldCollapse()) { // do not hide it if it has got the focus // or if a non-collapsible operation is occuring expandPanel.collapse(); } } }); /** groups of tabs (used to re-tab autohidden dockable) */ protected HashMap> tabbedGroups = new HashMap(); // / private FocusHandler focusHandler = new FocusHandler(); /** return state for floating dockables */ protected HashMap previousFloatingDockableStates = new HashMap(); // key // dockable // / // value // dockable // state /** * Unique name for this desktop : used since 2.1 to support multiple * desktops */ private String desktopName; // 2005/10/10 added support for moving the floating dialogs with the frame private Point lastWindowLocation = null; private ComponentAdapter windowMovementListener = new ComponentAdapter() { public void componentMoved(ComponentEvent e) { moveFloatingWindows(); } }; WindowListener windowListener = new WindowAdapter() { public void windowActivated(WindowEvent e) { context.windowActivated(e); // foward activation events to the // context } }; /** Action used for keyboard binding : closes the current dockable */ private AbstractAction closeAction = new AbstractAction() { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { Dockable d = focusHandler.getCurrentDockable(); if (d != null) { if (d.getDockKey().isCloseEnabled()) { DockableState.Location location = d.getDockKey() .getLocation(); if (location == DockableState.Location.DOCKED || location == DockableState.Location.FLOATING || location == DockableState.Location.HIDDEN) { close(d); } } } } }; /** Action used for keyboard binding : maximize/restore the current dockable */ private AbstractAction maximizeAction = new AbstractAction() { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { Dockable d = focusHandler.getCurrentDockable(); if (d != null) { if (d.getDockKey().isMaximizeEnabled()) { DockableState.Location location = d.getDockKey() .getLocation(); if (location == DockableState.Location.DOCKED) { maximize(d); } else if (location == DockableState.Location.MAXIMIZED) { restore(d); } } } } }; /** Action used for keyboard binding : autohide/dock the current dockable */ private AbstractAction dockAction = new AbstractAction() { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { Dockable d = focusHandler.getCurrentDockable(); if (d != null) { if (d.getDockKey().isAutoHideEnabled()) { DockableState.Location location = d.getDockKey() .getLocation(); if (location == DockableState.Location.DOCKED) { setAutoHide(d, true); } else if (location == DockableState.Location.HIDDEN) { setAutoHide(d, false); } } } } }; /** Action used for keyboard binding : float/attach the current dockable */ private AbstractAction floatAction = new AbstractAction() { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { Dockable d = focusHandler.getCurrentDockable(); if (d != null) { if (d.getDockKey().isFloatEnabled()) { DockableState.Location location = d.getDockKey() .getLocation(); if (location == DockableState.Location.DOCKED) { setFloating(d, true); } else if (location == DockableState.Location.FLOATING) { setFloating(d, false); } } } } }; /** Action used for keyboard binding : cancel the current operation */ private AbstractAction cancelAction = new AbstractAction() { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { dragControler.cancelDrag(); } }; /** * Constructs a DockingDesktop with a default name (suitable for * single-desktop applications). */ public DockingDesktop() { this("", null); } /** * Constructs a DockingDesktop with a given name (suitable for * multiple-desktop applications). *

* This also constructs a new Docking Context, that can be shared with other * Desktops. */ public DockingDesktop(String desktopName) { this(desktopName, null); } /** * Constructs a DockingDesktop with a given name (suitable for * multiple-desktop applications). */ public DockingDesktop(String desktopName, DockingContext context) { setDesktopName(desktopName); if (context == null) { this.context = new DockingContext(); // initial (single desktop) // context } else { this.context = context; // shared context issued from another // dekstop } this.context.addDesktop(this); this.dragControler = DragControlerFactory.getInstance() .createDragControler(this); // // add(contentPane, BorderLayout.CENTER); topBorderPane.setVisible(false); leftBorderPane.setVisible(false); bottomBorderPane.setVisible(false); rightBorderPane.setVisible(false); contentPane.add(topBorderPane, BorderLayout.NORTH); contentPane.add(leftBorderPane, BorderLayout.WEST); contentPane.add(bottomBorderPane, BorderLayout.SOUTH); contentPane.add(rightBorderPane, BorderLayout.EAST); contentPane.add(dockingPanel, BorderLayout.CENTER); add(contentPane, DEFAULT_LAYER); mouseMotionGrabber.setVisible(false); mouseMotionGrabber.addMouseListener(new MouseAdapter() { boolean canUseMouseInfo = DockingUtilities.canUseMouseInfo(); public void mouseEntered(MouseEvent e) { // means that the mouse is not above the expanded panel if (!canUseMouseInfo) { // only for 1.4 codebase or untrusted // envs mouseOutOfExpandedPanelTimer.restart(); // 2005/11/01 } } public void mouseExited(MouseEvent e) { // means that the mouse is probably above the expanded panel (or // out of the window) if (!canUseMouseInfo) { // only for 1.4 codebase or untrusted // envs mouseOutOfExpandedPanelTimer.stop(); // 2005/11/01 } } public void mousePressed(MouseEvent e) { // collapse the expanded panel and redispatch the event to the // underlying frame // for processing by the real component clicked by the user expandPanel.collapse(); Window w = SwingUtilities .getWindowAncestor(DockingDesktop.this); if (w != null) { w.dispatchEvent(e); } } }); expandPanel.installDocking(this); expandPanel.setVisible(false); add(mouseMotionGrabber, new Integer(MODAL_LAYER.intValue() - 1)); add(expandPanel, MODAL_LAYER); ComponentListener resizeListener = new ComponentAdapter() { /* resize listener is added to the desktop and to the contentPane */ public void componentResized(ComponentEvent event) { int w = getWidth(); int h = getHeight(); Insets i = getDockingPanelInsets(); if (event.getComponent() == DockingDesktop.this) { // hide the expanded panel if necessary expandPanel.collapse(); // resize the panel contentPane.setBounds(0, 0, w, h); revalidate(); } else if (event.getComponent() == dockingPanel) { if (maximizedComponent != null) { if (DockingPreferences.isLightWeightUsageEnabled()) { maximizedComponent.setBounds(i.left, i.top, w - i.left - i.right, h - i.top - i.bottom); } else { if (DockingPreferences .isSingleHeavyWeightComponent()) { if (DockingUtilities .isHeavyWeightComponent(maximizedComponent)) { maximizedComponent.setBounds(i.left, i.top, w - i.left - i.right, h - i.top - i.bottom); } else { maximizedComponent.getParent().setBounds( i.left, i.top, w - i.left - i.right, h - i.top - i.bottom); } } else { maximizedComponent.getParent().setBounds( i.left, i.top, w - i.left - i.right, h - i.top - i.bottom); } } } mouseMotionGrabber.setBounds(i.left, i.top, w - i.left - i.right, h - i.top - i.bottom); dockingPanel.revalidate(); } } }; addComponentListener(resizeListener); dockingPanel.addComponentListener(resizeListener); expandPanel.addPropertyChangeListener( AutoHideExpandPanel.PROPERTY_EXPANDED, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { if (e.getNewValue().equals(Boolean.TRUE)) { mouseMotionGrabber.setVisible(true); } else { mouseMotionGrabber.setVisible(false); } } }); mouseOutOfExpandedPanelTimer.setRepeats(false); // avoid loops /* * KeyboardFocusManager.getCurrentKeyboardFocusManager(). * addPropertyChangeListener( "focusOwner", focusHandler); //2006/08/21 * : back to life (was in comments in 2.1.0) */ installKeyboardBindings(); // optional window following final boolean floatingContainerFollowParentWindow = UIManager .getBoolean("FloatingContainer.followParentWindow"); addAncestorListener(new AncestorListener() { public void ancestorAdded(AncestorEvent event) { KeyboardFocusManager.getCurrentKeyboardFocusManager() .addPropertyChangeListener("focusOwner", focusHandler); // 2006/08/21 // : // back // to // life // (was // in // comments // in // 2.1.0) // 2006/12/19 now integrated to ancestor hierarchy to avoid gc // leaks Window w = SwingUtilities .getWindowAncestor(DockingDesktop.this); w.addWindowListener(windowListener); DockingDesktop.this.context.registerWindow(w); // first // activation // required to // register the // window if (floatingContainerFollowParentWindow) { w.addComponentListener(windowMovementListener); } } public void ancestorRemoved(AncestorEvent event) {// 2005/12/08 KeyboardFocusManager.getCurrentKeyboardFocusManager() .removePropertyChangeListener("focusOwner", focusHandler); // 2006/12/19 if (event == null || event.getAncestorParent() == null) { // 2006/12/01 protection againts NPE return; } else { Window w = SwingUtilities.getWindowAncestor(event .getAncestorParent()); if (w != null) { // 2007/03/07 hope it helps with desktops // on JDialogs w.removeWindowListener(windowListener); if (floatingContainerFollowParentWindow) { w.removeComponentListener(windowMovementListener); } } } } public void ancestorMoved(AncestorEvent event) { } }); } /** * Registers listeners for notable keyboard events (CLOSE, DOCK/HIDE, * MAXIMIZE/RESTORE, float/attach). KeyStroke bindings can be defined and * overriden this UIManager properties (see DockingUISettings for details). * */ private void installKeyboardBindings() { KeyStroke ks = (KeyStroke) UIManager .get("DockingDesktop.closeActionAccelerator"); if (ks != null) { getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ks, "close"); getActionMap().put("close", closeAction); } ks = (KeyStroke) UIManager .get("DockingDesktop.maximizeActionAccelerator"); if (ks != null) { getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ks, "maximize"); getActionMap().put("maximize", maximizeAction); } ks = (KeyStroke) UIManager.get("DockingDesktop.dockActionAccelerator"); if (ks != null) { getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ks, "dock"); getActionMap().put("dock", dockAction); } ks = (KeyStroke) UIManager.get("DockingDesktop.floatActionAccelerator"); if (ks != null) { getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ks, "float"); getActionMap().put("float", floatAction); } ks = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); // general cancel // action 2005/10/07 getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, "cancel"); getActionMap().put("cancel", cancelAction); } /** * Returns the currently selected dockable, or null if none is selected. *

* A selected dockable is a dockable whose component contains the keyboard * focus. */ public Dockable getSelectedDockable() { return focusHandler.currentDockable; } /** * Set the desktop contents to be opaque or transparent. *

* Transparent contents allow adding background images/information when no * dockable is visible (everything closed or autohidden). *

* Default value is true (opaque). * * @since 2.0.4 */ public void setOpaqueContents(boolean opaque) { contentPane.setOpaque(opaque); dockingPanel.setOpaque(opaque); } /** * Returns whether this desktop's contents are opaque or not. *

* Default value is true (opaque). * * @see #setOpaqueContents(boolean). * @since 2.0.4 */ public boolean isOpaqueContents() { return contentPane.isOpaque(); } /** * Returns the docking panel used by this desktop. * * Usage of this method should be limited to VLDocking extensions (simple * users shouldn't rely on the underlying DockingPanel existence) */ DockingPanel getDockingPanel() { /* package protected method */ return dockingPanel; } /** * Every dockable must be registered in order to be shown in the * DockingDesktop. * *

* Registration is automatic for shown dockables : methods * setCentralDockable(), split(), createTab(), hide()... leading to have the * dockable visible call registerDockable() ) *

* for not shown dockable (in order to read a configuration from an XML * stream, or to list the dockable in DockingSelectorDialog ), this method * must be called manually. *

* As of version 2.1, this method call is forwarded to the DockingContext * */ public void registerDockable(Dockable dockable) { context.registerDockable(dockable); } /** * Unregisters the dockable, which can be garbage collected (no longer used * by the docking desktop. *

* As of version 2.1, this method call is forwarded to the DockingContext * */ public void unregisterDockable(Dockable dockable) { // context.registerDockable(dockable); // 2006/09/06 context.unregisterDockable(dockable); // 2006/09/06 } /** * Returns a String containing the version of the docking framework in the * format M.m.r where M is the major , m the minor and r the release. * * @since 2.0 */ public static String getDockingFrameworkVersion() { return CURRENT_VERSION_NUMBER; } /** * Returns a String containing the release date of the current version. * * @since 2.0 */ public static String getDockingFrameworkBuildDate() { return BUILD_DATE; } /** * Adds a view in a tab, or create it if it doesn't exist. * * @param base * the reference dockable * @param dockable * a dockable to add at the same position than base. * if base is not already child of a tabbedpane, a new tabbedpane * will be created and inserted at base's location. * @param order * the tab order of view in its tabbed pane. * */ public void createTab(Dockable base, Dockable dockable, int order) { createTab(base, dockable, order, false); } /** * Add a view in a tab, or create it if it doesn't exist. *

* Optional added tab selection. * * @param base * an existing dockable, either displayed in a DockableContainer * or in a TabbedDockableContainer. *

* If base is displayed by a DockableContainer, this container * will be replaced by a TabbedDockableContainer. * @param dockable * the dockable to add * @param order * the tab order of view in its tabbed pane. * @param select * if true, will select the added tab (make it appear at front) * */ public void createTab(Dockable base, Dockable dockable, int order, boolean select) { createTab(base, dockable, order, select, true); } /** * private implementation wich allows for triggering state change event or * not (depending on the caller). */ private void createTab(Dockable base, Dockable dockable, int order, boolean select, boolean triggerEvents) { /* * createTab() is called by : - DockView/DetachedDockView during DnD - * DockTabbedPane during DnD - show() which is called by - * setFloating(false) - setAutoHide(false) */ if (base == null) throw new NullPointerException("base must not be null"); if (dockable == null) throw new NullPointerException("dockable must not be null"); context.registerDockable(dockable); // 2007/08/11 if (getMaximizedDockable() == base) { // 2007/08/11 added safety restore restore(getMaximizedDockable()); } DockableState currentState = getDockableState(dockable); DockableState.Location currentLocation = getLocation(currentState); // currentState might be null CLOSED HIDDEN DOCKED FLOATING DockableState newState = null; // 2005/10/06 - support for floatable // tabs : the future state can be docked // or floating if (base.getDockKey().getLocation() == DockableState.Location.FLOATING) { RelativeDockablePosition position = new RelativeDockablePosition( dockingPanel, dockable); newState = new DockableState(this, dockable, base.getDockKey() .getLocation(), position); } else { newState = new DockableState(this, dockable, base.getDockKey() .getLocation()); } DockableStateWillChangeEvent dswe = new DockableStateWillChangeEvent( currentState, newState); DockingActionEvent dae = new DockingActionCreateTabEvent(this, dockable, currentLocation, newState.getLocation(), base, order); // boolean stateChange = currentState == null || // !currentState.isDocked(); // boolean stateChange = currentState == null || // currentState.getLocation() != newState.getLocation(); //2005/10/07 if (triggerEvents) { if (!isDockingActionAccepted(dae, dswe)) { return; // vetoed } } TabbedDockableContainer dockableTab = null; if (currentLocation != DockableState.Location.CLOSED) { // don't search tabs for closed dockables // 2007/02/27 dockableTab = DockingUtilities .findTabbedDockableContainer(dockable); } // TabbedDockableContainer baseTab = // DockingUtilities.findTabbedDockableContainer(dockable); // 2005/05/19 TabbedDockableContainer baseTab = DockingUtilities .findTabbedDockableContainer(base); // 2005/05/19 if (dockableTab != null && dockableTab != baseTab) { // don't belong to the same tabbed pane, so remove first the // dockable remove(dockable); // TODO : check this : removal should have been // done earlier (in dropRemove() ) } // if ( currentState != null && (!currentState.isFloating()) && // newState.isFloating()){ if (currentState != null && currentState.isFloating() && newState.isFloating()) { // this case is when dragging a floating dockable into another // floating window Window w = SwingUtilities .getWindowAncestor(dockable.getComponent()); Window w2 = SwingUtilities.getWindowAncestor(base.getComponent()); if (w == null) { // the dockable has already been removed } else if (w != w2) { // when creating a floating tab, we have to manually remove the // dockable remove(dockable); } else { // else same window : no need to remove it remove(dockable); } } else if (currentState != null && (!currentState.isFloating()) && newState.isFloating()) { // from !floating to floating : // when creating a floating tab, we have to manually remove the // dockable remove(dockable); } if (!newState.isFloating()) { // remove old attachment except when creating a floating tab removeFromTabbedGroup(dockable); // 2005/07/13 } if (baseTab != null) { // add a tab baseTab.addDockable(dockable, order); } else { // base isn't included in a tabbed pane, so we have to create one DockableContainer baseOldContainer = DockingUtilities .findSingleDockableContainer(base); baseOldContainer.uninstallDocking(this); baseTab = DockableContainerFactory.getFactory() .createTabbedDockableContainer(); baseTab.installDocking(this); baseTab.addDockable(base, 0); baseTab.addDockable(dockable, 1); ((JTabbedPane) baseTab).addChangeListener(focusHandler); // our best // way // to // track // selection // (focus) // changes DockingUtilities.replaceChild( ((Component) baseOldContainer).getParent(), (Component) baseOldContainer, (Component) baseTab); } if (select) { baseTab.setSelectedDockable(dockable); } // context.registerDockable(dockable); //2007/08/11 context.setDockableState(dockable, newState); if (newState.isFloating() && !currentState.isFloating()) { // we need to store the return information storePreviousFloatingState(dockable, currentState); } if (triggerEvents) { dockable.getDockKey().setLocation(base.getDockKey().getLocation()); // 2005/10/06 fireDockingAction(dae, new DockableStateChangeEvent(currentState, newState)); } if (!newState.isFloating()) { // register tab group association except if we are going floating... addToTabbedGroup(base, dockable); // 2005/07/13 } DockingUtilities.updateResizeWeights(dockingPanel); } /** * Splits a Dockable in 2 parts, if possible. *

* The base dockable is the reference, the second newDockable will be added * according to the position parameter. *

* If base is contained in a non splitable container (like a tab of * DockTabbedPane) then, a splitable ancestor will be searched (until the * root desktop pane is reached) to apply splitting. * * @param base * an already docked Dockable * @param newDockable * the added dockable * @param position * position of newDockable relative to base * @param proportion * proportion of the initial dockable space taken by the new * dockable a negative proportion, like -1, will be ignored (and * split will be based on component preferred sizes and weights). * This parameter is an alternative to * DockingDesktop.setDockableHeight() and setDockableWidth() * methods * @see DockingDesktop#setDockableHeight(com.vlsolutions.swing.docking.Dockable, * double) * @see DockingDesktop#setDockableWidth(com.vlsolutions.swing.docking.Dockable, * double) */ public void split(Dockable base, Dockable newDockable, DockingConstants.Split position, double proportion) { /* * split() is used internally by the framework in the following cases : * - from a move() API invocation - from a DnD on DockTabbedPane * (overriding BorderSplitter) but only when the dockable is not * floating * * => we can safely assume that the future state of the dockable will be * "Docked" */ if (base == null) throw new NullPointerException("base must not be null"); if (newDockable == null) throw new NullPointerException("newDockable must not be null"); DockableState currentState = getDockableState(newDockable); DockableState.Location currentLocation = getLocation(currentState); boolean stateChange = currentState == null || !currentState.isDocked(); // todo : new state should be DOCKED *OR* FLOATING DockableState newState = new DockableState(this, newDockable, DockableState.Location.DOCKED); DockingActionEvent dae = new DockingActionSplitDockableEvent(this, newDockable, currentLocation, newState.getLocation(), base, position, 0.5f); DockableStateWillChangeEvent event = new DockableStateWillChangeEvent( currentState, newState); if (!isDockingActionAccepted(dae, event)) { return; // vetoed } TabbedDockableContainer baseTab = DockingUtilities .findTabbedDockableContainer(base); DockableContainer dockableContainer = DockableContainerFactory .getFactory() .createDockableContainer( newDockable, DockableContainerFactory.ParentType.PARENT_SPLIT_CONTAINER); dockableContainer.installDocking(this); // create a new splitcontainer that will replace baseDockable's // container SplitContainer split; if (position == DockingConstants.SPLIT_TOP || position == DockingConstants.SPLIT_BOTTOM) { split = new SplitContainer(JSplitPane.VERTICAL_SPLIT); } else /* * if (position == DockingConstants.SPLIT_LEFT || position == * DockingConstants.SPLIT_RIGHT) */{ split = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); } Component left, right; // baseTab = null; // V2.1 TEST if (baseTab != null) { // base is contained in a tab, so the split will occur between the // tab and // newDockable (a tabbed component cannot be splitted) DockingUtilities.replaceChild(((Component) baseTab).getParent(), ((Component) baseTab), split); if (position == DockingConstants.SPLIT_TOP || position == DockingConstants.SPLIT_LEFT) { left = (Component) dockableContainer; right = (Component) baseTab; } else { left = (Component) baseTab; right = (Component) dockableContainer; } } else { // base is not contained in a tab, so it must be a DockableContainer DockableContainer baseContainer = DockingUtilities .findSingleDockableContainer(base); assert baseContainer != null; DockingUtilities.replaceChild( ((Component) baseContainer).getParent(), ((Component) baseContainer), split); if (position == DockingConstants.SPLIT_TOP || position == DockingConstants.SPLIT_LEFT) { left = (Component) dockableContainer; right = (Component) baseContainer; } else { left = (Component) baseContainer; right = (Component) dockableContainer; } } // now, we have to fill split with base and dockable split.setLeftComponent(left); split.setRightComponent(right); context.registerDockable(newDockable); context.setDockableState(newDockable, newState); newDockable.getDockKey().setLocation(DockableState.Location.DOCKED); fireDockingAction(dae, new DockableStateChangeEvent(currentState, newState)); removeFromTabbedGroup(newDockable); // 2005/10/10 DockingUtilities.updateResizeWeights(dockingPanel); if (proportion >= 0) { SwingUtilities.invokeLater(new SplitResizer(split, proportion)); } } /** * Splits a Dockable in 2 parts, if possible. *

* The base dockable is the reference, the second newDockable will be added * according to the position parameter. *

* If base is contained in a non splitable container (like a tab of * DockTabbedPane) then, a splitable ancestor will be searched (until the * root desktop pane is reached) to apply splitting. * * @param base * an already docked Dockable * @param newDockable * the added dockable * @param position * position of newDockable relative to base */ public void split(Dockable base, Dockable newDockable, DockingConstants.Split position) { split(base, newDockable, position, -1); } /** * Replaces the base component by a split pane oriented according to * position, and put dockable at position. *

* Note : This method is for DockableContainers. API users should * use the {@link #split(Dockable,Dockable,DockingConstants.Split) split} * method. * * @param base * the reference component (a dockablecontainer or a split * container) * @param dockable * the dockable to add * @param position * the position of dockable. * * */ public void splitComponent(Component base, Dockable dockable, DockingConstants.Split position) { /* * splitComponent() is called from SplitContainer and BorderSplitter * BorderSplitter is used by : - DockView (not floating, as the * DetachedDockView child overrides the scanDrop method and doesn't use * the BorderSplitter - DockTabbedPane (only when not floating) * SplitContainer is used for DnD operations that can occur from * Hide/Docked/Floating elements * * => The future state will be DOCKED, but we cannot guess the current * state (HIDE/FLOAT/DOCKED)=> as of 2.1 : the future state can be * DOCKED or FLOATING (with the help of compound dockable) */ if (base == null) throw new NullPointerException("base"); if (dockable == null) throw new NullPointerException("dockable"); context.registerDockable(dockable); // int futureState = DockableState.DOCKED; DockableState.Location futureLocation = DockingUtilities .getDockableLocationFromHierarchy(base); /* * if (!dockingPanel.isAncestorOf(base)){ futureState = * DockableState.FLOATING; } */ DockableState currentState = getDockableState(dockable); DockableState.Location currentLocation = getLocation(currentState); boolean stateChange = false; if (currentState == null) { stateChange = true; } else if (currentState.getLocation() != futureLocation) { stateChange = true; } DockableState newState = new DockableState(this, dockable, futureLocation); // DockableState.DOCKED); DockableStateWillChangeEvent dswe = new DockableStateWillChangeEvent( currentState, newState); DockingActionEvent dae = new DockingActionSplitComponentEvent(this, dockable, currentLocation, newState.getLocation(), base, position, 0.5f); if (!isDockingActionAccepted(dae, dswe)) { return; // vetoed } if (stateChange) { if (currentState.isFloating()) { removePreviousFloatingState(dockable); // clear reference of the // previous state } } Container oldContainer = (Container) DockingUtilities .findSingleDockableContainer(dockable); int oldWidth = 0; int oldHeight = 0; if (oldContainer != null) { oldWidth = oldContainer.getWidth(); oldHeight = oldContainer.getHeight(); } else { oldWidth = base.getWidth() / 2; oldHeight = base.getHeight() / 2; } DockableContainer dockableContainer = DockableContainerFactory .getFactory() .createDockableContainer( dockable, DockableContainerFactory.ParentType.PARENT_SPLIT_CONTAINER); dockableContainer.installDocking(this); // create a new splitcontainer that will replace baseDockable's // container SplitContainer split; if (position == DockingConstants.SPLIT_TOP || position == DockingConstants.SPLIT_BOTTOM) { split = new SplitContainer(JSplitPane.VERTICAL_SPLIT); } else /* * if (position == DockingConstants.SPLIT_LEFT || position == * DockingConstants.SPLIT_RIGHT) */{ split = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); } if (base != dockingPanel) { // 2005/11/08 support for splitting from // dockingPanel DockingUtilities.replaceChild(base.getParent(), base, split); if (position == DockingConstants.SPLIT_TOP || position == DockingConstants.SPLIT_LEFT) { split.setLeftComponent((Component) dockableContainer); split.setRightComponent(base); } else { split.setRightComponent((Component) dockableContainer); split.setLeftComponent(base); } } else { // docking panel must remain the top level ancestor if (dockingPanel.getComponentCount() != 0) { Component dockingPanelChild = dockingPanel.getComponent(0); DockingUtilities.replaceChild(dockingPanel, dockingPanelChild, split); if (position == DockingConstants.SPLIT_TOP || position == DockingConstants.SPLIT_LEFT) { split.setLeftComponent((Component) dockableContainer); split.setRightComponent(dockingPanelChild); } else { split.setRightComponent((Component) dockableContainer); split.setLeftComponent(dockingPanelChild); } } else { // dockingpanel is empty dockingPanel.add((Component) dockableContainer); } } // if (oldContainer != null){ // now try to keep same size as before the drop // we do this in invokelater because split.getWidth()/getHeight() // returns 0 at this time // and we need this value to do a correct setDividerLocation. if (position == DockingConstants.SPLIT_TOP) { SwingUtilities.invokeLater(new SplitResizer(split, oldHeight)); } else if (position == DockingConstants.SPLIT_BOTTOM) { SwingUtilities.invokeLater(new SplitResizer(split, -oldHeight)); } else if (position == DockingConstants.SPLIT_LEFT) { SwingUtilities.invokeLater(new SplitResizer(split, oldWidth)); } else if (position == DockingConstants.SPLIT_RIGHT) { SwingUtilities.invokeLater(new SplitResizer(split, -oldWidth)); } // } context.setDockableState(dockable, newState); if (stateChange) { if (futureLocation == DockableState.Location.FLOATING) { // splitting from ? (should be Docked) to floating // we have to store a return state. storePreviousFloatingState(dockable, currentState); } } dockable.getDockKey().setLocation(futureLocation); fireDockingAction(dae, new DockableStateChangeEvent(currentState, newState)); removeFromTabbedGroup(dockable); // 2005/10/10 DockingUtilities.updateResizeWeights(dockingPanel); } /** * Replaces the base component by a split pane oriented according to * position, and put the dockablesContainer at position. *

* Note : This method is for DockableContainers. API users should * use the {@link #split(Dockable,Dockable,DockingConstants.Split) split} * method. * * @param base * the reference component (a dockablecontainer or a split * container) * @param dockablesContainer * the dockable container * @param position * the position of dockable. * * */ public void splitComponent(Component base, Container dockablesContainer, DockingConstants.Split position) { if (dockablesContainer instanceof SingleDockableContainer) { splitComponent(base, ((SingleDockableContainer) dockablesContainer) .getDockable(), position); } else if (dockablesContainer instanceof TabbedDockableContainer) { splitTab(base, (TabbedDockableContainer) dockablesContainer, position); } else { System.err.println("unknow split request !" + dockablesContainer); } } private void splitTab(Component base, TabbedDockableContainer tdc, DockingConstants.Split position) { // should be used only when drag and dropping if (base == null) throw new NullPointerException("base"); Dockable firstDockable = tdc.getDockableAt(0); DockableState currentState = getDockableState(firstDockable); boolean stateChange = false; if (currentState.isFloating()) { removePreviousFloatingStates(tdc); // clear reference of the // previous state stateChange = true; } Container oldContainer = (Container) tdc; int oldWidth = 0; int oldHeight = 0; if (oldContainer != null) { oldWidth = oldContainer.getWidth(); oldHeight = oldContainer.getHeight(); } else { oldWidth = base.getWidth() / 2; oldHeight = base.getHeight() / 2; } DockableContainer dockableContainer = tdc; // create a new splitcontainer that will replace baseDockable's // container SplitContainer split; if (position == DockingConstants.SPLIT_TOP || position == DockingConstants.SPLIT_BOTTOM) { split = new SplitContainer(JSplitPane.VERTICAL_SPLIT); } else /* * if (position == DockingConstants.SPLIT_LEFT || position == * DockingConstants.SPLIT_RIGHT) */{ split = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); } if (base != dockingPanel) { // 2005/11/08 support for splitting from // dockingPanel DockingUtilities.replaceChild(base.getParent(), base, split); if (position == DockingConstants.SPLIT_TOP || position == DockingConstants.SPLIT_LEFT) { split.setLeftComponent((Component) dockableContainer); split.setRightComponent(base); } else { split.setRightComponent((Component) dockableContainer); split.setLeftComponent(base); } } else { // docking panel must remain the top level ancestor if (dockingPanel.getComponentCount() != 0) { Component dockingPanelChild = dockingPanel.getComponent(0); DockingUtilities.replaceChild(dockingPanel, dockingPanelChild, split); if (position == DockingConstants.SPLIT_TOP || position == DockingConstants.SPLIT_LEFT) { split.setLeftComponent((Component) dockableContainer); split.setRightComponent(dockingPanelChild); } else { split.setRightComponent((Component) dockableContainer); split.setLeftComponent(dockingPanelChild); } } else { // dockingpanel is empty dockingPanel.add((Component) dockableContainer); } } // if (oldContainer != null){ // now try to keep same size as before the drop // we do this in invokelater because split.getWidth()/getHeight() // returns 0 at this time // and we need this value to do a correct setDividerLocation. if (position == DockingConstants.SPLIT_TOP) { SwingUtilities.invokeLater(new SplitResizer(split, oldHeight)); } else if (position == DockingConstants.SPLIT_BOTTOM) { SwingUtilities.invokeLater(new SplitResizer(split, -oldHeight)); } else if (position == DockingConstants.SPLIT_LEFT) { SwingUtilities.invokeLater(new SplitResizer(split, oldWidth)); } else if (position == DockingConstants.SPLIT_RIGHT) { SwingUtilities.invokeLater(new SplitResizer(split, -oldWidth)); } // } if (stateChange) { // this part is tricky : we assume the caller is DragContoller (it's // the only // legal way to invoke this method). DragController triggers event // change for (int i = 0; i < tdc.getTabCount(); i++) { Dockable d = tdc.getDockableAt(i); DockableState newState = new DockableState(this, d, DockableState.Location.DOCKED); context.setDockableState(d, newState); } } // registerDockable(dockable); // dockableStates.put(dockable, newState); // if (stateChange){ // dockable.getDockKey().setLocation(DockableState.DOCKED); // fireDockableStateChange(new DockableStateChangeEvent(currentState, // newState)); // } // // removeFromTabbedGroup(dockable); //2005/10/10 // DockingUtilities.updateResizeWeights(dockingPanel); } /** * Moves a dockable to another position (relative to a destination dockable) * * * @param dockable * must be a registered Dockable * @param base * must be a visible Dockable * @param position * relative positionning */ public void move(Dockable base, Dockable dockable, DockingConstants.Split position) { if (base == null) throw new NullPointerException("base must not be null"); if (dockable == null) throw new NullPointerException("dockable must not be null"); if (dockable == base) return; remove(dockable); removeFromTabbedGroup(dockable); // 2005/07/13 split(base, dockable, position); } /** * Shows again a dockable (if previously hidden, floating or closed). *

* The dockable is inserted in the docking desktop where it was before, if * possible. if not, an approximated place will be looked for. * */ private void show(Dockable dockable, DockingActionEvent action) { if (dockable == null) throw new NullPointerException("dockable must not be null"); DockableState state = context.getDockableState(dockable); RelativeDockablePosition position = state.getPosition(); if (position == null) { // not shown before, ask best position to the preferences // TODO throw new NullPointerException( "trying to show a view that was not hidden"); } LinkedList group = tabbedGroups.get(dockable); // 2005/07/13... boolean tabbed = false; if (group != null) { // look for a still visible dockable in the group Iterator it = group.iterator(); while (it.hasNext() && !tabbed) { Dockable d = (Dockable) it.next(); if (d != dockable && getDockableState(d).isDocked()) { createTab(d, dockable, Integer.MAX_VALUE, true, false); tabbed = true; } } } if (!tabbed) { // ...2005/07/13 SingleDockableContainer sdc = RelativeDockingUtilities .applyDockingAction(dockable, action); // SingleDockableContainer sdc = // RelativeDockingUtilities.insertDockable( // position.getRelativeAncestorContainer(), dockable, position); sdc.installDocking(this); } } /** * Removes a visible dockable from the containment hierarchy (including * autohide border buttons). *

* This method shouldn't be used by user applications (only by the * framework). *

* To poperly remove a component from the desktop, use the close(Dockable) * method instead *

* If the dockable is not visible, an error will occur *

* This method does not unregister the dockable. * * @throws IllegalArgumentException * if the dockable is not visible (docked or auto-hide) * */ public void remove(Dockable dockable) { // TODO : check this : split this method in two (removeImpl() should be // used form inside the framework, and // remove should trigger CLOSE state change events // if (dockingPanel.isAncestorOf(dockable.getComponent())){ //2005/10/06 // ... DockableState.Location dockLocation = dockable.getDockKey() .getLocation(); SingleDockableContainer dockableContainer = null; Container parentOfSdc = null; boolean isChildOfCompoundDockable = false; // v2.1 if (dockLocation == DockableState.Location.DOCKED || dockLocation == DockableState.Location.FLOATING) { // ...2005/10/06 // we must guess that before removing the dockable from its // parent... isChildOfCompoundDockable = DockingUtilities .isChildOfCompoundDockable(dockable); dockableContainer = DockingUtilities .findSingleDockableContainer(dockable); parentOfSdc = ((JComponent) dockableContainer).getParent(); removeContainer(dockableContainer); } if (dockLocation == DockableState.Location.FLOATING) { FloatingDockableContainer fdc = (FloatingDockableContainer) SwingUtilities .getWindowAncestor(dockable.getComponent()); if (parentOfSdc instanceof TabbedDockableContainer) { // dockable was contained in a tab on the floatable : we must // not dispose the window } else if (isChildOfCompoundDockable) { // dockable was a child of a compound dockable : don't dispose } else { DockingUtilities.dispose(fdc); // ((JDialog)dlg).dispose(); } } else if (dockLocation == DockableState.Location.HIDDEN) { // DockableState state = (DockableState) // dockableStates.get(dockable); // if (state.isHidden()) { // component is removed from the auto-hide list // dockableStates.put(dockable, new DockableState(dockable, // DockableState.CLOSED)); // 2005/10/10 removed this : wrong place to change a dockable state AutoHideButton btn = autoHideButtons.get(dockable.getDockKey()); if (btn == null) { // (v2.1) no button : that means this dockable is a child of a // hidden compound dockable // so we just use the standard removing pattern dockableContainer = DockingUtilities .findSingleDockableContainer(dockable); parentOfSdc = ((JComponent) dockableContainer).getParent(); removeContainer(dockableContainer); } else { // single auto-hide dockable btn.setVisible(false); expandPanel.remove(dockable); // in case the dockable was the // current visible dockable } revalidate(); /* * } else if (state.isFloating()){ * * Window w = * SwingUtilities.getWindowAncestor(dockable.getComponent()); * w.dispose(); } else { // well, it's not shown, and not hidden... * // nop } */ } } /** * Removes a visible dockable : called from a drag and drop operation. *

* Don't call this method directly, as it is meant to be used only by the * drag and drop event components. */ public void dropRemove(DockableDragSource dragSource) { // before removing the dockable, we update its state to store its new // relative position Dockable d = dragSource.getDockable(); DockableState state = context.getDockableState(d); if (state != null) { // some drag source don't have state associated with them (like // whole TabbedContainers) DockableState updatedState = new DockableState(state, new RelativeDockablePosition( getRelativeAncestorContainer(d), d)); context.setDockableState(dragSource.getDockable(), updatedState); } Container dockableContainer = dragSource.getDockableContainer(); if (dockableContainer instanceof TabbedDockableContainer) { remove((TabbedDockableContainer) dockableContainer); } else { remove(dragSource.getDockable()); } // removeFromTabbedGroup(dockable); 2005/10/10 don't remove from tab : // it's too early to be sure we won't need it again // for example : when removing from a tab to create a floating tab (we // have to keep the old attachment) } /** * Removes a whole tab container (which is beeing moved to somewhere else) *

* This operation is done only during a drag and drop process. * * @throws IllegalArgumentException * if the dockable is not visible (docked or auto-hide) * */ private void remove(TabbedDockableContainer tdc) { // TODO : check this : split this method in two (removeImpl() should be // used form inside the framework, and // remove should trigger CLOSE state change events Dockable firstDockable = tdc.getDockableAt(0); // if (dockingPanel.isAncestorOf(dockable.getComponent())){ //2005/10/06 // ... DockableState.Location dockLocation = firstDockable.getDockKey() .getLocation(); if (dockLocation == DockableState.Location.FLOATING) { FloatingDockableContainer fdc = (FloatingDockableContainer) SwingUtilities .getWindowAncestor((Container) tdc); DockingUtilities.dispose(fdc); // ((JDialog)dlg).dispose(); } boolean invalidateDesktop = true; // always, except for floating // dockables Component parent = ((Component) tdc).getParent(); if (parent != null) { if (parent instanceof SplitContainer) { SplitContainer viewParent = (SplitContainer) parent; if (viewParent.getLeftComponent() == tdc) { viewParent.remove((Component) tdc); Component other = viewParent.getRightComponent(); // replace viewParent by other in viewParent's hierarchy Container viewGParent = (Container) viewParent.getParent(); DockingUtilities.replaceChild(viewGParent, viewParent, other); } else { viewParent.remove((Component) tdc); Component other = viewParent.getLeftComponent(); Container viewGParent = (Container) viewParent.getParent(); DockingUtilities.replaceChild(viewGParent, viewParent, other); } } else if (parent == dockingPanel) { // no more views to show dockingPanel.remove(0); } else if (SwingUtilities.getWindowAncestor(parent) instanceof FloatingDockableContainer) { // removing from a FloatingDockableContainer... nothing to do invalidateDesktop = false; } else { throw new IllegalStateException( "View is not contained in desktop hierarchy " + parent); } if (invalidateDesktop) { dockingPanel.invalidate(); dockingPanel.validate(); dockingPanel.repaint(); } } } /** * Extends the size of this dockable to fill the docking panel. *

* The component must be docked before beeing maximized, otherwise an * IllegalArgumentException will be thrown. *

* The opposite method of maximize is restore(Dockable). * * @see #restore(Dockable) * */ public void maximize(Dockable dockable) { if (dockable.getDockKey().getLocation() != DockableState.Location.DOCKED) { // development error (could have been an assertion). throw new IllegalArgumentException( "Dockable isn't currently in the DOCKED state : " + dockable); } DockableState currentState = getDockableState(dockable); boolean stateChange = currentState == null || !currentState.isMaximized(); DockableState newState = new DockableState(this, dockable, DockableState.Location.MAXIMIZED); DockableState.Location currentLocation = getLocation(currentState); DockableStateWillChangeEvent dswe = new DockableStateWillChangeEvent( currentState, newState); DockingActionEvent dae = new DockingActionSimpleStateChangeEvent(this, dockable, currentLocation, DockableState.Location.MAXIMIZED); if (!isDockingActionAccepted(dae, dswe)) { return; // vetoed } // v2.1 : if the currently maximized dockable is a compound dockable, // than its children // can still be maximized. // to avoid "stacking" maximized component, we just "restore" the // compound dockable SingleDockableContainer currentMaximizedContainer = (SingleDockableContainer) maximizedComponent; if (currentMaximizedContainer != null && currentMaximizedContainer.getDockable() != dockable) { // there's already a dockable which is maximized : restore it first restore(currentMaximizedContainer.getDockable()); } SingleDockableContainer sdc = DockingUtilities .findSingleDockableContainer(dockable); Component dockableContainer = (Component) sdc; DockingUtilities.replaceChild(dockableContainer.getParent(), dockableContainer, dummyMaximedReplacer); SingleDockableContainer maxDockableContainer = DockableContainerFactory .getFactory().createDockableContainer(dockable, DockableContainerFactory.ParentType.PARENT_DESKTOP); maxDockableContainer.installDocking(this); this.maximizedComponent = (Component) maxDockableContainer; Insets i = getDockingPanelInsets(); if (DockingPreferences.isLightWeightUsageEnabled()) { maximizedComponent.setBounds(i.left, i.top, getWidth() - i.left - i.right, getHeight() - i.top - i.bottom); add(maximizedComponent, JLayeredPane.PALETTE_LAYER); } else { this.currentMaximizedComponentIsHeavyWeight = false; if (DockingPreferences.isSingleHeavyWeightComponent()) { // first, check if the heavyweight component IS this dockable Component comp = dockable.getComponent(); // 2005/10/20 support // for single // heavyweight if (DockingUtilities.isHeavyWeightComponent(comp)) { // it's the heavyweight component (and the only one) // so we just have to put it there (no need for an // in-between awt panel) maximizedComponent.setBounds(i.left, i.top, getWidth() - i.left - i.right, getHeight() - i.top - i.bottom); add(maximizedComponent, JLayeredPane.PALETTE_LAYER); currentMaximizedComponentIsHeavyWeight = true; } else { // this one is not the heavyweight : we have to put it on // top of a fresh awt Panel Panel awtPanel = new Panel(new BorderLayout()); awtPanel.setBounds(i.left, i.top, getWidth() - i.left - i.right, getHeight() - i.top - i.bottom); awtPanel.add(maximizedComponent, BorderLayout.CENTER); awtPanel.validate(); add(awtPanel, JLayeredPane.PALETTE_LAYER); } } else { // if there are heavyweight components around, we need to add an // in-between // awt Panel to avoid those components to be drawn on top of the // maximized component Panel awtPanel = new Panel(new BorderLayout()); awtPanel.setBounds(i.left, i.top, getWidth() - i.left - i.right, getHeight() - i.top - i.bottom); awtPanel.add(maximizedComponent, BorderLayout.CENTER); awtPanel.validate(); add(awtPanel, JLayeredPane.PALETTE_LAYER); } } context.setDockableState(dockable, newState); dockable.getDockKey().setLocation(DockableState.Location.MAXIMIZED); fireDockingAction(dae, new DockableStateChangeEvent(currentState, newState)); dockable.getComponent().requestFocus(); repaint(); } /** * Restore the dockable to the docking position it was before beeing * maximized. *

* The dockable must be already maximized (otherwise an * IllegalArgumentException will be thrown) * * @see #maximize(Dockable) * */ public void restore(final Dockable dockable) { if (dockable.getDockKey().getLocation() != DockableState.Location.MAXIMIZED) { // development error (could have been an assertion). throw new IllegalArgumentException( "Dockable isn't currently in the MAXIMIZED state : " + dockable); } DockableState currentState = getDockableState(dockable); @SuppressWarnings("null") boolean stateChange = currentState != null || currentState.isMaximized(); DockableState newState = new DockableState(this, dockable, DockableState.Location.DOCKED); DockableState.Location currentLocation = getLocation(currentState); DockableStateWillChangeEvent dswe = new DockableStateWillChangeEvent( currentState, newState); DockingActionEvent dae = new DockingActionSimpleStateChangeEvent(this, dockable, currentLocation, DockableState.Location.DOCKED); if (!isDockingActionAccepted(dae, dswe)) { return; // vetoed } if (!DockingPreferences.isLightWeightUsageEnabled()) { if (DockingPreferences.isSingleHeavyWeightComponent() && this.currentMaximizedComponentIsHeavyWeight) { // 2005/10/20 remove(maximizedComponent); } else { remove(maximizedComponent.getParent()); // remove the awt panel } } else { remove(maximizedComponent); } ((SingleDockableContainer) maximizedComponent).uninstallDocking(this); SingleDockableContainer sdc = null; if (dummyMaximedReplacer.getParent() instanceof TabbedDockableContainer) { sdc = DockableContainerFactory .getFactory() .createDockableContainer( dockable, DockableContainerFactory.ParentType.PARENT_TABBED_CONTAINER); } else { sdc = DockableContainerFactory .getFactory() .createDockableContainer( dockable, DockableContainerFactory.ParentType.PARENT_SPLIT_CONTAINER); } DockingUtilities.replaceChild(dummyMaximedReplacer.getParent(), dummyMaximedReplacer, (Component) sdc); context.setDockableState(dockable, newState); dockable.getDockKey().setLocation(DockableState.Location.DOCKED); fireDockingAction(dae, new DockableStateChangeEvent(currentState, newState)); SwingUtilities.invokeLater(new Runnable() { public void run() { dockable.getComponent().requestFocus(); } }); sdc.installDocking(this); maximizedComponent = null; repaint(); } /** * Detach or attach the dockable from/to the desktop. *

* When detached, the dockable is centered on the desktop. */ public void setFloating(final Dockable dockable, boolean floating) { setFloating(dockable, floating, null); } /** * Used only with DOCKED dockables : returns the nearest ancestor container * (can be a CompoundDockingPanel if nested, or the DockingPanel). */ private Container getRelativeAncestorContainer(Dockable dockable) { Container compoundAncestor = DockingUtilities .findCompoundAncestorContainer(dockable); if (compoundAncestor != null) { return compoundAncestor; } else { return dockingPanel; } } /** * Detach or attach the dockable from/to the desktop. *

* show the dockable at sceenPosition (when not null) or centered (if * screenPosition is null) * */ public void setFloating(final Dockable dockable, boolean floating, Point screenPosition) { if (dockable == null) throw new NullPointerException("dockable"); DockableState currentState = getDockableState(dockable); DockableState.Location currentLocation = getLocation(currentState); SingleDockableContainer dockableContainer = DockingUtilities .findSingleDockableContainer(dockable); if (floating) { DockableState.Location location = dockable.getDockKey() .getLocation(); RelativeDockablePosition position = null; switch (location) { case DOCKED: position = new RelativeDockablePosition( getRelativeAncestorContainer(dockable), dockable); break; case HIDDEN: position = currentState.getPosition(); // get the position that // was stored before break; case FLOATING: // from floating..to floating. It's still possible, if the // component was previously tabbed (now it will have its // own window if (DockingUtilities.findTabbedDockableContainer(dockable) != null) { // ok, it was tabbed and floating } else { throw new IllegalArgumentException("floating not tabbed"); } break; case CLOSED: break; default: throw new IllegalArgumentException("not docked " + location); } DockableState newState = new DockableState(this, dockable, DockableState.Location.FLOATING, position); DockableStateWillChangeEvent event = new DockableStateWillChangeEvent( currentState, newState); if (location == DockableState.Location.FLOATING) { // floating to floating (create a new floating dialog by // removing a dockable from a detached tab) // note (@todo): as of version 2.1, we should trigger a // dockingActionEvent here... but which one ? // an addDockable with a floating state ? Dimension previousSize = null; remove(dockable); if (dockableContainer != null) { previousSize = ((Component) dockableContainer).getSize(); } FloatingDockableContainer fdc = createFloatingDockableContainer(dockable); // JDialog dialog = (JDialog) fdc; if (previousSize != null) { DockingUtilities.setSize(fdc, previousSize); // 2006/02/20 DockingUtilities.validate(fdc); // dialog.setSize(previousSize); // dialog.validate(); } else { DockingUtilities.pack(fdc); // dialog.pack(); } if (screenPosition == null) { DockingUtilities.setLocationRelativeTo(fdc, this); // dialog.setLocationRelativeTo(this); } else { DockingUtilities.setLocation(fdc, screenPosition); // dialog.setLocation(screenPosition); } DockingUtilities.setVisible(fdc, true); // dialog.setVisible(true); } else if (currentState != null) { DockingActionEvent dae = new DockingActionSimpleStateChangeEvent( this, dockable, currentLocation, DockableState.Location.FLOATING); if (isDockingActionAccepted(dae, event)) { // not already floating so we trigger state events Dimension previousSize = null; if (dockableContainer != null) { previousSize = ((Component) dockableContainer) .getSize(); } remove(dockable); // store a return state, based on the current state + // updated relative position storePreviousFloatingState(dockable, new DockableState( currentState, position)); FloatingDockableContainer fdc = createFloatingDockableContainer(dockable); // JDialog dialog = (JDialog) fdc; if (previousSize != null) { DockingUtilities.setSize(fdc, previousSize); DockingUtilities.validate(fdc); // dialog.setSize(previousSize); // dialog.validate(); } else { DockingUtilities.pack(fdc); // dialog.pack(); } if (screenPosition == null) { DockingUtilities.setLocationRelativeTo(fdc, this); // dialog.setLocationRelativeTo(this); } else { DockingUtilities.setLocation(fdc, screenPosition); // dialog.setLocation(screenPosition); } DockingUtilities.setVisible(fdc, true); // dialog.setVisible(true); context.setDockableState(dockable, newState); dockable.getDockKey().setLocation( DockableState.Location.FLOATING); fireDockingAction(dae, new DockableStateChangeEvent( currentState, newState)); if (dockable instanceof CompoundDockable) { updateCompoundChildrenState( (CompoundDockable) dockable, DockableState.Location.FLOATING); } DockingUtilities.updateResizeWeights(dockingPanel); revalidate(); } } } else { // attach ! // remove the button, show again the view // was the dockable docked or hidden ? DockableState previousState = getPreviousDockableState(dockable); DockableState newState = new DockableState(this, dockable, previousState.getLocation(), previousState.getPosition()); DockableStateWillChangeEvent event = new DockableStateWillChangeEvent( currentState, newState); DockingActionEvent dae; if (currentState != null && currentState.isFloating()) { if (previousState.isDocked()) { RelativeDockablePosition prevPos = previousState .getPosition(); Container relativeAncestor = prevPos .getRelativeAncestorContainer(); if (relativeAncestor == null) { relativeAncestor = dockingPanel; // safety : @todo we // have to refactor // xmlBuildFloatingNode // to // store the relativeAncestorContainer } dae = RelativeDockingUtilities.getInsertionDockingAction( relativeAncestor, dockable, currentState, newState); } else if (previousState.isHidden()) { // it was hidden dae = new DockingActionSimpleStateChangeEvent(this, dockable, DockableState.Location.FLOATING, DockableState.Location.HIDDEN); } else { // shoudn't be possible throw new RuntimeException(); } if (isDockingActionAccepted(dae, event)) { removePreviousFloatingState(dockable); Container parentOfSdc = null; // 2005/10/07 parentOfSdc = ((JComponent) dockableContainer).getParent(); removeContainer(dockableContainer); FloatingDockableContainer fdc = (FloatingDockableContainer) SwingUtilities .getWindowAncestor(dockable.getComponent()); if (parentOfSdc instanceof TabbedDockableContainer) { // dockable was contained in a tab on the floatable : we // must not dispose the window } else { DockingUtilities.dispose(fdc); // ((JDialog)fdc).dispose(); } context.setDockableState(dockable, newState); if (previousState.isDocked()) { show(dockable, dae); // TODO Fix this null } else if (previousState.isHidden()) { // it was hidden floatingToHide(dockable, previousState.getPosition()); } else { // unmanaged state throw new RuntimeException(); } dockable.getDockKey().setLocation( previousState.getLocation()); fireDockingAction(dae, new DockableStateChangeEvent( currentState, newState)); dockable.getComponent().requestFocus(); if (dockable instanceof CompoundDockable) { updateCompoundChildrenState( (CompoundDockable) dockable, newState.getLocation()); } DockingUtilities.updateResizeWeights(dockingPanel); revalidate(); } } } } /** * Detach or attach a whole tabbed dockable container from/to the desktop. *

* displays the component at sceenPosition (when not null) or centered (if * screenPosition is null) * */ void setFloating(final TabbedDockableContainer tdc, Point screenPosition) { /* * package protected, used by OldDragControler to detach a * tabbedcontainer */ Dockable firstDockable = tdc.getDockableAt(0); // all dockables have the same state, as they are in the same tabpane DockableState currentState = getDockableState(firstDockable); if (!currentState.isDocked()) { throw new IllegalArgumentException("not docked"); } else { if (checkDockableStateWillChange(tdc, DockableState.Location.FLOATING)) { RelativeDockablePosition position = new RelativeDockablePosition( dockingPanel, firstDockable); // no veto has been raised by the compound dockables Dimension previousSize = ((Component) tdc).getSize(); remove(tdc); storePreviousFloatingStates(tdc); FloatingDockableContainer fdc = createFloatingDockableContainer(tdc); // JDialog dialog = (JDialog) fdc; // dialog.setSize(previousSize); // dialog.validate(); DockingUtilities.setSize(fdc, previousSize); DockingUtilities.validate(fdc); if (screenPosition == null) { DockingUtilities.setLocationRelativeTo(fdc, this); // dialog.setLocationRelativeTo(this); } else { DockingUtilities.setLocation(fdc, screenPosition); // dialog.setLocation(screenPosition); } DockingUtilities.setVisible(fdc, true); // dialog.setVisible(true); fireStateChanged(tdc, DockableState.Location.FLOATING, position); DockingUtilities.updateResizeWeights(dockingPanel); revalidate(); } } } private void storePreviousFloatingStates(TabbedDockableContainer tdc) { for (int i = 0; i < tdc.getTabCount(); i++) { Dockable d = tdc.getDockableAt(i); DockableState current = getDockableState(d); storePreviousFloatingState(d, current); } } private boolean checkDockableStateWillChange(TabbedDockableContainer tdc, DockableState.Location futureLocation) { for (int i = 0; i < tdc.getTabCount(); i++) { Dockable d = tdc.getDockableAt(i); DockableState currentState = getDockableState(d); DockableState.Location currentLocation = getLocation(currentState); DockableState newState = new DockableState(this, d, futureLocation, null); DockableStateWillChangeEvent event = new DockableStateWillChangeEvent( currentState, newState); DockingActionEvent dae = new DockingActionSimpleStateChangeEvent( this, d, currentLocation, newState.getLocation()); if (!isDockingActionAccepted(dae, event)) { return false; } } return true; } private void fireStateChanged(TabbedDockableContainer tdc, DockableState.Location futureLocation, RelativeDockablePosition position) { for (int i = 0; i < tdc.getTabCount(); i++) { Dockable d = tdc.getDockableAt(i); DockableState currentState = getDockableState(d); DockableState.Location currentLocation = getLocation(currentState); DockableState newState = new DockableState(this, d, futureLocation, position); context.setDockableState(d, newState); d.getDockKey().setLocation(DockableState.Location.FLOATING); DockingActionEvent dae = new DockingActionSimpleStateChangeEvent( this, d, currentLocation, newState.getLocation()); fireDockingAction(dae, new DockableStateChangeEvent(currentState, newState)); } } private DockableState removePreviousFloatingStates( TabbedDockableContainer tdc) { DockableState first = removePreviousFloatingState(tdc.getDockableAt(0)); for (int i = 1; i < tdc.getTabCount(); i++) { Dockable d = tdc.getDockableAt(i); removePreviousFloatingState(d); } return first; } /** * Returns the previous state of a hidden or floating dockable (when that * dockable was in the DOCKED state. * * @since 2.0.4 * */ public DockableState getPreviousDockableState(Dockable dockable) { /* method mostly used internally */ return previousFloatingDockableStates.get(dockable); } private DockableState removePreviousFloatingState(Dockable dockable) { if (dockable instanceof CompoundDockable) { // we also need to clear states of the compound children ArrayList children = DockingUtilities .findCompoundDockableChildren((CompoundDockable) dockable); for (int i = 0; i < children.size(); i++) { Dockable d = (Dockable) children.get(i); previousFloatingDockableStates.remove(d); } } return previousFloatingDockableStates.remove(dockable); } private void storePreviousFloatingState(Dockable dockable, DockableState state) { // when storing a previous dockable state before going floating, we have // to ensure the relativeDockableAncestorContainer is defined RelativeDockablePosition pos = state.getPosition(); if (pos.getRelativeAncestorContainer() == null) { Container c = DockingUtilities .findCompoundAncestorContainer(dockable); if (c != null) { pos.resetRelativePosition(c, dockable); } else { pos.resetRelativePosition(dockingPanel, dockable); } } previousFloatingDockableStates.put(dockable, state); if (dockable instanceof CompoundDockable) { // more to do : the compund dockable may have children : they will // share the // same return position ArrayList children = DockingUtilities .findCompoundDockableChildren((CompoundDockable) dockable); for (int i = 0; i < children.size(); i++) { Dockable d = (Dockable) children.get(i); previousFloatingDockableStates.put(d, new DockableState(this, d, state.getLocation(), state.getPosition())); } } } /** * simplified auto-hide version used when the dockable was previously in * FLOATING state */ private void floatingToHide(Dockable dockable, RelativeDockablePosition position) { // doesn't trigger change event as it is managed by setFloatin(false) DockKey k = dockable.getDockKey(); AutoHideButton btn = autoHideButtons.get(k); if (btn == null) { btn = new AutoHideButton(); autoHideButtons.put(k, btn); int zone; if (k.getAutoHideBorder() == null) { zone = AutoHidePolicy.getPolicy().getDefaultHideBorder() .value(); } else { zone = k.getAutoHideBorder().value(); } btn.init(dockable, zone); borderPanes[zone].setVisible(true); // border may not be visible borderPanes[zone].add(btn); borderPanes[zone].revalidate(); } else { // btn already existing, show it again int zone = btn.getZone(); borderPanes[zone].setVisible(true); // may not be visible btn.setVisible(true); borderPanes[zone].revalidate(); } } private void moveFloatingWindows() { // 2005/10/10 Window w = SwingUtilities.getWindowAncestor(this); if (w == null) { return; // 2007/02/27 fixed NPE } Point newLocation = w.getLocation(); if (this.lastWindowLocation != null) { int dx = newLocation.x - lastWindowLocation.x; int dy = newLocation.y - lastWindowLocation.y; Window[] childWindow = w.getOwnedWindows(); for (int i = 0; i < childWindow.length; i++) { if (childWindow[i] instanceof FloatingDockableContainer && childWindow[i].isVisible()) { Point p = childWindow[i].getLocation(); childWindow[i].setLocation(p.x + dx, p.y + dy); } } } lastWindowLocation = newLocation; } /** * Creates a floating JDialog to be used with this dockable. *

* This method is protected to give access to implementors wanting to * customize its look and feel (for example : removing the title bar by * setting it to "undecorated"). *

* The old API has been removed (it returned a JDialog) as the * DockingDesktop can only work with FloatingDockableContainers. */ protected FloatingDockableContainer createFloatingDockableContainer( final Dockable dockable) { Window ownerWindow = SwingUtilities.getWindowAncestor(this); FloatingDockableContainer fdc = DockableContainerFactory.getFactory() .createFloatingDockableContainer(ownerWindow); fdc.installDocking(this); fdc.setInitialDockable(dockable); // JDialog dialog = (JDialog) fdc; KeyStroke ks = (KeyStroke) UIManager .get("DockingDesktop.floatActionAccelerator"); if (ks != null) { JRootPane root = DockingUtilities.getRootPane(fdc); root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) .put(ks, "float"); root.getActionMap().put("float", floatAction); } // dialog.pack(); // dialog.setVisible(true); return fdc; } /** * Creates a floating JDialog to be used for a whole * TabbedDockableContainer. *

* This method is protected to give access to implementors wanting to * customize its look and feel (for example : removing the title bar by * setting it to "undecorated"). *

* The old API has been removed (it returned a JDialog) as the * DockingDesktop can only work with FloatingDockableContainers. */ protected FloatingDockableContainer createFloatingDockableContainer( TabbedDockableContainer tdc) { Window ownerWindow = SwingUtilities.getWindowAncestor(this); FloatingDockableContainer fdc = DockableContainerFactory.getFactory() .createFloatingDockableContainer(ownerWindow); fdc.installDocking(this); fdc.setInitialTabbedDockableContainer(tdc); // JDialog dialog = (JDialog) fdc; KeyStroke ks = (KeyStroke) UIManager .get("DockingDesktop.floatActionAccelerator"); if (ks != null) { JRootPane root = DockingUtilities.getRootPane(fdc); root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) .put(ks, "float"); root.getActionMap().put("float", floatAction); } // dialog.pack(); // dialog.setVisible(true); return fdc; } /** Removes a dockable container. */ protected void removeContainer(SingleDockableContainer dc) { /* * to be improved : this method supposes a direct ancestor link between * DockableContainer and TabbedDockableContainer */ dc.uninstallDocking(this); boolean invalidateDesktop = true; // always, except for floating // dockables Component parent = ((Component) dc).getParent(); if (parent != null) { try { if (parent instanceof SplitContainer) { SplitContainer viewParent = (SplitContainer) parent; if (viewParent.getLeftComponent() == dc) { viewParent.remove((Component) dc); Component other = viewParent.getRightComponent(); // replace viewParent by other in viewParent's hierarchy Container viewGParent = (Container) viewParent .getParent(); DockingUtilities.replaceChild(viewGParent, viewParent, other); } else { viewParent.remove((Component) dc); Component other = viewParent.getLeftComponent(); Container viewGParent = (Container) viewParent .getParent(); DockingUtilities.replaceChild(viewGParent, viewParent, other); } } else if (parent instanceof TabbedDockableContainer) { TabbedDockableContainer tparent = (TabbedDockableContainer) parent; tparent.removeDockable(dc.getDockable()); if (tparent.getTabCount() == 1) { // no more use for tabs Dockable last = tparent.getDockableAt(0); remove(last); /* tparent.removeDockable(last); //2007/11/14 */ tparent.uninstallDocking(this); ((JTabbedPane) tparent) .removeChangeListener(focusHandler); boolean floating = last.getDockKey().getLocation() == DockableState.Location.FLOATING; DockableContainer lastContainer = null; if (floating) { lastContainer = DockableContainerFactory .getFactory() .createDockableContainer( last, DockableContainerFactory.ParentType.PARENT_DETACHED_WINDOW); } else { lastContainer = DockableContainerFactory .getFactory() .createDockableContainer( last, DockableContainerFactory.ParentType.PARENT_SPLIT_CONTAINER); } lastContainer.installDocking(this); DockingUtilities.replaceChild( ((Component) tparent).getParent(), (Component) tparent, (Component) lastContainer); } } else if (parent == dockingPanel) { // no more views to show dockingPanel.remove(0); } else if (SwingUtilities.getWindowAncestor(parent) instanceof FloatingDockableContainer) { // removing from a FloatingDockableContainer... nothing to // do invalidateDesktop = false; } else { ((Container) parent).remove((Component) dc); // throw new // IllegalStateException("View is not contained in desktop hierarchy " // + parent); } if (invalidateDesktop) { dockingPanel.invalidate(); dockingPanel.validate(); dockingPanel.repaint(); } } catch (Exception e) { e.printStackTrace(); } } } /** * Returns the current state of a dockable (CLOSED, HIDDEN, DOCKED, * MAXIMIZED, FLOATING) */ public DockableState getDockableState(Dockable dockable) { return context.getDockableState(dockable); } /** * Disposes the dockable container of this dockable. *

* If the dockable is not currently displayed (or auto-hidden), this method * will do nothing. *

* the dockable remains registered and can later be shown again at the same * location, using addDockable(Dockable, RelativeDockablePosition). *

* To have access to the RelativeDockablePosition at closing time, one has * to install a DockableEventListener like this : * *

	 * desk.addDockingActionListener(new DockingActionListener() {
	 *     public boolean acceptDockingAction(DockingActionEvent event) {
	 *       return true;
	 *     }
	 *     public void dockingActionPerformed(DockingActionEvent event) {
	 *       if (event.getActionType() == DockingActionEvent.ACTION_CLOSE){
	 *         closedDockable = ((DockingActionCloseEvent)event).getDockable();
	 *          RelativeDockablePostion position = desk.getLocation(closedDockable).getPosition();
	 *          // we now have a position we'll be able to reuse in addDockable()
	 *       }
	 *     }
	 *   });
	 * 
	 * 
* */ public void close(Dockable dockable) { // keep track of where the dockable was DockableState currentState = getDockableState(dockable); if (currentState == null || currentState.isClosed()) {// 2006/12/01 return; // no need to continue } DockableState.Location currentLocation = getLocation(currentState); RelativeDockablePosition position = new RelativeDockablePosition( dockingPanel, dockable); DockableState newState = new DockableState(this, dockable, DockableState.Location.CLOSED, position); DockableStateWillChangeEvent dswe = new DockableStateWillChangeEvent( currentState, newState); DockingActionEvent dae = new DockingActionCloseEvent(this, dockable, currentLocation); if (dockingPanel.isAncestorOf(dockable.getComponent())) { if (isDockingActionAccepted(dae, dswe)) { if (dockable instanceof CompoundDockable) { // V2.1 : propagate closing state to children updateCompoundChildrenState((CompoundDockable) dockable, DockableState.Location.CLOSED); } remove(dockable); removeFromTabbedGroup(dockable); // 2005/07/13 context.setDockableState(dockable, newState); dockable.getDockKey() .setLocation(DockableState.Location.CLOSED); fireDockingAction(dae, new DockableStateChangeEvent( currentState, newState)); DockingUtilities.updateResizeWeights(dockingPanel); } } else if (currentState.isHidden()) { if (isDockingActionAccepted(dae, dswe)) { if (dockable instanceof CompoundDockable) { // V2.1 : propagate closing state to children updateCompoundChildrenState((CompoundDockable) dockable, DockableState.Location.CLOSED); } remove(dockable); removeFromTabbedGroup(dockable); // 2005/07/13 context.setDockableState( dockable, new DockableState(this, dockable, DockableState.Location.CLOSED, currentState .getPosition())); dockable.getDockKey() .setLocation(DockableState.Location.CLOSED); fireDockingAction(dae, new DockableStateChangeEvent( currentState, newState)); } } else if (currentState.isFloating()) { if (isDockingActionAccepted(dae, dswe)) { if (dockable instanceof CompoundDockable) { // V2.1 : propagate closing state to children updateCompoundChildrenState((CompoundDockable) dockable, DockableState.Location.CLOSED); } remove(dockable); removeFromTabbedGroup(dockable); context.setDockableState(dockable, newState); dockable.getDockKey() .setLocation(DockableState.Location.CLOSED); fireDockingAction(dae, new DockableStateChangeEvent( currentState, newState)); } } else if (currentState.isMaximized()) { // 2006/11/20 restore(dockable); if (getDockableState(dockable).isDocked()) { // ok restore hasn't been vetoed close(dockable); // once again we close, but this time with // standard (DOCKED) behaviour } } } /** * Iterates through this compound children and properly close them (without * removing them from their parent container) */ private void updateCompoundChildrenState(CompoundDockable cDockable, DockableState.Location state) { ArrayList children = DockingUtilities .findCompoundDockableChildren(cDockable); for (int i = 0; i < children.size(); i++) { Dockable d = (Dockable) children.get(i); d.getDockKey().setLocation(state); DockableState childState = getDockableState(d); DockableState childNewState = new DockableState(this, d, state); context.setDockableState(d, childNewState); context.fireDockableStateChange(new DockableStateChangeEvent( childState, childNewState)); } } /** * Convenience method to close all dockables of a TabbedDockableContainer * except one. *

* Note : is a dockable is not allowed to close (key.isCloseEnabled() * returns false) then it won't be closed by this method. *

* If the 'exception' dockable isn't contained in a tab, then nothing will * happen. */ public void closeAllOtherDockablesInTab(Dockable exception) { TabbedDockableContainer tabContainer = DockingUtilities .findTabbedDockableContainer(exception); if (tabContainer != null) { ArrayList dockables = new ArrayList(tabContainer.getTabCount() - 1); for (int i = 0; i < tabContainer.getTabCount(); i++) { if (tabContainer.getDockableAt(i) != exception) { dockables.add(tabContainer.getDockableAt(i)); } } for (int i = 0; i < dockables.size(); i++) { Dockable d = (Dockable) dockables.get(i); if (d.getDockKey().isCloseEnabled()) { this.close(d); } } } } /** * Convenience method to close all dockables of the tabbedContainer * containing "base" (including the base dockable). *

* see also {@link #closeAllOtherDockablesInTab(Dockable)}. *

* Note : is a dockable is not allowed to close (key.isCloseEnabled() * returns false) then it won't be closed by this method. *

* If the 'base' dockable isn't contained in a tab, then nothing will * happen. * */ public void closeAllDockablesInTab(Dockable base) { TabbedDockableContainer tabContainer = DockingUtilities .findTabbedDockableContainer(base); if (tabContainer != null) { ArrayList dockables = new ArrayList(tabContainer.getTabCount()); for (int i = 0; i < tabContainer.getTabCount(); i++) { dockables.add(tabContainer.getDockableAt(i)); } for (int i = 0; i < dockables.size(); i++) { Dockable d = (Dockable) dockables.get(i); if (d.getDockKey().isCloseEnabled()) { this.close(d); } } } } /** * Toggles the position of a view between hidden (true) and docked (false). * */ public void setAutoHide(Dockable dockable, boolean hide) { /* * setAutoHide is called by user applications (or addHidenDockable() ) * and from inside the framework : - Tab actions (only when in the * DOCKED state) - DockView (listening to DockViewTitleBar property * change - key events from the desktop - the AutoHideExpandPanel * listening to DockViewTitleBar changes * * this method is not used when hiding from FLOATING state, the * "floatingToHide" method is used istead to avoid triggering unused * events */ DockKey k = dockable.getDockKey(); DockableState currentState = getDockableState(dockable); DockableState.Location currentLocation = getLocation(currentState); if (hide) { // build a relative position based on the compound container or top // container. RelativeDockablePosition position = new RelativeDockablePosition( getRelativeAncestorContainer(dockable), dockable); DockableState newState = new DockableState(this, dockable, DockableState.Location.HIDDEN, position); DockableStateWillChangeEvent dswe = new DockableStateWillChangeEvent( currentState, newState); DockingActionEvent dae = new DockingActionSimpleStateChangeEvent( this, dockable, currentLocation, DockableState.Location.HIDDEN); if (currentLocation != DockableState.Location.HIDDEN && isDockingActionAccepted(dae, dswe)) { AutoHideButton btn = autoHideButtons.get(k); if (btn == null) { btn = new AutoHideButton(); autoHideButtons.put(k, btn); int zone; if (k.getAutoHideBorder() == null) { zone = AutoHidePolicy.getPolicy() .getDefaultHideBorder().value(); } else { zone = k.getAutoHideBorder().value(); } btn.init(dockable, zone); borderPanes[zone].setVisible(true); // border may not be // visible borderPanes[zone].add(btn); borderPanes[zone].revalidate(); } else { // btn already existing, show it again int zone = btn.getZone(); borderPanes[zone].setVisible(true); // may not be visible btn.setVisible(true); borderPanes[zone].revalidate(); } // now, remove the view from the splitcontainers hide(dockable); context.setDockableState(dockable, newState); k.setLocation(DockableState.Location.HIDDEN); fireDockingAction(dae, new DockableStateChangeEvent( currentState, newState)); if (dockable instanceof CompoundDockable) { // V2.1 : also trigger a dockable state change event for // compound dockable children updateCompoundChildrenState((CompoundDockable) dockable, DockableState.Location.HIDDEN); } DockingUtilities.updateResizeWeights(dockingPanel); revalidate(); } } else { // SHOW // remove the button, show again the view DockableState newState = new DockableState(this, dockable, DockableState.Location.DOCKED); DockableStateWillChangeEvent dswe = new DockableStateWillChangeEvent( currentState, newState); RelativeDockablePosition pos = currentState.getPosition(); Container relativeContainer = pos.getRelativeAncestorContainer(); if (relativeContainer == null) { relativeContainer = dockingPanel; // safety : when a component // is loaded from workspace, // we currently loose the container information @todo fix this // container in xmlBuildAutoHideNode } DockingActionEvent dae = RelativeDockingUtilities .getInsertionDockingAction(relativeContainer, dockable, currentState, newState); if (!currentState.isDocked() && isDockingActionAccepted(dae, dswe)) { AutoHideButton btn = autoHideButtons.get(k); assert btn != null; int zone = btn.getZone(); btn.setVisible(false); expandPanel.collapse(); if (borderPanes[zone].getVisibleButtonCount() == 0) { // hide button panel if no more buttons (to avoid a // remaining visible border) borderPanes[zone].setVisible(false); revalidate(); } expandPanel.remove(dockable); show(dockable, dae); context.setDockableState(dockable, newState); k.setLocation(DockableState.Location.DOCKED); fireDockingAction(dae, new DockableStateChangeEvent( currentState, newState)); if (dockable instanceof CompoundDockable) { // V2.1 : also trigger a dockable state change event for // compound dockable children updateCompoundChildrenState((CompoundDockable) dockable, DockableState.Location.DOCKED); } DockingUtilities.updateResizeWeights(dockingPanel); revalidate(); } } } /** hide the view (used with autohide features) */ private void hide(Dockable dockable) { if (dockable == null) { throw new NullPointerException("dockable"); } DockableContainer dockableContainer = DockingUtilities .findSingleDockableContainer(dockable); if (dockableContainer == null) {// || // !dockingPanel.isAncestorOf((Component) // dockableContainer)){ throw new IllegalArgumentException("not docked"); } remove(dockable); } /** * recalculates and returns the insets taken by autoexpand borders around * the docking panel. * */ public Insets getDockingPanelInsets() { // recalculate the location and size of the mouse grabber Insets i = new Insets(0, 0, 0, 0); if (topBorderPane != null && topBorderPane.isVisible()) { i.top += topBorderPane.getHeight(); } if (leftBorderPane != null && leftBorderPane.isVisible()) { i.left += leftBorderPane.getWidth(); } if (bottomBorderPane != null && bottomBorderPane.isVisible()) { i.bottom += bottomBorderPane.getHeight(); } if (rightBorderPane != null && rightBorderPane.isVisible()) { i.right += rightBorderPane.getWidth(); } return i; } /** * Creates and returns an array of all registered dockable with their * current state. *

* Visibility states are [DockableState.CLOSED, DOCKED, HIDDEN] * * @return an array of DockableState */ public DockableState[] getDockables() { return context.getDockables(); } /** * Installs multiple drag sources. * * @see #installDockableDragSource(DockableDragSource) * * */ public void installDockableDragSources(DockableDragSource[] sources) { if (sources != null) { for (int i = 0; i < sources.length; i++) { installDockableDragSource(sources[i]); } } } /** * Uninstalls multiple drag sources. * * @see #uninstallDockableDragSource(DockableDragSource) * * */ public void uninstallDockableDragSources(DockableDragSource[] sources) { if (sources != null) { for (int i = 0; i < sources.length; i++) { uninstallDockableDragSource(sources[i]); } } } /** * This method is used by DockableContainers in order to register their * DockableDragSource(s) to the OldDragControler. *

* Adds a MouseListener and a MouseMotionListener to the * Component-DockableDragSource source. These listeners are * used to perform start-dragging-docking actions over the source component */ public void installDockableDragSource(DockableDragSource source) { ((Component) source).addMouseListener(dragControler); ((Component) source).addMouseMotionListener(dragControler); } /** * This method is used by DockableContainers in order to unregister their * DockableDragSource(s) to the OldDragControler. *

* Removes the MouseListener and MouseMotionListener added on * installDockableDragSource() * * @see #installDockableDragSource(DockableDragSource) * */ public void uninstallDockableDragSource(DockableDragSource source) { ((Component) source).removeMouseListener(dragControler); ((Component) source).removeMouseMotionListener(dragControler); } /** * Request this desktop to reset it's contained views to their preferred * size, if possible. *

* This method should be invoked when the component is realized (visible) * due to Split Panes implementation. * */ public void resetToPreferredSize() { dockingPanel.resetToPreferredSize(); } /** * Saves the current desktop configuration into an XML stream. *

* The stream is not closed at the end of the operation. *

* As of version 2.1, this method delegates the work to * DockingContext.writeXML, which will export every dekstop sharing the same * context (and not only this one) * * @see #readXML(InputStream) * */ public void writeXML(OutputStream stream) throws IOException { context.writeXML(stream); // will call back writeDesktopXML for each desktop } /* package protected for callback from DockingContext */ void writeDesktopNode(PrintWriter out) throws IOException { Window desktopWindow = SwingUtilities.getWindowAncestor(this); Point windowLocation; if (desktopWindow != null) { windowLocation = desktopWindow.getLocation(); } else { windowLocation = new Point(); // fail safe } out.println(""); out.println(""); if (dockingPanel.getComponentCount() > 0) { // only one top component (DockableContainer or SplitContainer) xmlWriteComponent(dockingPanel.getComponent(0), out); } Dockable max = getMaximizedDockable(); // 2007/01/08 if (max != null) { out.println(""); DockKey key = max.getDockKey(); out.println(""); out.println(""); } out.println(""); for (int i = 0; i < borderPanes.length; i++) { xmlWriteBorder(borderPanes[i], out); } // finish with the floating dockables xmlWriteFloating(out); // and the tab groups xmlWriteTabGroups(out); out.println(""); } private void xmlWriteBorder(AutoHideButtonPanel borderPanel, PrintWriter out) throws IOException { if (borderPanel.isVisible()) { out.println(""); Component[] comps = borderPanel.getComponents(); for (int i = 0; i < comps.length; i++) { if (comps[i] instanceof AutoHideButton) { xmlWriteBorderDockable(((AutoHideButton) comps[i]), out); } } out.println(""); } } private void xmlWriteFloating(PrintWriter out) throws IOException { // there is no list of floating : we have to fetch the dockable states // updated : we also need to store grouping information ArrayList processedDockables = new ArrayList(); Window desktopWindow = SwingUtilities.getWindowAncestor(this); Point windowLocation; if (desktopWindow != null) { windowLocation = desktopWindow.getLocation(); } else { windowLocation = new Point(); // fail safe } ArrayList floatingDockables = context.getDockablesByState( this, DockableState.Location.FLOATING); for (int i = 0; i < floatingDockables.size(); i++) { Dockable d = floatingDockables.get(i); // DockableState state = (DockableState)floatingDockables.get(i); // Dockable d = (Dockable) state.getDockable(); if (processedDockables.contains(d)) { continue; // ignore this dockable : already processed } Window w = SwingUtilities.getWindowAncestor(d.getComponent()); Rectangle r = w.getBounds(); // out.println(""); out.println(""); TabbedDockableContainer tabContainer = DockingUtilities .findTabbedDockableContainer(d); if (tabContainer != null) { // fetch all the dockables of this container for (int t = 0; t < tabContainer.getTabCount(); t++) { Dockable tabDockable = tabContainer.getDockableAt(t); processedDockables.add(tabDockable); xmlWriteFloatingDockable(tabDockable, out); } } else { // single floating processedDockables.add(d); xmlWriteFloatingDockable(d, out); } out.println(""); } } private void xmlWriteComponent(Component comp, PrintWriter out) throws IOException { if (comp instanceof SplitContainer) { xmlWriteSplit((SplitContainer) comp, out); } else if (comp instanceof TabbedDockableContainer) { xmlWriteTab((TabbedDockableContainer) comp, out); } else if (comp instanceof SingleDockableContainer) { Dockable d = ((SingleDockableContainer) comp).getDockable(); xmlWriteDockable(d, out); } else if (comp == dummyMaximedReplacer) { // 2006/12/01 (maximized // component wasn't saved) SingleDockableContainer maxContainer = (SingleDockableContainer) maximizedComponent; Dockable d = maxContainer.getDockable(); xmlWriteDockable(d, out); } } private void xmlWriteTab(TabbedDockableContainer tpane, PrintWriter out) throws IOException { out.println(""); for (int i = 0; i < tpane.getTabCount(); i++) { Dockable d = tpane.getDockableAt(i); if (d == null) { // 2008/07/05 // means that the dockable has been (and is still) maximized SingleDockableContainer maxContainer = (SingleDockableContainer) maximizedComponent; d = maxContainer.getDockable(); xmlWriteDockable(d, out); } else { xmlWriteDockable(d, out); } } out.println(""); } private void xmlWriteDockable(Dockable dockable, PrintWriter out) throws IOException { boolean isCompound = dockable instanceof CompoundDockable; if (isCompound) { out.println(""); } else { out.println(""); } DockKey key = dockable.getDockKey(); out.println(""); if (isCompound) { CompoundDockable d = (CompoundDockable) dockable; CompoundDockingPanel cdp = (CompoundDockingPanel) d.getComponent(); // no // choice // here if (cdp.getComponentCount() > 0) { // compound panels cannont have more than one child // (split/tab/single) Component child = cdp.getComponent(0); xmlWriteComponent(child, out); } } out.println(""); } private void xmlWriteCompoundDockable(CompoundDockable dockable, PrintWriter out) throws IOException { out.println(""); DockKey key = dockable.getDockKey(); out.println(""); CompoundDockingPanel cdp = (CompoundDockingPanel) dockable .getComponent(); // no choice here if (cdp.getComponentCount() > 0) { // compound panels cannont have more than one child // (split/tab/single) Component child = cdp.getComponent(0); xmlWriteComponent(child, out); } out.println(""); } private void xmlWriteBorderDockable(AutoHideButton btn, PrintWriter out) throws IOException { if (btn.isVisible()) { Dockable dockable = btn.getDockable(); xmlWriteDockableWithRelativePosition(dockable, out); } } private void xmlWriteDockableWithRelativePosition(Dockable dockable, PrintWriter out) throws IOException { DockableState state = context.getDockableState(dockable); RelativeDockablePosition position = (RelativeDockablePosition) state .getPosition(); boolean isCompound = dockable instanceof CompoundDockable; if (isCompound) { out.println(""); } else { out.println(""); } DockKey key = dockable.getDockKey(); out.println(""); out.println(""); if (isCompound) { CompoundDockable d = (CompoundDockable) dockable; CompoundDockingPanel cdp = (CompoundDockingPanel) d.getComponent(); // no // choice // here if (cdp.getComponentCount() > 0) { // compound panels cannont have more than one child // (split/tab/single) Component child = cdp.getComponent(0); xmlWriteComponent(child, out); } } out.println(""); } private void xmlWriteCompoundDockableWithRelativePosition( CompoundDockable dockable, PrintWriter out) { /* * The autohide component is a compound dockable : we'll have to save * its position then traverse its children */ DockableState state = context.getDockableState(dockable); RelativeDockablePosition position = (RelativeDockablePosition) state .getPosition(); DockKey key = dockable.getDockKey(); out.println(""); out.println(""); out.println(""); } private void xmlWriteFloatingDockable(Dockable dockable, PrintWriter out) throws IOException { DockableState state = context.getDockableState(dockable); RelativeDockablePosition position = (RelativeDockablePosition) state .getPosition(); boolean isCompound = dockable instanceof CompoundDockable; if (isCompound) { out.println(""); } else { out.println(""); } DockKey key = dockable.getDockKey(); out.println(""); out.println(""); DockableState prev = previousFloatingDockableStates.get(dockable); out.println(""); if (isCompound) { CompoundDockable d = (CompoundDockable) dockable; CompoundDockingPanel cdp = (CompoundDockingPanel) d.getComponent(); // no // choice // here if (cdp.getComponentCount() > 0) { // compound panels cannont have more than one child // (split/tab/single) Component child = cdp.getComponent(0); xmlWriteComponent(child, out); } } out.println(""); } private void xmlWriteSplit(SplitContainer split, PrintWriter out) throws IOException { double location; if (split.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) { location = split.getLeftComponent().getWidth() / (double) (split.getWidth() - split.getDividerSize()); // 2006/09/25 } else { location = split.getTopComponent().getHeight() / (double) (split.getHeight() - split.getDividerSize()); } out.println(""); xmlWriteComponent(split.getLeftComponent(), out); xmlWriteComponent(split.getRightComponent(), out); out.println(""); } /** * TabGroups are the memory of tabs (even for hidden or floating dockables) * used to put them back on the right tab when docked again */ private void xmlWriteTabGroups(PrintWriter out) throws IOException { // there is redundant information in the tabbedGroups Map... so we have // to simplify it ArrayList uniqueGroups = new ArrayList(); ArrayList processedDockables = new ArrayList(); Iterator it = tabbedGroups.keySet().iterator(); while (it.hasNext()) { Dockable d = it.next(); if (!processedDockables.contains(d)) { processedDockables.add(d); LinkedList tabList = tabbedGroups.get(d); Iterator listIt = tabList.iterator(); while (listIt.hasNext()) { Dockable d2 = (Dockable) listIt.next(); if (!processedDockables.contains(d2)) { processedDockables.add(d2); } } uniqueGroups.add(tabList); } } out.println(""); for (int i = 0; i < uniqueGroups.size(); i++) { out.println(""); LinkedList group = (LinkedList) uniqueGroups.get(i); Iterator listIt = group.iterator(); while (listIt.hasNext()) { Dockable d = (Dockable) listIt.next(); xmlWriteDockableTab(d, out); } out.println(""); } out.println(""); } private void xmlWriteDockableTab(Dockable dockable, PrintWriter out) throws IOException { out.println(""); DockKey key = dockable.getDockKey(); out.println(""); out.println(""); } /** * Reads an XML encoded stream as the new desktop configuration. *

* When the method returns, the desktop is totally reconfigured with * posiibly different dockable at different positions. *

* Note : The DockKeys of the stream must be registered * with the {@link #registerDockable(Dockable) registerDockable} method, * prior readXML.
* This is the case if the desktop is already open and dockables laid out, * but might not be the case if this method is used at application startup * to populate an empty desktop. * *

* Dismisses all visible dockables (docked and auto-hidden), and clear their * DockableState. *

* The stream is not closed at the end of the operation. * * @see #writeXML(OutputStream) * @see #registerDockable(Dockable) * */ public void readXML(InputStream in) throws ParserConfigurationException, IOException, SAXException { context.readXML(in); } /** removes every dockables from this desktop */ public void clear() { dockingPanel.removeAll(); for (int i = 0; i < borderPanes.length; i++) { borderPanes[i].removeAll(); borderPanes[i].setVisible(false); } boolean wasHeavyMaximized = false; if (maximizedComponent != null) { // clean up maximization state if (DockingPreferences.isLightWeightUsageEnabled()) { remove(maximizedComponent); // remove the single dockable // container } else { remove(maximizedComponent.getParent()); // remove the awt panel wasHeavyMaximized = true; } maximizedComponent = null; // 2006/11/20 ooops ! } autoHideButtons.clear(); expandPanel.collapse(); expandPanel.clear(); previousFloatingDockableStates.clear(); tabbedGroups.clear(); // clear the floatables windows ArrayList floatingDockables = context.getDockablesByState( this, DockableState.Location.FLOATING); for (int i = 0; i < floatingDockables.size(); i++) { Dockable d = (Dockable) floatingDockables.get(i); remove(d); } } /* package protected */ void readDesktopNode(Element desktopElement) throws SAXException { /* * called back by DockingContext to read (and install) a desktop * configuration from an xml stream */ NodeList children = desktopElement.getChildNodes(); for (int i = 0, len = children.getLength(); i < len; i++) { Node child = children.item(i); xmlBuildRootNode(child); } DockingUtilities.updateResizeWeights(dockingPanel); // 2006/12/01 revalidate(); } private void xmlBuildRootNode(Node node) throws SAXException { if (node.getNodeType() == Node.ELEMENT_NODE) { Element elt = (Element) node; String name = elt.getNodeName(); if (name.equals("DockingPanel")) { // only one child at most NodeList children = elt.getChildNodes(); for (int i = 0, len = children.getLength(); i < len; i++) { xmlBuildDockingPanelNode(elt.getChildNodes().item(i)); } try { final int x = Integer.parseInt(elt.getAttribute("x")); final int y = Integer.parseInt(elt.getAttribute("y")); final int width = Integer.parseInt(elt .getAttribute("width")); final int height = Integer.parseInt(elt .getAttribute("height")); Window w = SwingUtilities .getWindowAncestor(DockingDesktop.this); if (w != null && w.isVisible()) { w.setBounds(x, y, width, height); } // will make window bounce :-( addAncestorListener(new AncestorListener() { @Override public void ancestorAdded(AncestorEvent event) { Window w = SwingUtilities .getWindowAncestor(DockingDesktop.this); w.setBounds(x, y, width, height); removeAncestorListener(this); } @Override public void ancestorRemoved(AncestorEvent event) { } @Override public void ancestorMoved(AncestorEvent event) { } }); } catch (Exception e) { log.debug("", e); } } else if (name.equals("Border")) { int zone = Integer.parseInt(elt.getAttribute("zone")); AutoHideButtonPanel borderPanel = borderPanes[zone]; borderPanel.setVisible(true); // border may not be visible NodeList children = elt.getElementsByTagName("Dockable"); for (int i = 0, len = children.getLength(); i < len; i++) { xmlBuildAutoHideNode(borderPanel, (Element) children.item(i)); } borderPanel.revalidate(); } else if (name.equals("Floating")) { int x = Integer.parseInt(elt.getAttribute("x")); int y = Integer.parseInt(elt.getAttribute("y")); int width = Integer.parseInt(elt.getAttribute("width")); int height = Integer.parseInt(elt.getAttribute("height")); Rectangle r = new Rectangle(x, y, width, height); GraphicsEnvironment ge = GraphicsEnvironment .getLocalGraphicsEnvironment(); GraphicsDevice[] gs = ge.getScreenDevices(); for (int j = 0; j < gs.length; j++) { GraphicsDevice gd = gs[j]; GraphicsConfiguration[] gc = gd.getConfigurations(); for (int i = 0; i < gc.length; i++) { if (gc[i].getBounds().contains(r)) { // log.error(r + " is on screen[" + j + "] " // + gc[i].getBounds()); } else { // log.error(r + " is NOT on screen[" + j + "] " // + gc[i].getBounds()); } } } NodeList children = elt.getElementsByTagName("Dockable"); xmlBuildFloatingNode(children, new Rectangle(x, y, width, height)); // 2005/10/10 /* * for (int i = 0, len = children.getLength(); i < len; i++) { * xmlBuildFloatingNode((Element)children.item(i), new * Rectangle(x, y, width, height)); } */ } else if (name.equals("TabGroups")) { NodeList children = elt.getElementsByTagName("TabGroup"); xmlBuildTabGroup(children); // 2005/10/10 } else { throw new SAXNotRecognizedException(name); } } } private void xmlBuildAutoHideNode(AutoHideButtonPanel borderPanel, Element dockableElt) throws SAXException { Element hideElt = (Element) dockableElt.getElementsByTagName( "RelativePosition").item(0); float x = Float.parseFloat(hideElt.getAttribute("x")); float y = Float.parseFloat(hideElt.getAttribute("y")); float w = Float.parseFloat(hideElt.getAttribute("w")); float h = Float.parseFloat(hideElt.getAttribute("h")); RelativeDockablePosition position = new RelativeDockablePosition(x, y, w, h); AutoHideButton btn = new AutoHideButton(); Dockable dockable = xmlGetDockable(dockableElt); autoHideButtons.put(dockable.getDockKey(), btn); context.setDockableState(dockable, new DockableState(this, dockable, DockableState.Location.HIDDEN, position)); dockable.getDockKey().setLocation(DockableState.Location.HIDDEN); btn.init(dockable, borderPanel.getBorderZone()); borderPanel.add(btn); if (dockable instanceof CompoundDockable) { // check for children and build them xmlBuildCompoundDockable((CompoundDockable) dockable, dockableElt, DockableState.Location.HIDDEN); } } /* * private void xmlBuildFloatingNode(Element dockableElt, Rectangle bounds) * { */ private void xmlBuildFloatingNode(NodeList dockables, Rectangle bounds) throws SAXException { // @todo not optimal.. we should refactor it oustide this method Window desktopWindow = SwingUtilities.getWindowAncestor(this); if (desktopWindow != null) { Point windowLocation = desktopWindow.getLocation(); bounds.x += windowLocation.x; // position is relative bounds.y += windowLocation.y; } // JDialog dialog = null; FloatingDockableContainer fdc = null; TabbedDockableContainer tdc = null; if (dockables.getLength() > 1) { // it's a floating tab tdc = DockableContainerFactory.getFactory() .createTabbedDockableContainer(); tdc.installDocking(this); ((JTabbedPane) tdc).addChangeListener(focusHandler); // our best way // to track // selection // (focus) // changes } Dockable baseDockable = null; // used when there are tabs for (int i = 0; i < dockables.getLength(); i++) { Element dockableElt = (Element) dockables.item(i); Element hideElt = (Element) dockableElt.getElementsByTagName( "RelativePosition").item(0); float x = Float.parseFloat(hideElt.getAttribute("x")); float y = Float.parseFloat(hideElt.getAttribute("y")); float w = Float.parseFloat(hideElt.getAttribute("w")); float h = Float.parseFloat(hideElt.getAttribute("h")); RelativeDockablePosition position = new RelativeDockablePosition( dockingPanel, x, y, w, h); Dockable dockable = xmlGetDockable(dockableElt); if (i == 0) { baseDockable = dockable; } Element previousState = (Element) dockableElt.getElementsByTagName( "PreviousState").item(0); int istate = Integer.parseInt(previousState.getAttribute("state")); DockableState state = new DockableState(this, dockable, DockableState.getLocationFromInt(istate), position); storePreviousFloatingState(dockable, state); if (fdc == null) { // if (dialog == null}){ // dialog = (JDialog) createFloatingDockableContainer(dockable); fdc = createFloatingDockableContainer(dockable); } else { // add as a tab if (tdc.getTabCount() == 0) { // first tab : replace the current DetachedDockView by the // tab container // not very efficient... @todo : sort this out DockableContainer base = DockingUtilities .findDockableContainer(baseDockable); DockingUtilities.replaceChild( ((Component) base).getParent(), (Component) base, (Component) tdc); tdc.addDockable(baseDockable, 0); } tdc.addDockable(dockable, tdc.getTabCount()); } context.setDockableState(dockable, new DockableState(this, dockable, DockableState.Location.FLOATING, position)); dockable.getDockKey().setLocation(DockableState.Location.FLOATING); if (dockable instanceof CompoundDockable) { // check for children and build them xmlBuildCompoundDockable((CompoundDockable) dockable, dockableElt, DockableState.Location.FLOATING); } } DockingUtilities.setBounds(fdc, bounds); // dialog.setBounds(bounds); // dialog.validate(); // dialog.setVisible(true); DockingUtilities.validate(fdc); DockingUtilities.setVisible(fdc, true); } private void xmlBuildDockingPanelNode(Node node) throws SAXException { if (node.getNodeType() == Node.ELEMENT_NODE) { Component comp = xmlCreateComponent((Element) node, DockableState.Location.DOCKED); if (comp != null) { dockingPanel.add(comp, BorderLayout.CENTER); } } } private Component xmlCreateComponent(Element elt, DockableState.Location dockableLocation) throws SAXException { if (elt.getNodeName().equals("Split")) { SplitContainer split = xmlBuildSplitContainer(elt, dockableLocation); return split; } else if (elt.getNodeName().equals("Dockable")) { Dockable d = xmlGetDockable(elt); SingleDockableContainer sdc = DockableContainerFactory .getFactory() .createDockableContainer( d, DockableContainerFactory.ParentType.PARENT_SPLIT_CONTAINER); context.setDockableState(d, new DockableState(this, d, dockableLocation)); d.getDockKey().setLocation(dockableLocation); sdc.installDocking(this); if (d instanceof CompoundDockable) { // check for children and build them xmlBuildCompoundDockable((CompoundDockable) d, elt, dockableLocation); } return (Component) sdc; } else if (elt.getNodeName().equals("TabbedDockable")) { TabbedDockableContainer tdc = xmlBuildTabbedDockableContainer(elt, dockableLocation); return (Component) tdc; } else if (elt.getNodeName().equals("MaximizedDockable")) { // this should be the last element from DockingPanel node Dockable d = xmlGetDockable(elt); maximize(d); return null; } else { throw new SAXNotRecognizedException(elt.getNodeName()); } } private void xmlBuildCompoundDockable(CompoundDockable dockable, Element compoundElt, DockableState.Location dockableLocation) throws SAXException { /* a compound dockable can hold a sub dockable (or split/tabs) */ CompoundDockingPanel compoundPanel = (CompoundDockingPanel) dockable .getComponent(); compoundPanel.removeAll(); // cleanup the compound at every workspace // reloading 2007/01/08 NodeList children = compoundElt.getChildNodes(); for (int i = 0, len = children.getLength(); i < len; i++) { Node node = children.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { Element elt = (Element) node; if (elt.getNodeName().equals("Key")) { // ignore : it's the key of the compound dockable } else { Component comp = xmlCreateComponent(elt, dockableLocation); compoundPanel.add(comp, BorderLayout.CENTER); return; // no more than a single child } } } } private SplitContainer xmlBuildSplitContainer(Node node, DockableState.Location dockableLocation) throws SAXException { Element elt = (Element) node; int orientation = Integer.parseInt(elt.getAttribute("orientation")); String loc = elt.getAttribute("location"); double location = 0.5; if (loc != null && !loc.equals("")) { location = Double.parseDouble(loc); } SplitContainer split = new SplitContainer(orientation); split.setDividerLocation(location); boolean left = true; for (int i = 0; i < node.getChildNodes().getLength(); i++) { Node child = node.getChildNodes().item(i); if (child.getNodeType() == Node.ELEMENT_NODE) { Component comp = xmlCreateComponent((Element) child, dockableLocation); if (left) { split.setLeftComponent(comp); left = false; } else { split.setRightComponent(comp); } } } return split; } private TabbedDockableContainer xmlBuildTabbedDockableContainer( Element elt, DockableState.Location dockableLocation) throws SAXException { TabbedDockableContainer tdc = DockableContainerFactory.getFactory() .createTabbedDockableContainer(); tdc.installDocking(this); ((JTabbedPane) tdc).addChangeListener(focusHandler); // our best way to // track // selection // (focus) // changes Dockable base = null; for (int i = 0; i < elt.getChildNodes().getLength(); i++) { Node child = elt.getChildNodes().item(i); if (child.getNodeType() == Node.ELEMENT_NODE) { Dockable d = xmlGetDockable((Element) child); if (base == null) { base = d; } context.setDockableState(d, new DockableState(this, d, dockableLocation)); d.getDockKey().setLocation(dockableLocation); tdc.addDockable(d, tdc.getTabCount()); // update the tab group if (base != d) { addToTabbedGroup(base, d); } if (d instanceof CompoundDockable) { // check for children and build them is needed xmlBuildCompoundDockable((CompoundDockable) d, (Element) child, dockableLocation); } } } return tdc; } private Dockable xmlGetDockable(Element dockableElt) { Element key = (Element) dockableElt.getElementsByTagName("Key").item(0); String name = key.getAttribute("dockName"); Dockable dockable = context.getDockableByKey(name); if (dockable == null) { throw new NullPointerException("Dockable " + name + " not registered"); } return dockable; } /** rebuild the tabbedGroups structure (memory of tabbed dockables) */ private void xmlBuildTabGroup(NodeList group) { // this pass is useful for hidden dockable that need to be reassociated // with their tab group. // (tabbed dockable don't need it as this information is implicit // (during xml tab creation) for (int i = 0; i < group.getLength(); i++) { Element groupElt = (Element) group.item(i); NodeList dockables = groupElt.getElementsByTagName("Dockable"); Dockable base = null; for (int j = 0; j < dockables.getLength(); j++) { Element dockableElt = (Element) dockables.item(j); Dockable d = xmlGetDockable(dockableElt); if (j == 0) { base = d; } else { addToTabbedGroup(base, d); } } } } /** * Adds a dockable in the docking desktop. *

* This method can be used mainly in two situations : *

    *
  • the desktop is empty (when not empty, you can use split() or * createTab() to add a dockable relatively to another) *
  • the dockable is currently closed, and it must be shown again *
  • note that if the desktop is not empty, the dockable will be added in * the bottom of the desktop (equivalent to addDockable(dockable * 0,0.8,1,0.2)). *
*/ public void addDockable(Dockable dockable) { /* * addDockable isn't called internally by the API : just for user * applications */ addDockable(dockable, new RelativeDockablePosition(0, 0.8, 0.5, 0.2)); } /** * Adds a dockable in the docking desktop, and tries to respect the relative * positionning provided. *

* This method is used to reposition a closed dockable at its previous * location on the desktop. As it relies on the * Component.findComponentAt(Point) method , the desktop must already be * visible. * *

* The preferred way to obtain a particular visual docking configuration is * to use a combination of add(), split() and createTab() methods, as these * methods do not rely on an interpretation (and approximation) of * constraints. * *

* Precision of constraints : as the docking management is based on a mix of * horizontal and vertical splitting zones, it is not always possible to * respect the constraints given. *

* The current implementation will do the following : *

    *
  • find the splitter containing the given center (x + width/2, y + * height/2) of the dockable *
  • try to respect the x and y, constraints. *
  • try to respect the width and height constraints. *
  • sub-split the splitter (horizontally or vertically) zone and position * the Dockable in the most appropriate zone (top, left, bottom, right). *
* * @param dockable * the dockable to add (must not be already visible) * @param position * relative position of the dockable * * @throws IllegalArgumentException * if the dockable already belongs to the desktop containment * hierarchy. */ public void addDockable(Dockable dockable, RelativeDockablePosition position) { /* * addDockable isn't called internally by the API : just for user * applications */ if (this.isAncestorOf(dockable.getComponent())) { throw new IllegalArgumentException( "Dockable is already contained in the desktop"); } registerDockable(dockable); if (DockingUtilities.findSingleDockableContainer(dockable) != null) { remove(dockable); } DockableState newState = new DockableState(this, dockable, DockableState.Location.DOCKED, position); DockableState currentState = getDockableState(dockable); DockableState.Location currentLocation = getLocation(currentState); DockableStateWillChangeEvent dswe = new DockableStateWillChangeEvent( currentState, newState); DockingActionEvent dae = new DockingActionAddDockableEvent(this, dockable, currentLocation, newState.getLocation(), dockingPanel); if (isDockingActionAccepted(dae, dswe)) { @SuppressWarnings("deprecation") SingleDockableContainer sdc = RelativeDockingUtilities .insertDockable(dockingPanel, dockable, position); sdc.installDocking(this); context.setDockableState(dockable, newState); dockable.getDockKey().setLocation(DockableState.Location.DOCKED); DockableStateChangeEvent dse = new DockableStateChangeEvent( currentState, newState); fireDockingAction(dae, dse); DockingUtilities.updateResizeWeights(dockingPanel); } } /** * Replaces a dockable by another one. *

* Useful for example to reserve some space on a desktop by using a * "placeholder' when other dockables aren't visible (Multiple Tabbed * Document Interface with always a dockable visible even when no document * is loaded). *

* Implementation note : this method assumes only the "base" dockable is * visible (the replacer must be in the CLOSED state). It also assumes the * base dockable isn't a compound dockable. These limitations will be * removed in a later release. * *

* There is currently no DnD gesture associated to this action (although the * "HotSwap" gesture would be a good candidate). So this method currently * doesn't trigger any event (state change, action), yet it could change * later. * * @since 2.1 * @throws IllegalArgumentException * when dockables aren't in the appropriate state or hierarchy. */ public void replace(Dockable base, Dockable replacer) { DockableState baseState = context.getDockableState(base); DockableState replacerState = context.getDockableState(replacer); DockableState newBaseState = new DockableState( replacerState.getDesktop(), base, replacerState.getLocation()); DockableState newReplacerState = new DockableState( baseState.getDesktop(), replacer, baseState.getLocation()); TabbedDockableContainer tdcBase = DockingUtilities .findTabbedDockableContainer(base); if (!replacerState.isClosed()) { throw new IllegalArgumentException("replacer isn't closed"); } if (base instanceof CompoundDockable) { throw new IllegalArgumentException( "base cannot be a compound dockable"); } if (tdcBase != null) { int iBase = tdcBase.indexOfDockable(base); tdcBase.removeDockable(base); tdcBase.addDockable(replacer, iBase); } else { SingleDockableContainer sdcBase = DockingUtilities .findSingleDockableContainer(base); Container sdcBaseParent = ((Component) sdcBase).getParent(); if (sdcBaseParent instanceof SplitContainer) { SplitContainer split = (SplitContainer) sdcBaseParent; boolean isLeft = split.getLeftComponent() == sdcBase; SingleDockableContainer sdc = DockableContainerFactory .getFactory() .createDockableContainer( replacer, DockableContainerFactory.ParentType.PARENT_SPLIT_CONTAINER); sdc.installDocking(this); if (isLeft) { split.setLeftComponent((Component) sdc); } else { split.setRightComponent((Component) sdc); } split.revalidate(); } else if (sdcBaseParent instanceof DockingPanel) { // a single component DockingPanel dp = (DockingPanel) sdcBaseParent; dp.remove(0); SingleDockableContainer sdc = DockableContainerFactory .getFactory() .createDockableContainer( replacer, DockableContainerFactory.ParentType.PARENT_SPLIT_CONTAINER); sdc.installDocking(this); dp.add((Component) sdc, BorderLayout.CENTER); dp.revalidate(); } else if (sdcBaseParent instanceof CompoundDockingPanel) { // a single component CompoundDockingPanel cdp = (CompoundDockingPanel) sdcBaseParent; cdp.remove(0); SingleDockableContainer sdc = DockableContainerFactory .getFactory() .createDockableContainer( replacer, DockableContainerFactory.ParentType.PARENT_SPLIT_CONTAINER); sdc.installDocking(this); cdp.add((Component) sdc, BorderLayout.CENTER); cdp.revalidate(); } else { throw new RuntimeException("Wrong container hierarchy : " + sdcBaseParent); } } // swap states context.setDockableState(base, newBaseState); context.setDockableState(replacer, newReplacerState); } /* * small utility method to avoid bloating code everywhere (return a default * state value if state object is null) */ private static DockableState.Location getLocation(DockableState state) { if (state == null) { return DockableState.Location.CLOSED; } else { return state.getLocation(); } } /** * Adds a dockable inside a compound dockable. *

* This is the method to start a nesting hierarchy inside a compound * dockable (once the first dockable is added, you add subsequent dockables * with standard split/createTab methods) *

    *
  • note that if the compound dockable is not empty, this method will * raise an exception. *
* * @since 2.1 */ public void addDockable(CompoundDockable base, Dockable dockable) { registerDockable(dockable); DockableState currentState = getDockableState(dockable); DockableState.Location currentLocation = getLocation(currentState); DockableState newState = new DockableState(this, dockable, DockableState.Location.DOCKED); DockableStateWillChangeEvent dswe = new DockableStateWillChangeEvent( currentState, newState); CompoundDockingPanel panel = (CompoundDockingPanel) base.getComponent(); DockingActionEvent dae = new DockingActionAddDockableEvent(this, dockable, currentLocation, newState.getLocation(), panel); if (isDockingActionAccepted(dae, dswe)) { DockableContainer dockableContainer = DockableContainerFactory .getFactory().createDockableContainer(dockable, DockableContainerFactory.ParentType.PARENT_DESKTOP); dockableContainer.installDocking(this); // TODO : check and raise exception if not empty panel.add((JComponent) dockableContainer, BorderLayout.CENTER); context.setDockableState(dockable, newState); dockable.getDockKey().setLocation(DockableState.Location.DOCKED); fireDockingAction(dae, new DockableStateChangeEvent(currentState, newState)); } } /** * Evaluates and returns the preferred size of the desktop, according to its * contents and auto-hide borders. */ public Dimension getPreferredSize() { Insets i = getDockingPanelInsets(); Dimension dim = dockingPanel.getPreferredSize(); dim.width += i.left + i.right; dim.height += i.top + i.bottom; return dim; } /** * Adds a new DockableStateChangeListener to this desktop. *

* DockableStateChange Events are triggered after the state change. * *

* As of version 2.0 of the framework, this method can also be replaced by * adding a propertychangeListener on the DockKey object (and react to its * DockableState property). * * */ public void addDockableStateChangeListener( DockableStateChangeListener listener) { context.addDockableStateChangeListener(listener); } /** * Removes a DockableStateChangeListener from this desktop. * */ public void removeDockableStateChangeListener( DockableStateChangeListener listener) { context.removeDockableStateChangeListener(listener); } /** * Adds a new DockableStateWillChangeListener to this desktop. *

* DockableStateWillChange Events are triggered before the state * change, and are vetoable. * */ public void addDockableStateWillChangeListener( DockableStateWillChangeListener listener) { context.addDockableStateWillChangeListener(listener); } /** * Removes a DockableStateWillChangeListener from this desktop. * */ public void removeDockableStateWillChangeListener( DockableStateWillChangeListener listener) { context.removeDockableStateWillChangeListener(listener); } /** * Adds a new DockingActionListener to this desktop. *

* DockingAction Events are triggered before and after any docking action * (split, tab, close, hide...) and allow for precise tracking (and vetoing) * of these operations. * * @see #removeDockingActionListener(DockingActionListener) */ public void addDockingActionListener(DockingActionListener listener) { context.addDockingActionListener(listener); } /** * Removes a DockingActionListener from this desktop. * * @see #addDockingActionListener(DockingActionListener) */ public void removeDockingActionListener(DockingActionListener listener) { context.removeDockingActionListener(listener); } /** * Adds a new DockableSelectionListener to this desktop. *

* DockableSelection Events are triggered when a dockable takes the focus. * */ public void addDockableSelectionListener(DockableSelectionListener listener) { context.addDockableSelectionListener(listener); } /** * Removes a DockableSelectionListener from this desktop. * */ public void removeDockableSelectionListener( DockableSelectionListener listener) { context.removeDockableSelectionListener(listener); } /** * Registers and add a dockable on an auto-hide border. *

* this method should be called at startup time (when the dockable isn't yet * displayed). to toggle a dockable from docked to auto-hide, please use * setAutoHide(Dockable, boolean) instead. * *

* However, this method will not fail if the dockable is already displayed : * in that case, it will delegate autohide to setAutoHide(Dockable, * boolean), thus dropping the dockedPosition argument. * * @param dockable * the dockable to add (to select the border where the dockable * will be positionned, use the DockKey.setAutoHideBorder mehod * * @param dockedPosition * relative positionning (may be null) indicating where to dock * the dockable when leaving its auto-hide border. * */ public void addHiddenDockable(Dockable dockable, RelativeDockablePosition dockedPosition) { /* not used from inside the API : only for user applications */ DockableState currentState = getDockableState(dockable); // should be // null if (currentState == null || currentState.isClosed()) { // 2007/03/19 // reformulate // tests // ok, that's the normal use case } else if (currentState.isHidden()) { // already hidden... avoid ! return; // should I throw an exception ? } else if (currentState.isDocked()) { // if (currentState != null && !currentState.isHidden()){ // delegate autohide to the appropriate method setAutoHide(dockable, true); return; } registerDockable(dockable); currentState = getDockableState(dockable); // now should be CLOSED DockableState.Location currentLocation = getLocation(currentState); DockableState newState = new DockableState(this, dockable, DockableState.Location.HIDDEN, dockedPosition); DockableStateWillChangeEvent dswe = new DockableStateWillChangeEvent( currentState, newState); DockingActionEvent dae = new DockingActionSimpleStateChangeEvent(this, dockable, currentLocation, DockableState.Location.HIDDEN); DockKey k = dockable.getDockKey(); if (currentLocation != DockableState.Location.HIDDEN && isDockingActionAccepted(dae, dswe)) { AutoHideButton btn = autoHideButtons.get(k); if (btn == null) { btn = new AutoHideButton(); autoHideButtons.put(k, btn); int zone; if (k.getAutoHideBorder() == null) { zone = AutoHidePolicy.getPolicy().getDefaultHideBorder() .value(); } else { zone = k.getAutoHideBorder().value(); } btn.init(dockable, zone); borderPanes[zone].setVisible(true); // border may not be visible borderPanes[zone].add(btn); borderPanes[zone].revalidate(); } else { // btn already existing, show it again int zone = btn.getZone(); borderPanes[zone].setVisible(true); // may not be visible btn.setVisible(true); borderPanes[zone].revalidate(); } context.setDockableState(dockable, newState); dockable.getDockKey().setLocation(DockableState.Location.HIDDEN); fireDockingAction(dae, new DockableStateChangeEvent(currentState, newState)); revalidate(); } } /** * Changes the width of a dockable (the dockable must already be visible). * *

* Note that this method works by modifying the divider location of the * nearest SplitContainer ancestor of the dockable (the first splitted * horizontally). * *

* As this method must be called when the desktop is visible, a simple way * to do this is to add a window listener to the parent frame of the * desktop, and call this method from the windowOpened(WindowEvent) * notification. * * @param width * new width (if between 0 and 1, width is taken as a * proportional width, otherwise it is a pixel width. * * */ public void setDockableWidth(Dockable dockable, double width) { SplitContainer split = DockingUtilities.getSplitPane(dockable, JSplitPane.HORIZONTAL_SPLIT); if (split == null) return; if (((Container) split.getLeftComponent()).isAncestorOf(dockable .getComponent())) { split.setDividerLocation(width); } else { split.setDividerLocation(1.0 - width); } } /** * Changes the height of a dockable (the dockable must already be visible). * *

* Note that this method works by modifying the divider location of the * nearest SplitContainer ancestor of the dockable (the first splitted * vertically). * *

* As this method must be called when the desktop is visible, a simple way * to do this is to add a window listener to the parent frame of the * desktop, and call this method from the windowOpened(WindowEvent) * notification. * * @param height * new height (if between 0 and 1, height is taken as a * proportional height, otherwise it is a pixel height. * * */ public void setDockableHeight(Dockable dockable, double height) { SplitContainer split = DockingUtilities.getSplitPane(dockable, JSplitPane.VERTICAL_SPLIT); if (split == null) return; if (((Container) split.getTopComponent()).isAncestorOf(dockable .getComponent())) { split.setDividerLocation(height); } else { split.setDividerLocation(1 - height); } } /** * Updates the resizing behaviour of the desktop in order to resize this * dockable (and keep others at fixed size). *

* This method should be called at least once (prior to showing the desktop) * with an already docked dockable. *

* If the dockable doesn't belong to the desktop containment hierarchy, this * method will do nothing. * * @deprecated use setResizeWeight() in every dockKey for a better resizing * behaviour * */ public void setAutoResizableDockable(Dockable dockable) { /* this.autoResizeableDockable = dockable; */ DockingUtilities.updateResizeWeights(dockingPanel); } /** * Registers a dockable as belonging to a tab group. *

* It is used to have a memory of grouped (tabbed) dockables in order to * keep the group together when dockable are restored from auto-hide mode. *

* This method is generally called by the tabbed container management, and * not directly by the developper. * *

* However, there is a case where calling this method can be usefull : when, * at startup, a desktop is built with multiple hidden dockables, and the * developper wants them to be grouped in a tab container when they are * restored to the desktop. * *

* note that the method is symetric when a group is empty : it such a case * base and newTab args can be swapped. * * @param base * an already tabbed dockable * @param newTab * a dockable to add to the tab group * * @since 1.1.2 */ public void addToTabbedGroup(Dockable base, Dockable newTab) {// 2005/07/13 /* * this method is called when a dockable is added to a * dockableTabbedContainer */ LinkedList group = tabbedGroups.get(base); if (group == null) { group = new LinkedList(); group.add(base); tabbedGroups.put(base, group); } if (!group.contains(newTab)) { group.add(newTab); tabbedGroups.put(newTab, group); } } /** * Unregisters a dockable from its current tab group (when it's removed from * it). *

* For an application developper, there should be no need to call this * method as it is managed internally by the framework, unless the * developper wants to explicitely remove a component from a tab group when * this component is in the auto-hide state. * * @since 1.1.2 */ public void removeFromTabbedGroup(Dockable dockable) { // 2005/07/13 /* package protected */ /* * This method is invoked when a component is dragged outside of a tab * group : meaning the user doesn't want anymore this dockable to be * grouped in that tab. */ LinkedList group = tabbedGroups.get(dockable); if (group != null) { tabbedGroups.remove(dockable); group.remove(dockable); if (group.size() == 1) { // end of grouping as there are no more // dockables linked. Dockable d = (Dockable) group.removeFirst(); tabbedGroups.remove(d); } } } /** * Creates the autohide expand panel to be used in this desktop. *

* This method gives a chance to the developer to override expand panel * creation and provide a custom subclass. */ protected AutoHideExpandPanel createAutoHideExpandPanel() { return new AutoHideExpandPanel(); } /** * used to track focus changes for DockableSelection events */ private class FocusHandler implements PropertyChangeListener, ChangeListener { /** this one is never null (except at first time) */ Dockable lastFocusedDockable; /** this one can be null between focusLost() and focusGained() */ Dockable currentDockable; // focusOwner public void propertyChange(PropertyChangeEvent e) { Component c = (Component) e.getNewValue(); while (c != null && !(c instanceof SingleDockableContainer)) { c = c.getParent(); } if (c instanceof SingleDockableContainer) { SingleDockableContainer sdc = (SingleDockableContainer) c; currentDockable = sdc.getDockable(); if (sdc.getDockable() != lastFocusedDockable) { context.fireDockableSelectionChange(new DockableSelectionEvent( sdc.getDockable())); } lastFocusedDockable = sdc.getDockable(); } else { // c == null currentDockable = null; } } // This method is called whenever the selected tab of all // TabbedDockableContainers changes public void stateChanged(ChangeEvent evt) { // our only problem is at startup : the focus may be out of the // tabbed pane // and we are firing a false selection event. // @todo correct this behaviour by checking if the focus is not // already // outside this component JTabbedPane pane = (JTabbedPane) evt.getSource(); TabbedDockableContainer tdc = ((TabbedDockableContainer) pane); Dockable selDockable = tdc.getSelectedDockable(); if (selDockable == null) { // this may happen when maximization // occurs // ignore } else { currentDockable = selDockable; if (selDockable != lastFocusedDockable) { lastFocusedDockable = selDockable; context.fireDockableSelectionChange(new DockableSelectionEvent( selDockable)); } } } Dockable getCurrentDockable() { return currentDockable; } } /** Returns the name of this desktop (used by workspace management) */ public String getDesktopName() { return desktopName; } /** Updates the name of this desktop (used by workspace management) */ public void setDesktopName(String desktopName) { this.desktopName = desktopName; } /** * Returns the docking context used by this desktop (might be shared with * other desktop). * * @since 2.1 */ public DockingContext getContext() { return context; } /** * Updates the docking context used by this desktop. *

* Warning : this method should only be used by the framework itself : * changing a context "live" can have unpredicted and undesired side effect. * * @since 2.1 */ public void setContext(DockingContext context) { this.context = context; } /** * returns the currently maximized dockable (or null if no dockable is in * that state) */ public Dockable getMaximizedDockable() { if (maximizedComponent == null) { return null; } else { SingleDockableContainer maxContainer = (SingleDockableContainer) maximizedComponent; return maxContainer.getDockable(); } } /** * combines a docking action event and vetoable state change event to accept * or reject a docking action. */ private boolean isDockingActionAccepted(DockingActionEvent dae, DockableStateWillChangeEvent dse) { boolean accepted = context.fireAcceptDockingAction(dae); if (accepted) { if (dse != null && dae.getInitialLocation() != dae.getNextLocation()) { return context.fireDockableStateWillChange(dse); } else { return true; } } else { return false; } } private void fireDockingAction(DockingActionEvent dae, DockableStateChangeEvent dse) { context.fireDockingActionPerformed(dae); if (dse != null && dae.getInitialLocation() != dae.getNextLocation()) { context.fireDockableStateChange(dse); } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockingPanel.java000066400000000000000000000123661243334202400312430ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.Shape; import javax.swing.*; import java.awt.Rectangle; import java.awt.BorderLayout; import java.awt.geom.Rectangle2D; import com.vlsolutions.swing.docking.event.DockDragEvent; import com.vlsolutions.swing.docking.event.DockDropEvent; import com.vlsolutions.swing.docking.event.DockEvent; import com.vlsolutions.swing.docking.event.DockingActionSplitComponentEvent; import com.vlsolutions.swing.docking.event.DockingActionSplitDockableContainerEvent; import java.awt.Point; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; /** This class is responsible for the containment of a Dockable component. *

* Users of the VLDocking Framework should not call this class which is * a utility component of DockingDesktop. * *

* Please rely on DockingDesktop capabilities. * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * @update 2005/11/08 Lilian Chamontin : added support for global width/height drop */ public class DockingPanel extends JPanel implements DockDropReceiver { /** @todo see if we still need the DockDropReceiver */ private static final long serialVersionUID = 1L; /** Javabeans constructor */ public DockingPanel() { super(new BorderLayout()); } /** act the same as a splitContainer : allow drop on the borders*/ public void processDockableDrag(DockDragEvent event) { scanContainer(event, false); } public void processDockableDrop(DockDropEvent event) { scanContainer(event, true); } private void acceptDrop(DockEvent event, DockingConstants.Split position) { Container dragContainer = event.getDragSource().getDockableContainer(); ((DockDropEvent) event).acceptDrop(); if(dragContainer instanceof TabbedDockableContainer) { event.getDesktop().splitComponent(this, dragContainer, position); } else { event.getDesktop().splitComponent(this, event.getDragSource().getDockable(), position); } } private void acceptDrag(DockEvent event, DockingConstants.Split position, Shape shape) { Container dragContainer = event.getDragSource().getDockableContainer(); Dockable dockable = event.getDragSource().getDockable(); DockableState.Location initialState = dockable.getDockKey().getLocation(); DockableState.Location nextState = DockableState.Location.DOCKED; if(dragContainer instanceof TabbedDockableContainer) { event.setDockingAction(new DockingActionSplitDockableContainerEvent(event.getDesktop(), initialState, nextState, this, dragContainer, position, 0.5f)); } else { event.setDockingAction(new DockingActionSplitComponentEvent(event.getDesktop(), dockable, initialState, nextState, this, position, 0.5f)); } ((DockDragEvent) event).acceptDrag(shape); } private void scanContainer(DockEvent event, boolean drop) { Point p = event.getMouseEvent().getPoint(); Rectangle compBounds = getBounds(); int distTop = p.y; int distLeft = p.x; int min = Math.min(distTop, distLeft); int distRight = compBounds.width - p.x; int distBottom = compBounds.height - p.y; int min2 = Math.min(distBottom, distRight); min = Math.min(min, min2); Dimension size = getSize(); Dockable dragged = event.getDragSource().getDockable(); // the drag size is the one of the parent dockable container Dimension draggedSize = dragged.getComponent().getParent().getSize(); int bestHeight = (int) Math.min(draggedSize.height, size.height * 0.5); int bestWidth = (int) Math.min(draggedSize.width, size.width * 0.5); if(min == distTop) { // dock on top if(drop) { acceptDrop(event, DockingConstants.SPLIT_TOP); } else { Rectangle2D r2d = new Rectangle2D.Float(0, 0, compBounds.width, bestHeight); acceptDrag(event, DockingConstants.SPLIT_TOP, r2d); } } else if(min == distLeft) { if(drop) { acceptDrop(event, DockingConstants.SPLIT_LEFT); } else { Rectangle2D r2d = new Rectangle2D.Float(0, 0, bestWidth, compBounds.height); acceptDrag(event, DockingConstants.SPLIT_LEFT, r2d); } } else if(min == distBottom) { if(drop) { acceptDrop(event, DockingConstants.SPLIT_BOTTOM); } else { Rectangle2D r2d = new Rectangle2D.Float(0, compBounds.height - bestHeight, compBounds.width, bestHeight); acceptDrag(event, DockingConstants.SPLIT_BOTTOM, r2d); } } else { // right if(drop) { acceptDrop(event, DockingConstants.SPLIT_RIGHT); } else { Rectangle2D r2d = new Rectangle2D.Float(compBounds.width - bestWidth, 0, bestWidth, compBounds.height); acceptDrag(event, DockingConstants.SPLIT_RIGHT, r2d); } } } public void resetToPreferredSize() { Component mainComp = getComponent(0); if(mainComp instanceof SplitContainer) { ((SplitContainer) mainComp).resetToPreferredSizes(); } } public String toString() { return "DockingPanel[" + hashCode() + "]"; // 2007/01/24 } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockingPreferences.java000066400000000000000000000155541243334202400324470ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.docking.ui.DockingUISettings; import java.awt.Color; import java.awt.image.BufferedImage; import javax.swing.BorderFactory; import javax.swing.JPopupMenu; import javax.swing.SwingConstants; import javax.swing.ToolTipManager; import javax.swing.UIManager; import javax.swing.border.Border; /** This is the centralized settings repository for managing docking look and feel. *

* It acts as a facade for installing common settings. *

* This class contains only high-level settings, like the heavyweight components support * or the global desktop style (shadowed or flat). To access low-level properties, use * the DockingUISettings class instead. * * @author Lilian Chamontin, VLSolutions * @since 1.1 * @see com.vlsolutions.swing.docking.ui.DockingUISettings */ public class DockingPreferences { private static boolean isLightWeightUsageEnabled = true; private static boolean isSingleHeavyWeightComponent = false; /** private stuff : use static methods only */ private DockingPreferences() {} public static final AutoHidePolicy getAutoHidePolicy() { return AutoHidePolicy.getPolicy(); } /** A simple utility method to configure the docking framework to work properly with * heavyweight component. *

* Don't forget to invoke also the following general swing methods : *

	 *      ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);
	 *      JPopupMenu.setDefaultLightWeightPopupEnabled(false);        
	 *
*

* If you are sure you will always use heavyweight component, you can replace this * method invocation by initHeavyWeightUsage(), which will do all the work for you * (even the general swing methods invocation). * */ public static void setLightweigthComponentEnabled(boolean lightweight) { isLightWeightUsageEnabled = lightweight; } public static boolean isLightWeightUsageEnabled() { return isLightWeightUsageEnabled; } /** Notifies the framework that there is only one dockable that is heavyweight. *

This allows optimizations and workarounds (for properly using the JDIC WebBrowser * for example). */ public static void setSingleHeavyWeightComponent(boolean single) { isSingleHeavyWeightComponent = single; } public static boolean isSingleHeavyWeightComponent() { return isSingleHeavyWeightComponent; } /** Facade method used to allow mixing of lightweight and heavyweight components in the * desktop. *

* This method is a shortcut for : *

	 *        ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);
	 *        JPopupMenu.setDefaultLightWeightPopupEnabled(false);        
	 *        setLightweigthComponentEnabled(false);
	 *        getAutoHidePolicy().setExpansionDuration(0);
	 * 
*/ public static void initHeavyWeightUsage() { // for now, there are only two methods used. ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false); JPopupMenu.setDefaultLightWeightPopupEnabled(false); setLightweigthComponentEnabled(false); getAutoHidePolicy().setExpansionDuration(0); } /** Facade method used to allow mixing of lightweight and heavyweight components in the * desktop. */ public static void initHeavyWeightUsage(boolean isSingleHeavyWeightComponent) { initHeavyWeightUsage(); setSingleHeavyWeightComponent(isSingleHeavyWeightComponent); } /** Convenience method to use the VLDocking 1.0 layout and border style (with shadows around dockables) */ public static void setShadowDesktopStyle() { DockingUISettings.getInstance().installUI(); UIManager.put("DockView.singleDockableBorder", new ShadowBorder()); UIManager.put("DockView.tabbedDockableBorder", new ShadowBorder(false)); UIManager.put("TabbedDockableContainer.tabPlacement", new Integer(SwingConstants.BOTTOM)); } /** Convenience method to use the VLDocking 2.0 layout and border style. *

* The new "flat style" uses light borders around dockables and top tab placements. *

* This style is the new default one, so there is no need to call this method unless you want * to swap dynamically between desktop styles. */ public static void setFlatDesktopStyle() { DockingUISettings.getInstance().installUI(); // flat style is the default (outside : empty 1 pix / inside : hightlight-top-left + shadow-bottom-right Color shadow = UIManager.getColor("VLDocking.shadow"); Color highlight = UIManager.getColor("VLDocking.highlight"); Border innerFlatSingleBorder = BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(1, 1, 0, 0, highlight), BorderFactory.createMatteBorder(0, 0, 1, 1, shadow)); Border flatSingleBorder = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1), innerFlatSingleBorder); UIManager.put("DockView.singleDockableBorder", flatSingleBorder); UIManager.put("DockView.tabbedDockableBorder", null); UIManager.put("TabbedDockableContainer.tabPlacement", new Integer(SwingConstants.TOP)); } /** Another docking style with ligh dots between dockables. */ public static void setDottedDesktopStyle() { DockingUISettings.getInstance().installUI(); Color shadow = UIManager.getColor("VLDocking.shadow"); Color highlight = UIManager.getColor("VLDocking.highlight"); Border innerFlatSingleBorder = BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(1, 1, 0, 0, highlight), BorderFactory.createMatteBorder(0, 0, 1, 1, shadow)); UIManager.put("DockView.singleDockableBorder", innerFlatSingleBorder); //BorderFactory.createLineBorder(shadow)); UIManager.put("DockView.tabbedDockableBorder", null); UIManager.put("TabbedDockableContainer.tabPlacement", new Integer(SwingConstants.TOP)); UIManager.put("SplitContainer.drawDotsDelimitors", Boolean.TRUE); } /** Another docking style with custom tiles between dockables. */ public static void setCustomSplitDesktopStyle(BufferedImage horizontalTile, BufferedImage verticalTile) { DockingUISettings.getInstance().installUI(); //UIManager.put("DockView.singleDockableBorder", null); UIManager.put("DockView.tabbedDockableBorder", null); UIManager.put("TabbedDockableContainer.tabPlacement", new Integer(SwingConstants.TOP)); UIManager.put("SplitContainer.drawDotsDelimitors", Boolean.FALSE); UIManager.put("SplitContainer.hImage", horizontalTile); UIManager.put("SplitContainer.vImage", verticalTile); UIManager.put("SplitContainer.useCustomImages", Boolean.TRUE); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockingSelectorDialog.java000066400000000000000000000235771243334202400331120ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import javax.swing.*; import java.awt.*; import java.util.*; import java.awt.event.*; import java.awt.event.ActionEvent; import javax.swing.table.*; /** A Helper class providing information about the visibility of user components. *

* This dialog shows which user components are docked, auto-hidden, * not visible, and is capable of dynamicaly altering the dockingpanel layout * on user selection (for example, to show an unvisible component). * *

* User components shown are those which are already docked and those * which have been registered with the registerDockableComponent() method of DockingPanel. * *

* Example of usage : *

 * Frame f = ...  // frame containing the docking panel
 * DockingPanel dockingPanel = ...
 * DockingSelectorDialog dlg = new DockingSelectorDialog(f);
 * dlg.setDockingPanel(dockingPanel);
 * dlg.pack();
 * dlg.setLocationRelativeTo(f);
 * dlg.setVisible(true); // modal
 *
 * // optional
 * if (dlg.getClosingState() == DockingSelectorDialog.CONFIRM){
 *    // do something more
 * }
 * 
* * @see DockingPanel * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ @SuppressWarnings({"rawtypes", "unchecked"}) public class DockingSelectorDialog extends JDialog { private static final long serialVersionUID = 1L; /** Closing state of the dialog when the user has selected the confirm option * @see #getClosingState() */ public static final int CONFIRM = 0; /** Closing state of the dialog when the user has selected the cancel option * @see #getClosingState() */ public static final int CANCEL = 1; private DockablesTableModel model; private DockingDesktop desktop; private static final String TITLE = "Docking Configuration"; private JButton confirmButton = new JButton("Ok"); private JButton cancelButton = new JButton("Cancel"); private JTable table = new JTable(); JLabel wizardLabel = new JLabel() { private static final long serialVersionUID = 1L; public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; Paint p = g2.getPaint(); g2.setPaint(new GradientPaint(0, 0, Color.WHITE, getWidth(), 0, getBackground())); g2.fillRect(0, 0, getWidth(), getHeight()); g2.setPaint(p); super.paintComponent(g); } }; private String wizardLabelText = "

This window helps you to manage the " + " views composing your application workspace.

" + "

By clicking on the table checkboxes below, you can select if " + "a view will be diplayed or not

" + "

Click on the Ok button to apply your changes or on " + "the Cancel button if you do not want to save your changes." + " "; private int closingState = CANCEL; private HashMap visibleViews = new HashMap(); // DockableState / Boolean (visible?) /** Default constructor. *

modal dialog with DISPOSE_ON_CLOSE option, * needs a pack() and setVisible(true) after creation * */ public DockingSelectorDialog() { setModal(true); setDefaultCloseOperation(DISPOSE_ON_CLOSE); setTitle(TITLE); init(); } /** Constructor for Dialog parent window. *

modal dialog with DISPOSE_ON_CLOSE option, * needs a pack() and setVisible(true) after creation. */ public DockingSelectorDialog(Dialog owner) { super(owner, true); setDefaultCloseOperation(DISPOSE_ON_CLOSE); setTitle(TITLE); init(); } /** Constructor for Frame parent window. *

modal dialog with DISPOSE_ON_CLOSE option, * needs a pack() and setVisible(true) after creation. * */ public DockingSelectorDialog(Frame owner) { super(owner, true); setDefaultCloseOperation(DISPOSE_ON_CLOSE); setTitle(TITLE); init(); } private void init() { getContentPane().setLayout(new BorderLayout(5, 5)); JScrollPane jsp = new JScrollPane(table); jsp.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5), jsp.getBorder())); getContentPane().add(jsp, BorderLayout.CENTER); confirmButton.setToolTipText("Close this window and update the views"); cancelButton.setToolTipText("Close this window without updating the views"); confirmButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { closingState = CONFIRM; for(int i = 0; i < model.states.length; i++) { DockableState state = model.states[i]; boolean newVisible = ((Boolean) visibleViews.get(state)).booleanValue(); boolean oldVisible = state.getLocation() != DockableState.Location.CLOSED; if(oldVisible != newVisible) { if(newVisible) { desktop.addDockable(state.getDockable(), state.getPosition()); } else { desktop.close(state.getDockable()); } } } DockingSelectorDialog.this.dispose(); } }); Action closeAction = new AbstractAction("Cancel") { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent actionEvent) { closingState = CANCEL; DockingSelectorDialog.this.dispose(); } }; cancelButton.setAction(closeAction); JPanel buttons = new JPanel(new FlowLayout(FlowLayout.TRAILING)); JPanel grid = new JPanel(new GridLayout(1, 0, 5, 0)); // buttons of same size grid.add(confirmButton); grid.add(cancelButton); buttons.add(grid); getContentPane().add(buttons, BorderLayout.SOUTH); wizardLabel.setText(wizardLabelText); wizardLabel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.DARK_GRAY), BorderFactory.createEmptyBorder(5, 5, 5, 5))); getContentPane().add(wizardLabel, BorderLayout.NORTH); // ESCAPE == CLOSE KeyStroke ESC = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ESC, "CLOSE"); getRootPane().getActionMap().put("CLOSE", closeAction); table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ESC, "CLOSE"); table.getActionMap().put("CLOSE", closeAction); addWindowListener(new WindowAdapter() { public void windowOpened(WindowEvent e) { getRootPane().setDefaultButton(confirmButton); } }); } /** Change the confirm button text (hook for i18n)*/ public void setConfirmButtonText(String text) { confirmButton.setText(text); } /** Change the cancel button text (hook for i18n)*/ public void setCancelButtonText(String text) { cancelButton.setText(text); } /** Change the confirm button tooltip text (hook for i18n)*/ public void setConfirmButtonTooltipText(String text) { confirmButton.setToolTipText(text); } /** Change the cancel button tootip text (hook for i18n)*/ public void setCancelButtonTooltipText(String text) { cancelButton.setToolTipText(text); } /** Change the wizard label text (an explanation of the behaviour of this dialog). *

HTML format is supported like in any JLabel. * */ public void setWizardLabelText(String wizardLabelText) { this.wizardLabel.setText(wizardLabelText); } /** Requiered to initialize this dialog. *

Invoke this method before packing the dialog. * * */ public void setDockingDesktop(DockingDesktop desktop) { this.desktop = desktop; DockableState[] states = desktop.getDockables(); Arrays.sort(states); this.model = new DockablesTableModel(states); table.setModel(model); table.getColumnModel().getColumn(0).setPreferredWidth(25); table.getColumnModel().getColumn(1).setPreferredWidth(200); table.getColumnModel().getColumn(2).setPreferredWidth(70); table.setPreferredScrollableViewportSize(new Dimension(300, 300)); table.setCellSelectionEnabled(true); table.setShowVerticalLines(false); table.setRowHeight(20); } /** Returns the users close choice as CONFIRM or CANCEL (remember this dialog is modal). *

Use this method if you need to know how is was closed. * If the used has confirmed, the docking panel is automaticaly updated * by the confirm button action. */ public int getClosingState() { return closingState; } class DockablesTableModel extends AbstractTableModel { private static final long serialVersionUID = 1L; String[] colNames = {" ", "Name", "Visible"}; private DockableState[] states; DockablesTableModel(DockableState[] states) { this.states = states; for(int i = 0; i < states.length; i++) { visibleViews.put(states[i], states[i].getLocation() == DockableState.Location.CLOSED ? Boolean.FALSE : Boolean.TRUE); } } public int getColumnCount() { return colNames.length; } public int getRowCount() { return states.length; } public String getColumnName(int col) { return colNames[col]; } public boolean isCellEditable(int row, int col) { if(col != 2) return false; Dockable dockable = states[row].getDockable(); if(dockable.getDockKey().isCloseEnabled()) { return true; } else { return false; } } public Class getColumnClass(int col) { switch(col) { case 0: return Icon.class; case 1: return String.class; case 2: return Boolean.class; } return null; } public Object getValueAt(int row, int col) { DockableState state = states[row]; switch(col) { case 0: return state.getDockable().getDockKey().getIcon(); case 1: return state.getDockable().getDockKey().getName(); case 2: return (Boolean) visibleViews.get(state); } return null; } public void setValueAt(Object v, int row, int col) { DockableState state = states[row]; visibleViews.put(state, (Boolean) v); } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DockingUtilities.java000066400000000000000000000430511243334202400321520ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.*; import java.awt.peer.LightweightPeer; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import javax.swing.*; /** Utility class implementing search/replace algorithms used by the framework. *

* This class is not inteded for API users, it should be let to framework developpers. * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public class DockingUtilities { private DockingUtilities() { // singleton } /** returns the first DockableContainer which is parent of this dockable component */ public static DockableContainer findDockableContainer(Dockable dockable) { if(dockable == null) return null; Component comp = dockable.getComponent(); if(comp == null) return null; while(comp != null) { if(comp instanceof DockableContainer) { return (DockableContainer) comp; } comp = comp.getParent(); } return null; } /** returns the first DockableContainer which is parent of this dockable component */ public static SingleDockableContainer findSingleDockableContainer(Dockable dockable) { if(dockable == null) return null; Component comp = dockable.getComponent(); if(comp == null) return null; while(comp != null) { if(comp instanceof SingleDockableContainer) { return (SingleDockableContainer) comp; } comp = comp.getParent(); } return null; } /** Returns the first TabbedDockableContainer which is parent of this dockable component, or * null is there isn't any. * */ public static TabbedDockableContainer findTabbedDockableContainer(Dockable dockable) { if(dockable == null) return null; Component comp = dockable.getComponent(); if(comp == null) return null; /* while (comp != null){ //2005/10/10 if (comp instanceof TabbedDockableContainer){ return (TabbedDockableContainer) comp; } comp = comp.getParent(); } */ while(comp != null) { // new version to support compoundDockable : stop after the first parent of // the first SingleDockableContainer found if(comp instanceof SingleDockableContainer) { comp = comp.getParent(); if(comp instanceof TabbedDockableContainer) { return (TabbedDockableContainer) comp; } else { return null; } } comp = comp.getParent(); } return null; } private static void swapComponents(SplitContainer split1, SplitContainer split2, Component comp1, Component comp2) { boolean isLeft1 = split1.getLeftComponent() == comp1; int divider1 = split1.getDividerLocation(); if(split1 == split2) { split1.remove(comp1); split1.remove(comp2); if(isLeft1) { split1.setLeftComponent(comp2); split1.setRightComponent(comp1); } else { split1.setLeftComponent(comp1); split1.setRightComponent(comp2); } split1.setDividerLocation(divider1); split1.revalidate(); } else { boolean isLeft2 = split2.getLeftComponent() == comp2; int divider2 = split2.getDividerLocation(); split1.remove(comp1); split2.remove(comp2); if(isLeft1) { split1.setLeftComponent(comp2); } else { split1.setRightComponent(comp2); } split1.setDividerLocation(divider1); if(isLeft2) { split2.setLeftComponent(comp1); } else { split2.setRightComponent(comp1); } split2.setDividerLocation(divider2); } } /** Swaps two toplevel DockableContainers (their parent must be a SplitContainer) */ public static void swapComponents(Component comp1, Component comp2) { Container parent1 = comp1.getParent(); Container parent2 = comp2.getParent(); if(parent1 instanceof SplitContainer) { if(parent2 instanceof SplitContainer) { swapComponents((SplitContainer) parent1, (SplitContainer) parent2, comp1, comp2); } else { // nothing } } } /** Invoked every time the layout is changed, to rebuild the weighting of split containers */ public static void updateResizeWeights(DockingPanel dockingPanel) { if(dockingPanel.getComponentCount() > 0) { resetSplitWeight(dockingPanel.getComponent(0)); } } private static float resetSplitWeight(Component comp) { if(comp instanceof SplitContainer) { SplitContainer split = (SplitContainer) comp; float leftWeight = resetSplitWeight(split.getLeftComponent()); float rightWeight = resetSplitWeight(split.getRightComponent()); float sum = leftWeight + rightWeight; if(sum == 0) { split.setResizeWeight(0.5); // half weight for each side return 0; } else if(leftWeight == 0) { // and rightWeight != 0 split.setResizeWeight(0); // every resize goes to the right return rightWeight; } else if(rightWeight == 0) { // and leftWeight != 0 split.setResizeWeight(1); // every resize goes to the left return leftWeight; } else { float proportion = leftWeight / sum; // when near 0 => right, when near 1 => left split.setResizeWeight(proportion); return Math.max(leftWeight, rightWeight); } } else if(comp instanceof SingleDockableContainer) { return ((SingleDockableContainer) comp).getDockable().getDockKey().getResizeWeight(); } else if(comp instanceof TabbedDockableContainer) { TabbedDockableContainer tab = (TabbedDockableContainer) comp; float max = 0; for(int i = 0; i < tab.getTabCount(); i++) { Dockable d = tab.getDockableAt(i); if(d != null) { float v = d.getDockKey().getResizeWeight(); if(v > max) { max = v; } } } return max; } else if(comp instanceof MaximizedComponentReplacer) { //2007/01/18 // ignore as this component replaces the maximized dockable in the // docking container hierarchy } else { System.err.println("Wrong hierarchy in docking panel (resetSplitWeight error) " + comp); } return 0; } /** Child replacement */ public static void replaceChild(Container parent, Component child, Component newChild) { //System.out.println("replace child : PARENT=" + parent + ", CHILD=" + child + ", NEW=" + newChild); if(parent instanceof SplitContainer) { final SplitContainer split = (SplitContainer) parent; final int location = split.getDividerLocation(); if(split.getLeftComponent() == child) { split.remove(child); split.setLeftComponent(newChild); } else if(split.getRightComponent() == child) { split.remove(child); split.setRightComponent(newChild); } else { throw new IllegalArgumentException("wrong hierarchy"); } // SwingUtilities.invokeLater(new Runnable() { // public void run() { split.setDividerLocation(location); split.revalidate(); split.doLayout(); // } // }); } else if(parent instanceof TabbedDockableContainer) { // 2005/07/12... // interface trick : we need to access the JTabbedPane internals // the newChild can be a dummy JComponent (when used in maximize/restore) // or a fully featured dockable (other usages) // this is not really clean : it's the problem when using interfaces over subclasses... if(parent instanceof JTabbedPane) { TabbedDockableContainer tparent = (TabbedDockableContainer) parent; JTabbedPane jtp = (JTabbedPane) tparent; int index = jtp.indexOfComponent(child); jtp.remove(index); if(newChild instanceof SingleDockableContainer) { tparent.addDockable(((SingleDockableContainer) newChild).getDockable(), index); jtp.setSelectedIndex(index); } else { // dummy component jtp.add(newChild, index); jtp.setSelectedIndex(index); } } else { throw new RuntimeException("Unknown TabbedDockableContainer"); } // ...2005/07/12 } else { // we're on top level (panel with borderlayout) parent.remove(child); parent.add(newChild, BorderLayout.CENTER); parent.invalidate(); parent.validate(); } } /** Returns the split pane containing this dockable (if any), or null if this dockable * isn't contained in a splitpane. *

* If the dockable is nested in a TabbedDockableContainer, the split pane returned will * be the one containing the tabbed container (if any). * * */ public static SplitContainer getSplitPane(Dockable dockable, int orientation) { Component comp = dockable.getComponent(); boolean found = false; while(comp != null && ! found) { if(comp instanceof SplitContainer && ((SplitContainer) comp).getOrientation() == orientation) { found = true; } else { comp = comp.getParent(); } } return (SplitContainer) comp; } /** A utility method to find the first single dockable container ancestor of the given component. *

* This method may return null if no SingleDockableContainer ancestor is found. */ public static SingleDockableContainer findSingleDockableContainerAncestor(Component component) { Component parent = component.getParent(); while(parent != null && ! (parent instanceof SingleDockableContainer)) { parent = parent.getParent(); } return (SingleDockableContainer) parent; } /** Utility method to find out if a component is heavyweight (of if it contains a heavyweight comp)*/ public static boolean isHeavyWeightComponent(Component comp) { if(comp instanceof Container) { // short cut @SuppressWarnings("deprecation") Object peer = comp.getPeer(); if(! (peer == null || peer instanceof LightweightPeer)) { // it's not a lightweight return true; } else { // long way Container c = (Container) comp; for(int i = 0; i < c.getComponentCount(); i++) { Component child = c.getComponent(i); if(isHeavyWeightComponent(child)) { return true; } } return false; } } else { @SuppressWarnings("deprecation") Object peer = comp.getPeer(); return ! (peer == null || peer instanceof LightweightPeer); } } /** Returns whether we can use the secured and 1.5 MouseInfo class */ public static boolean canUseMouseInfo() { if(System.getProperty("java.version").compareTo("1.5") >= 0) { return getMouseLocation() != null; } else { return false; // not present in pre 1.5 versions } } /** Returns the mouse location on screen or null if ran in an untrusted environement/ java 1.4 */ public static Point getMouseLocation() { try { //Point mouseLocation = MouseInfo.getPointerInfo().getLocation(); // this class in not compatible with 1.4 // so instead we use reflection for allowing 1.4 compilation Class mouseInfoClass = Class.forName("java.awt.MouseInfo"); @SuppressWarnings("rawtypes") final Class[] noArgs = new Class[0]; Method m = mouseInfoClass.getMethod("getPointerInfo", noArgs); Object pointerInfo = m.invoke(null, (Object[]) null); Class pointerInfoClass = Class.forName("java.awt.PointerInfo"); Method getLocationMethod = pointerInfoClass.getMethod("getLocation", noArgs); Point mouseLocation = (Point) getLocationMethod.invoke(pointerInfo, (Object[]) null); return mouseLocation; } catch(ClassNotFoundException ignore) { } catch(NoSuchMethodException ignore) { } catch(IllegalAccessException e) { } catch(InvocationTargetException ignore) { } return null; } /** packs a detached dockable, regardless of its type (frame or dialog) */ public static void pack(FloatingDockableContainer fdc) { //2006/02/20 if(fdc instanceof JFrame) { ((JFrame) fdc).pack(); } else if(fdc instanceof JDialog) { ((JDialog) fdc).pack(); } } /** resizes a detached dockable, regardless of its type (frame or dialog) */ public static void setSize(FloatingDockableContainer fdc, Dimension size) { //2006/02/20 if(fdc instanceof JFrame) { ((JFrame) fdc).setSize(size); } else if(fdc instanceof JDialog) { ((JDialog) fdc).setSize(size); } } /** validates a detached dockable, regardless of its type (frame or dialog) */ public static void validate(FloatingDockableContainer fdc) { //2006/02/20 ((Window) fdc).validate(); } /** positions a detached dockable, regardless of its type (frame or dialog) */ public static void setLocation(FloatingDockableContainer fdc, Point location) { //2006/02/20 ((Window) fdc).setLocation(location); } /** positions a detached dockable, regardless of its type (frame or dialog) */ public static void setLocationRelativeTo(FloatingDockableContainer fdc, Component rel) { //2006/02/20 ((Window) fdc).setLocationRelativeTo(rel); } /** shows a detached dockable, regardless of its type (frame or dialog) */ public static void setVisible(FloatingDockableContainer fdc, boolean visible) { //2006/02/20 ((Window) fdc).setVisible(visible); } /** disposes a detached dockable, regardless of its type (frame or dialog) */ public static void dispose(FloatingDockableContainer fdc) { ((Window) fdc).dispose(); } /** returns the root pane used by this detached dockable container, regardless of its type (frame or dialog)*/ public static JRootPane getRootPane(FloatingDockableContainer fdc) { if(fdc instanceof JFrame) { return ((JFrame) fdc).getRootPane(); } else if(fdc instanceof JDialog) { return ((JDialog) fdc).getRootPane(); } else { return null; // not reachable } } static void setBounds(FloatingDockableContainer fdc, Rectangle bounds) { ((Window) fdc).setBounds(bounds); } /** Creates a list of all dockable children contained in the given compound dockable. *

If the compound dockable contains another compound dockable this one is also added, * along with its own children. * @return an ArrayList of Dockable */ public static ArrayList findCompoundDockableChildren(CompoundDockable compoundDockable) { ArrayList list = new ArrayList(); CompoundDockingPanel cdp = (CompoundDockingPanel) compoundDockable.getComponent(); fillCompoundChildren(cdp, list); return list; } private static void fillCompoundChildren(CompoundDockingPanel cdp, ArrayList list) { if(cdp.getComponentCount() > 0) { Component c = cdp.getComponent(0); fillCompoundChildren(c, list); } } private static void fillCompoundChildren(Component c, ArrayList list) { if(c instanceof CompoundDockingPanel) { fillCompoundChildren((CompoundDockingPanel) c, list); } else if(c instanceof SingleDockableContainer) { list.add(((SingleDockableContainer) c).getDockable()); } else if(c instanceof SplitContainer) { fillCompoundChildren(((SplitContainer) c).getLeftComponent(), list); fillCompoundChildren(((SplitContainer) c).getRightComponent(), list); } else if(c instanceof TabbedDockableContainer) { TabbedDockableContainer tdc = (TabbedDockableContainer) c; for(int i = 0; i < tdc.getTabCount(); i++) { Dockable d = tdc.getDockableAt(i); if(d instanceof CompoundDockable) { list.add(d); CompoundDockingPanel cdp = (CompoundDockingPanel) d.getComponent(); fillCompoundChildren(cdp, list); } else { list.add(d); } } } } /** checks if this dockable is a child of a compound dockable */ public static boolean isChildOfCompoundDockable(Dockable dockable) { Container container = dockable.getComponent().getParent(); while(container != null) { if(container instanceof CompoundDockingPanel && ((CompoundDockingPanel) container).getDockable() != dockable) { // avoid returning true if the dockable if itself a compound return true; } container = container.getParent(); } return false; } /** searches up the dockable container hierarchy and returns the first ancestor * which is a CompoundDockable (or null if not found). */ public static Container findCompoundAncestorContainer(Dockable dockable) { Container container = dockable.getComponent().getParent(); while(container != null) { if(container instanceof CompoundDockingPanel && ((CompoundDockingPanel) container).getDockable() != dockable) { // avoid returning true if the dockable if itself a compound return container; } container = container.getParent(); } return null; } /** searches up the dockable container hierarchy and returns the dockable state of the * last (top most) ancestor which is a CompoundDockable (or null if not found). */ public static DockableState.Location getTopMostAncestorContainerState(Dockable dockable) { Container container = dockable.getComponent().getParent(); Container topMostContainer = null; while(container != null) { if(container instanceof CompoundDockingPanel && ((CompoundDockingPanel) container).getDockable() != dockable) { // avoid returning true if the dockable if itself a compound topMostContainer = container; } container = container.getParent(); } if(topMostContainer != null) { CompoundDockingPanel cdp = (CompoundDockingPanel) topMostContainer; return cdp.getDockable().getDockKey().getLocation(); } return null; } /** Returns a DockableState value corresponding to this component or null if not found. *

* Two states are currently managed : docked and floating (not hidden/maximized/closed). */ public static DockableState.Location getDockableLocationFromHierarchy(Component comp) { if(comp == null) { return null; } while(comp != null) { if(comp instanceof DockingPanel) { return DockableState.Location.DOCKED; } else if(comp instanceof FloatingDockableContainer) { return DockableState.Location.FLOATING; } comp = comp.getParent(); } return null; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DragControler.java000066400000000000000000000020041243334202400314360ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.Shape; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; /** This interface defines the features required for a drag controler. * * @since 3.0 * @author Lilian Chamontin, vlsolutions. */ public interface DragControler extends MouseListener, MouseMotionListener { public void cancelDrag(); public Dockable getDockable(); public DockDropReceiver getDropReceiver(); public Shape getDropShape(); public boolean isFloatingShape(); } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DragControlerFactory.java000066400000000000000000000024011243334202400327670ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; /** A Basic factory providing a lightweight and heavyweight implementation of the * DragControler interface * * @author Lilian Chamontin, vlsolutions. */ public class DragControlerFactory { private static DragControlerFactory instance; public DragControler createDragControler(DockingDesktop desktop) { if(DockingPreferences.isLightWeightUsageEnabled()) { return new LightWeightDragControler(desktop); } else { return new HeavyWeightDragControler(desktop); } } public static DragControlerFactory getInstance() { if(instance == null) { instance = new DragControlerFactory(); } return instance; } public static void setInstance(DragControlerFactory instance) { DragControlerFactory.instance = instance; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/DragControlerGlassPane.java000066400000000000000000000131131243334202400332370ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Component; import java.awt.Composite; import java.awt.Cursor; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; import java.awt.Toolkit; import java.awt.event.MouseAdapter; import java.awt.event.MouseMotionAdapter; import java.awt.geom.AffineTransform; import javax.swing.JComponent; import javax.swing.SwingUtilities; import javax.swing.UIManager; /** A glasspane use to paint drag / drop shape on top of the desktop * * @author Lilian Chamontin, VLSolutions */ public class DragControlerGlassPane extends JComponent { private static final long serialVersionUID = 1L; Cursor stopDragCursor, dragCursor, floatCursor, swapDragCursor; Color innerColor = new Color(64, 64, 64, 64); Color textColor = Color.WHITE; Color textFillColor = new Color(32, 32, 32, 128); Color textBorderColor = new Color(64, 64, 64); boolean paintShapes = true; ShapeLabelPainter labelPainter = new ShapeLabelPainter(); ShapeOutlinePainter outlinePainer = new ShapeOutlinePainter(); private DragControler controler; DragControlerGlassPane(DragControler controler) { this.controler = controler; addMouseListener(new MouseAdapter() {}); // grab events addMouseMotionListener(new MouseMotionAdapter() {}); showDragCursor(); } /** Enables or disables shape painting */ public void setPaintShapes(boolean paintShapes) { this.paintShapes = paintShapes; } public void paintComponent(Graphics g) { if(paintShapes) { Graphics2D g2 = (Graphics2D) g; if(controler.getDropShape() != null) { Shape s = controler.getDropShape(); Point p = SwingUtilities.convertPoint((Component) controler.getDropReceiver(), 0, 0, this); Shape s2 = AffineTransform.getTranslateInstance(p.x, p.y).createTransformedShape(s); outlinePainer.paintShape(g2, s2); labelPainter.paintLabel(g2, s2, controler.getDockable().getDockKey().getName()); } } } public void showStopDragCursor() { if(stopDragCursor == null) { Image stopDragImage = (Image) UIManager.get("DragControler.stopDragCursor"); //2005/11/01 stopDragCursor = Toolkit.getDefaultToolkit().createCustomCursor(stopDragImage, new Point(16, 16), "stopdragcursor"); } setCursor(stopDragCursor); } public void showSwapDragCursor() { if(swapDragCursor == null) { Image swapDragImage = (Image) UIManager.get("DragControler.swapDragCursor"); //2005/11/01 swapDragCursor = Toolkit.getDefaultToolkit().createCustomCursor(swapDragImage, new Point(16, 16), "swapdragcursor"); } setCursor(swapDragCursor); } public void showFloatCursor() { if(floatCursor == null) { Image floatImage = (Image) UIManager.get("DragControler.detachCursor"); //2005/11/01 floatCursor = Toolkit.getDefaultToolkit().createCustomCursor(floatImage, new Point(16, 16), "floatcursor"); } setCursor(floatCursor); } public void showDragCursor() { if(dragCursor == null) { Image dragImage = (Image) UIManager.get("DragControler.dragCursor"); //2005/11/01 dragCursor = Toolkit.getDefaultToolkit().createCustomCursor(dragImage, new Point(16, 16), "dragcursor"); } setCursor(dragCursor); } /** the object responsible for painting the shape label */ class ShapeLabelPainter { private Color textColor = Color.WHITE; private Color textFillColor = new Color(32, 32, 32, 128); // private Color textFillColor = new Color(128, 128,128); private Color textBorderColor = new Color(64, 64, 64); public void paintLabel(Graphics2D g2, Shape s, String name) { Rectangle bounds = s.getBounds(); FontMetrics fm = g2.getFontMetrics(); int w = fm.stringWidth(name); g2.setColor(textFillColor); int bx, by; if(controler.isFloatingShape()) { bx = bounds.x + bounds.width / 2 - w / 2; by = bounds.y + bounds.height / 2 - fm.getHeight() / 2; } else { bx = 4 * ((bounds.x + bounds.width / 2 - w / 2) / 4); // 2005/11/01 small hack to overcome small drifts of the label // (for example when used on a tabbedpane and when the selected tab is // one or two pixels bigger than a non selected tab. // just snapping it with a 4*4 grid avoid those glitches (without changing // too much the shapes algorithm). by = 4 * ((bounds.y + bounds.height / 2 - fm.getHeight() / 2) / 4); } g2.fillRect(bx - 5, by, w + 10, fm.getHeight()); g2.setStroke(new BasicStroke(1)); g2.setColor(textBorderColor); g2.drawRect(bx - 5, by, w + 10, fm.getHeight()); g2.setColor(textColor); g2.drawString(name, bx, by + fm.getAscent()); } } } /** the object responsible for painting the shape outline */ class ShapeOutlinePainter { private Color innerColor = new Color(64, 64, 64); public void paintShape(Graphics2D g2, Shape s) { Composite old = g2.getComposite(); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.25f)); g2.setStroke(new BasicStroke(3)); g2.setColor(innerColor); g2.fill(s); g2.setComposite(old); g2.setColor(Color.DARK_GRAY); g2.draw(s); } }vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/FloatingDialog.java000066400000000000000000000303071243334202400315630ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.Dialog; import java.awt.Dimension; import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.Point; import java.awt.Rectangle; import java.awt.TexturePaint; import java.awt.Window; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.border.Border; /** * The floating jdialog for floatable dockables. This is the default * implementation of the FloatingDockableContainer interface. * * @author Lilian Chamontin, VLSolutions * @since 2.0 * @update 2005/10/06 Lilian Chamontin : Reworked the layout (added border * components) to have better cursor and resize management and to allow * nesting dockables as tabs. * */ @SuppressWarnings("unused") public class FloatingDialog extends JDialog implements FloatingDockableContainer { private static final long serialVersionUID = 1L; // constants to listen to border drags private static final int DRAG_TOP = 1; private static final int DRAG_LEFT = 2; private static final int DRAG_RIGHT = 4; private static final int DRAG_BOTTOM = 8; /** the drag header height */ protected int titleHeight = 6; private Color controlColor = UIManager.getColor("control"); private Color highlight = UIManager.getColor("VLDocking.highlight"); private Color shadow = UIManager.getColor("VLDocking.shadow"); private Color activeCaptionColor = UIManager.getColor("activeCaption"); private Color inactiveCaptionColor = UIManager.getColor("inactiveCaption"); private Color activeCaptionBorderColor = UIManager .getColor("activeCaptionBorder"); private Color inactiveCaptionBorderColor = UIManager .getColor("inactiveCaptionBorder"); private Border activeBorder = BorderFactory .createLineBorder(activeCaptionBorderColor); private Border inactiveBorder = BorderFactory .createLineBorder(inactiveCaptionBorderColor); private JComponent title = createTitlePanel(); private Resizer left = new Resizer(); private Resizer right = new Resizer(); private Resizer bottom = new Resizer(); protected DockingDesktop desktop; public FloatingDialog(Dialog parent) { super(parent); init(); } public FloatingDialog(Frame parent) { super(parent); // setIconImage(parent.getIconImage()); init(); } // added this to make floating windows appear in the taskbar. See // http://stackoverflow.com/questions/19116310/showing-jdialog-in-taskbar-not-working public FloatingDialog() { super((Window) null); init(); } /** initialisation of the title bar */ public void init() { installDecoration(); installBorders(); installResizers(); addWindowListener(new WindowAdapter() { public void windowActivated(WindowEvent e) { getRootPane().setBorder(getActiveBorder()); repaint(); } public void windowDeactivated(WindowEvent e) { getRootPane().setBorder(getInactiveBorder()); repaint(); } }); title.setPreferredSize(new Dimension(10, titleHeight)); getContentPane().add(title, BorderLayout.NORTH); // ResizeListener listener = new ResizeListener(); // addMouseMotionListener(listener); //2005/10/06 // addMouseListener(listener); } /** * Installs or not the window decorations on this dialog. *

* uses setUndecorated(booelan) */ public void installDecoration() { setUndecorated(true); } /** Creates the component used as a header to drag the window */ public JComponent createTitlePanel() { return new TitlePanel(); } /** Installs the borders of this dialog and its title header */ public void installBorders() { Border border = UIManager.getBorder("FloatingDialog.dialogBorder"); Border titleBorder = UIManager.getBorder("FloatingDialog.titleBorder"); title.setBorder(titleBorder); ((JPanel) getContentPane()).setBorder(border); } /** * installs the components used for resizing (on left/right/bottom borders) * * @since 2.0.1 */ public void installResizers() { // 2005/10/06 ResizeListener listener = new ResizeListener(); left.addMouseMotionListener(listener); left.addMouseListener(listener); right.addMouseMotionListener(listener); right.addMouseListener(listener); bottom.addMouseMotionListener(listener); bottom.addMouseListener(listener); title.addMouseMotionListener(listener); title.addMouseListener(listener); getContentPane().add(left, BorderLayout.WEST); getContentPane().add(right, BorderLayout.EAST); getContentPane().add(bottom, BorderLayout.SOUTH); Color inactive = UIManager.getColor("inactiveCaption"); left.setBackground(inactive); right.setBackground(inactive); bottom.setBackground(inactive); } public void installDocking(DockingDesktop desktop) { this.desktop = desktop; } public void setInitialDockable(Dockable dockable) { SingleDockableContainer sdc = DockableContainerFactory .getFactory() .createDockableContainer( dockable, DockableContainerFactory.ParentType.PARENT_DETACHED_WINDOW); sdc.installDocking(desktop); Component comp = (Component) sdc; getContentPane().add(comp); } public void setInitialTabbedDockableContainer(TabbedDockableContainer tdc) { Component comp = (Component) tdc; getContentPane().add(comp); } // utility resizer class private class ResizeListener implements MouseMotionListener, MouseListener { Point lastPoint = null; int dragType = -1; public void mouseDragged(MouseEvent e) { Rectangle bounds = getBounds(); Dimension d = getSize(); Point p = e.getPoint(); SwingUtilities.convertPointToScreen(p, e.getComponent()); int dx = p.x - lastPoint.x; int dy = p.y - lastPoint.y; switch (dragType) { case DRAG_TOP: Point loc = getLocation(); setLocation(loc.x + dx, loc.y + dy); break; case DRAG_TOP | DRAG_LEFT: invalidate(); bounds.x += dx; bounds.y += dy; bounds.width -= dx; bounds.height -= dy; setBounds(bounds); validate(); break; case DRAG_TOP | DRAG_RIGHT: invalidate(); bounds.y += dy; bounds.width += dx; bounds.height -= dy; setBounds(bounds); validate(); break; case DRAG_RIGHT: invalidate(); setSize(d.width + dx, d.height); validate(); break; case DRAG_RIGHT | DRAG_BOTTOM: invalidate(); setSize(d.width + dx, d.height + dy); validate(); break; case DRAG_BOTTOM: invalidate(); setSize(d.width, d.height + dy); validate(); break; case DRAG_BOTTOM | DRAG_LEFT: invalidate(); bounds.x += dx; bounds.width -= dx; bounds.height += dy; setBounds(bounds); validate(); break; case DRAG_LEFT: invalidate(); bounds.x += dx; bounds.width -= dx; setBounds(bounds); validate(); break; } lastPoint = p; } public void mouseReleased(MouseEvent e) { dragType = -1; } public void mousePressed(MouseEvent e) { dragType = 0; Point p = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), getContentPane()); /* * if (p.y < 10){ dragType |= DRAG_TOP; } if (p.x < 5){ dragType |= * DRAG_LEFT; } if (p.x > getWidth() - 5){ dragType |= DRAG_RIGHT; } * if (p.y > getHeight() - 5){ dragType |= DRAG_BOTTOM; } */ if (p.y < title.getY() + title.getHeight()) { dragType |= DRAG_TOP; } if (p.x < left.getX() + left.getWidth()) { dragType |= DRAG_LEFT; } if (p.x >= right.getX()) {// getWidth() - 5){ dragType |= DRAG_RIGHT; } if (p.y >= bottom.getY()) { dragType |= DRAG_BOTTOM; } lastPoint = e.getPoint(); SwingUtilities.convertPointToScreen(lastPoint, e.getComponent()); } public void mouseExited(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } public void mouseMoved(MouseEvent e) { Point p = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), getContentPane()); int dragType = 0; if (p.y < title.getY() + title.getHeight()) { dragType |= DRAG_TOP; } if (p.x < left.getX() + left.getWidth()) { dragType |= DRAG_LEFT; } if (p.x >= right.getX()) {// getWidth() - 5){ dragType |= DRAG_RIGHT; } if (p.y >= bottom.getY()) { dragType |= DRAG_BOTTOM; } Cursor c = null; switch (dragType) { case 0: c = Cursor.getDefaultCursor(); break; case DRAG_TOP: c = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR); break; case DRAG_TOP | DRAG_LEFT: c = Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR); break; case DRAG_TOP | DRAG_RIGHT: c = Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR); break; case DRAG_RIGHT: c = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); break; case DRAG_RIGHT | DRAG_BOTTOM: c = Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR); break; case DRAG_BOTTOM: c = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR); break; case DRAG_BOTTOM | DRAG_LEFT: c = Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR); break; case DRAG_LEFT: c = Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR); break; } if (!e.getComponent().getCursor().equals(c)) { e.getComponent().setCursor(c); } } } /** Class used as a title for dragging the window around */ protected class TitlePanel extends JComponent { private static final long serialVersionUID = 1L; public void paintComponent(Graphics g) { // @todo : this will be refactored to plug custom title rendering Color darker, brighter; if (isActive()) { darker = UIManager.getColor("activeCaption"); brighter = UIManager.getColor("activeCaptionBorder"); } else { darker = UIManager.getColor("inactiveCaption"); brighter = UIManager.getColor("inactiveCaptionBorder"); } /* * Graphics2D g2 = (Graphics2D) g; Paint paint = g2.getPaint(); * GradientPaint gradient = new GradientPaint(0,0, darker, 0, * getHeight(), brighter); g2.setPaint(gradient); g2.fillRect(0,0, * getWidth(), getHeight()); g2.setPaint(paint); // restore */ Graphics2D g2 = (Graphics2D) g; g2.setColor(darker); g2.fillRect(0, 0, getWidth(), getHeight()); int width = 5; int height = 5; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics ig = image.createGraphics(); ig.setColor(darker); ig.fillRect(0, 0, width, height); ig.setColor(new Color(1, 1, 1, 0.5f)); ig.fillRect(2, 2, 2, 2); ig.setColor(new Color(0, 0, 0, 0.2f)); ig.fillRect(1, 1, 2, 2); ig.dispose(); // Create a texture paint from the buffered image Rectangle r = new Rectangle(0, 0, width, height); TexturePaint tp = null; if (tp == null) { tp = new TexturePaint(image, r); } Paint old = g2.getPaint(); g2.setPaint(tp); g2.fillRect(0, 0, getWidth(), height); g2.setPaint(old); // g2.setColor(hightLight); // g2.fillRect(0,getHeight()-1, getWidth(), 1); } } protected class Resizer extends JComponent { private static final long serialVersionUID = 1L; Resizer() { setPreferredSize(new Dimension(3, 3)); setOpaque(true); } public void paintComponent(Graphics g) { if (isActive()) { g.setColor(UIManager.getColor("activeCaption")); } else { g.setColor(UIManager.getColor("inactiveCaption")); } g.fillRect(0, 0, getWidth(), getHeight()); } } public Border getInactiveBorder() { return inactiveBorder; } public Border getActiveBorder() { return activeBorder; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/FloatingDockableContainer.java000066400000000000000000000025141243334202400337320ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; /** The interface describing a Floating window used to display one or more dockables *

* Objects implementing this interface must be instances of JDialog , as the * pack(), setVisible(), setLocation(), dispose() etc. are assumed. * * @author Lilian Chamontin, VLSolutions */ public interface FloatingDockableContainer { /** This install method is invoked before adding the first dockable */ public void installDocking(DockingDesktop desktop); /** adds the initial dockable to this top-level container */ public void setInitialDockable(Dockable dockable); /** adds the initial tabbdeddockablecontainer to this top-level container. * This will happen when drag-n-dropping a whole tab container from the desktop. */ public void setInitialTabbedDockableContainer(TabbedDockableContainer tdc); } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/HeavyWeightDragControler.java000066400000000000000000000304041243334202400336100ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.Canvas; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Cursor; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; import java.awt.Window; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.lang.reflect.Method; import javax.swing.Icon; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLayeredPane; import javax.swing.SwingUtilities; import javax.swing.UIManager; /** A Heavyweight implementation of the drag controler, and its associated classes * * @since 3.0 * @author Lilian Chamontin, vlsolutions. */ class HeavyWeightDragControler extends AbstractDragControler { private boolean paintBackgroundUnderDragRect = UIManager.getBoolean("DragControler.paintBackgroundUnderDragRect"); /** instantiates a controler for a given docking panel*/ HeavyWeightDragControler(DockingDesktop desktop) { super(desktop); } /** find the top most component of this container */ protected Component findComponentAt(Container container, int x, int y) { Rectangle bounds = new Rectangle(); int count = container.getComponentCount(); //ShapePainterStrategy shapePainterStrategy = getShapePainter(container, null); for(int i = 0; i < count; i++) { Component child = container.getComponent(i); if(child.isVisible()) { child.getBounds(bounds); if(bounds.contains(x, y)) { if(child instanceof Container) { // recursive Component found = findComponentAt((Container) child, x - bounds.x, y - bounds.y); if(found != null) { return found; } else { return child; } } else if(! (child instanceof HeavyShape || child instanceof HeavyLabel)) { // skip our dedicated components for heavyweight support return child; // } else if (child != shapePainterStrategy.heavyShape && // child != shapePainterStrategy.heavyShape.label){ // // skip our dedicated components for heavyweight support // return child; } } } } return null; } @Override protected ShapePainterStrategy createShapePainterStrategy(Window w) { return new HWShapePainterStrategy(w); } public Dockable getDockable() { if(dockableDragSource != null) { return dockableDragSource.getDockable(); } else { return null; } } // ----------------------------------------------------------------------------------------------------------- // --------------------------------- you don't want to look at the code underneath this line... -------------- // ----------------------------------------------------------------------------------------------------------- // I'll rewrite it entirely someday as i'm not pleased with it (much too complex) /** This class holds implementation strategies of shapes painting. *

* As painting is different when pure Swing is used (glasspane) and * heavyweight components are mixed in (glasspane + canvas). */ private class HWShapePainterStrategy implements ShapePainterStrategy { private DragControlerGlassPane dragGlassPane = new DragControlerGlassPane(HeavyWeightDragControler.this); private Component oldGlassPane = null; private boolean oldGlassPaneVisible = false; private Window window = null; private boolean isDragStarted = false; // heavyweight support private HeavyShape heavyShape; // instanciated only when heavyweight suport is enabled /*public ShapePainterStrategy(){ if (! isLightWeight){ dragGlassPane.setPaintShapes(false); heavyShape = new HeavyShape(); } }*/ public HWShapePainterStrategy(Window window) { this.window = window; dragGlassPane.setPaintShapes(false); heavyShape = new HeavyShape(); } /** show the drag cursor */ public void showDragCursor() { dragGlassPane.showDragCursor(); heavyShape.setCursor(dragGlassPane.getCursor()); } /** show the stop-drag cursor (drag not enabled)*/ public void showStopDragCursor() { dragGlassPane.showStopDragCursor(); heavyShape.setCursor(dragGlassPane.getCursor()); } /** show the stop-drag cursor (drag not enabled)*/ public void showSwapDragCursor() { dragGlassPane.showSwapDragCursor(); heavyShape.setCursor(dragGlassPane.getCursor()); } /** show the float (detached) cursor */ public void showFloatCursor() { dragGlassPane.showFloatCursor(); heavyShape.setCursor(dragGlassPane.getCursor()); } public void repaint() { /* this is a hack that will be refactored : we post a repaint when there is * a need to show a drag shape */ if(dropShape != null) { heavyShape.moveToShape(dropShape); // adjust to the shape before repainting } else if(heavyShape.isVisible()) { heavyShape.setVisible(false); } } public void startDrag(DockableDragSource source) { if(isDragStarted || source == null) { // safety checks return; } Window aboveWindow = this.window; isDragStarted = true; if(heavyShape.getParent() == null) { // first use of the heavyshapes components if(aboveWindow instanceof JFrame) { JFrame fr = (JFrame) aboveWindow; fr.getLayeredPane().add(heavyShape, JLayeredPane.DRAG_LAYER); heavyShape.validate(); fr.getLayeredPane().add(heavyShape.label, JLayeredPane.DRAG_LAYER); } else if(aboveWindow instanceof JDialog) { JDialog dlg = (JDialog) aboveWindow; dlg.getLayeredPane().add(heavyShape, JLayeredPane.DRAG_LAYER); heavyShape.validate(); dlg.getLayeredPane().add(heavyShape.label, JLayeredPane.DRAG_LAYER); } heavyShape.setZOrder(); } heavyShape.label.setName(source.getDockable().getDockKey().getName()); // take a snapshot of the frame... ugly trick, but couldn't find anything better ! heavyShape.startDrag(); if(aboveWindow instanceof JFrame) { oldGlassPane = ((JFrame) aboveWindow).getGlassPane(); oldGlassPaneVisible = oldGlassPane.isVisible(); ((JFrame) aboveWindow).setGlassPane(dragGlassPane); dragGlassPane.setVisible(true); } else if(aboveWindow instanceof JDialog) { oldGlassPane = ((JDialog) aboveWindow).getGlassPane(); oldGlassPaneVisible = oldGlassPane.isVisible(); ((JDialog) aboveWindow).setGlassPane(dragGlassPane); dragGlassPane.setVisible(true); } } public void endDrag() { heavyShape.setVisible(false); Window aboveWindow = this.window;//SwingUtilities.getWindowAncestor(desktop); if(aboveWindow instanceof JFrame) { ((JFrame) aboveWindow).setGlassPane(oldGlassPane); } else if(aboveWindow instanceof JDialog) { ((JDialog) aboveWindow).setGlassPane(oldGlassPane); } oldGlassPane.setVisible(oldGlassPaneVisible); isDragStarted = false; } } /** heavyweight component used to paint shapes on top of heavyweight components */ private class HeavyShape extends Canvas { private static final long serialVersionUID = 1L; private Rectangle cachedShapeBounds; private BufferedImage desktopImage; // used for heavyweight painting private Image subImage; private Rectangle subImageBounds; private ShapeOutlinePainter outlinePainter = new ShapeOutlinePainter(); private HeavyLabel label = new HeavyLabel(); public HeavyShape() { setEnabled(false); // don't override the glaspane cursor } public void setZOrder() { // jdk1.5 only try { //desktop.setComponentZOrder(this, -1); // on top Method m = Container.class.getMethod("setComponentZOrder", new Class[] {Component.class, int.class}); m.invoke(getParent(), new Object[] {this, new Integer(0)}); } catch(Exception ignore) { } label.setZOrder(); } private void startDrag() { Container parent = getParent(); if(paintBackgroundUnderDragRect) { // 2007/02/27 if(desktopImage == null || (desktopImage.getWidth() != parent.getWidth()) || (desktopImage.getHeight() != parent.getHeight())) { desktopImage = (BufferedImage) parent.createImage(parent.getWidth(), parent.getHeight()); subImage = null; } Graphics g = desktopImage.getGraphics(); parent.paint(g); g.dispose(); } } public void paint(Graphics g) { if(dropShape != null) { Point p = SwingUtilities.convertPoint((Component) dropReceiver, 0, 0, getParent()); Rectangle r = dropShape.getBounds(); int shapeX = r.x, shapeY = r.y; if(paintBackgroundUnderDragRect) { r.x += p.x; r.y += p.y; r.width += 2; // stroked shape (+3 pixels, centered) r.height += 2; if(r.x + r.width > desktopImage.getWidth()) { r.width = desktopImage.getWidth() - r.x; } if(r.y + r.height > desktopImage.getHeight()) { r.height = desktopImage.getHeight() - r.y; } if(subImage == null || ! r.equals(subImageBounds)) { subImageBounds = r; subImage = desktopImage.getSubimage(r.x, r.y, r.width, r.height); } g.drawImage(subImage, 0, 0, null); } Shape s = AffineTransform.getTranslateInstance(- shapeX, - shapeY).createTransformedShape(dropShape); Graphics2D g2 = (Graphics2D) g; outlinePainter.paintShape(g2, s); } } public void setVisible(boolean visible) { super.setVisible(visible); label.setVisible(visible); } public void setCursor(Cursor cursor) { super.setCursor(cursor); label.setCursor(cursor); } /** moves and resizes the canvas to the position of the drop shape */ public void moveToShape(Shape newShape) { setVisible(true); @SuppressWarnings("unused") Shape s = dropShape; Container container = getParent(); Point p = SwingUtilities.convertPoint((Component) dropReceiver, 0, 0, container); Rectangle r = dropShape.getBounds(); r.x += p.x; r.y += p.y; r.width += 2; // shape has stroke(3), so we must extend it a little bit r.height += 2; if(r.x + r.width > container.getWidth()) { // check extend not out of bounds r.width = container.getWidth() - r.x; } if(r.y + r.height > container.getHeight()) { r.height = container.getHeight() - r.y; } if(! r.equals(cachedShapeBounds)) { setBounds(r); cachedShapeBounds = r; label.moveToCenter(r); } } } private class HeavyLabel extends Canvas { private static final long serialVersionUID = 1L; private Color textColor = Color.WHITE; private Color textFillColor = new Color(128, 128, 128); private Color textBorderColor = new Color(64, 64, 64); private String name; @SuppressWarnings("unused") private Icon icon; public HeavyLabel() { setEnabled(false); // don't override the glaspane cursor } public void setZOrder() { // jdk1.5 only (but we compile with source=1.4) try { //desktop.setComponentZOrder(this, -2); // on top of heavy panel Method m = Container.class.getMethod("setComponentZOrder", new Class[] {Component.class, int.class}); m.invoke(getParent(), new Object[] {this, new Integer(0)}); } catch(Exception ignore) { ignore.printStackTrace(); } } public void setName(String name) { this.name = name; } @SuppressWarnings("unused") public void setIcon(Icon icon) { this.icon = icon; } public void moveToCenter(Rectangle shapeBounds) { Font f = getFont(); if(f != null) { FontMetrics fm = getFontMetrics(f); int w = fm.stringWidth(name) + 10; int h = fm.getHeight() + 5; setBounds(shapeBounds.x + shapeBounds.width / 2 - w / 2, shapeBounds.y + shapeBounds.height / 2 - h / 2, w, h); } } public void paint(Graphics g) { FontMetrics fm = g.getFontMetrics(); int w = fm.stringWidth(name); int h = fm.getHeight(); g.setColor(textFillColor); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(textBorderColor); g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); g.setColor(textColor); g.drawString(name, getWidth() / 2 - w / 2, getHeight() / 2 + h / 2); } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/LightWeightDragControler.java000066400000000000000000000072211243334202400336040ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.Component; import java.awt.Container; import java.awt.Window; import javax.swing.JDialog; import javax.swing.JFrame; /** A Lightweight (standard) implementation of the drag controler, and its associated classes * * @author Lilian Chamontin, vlsolutions. * @since 3.0 */ class LightWeightDragControler extends AbstractDragControler { /** instantiates a controler for a given docking panel*/ LightWeightDragControler(DockingDesktop desktop) { super(desktop); } /** find the top most component of this container */ @Override protected Component findComponentAt(Container container, int x, int y) { return container.findComponentAt(x, y); } @Override protected ShapePainterStrategy createShapePainterStrategy(Window w) { return new LWShapePainterStrategy(w); } /** This class holds implementation strategies of shapes painting. *

* As painting is different when pure Swing is used (glasspane) and * heavyweight components are mixed in (glasspane + canvas). */ private class LWShapePainterStrategy implements ShapePainterStrategy { private DragControlerGlassPane dragGlassPane = new DragControlerGlassPane(LightWeightDragControler.this); private Component oldGlassPane = null; private boolean oldGlassPaneVisible = false; private Window window = null; private boolean isDragStarted = false; public LWShapePainterStrategy(Window window) { this.window = window; } /** show the drag cursor */ public void showDragCursor() { dragGlassPane.showDragCursor(); } /** show the stop-drag cursor (drag not enabled)*/ public void showStopDragCursor() { dragGlassPane.showStopDragCursor(); } /** show the stop-drag cursor (drag not enabled)*/ public void showSwapDragCursor() { dragGlassPane.showSwapDragCursor(); } /** show the float (detached) cursor */ public void showFloatCursor() { dragGlassPane.showFloatCursor(); } public void repaint() { /* this is a hack that will be refactored : we post a repaint when there is * a need to show a drag shape */ dragGlassPane.repaint(); } public void startDrag(DockableDragSource source) { if(isDragStarted || source == null) { // safety checks return; } Window aboveWindow = this.window; isDragStarted = true; if(aboveWindow instanceof JFrame) { oldGlassPane = ((JFrame) aboveWindow).getGlassPane(); oldGlassPaneVisible = oldGlassPane.isVisible(); ((JFrame) aboveWindow).setGlassPane(dragGlassPane); dragGlassPane.setVisible(true); } else if(aboveWindow instanceof JDialog) { oldGlassPane = ((JDialog) aboveWindow).getGlassPane(); oldGlassPaneVisible = oldGlassPane.isVisible(); ((JDialog) aboveWindow).setGlassPane(dragGlassPane); dragGlassPane.setVisible(true); } } public void endDrag() { Window aboveWindow = this.window;//SwingUtilities.getWindowAncestor(desktop); if(aboveWindow instanceof JFrame) { ((JFrame) aboveWindow).setGlassPane(oldGlassPane); } else if(aboveWindow instanceof JDialog) { ((JDialog) aboveWindow).setGlassPane(oldGlassPane); } oldGlassPane.setVisible(oldGlassPaneVisible); isDragStarted = false; } } }MaximizedComponentReplacer.java000066400000000000000000000016031243334202400341060ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import javax.swing.JComponent; /** A component used to replace the maximized dockable in the dockable container hierarchy *(as long as the dockable is maximized) * * @author Lilian Chamontin, VLSolutions */ class MaximizedComponentReplacer extends JComponent { private static final long serialVersionUID = 1L; public MaximizedComponentReplacer() {} } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/MaximizedDockView.java000066400000000000000000000025121243334202400322600ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.docking.event.DockDragEvent; import com.vlsolutions.swing.docking.event.DockDropEvent; /** A dockView suitable for maximized dockables * * @author Lilian Chamontin, VLSolutions * @update 2007/01/24 Lilian Chamontin : added DnD blocking (maximized components should't support * drag/drop from floating windows) */ public class MaximizedDockView extends DockView { private static final long serialVersionUID = 1L; public MaximizedDockView(Dockable dockable) { super(dockable, true); } /** maximized dockable don't support drag and drop */ public void processDockableDrag(DockDragEvent event) { //2007/01/24 event.rejectDrag(); } /** maximized dockable don't support drag and drop */ public void processDockableDrop(DockDropEvent event) { event.rejectDrop(); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/MaximizedDockViewAsTab.java000066400000000000000000000061461243334202400332020ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.docking.event.DockDragEvent; import com.vlsolutions.swing.docking.event.DockDropEvent; import java.awt.Point; import javax.swing.AbstractAction; import javax.swing.UIManager; /** A maximized view to use with the TabFactory. * * @author Lilian Chamontin, VLSolutions * @see TabFactory * @since 2.1.3 */ public class MaximizedDockViewAsTab extends DockViewAsTab { private static final long serialVersionUID = 1L; public MaximizedDockViewAsTab(Dockable dockable) { super(dockable); } protected void configureMaximizeButton() { if(isRestoreButtonDisplayed) { maximizeSmartIcon.setIcon(UIManager.getIcon("DockViewTitleBar.restore")); maximizeSmartIcon.setPressedIcon(UIManager.getIcon("DockViewTitleBar.restore.pressed")); maximizeSmartIcon.setRolloverIcon(UIManager.getIcon("DockViewTitleBar.restore.rollover")); // add a tooltip maximizeAction.putValue(AbstractAction.SHORT_DESCRIPTION, UIManager.get("DockViewTitleBar.restoreButtonText")); } } protected void configureFloatButton() { isFloatButtonDisplayed = false; } protected void configureHideButton() { isHideButtonDisplayed = false; } protected void configureCloseButton() { isCloseButtonDisplayed = false; } protected TabHeader createTabHeader() { return new MaximizedTabHeader(); } public void processDockableDrag(DockDragEvent event) { event.rejectDrag(); } public void processDockableDrop(DockDropEvent event) { event.rejectDrop(); } protected class MaximizedTabHeader extends TabHeader { private static final long serialVersionUID = 1L; /** {@inheritDoc} */ public boolean startDragComponent(Point p) { // disable DnD for some cases : // - child of a compound dockable, in hidden state // - child of a maximized compund dockable // - maximized dockable Dockable target = getDockable(); DockableState.Location targetState = target.getDockKey().getLocation(); if(targetState == DockableState.Location.HIDDEN) { if(DockingUtilities.isChildOfCompoundDockable(target)) { // nested hidden dockables cannot be drag and dropped return false; } } else if(targetState == DockableState.Location.DOCKED) { boolean isChildOfMaximizedContainer = false; if(desktop != null) { Dockable max = desktop.getMaximizedDockable(); if(max != null && max.getComponent().getParent().isAncestorOf(this)) { isChildOfMaximizedContainer = true; } } if(isChildOfMaximizedContainer) { return false; } } else if(targetState == DockableState.Location.MAXIMIZED) { return false; } return true; } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/RelativeDockablePosition.java000066400000000000000000000177741243334202400336420ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import javax.swing.*; import java.awt.*; /** This class is an immutable object used to remember the relative positionning * of docked components. *

* x, y, w, h fields are expressed with double values * varying from 0 to 1. *

*

    *
  • x : 0 = left, 1 = right *
  • y : 0 = top, 1 = bottom *
  • w : 0 = no width, 1-x = full remaining width *
  • h : 0 = no height, 1-y = full remaining height *
* *

* Objects of this class are used to reposition a Dockable on the desktop, based * on lazy constraints : As the desktop is a mix of horizontal and vertical * split panes ({@link SplitContainer}) it is not always possible to put a dockable * exactly where you want given a set of x,y, w, and h constraints. * * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public class RelativeDockablePosition { /** convenience field referencing the TOP border of the DockingDesktop */ public static final RelativeDockablePosition TOP = new RelativeDockablePosition(0, 0, 1, 0.2); /** convenience field referencing the CENTER part of TOP border of the DockingDesktop */ public static final RelativeDockablePosition TOP_CENTER = new RelativeDockablePosition(0.4, 0, 0.2, 0.2); /** convenience field referencing the TOP-RIGHT corner of the DockingDesktop */ public static final RelativeDockablePosition TOP_RIGHT = new RelativeDockablePosition(0, 0, 0.2, 0.2); /** convenience field referencing the TOP-LEFT corner of the DockingDesktop */ public static final RelativeDockablePosition TOP_LEFT = new RelativeDockablePosition(0.8, 0, 0.2, 0.2); /** convenience field referencing the RIGHT border of the DockingDesktop */ public static final RelativeDockablePosition RIGHT = new RelativeDockablePosition(0.8, 0, 0.2, 1); /** convenience field referencing the CENTER part of the RIGHT border of the DockingDesktop */ public static final RelativeDockablePosition RIGHT_CENTER = new RelativeDockablePosition(0.8, 0.4, 0.2, 0.2); /** convenience field referencing the TOP-RIGHT corner of the DockingDesktop */ public static final RelativeDockablePosition BOTTOM_RIGHT = new RelativeDockablePosition(0.8, 0.8, 0.2, 0.2); /** convenience field referencing the BOTTOM border of the DockingDesktop */ public static final RelativeDockablePosition BOTTOM = new RelativeDockablePosition(0, 0.8, 1, 0.2); /** convenience field referencing the CENTER part of the BOTTOM border of the DockingDesktop */ public static final RelativeDockablePosition BOTTOM_CENTER = new RelativeDockablePosition(0.4, 0.8, 0.2, 0.2); /** convenience field referencing the TOP-RIGHT corner of the DockingDesktop */ public static final RelativeDockablePosition BOTTOM_LEFT = new RelativeDockablePosition(0, 0.8, 0.2, 0.2); /** convenience field referencing the LEFT border of the DockingDesktop */ public static final RelativeDockablePosition LEFT = new RelativeDockablePosition(0, 0, 0.2, 1); /** convenience field referencing the CENTER part of the LEFT border of the DockingDesktop */ public static final RelativeDockablePosition LEFT_CENTER = new RelativeDockablePosition(0, 0.4, 0.2, 0.2); private double x, y, w; // relative positionning (0-1) of the component in the container /** The container used for relative positioning (can be a top level DockingPanel * or an intermediate CompoundDockingPanel) */ private Container relativeAncestorContainer; private double h; /** @see AnchorConstraints.ANCHOR_TOP (this field is an ORing of possible anchors) and contains * 4 boolean values (TOP, LEFT, BOTTOM, RIGHT) */ private int anchors; /** Construct a RelativeDockablePosition, assigning x, y, w, h values from the * current position of a dockable in its desktop container. *

* This constructor is a convenience for the framework, and should not be * used by API users (thus is package protected visibility). * */ RelativeDockablePosition(Container relativeAncestorContainer, Dockable dockable) { /* (package protected) */ resetRelativePosition(relativeAncestorContainer, dockable); } /** Constructs an empty relative position (all fields are initialized with 0.0 values) */ public RelativeDockablePosition() { } /** Constructs a relative position with given location and size. *

* Please remember that the values must be between 0 and 1, as they designate * relative coordinates position/size. * * @throws IllegalArgumentException if values are not in the given bounds * */ public RelativeDockablePosition(double x, double y, double w, double h) { this(null, x, y, w, h); } /** Constructs a relative position with a given location and size, relative to a container */ public RelativeDockablePosition(Container relativeAncestorContainer, double x, double y, double w, double h) { this.relativeAncestorContainer = relativeAncestorContainer; if(x < 0 || x > 1) { throw new IllegalArgumentException("x is out of bounds [0.0 , 1.0] " + x); } if(y < 0 || y > 1) { throw new IllegalArgumentException("y is out of bounds [0.0 , 1.0] " + y); } if(w < 0 || w > 1) { throw new IllegalArgumentException("w is out of bounds [0.0 , 1.0] " + w); } if(h < 0 || h > 1) { throw new IllegalArgumentException("h is out of bounds [0.0 , 1.0] " + h); } this.x = x; this.y = y; this.w = w; this.h = h; } /** Returns the relative x position of the dockable */ public double getX() { return x; } /** Returns the relative y position of the dockable */ public double getY() { return y; } /** Returns the relative width of the dockable */ public double getWidth() { return w; } /** Returns the relative height of the dockable */ public double getHeight() { return h; } /** Returns a meaningfull string representation of this RelativeDockablePosition */ public String toString() { return "RelativePosition [" + x + ", " + y + ", " + w + ", " + h + ", anchors=" + anchors + "]"; } /** Returns the ancestor container used as a reference for the relative potionning *

This can be a DockingPanel (top level ancestor) or CompoundDockingPanel (intermediate ancestor) */ public Container getRelativeAncestorContainer() { return relativeAncestorContainer; } /** Returns an integer value representing the anchoring of the dockable relatively to * its ancestor container. *

* For example a dockable at the top left angle of an ancestor container will have an * "anchors" value or : AnchorConstraints.ANCHOR_TOP|AnchorConstraints.ANCHOR_LEFT * @see AnchorConstraints */ public int getAnchors() { return anchors; } /** Updates the current relative ancestor container and anchor positionning */ public void resetRelativePosition(Container relativeAncestorContainer, Dockable dockable) { this.relativeAncestorContainer = relativeAncestorContainer; DockableContainer dockableContainer = DockingUtilities.findSingleDockableContainer(dockable); if(dockableContainer != null && relativeAncestorContainer != null) { Component c = (Component) dockableContainer; Rectangle converted = SwingUtilities.convertRectangle(c, new Rectangle(0, 0, c.getWidth(), c.getHeight()), relativeAncestorContainer); x = converted.x / (float) relativeAncestorContainer.getWidth(); y = converted.y / (float) relativeAncestorContainer.getHeight(); w = converted.width / (float) relativeAncestorContainer.getWidth(); h = converted.height / (float) relativeAncestorContainer.getHeight(); // also set boolean anchors this.anchors = RelativeDockingUtilities.findAnchors(dockable.getComponent(), relativeAncestorContainer); } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/RelativeDockingUtilities.java000066400000000000000000001727651243334202400336650ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.docking.event.DockingActionAddDockableEvent; import com.vlsolutions.swing.docking.event.DockingActionEvent; import com.vlsolutions.swing.docking.event.DockingActionSplitComponentEvent; import java.awt.*; import javax.swing.*; /** This class provides an algorithm for finding (and then inserting) the most suitable place to * show a dockable, based on a relative positionning. * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * @update 2005/10/10 Lilian Chamontin : improved heuristics of resizing (best matching of the appropriate SplitContainer) * @update 2005/10/10 Lilian Chamontin : improved again heuristics of resizing */ @SuppressWarnings("unused") class RelativeDockingUtilities { /* package class */ /* This class is an extraction of DockingDesktop - we will enhance (and complexify) * the algorithm later, * and should not mess up with DockingDesktop source code. * * */ private RelativeDockingUtilities() {} /** try to find the best suitable SplitContainer from where insertion will * be done. * */ private static SplitContainer findBestContainer(Container ancestorContainer, RelativeDockablePosition position) { // convert relative positionning to current positionning (depending // on the current size of dockingPanel) int x = (int) (position.getX() * ancestorContainer.getWidth()); int y = (int) (position.getY() * ancestorContainer.getHeight()); int w = (int) (position.getWidth() * ancestorContainer.getWidth()); int h = (int) (position.getHeight() * ancestorContainer.getHeight()); int centerX = x + w / 2; int centerY = y + h / 2; Component centerComp = ancestorContainer.findComponentAt(centerX, centerY); // find the splitcontainer containing centerComp, // and ensure this split is linked to ancestorContainer by a hierarchy of split containers // (to avoid selecting a split inside a sub-container) Component splitComp = centerComp; boolean found = false; while(splitComp != null && splitComp != ancestorContainer && ! found) { splitComp = splitComp.getParent(); if(splitComp instanceof SplitContainer) { // ok we've found a split : now let's check if there's a direct split hierarchy // between this one and the ancestor container Component up = splitComp.getParent(); while(up instanceof SplitContainer) { up = up.getParent(); } if(up == ancestorContainer) { found = true; } } } if(splitComp instanceof SplitContainer) { //2006/09/12 /* Try to find a larger splitcontainer that still fits well * with the position. * for example : * * [1|___2_____] * [1|[3|[4|5]]] * * if we remove "2", what remains is [1|[3|[4|5]]] * and on restoring, the selected split is [4|5], although [3|[4|5]] would be * a much better choice. * * to do that, we try to find the parent with the best "width" and "height" * */ float EPSILON = 0.05f; found = true; while(found && splitComp.getParent() instanceof SplitContainer) { found = false; float widthRatio = splitComp.getWidth() / (float) w; float heightRatio = splitComp.getHeight() / (float) h; SplitContainer parentSplit = (SplitContainer) splitComp.getParent(); float pWidthRatio = parentSplit.getWidth() / (float) w; float pHeightRatio = parentSplit.getHeight() / (float) h; boolean sameOrientation = ((SplitContainer) splitComp).getOrientation() == parentSplit.getOrientation(); if(sameOrientation) { if(parentSplit.getOrientation() == SplitContainer.HORIZONTAL_SPLIT) { // two horizontal, which one has the best width ? if(Math.abs(pWidthRatio - 1) < Math.abs(widthRatio - 1)) { //parents width is better : we upgrade splitcomp splitComp = splitComp.getParent(); found = true; // loop again } } else { // vertical == same width, is parent height better ? if(Math.abs(pHeightRatio - 1) < Math.abs(heightRatio - 1)) { //height is better : we upgrade splitcomp splitComp = splitComp.getParent(); found = true; // loop again } } } else { // opposite orientation if(parentSplit.getOrientation() == SplitContainer.HORIZONTAL_SPLIT) { // so split is V and parent is H // has parent a better width ratio ? if(Math.abs(pWidthRatio - 1) < Math.abs(widthRatio - 1)) { //parents width is better : we upgrade splitcomp splitComp = splitComp.getParent(); found = true; // loop again } } else { if(Math.abs(pHeightRatio - 1) < Math.abs(heightRatio - 1)) { //height is better : we upgrade splitcomp splitComp = splitComp.getParent(); found = true; // loop again } } } } } /*while (splitComp != null && splitComp != ancestorContainer && ! (splitComp instanceof SplitContainer)) { splitComp = splitComp.getParent(); }*/ if(splitComp instanceof SplitContainer) { // try to enhance the selection when there are global anchors //2005/10/10 // we're now looking for a split container whose anchors would better match // the ones of the dockable position // boolean anchoredTop = Math.abs( y - dockingPanel.getY()) < 5; // boolean anchoredLeft =Math.abs(x - dockingPanel.getX()) < 5; // boolean anchoredBottom = Math.abs(y + h - dockingPanel.getY() - dockingPanel.getHeight()) < 5; // boolean anchoredRight = Math.abs(x + w - dockingPanel.getX() - dockingPanel.getWidth()) < 5; /*boolean anchoredTop = y < 5; //2005/11/08 enhanced ! boolean anchoredLeft = x < 5; boolean anchoredBottom = Math.abs(y + h - ancestorContainer.getHeight()) < 5; boolean anchoredRight = Math.abs(x + w - ancestorContainer.getWidth()) < 5;*/ int anchors = position.getAnchors(); boolean anchoredTop = (anchors & AnchorConstraints.ANCHOR_TOP) > 0; boolean anchoredLeft = (anchors & AnchorConstraints.ANCHOR_LEFT) > 0; boolean anchoredBottom = (anchors & AnchorConstraints.ANCHOR_BOTTOM) > 0; boolean anchoredRight = (anchors & AnchorConstraints.ANCHOR_RIGHT) > 0; return findBetterContainer((SplitContainer) splitComp, ancestorContainer, anchoredTop, anchoredLeft, anchoredBottom, anchoredRight); } else { return null; } } /** try to find a SplitContainer up in the hierarchy, satisfying the global anchors */ private static SplitContainer findBetterContainer(SplitContainer split, Container dockingPanel, boolean anchoredTop, boolean anchoredLeft, boolean anchoredBottom, boolean anchoredRight) { // we already have found a splitContainer, but it can be subOptimal in some cases // for instance when we want to anchor a component at the bottom of the container (full width), // and there are two horizontal splits there, we might return the internal split (not full width), // and not the external (full width) one. // this method will try to find a splitcontainer upper in the hierarchy, with better anchors /*System.out.println("global anchors " + anchoredTop + " " + anchoredLeft + " " + anchoredBottom + " " + anchoredRight);*/ boolean[] globalAnchors = {anchoredTop, anchoredLeft, anchoredBottom, anchoredRight}; int globalCount = 0; // number of anchors to be found (at least) for(int i = 0; i < 4; i++) { if(globalAnchors[i]) { globalCount++; } } SplitContainer betterSplit = split; boolean[] splitAnchors = new boolean[4]; while(true) { int contacts = findAnchors(split, dockingPanel); splitAnchors[0] = (contacts & AnchorConstraints.ANCHOR_TOP) > 0; splitAnchors[1] = (contacts & AnchorConstraints.ANCHOR_LEFT) > 0; splitAnchors[2] = (contacts & AnchorConstraints.ANCHOR_BOTTOM) > 0; splitAnchors[3] = (contacts & AnchorConstraints.ANCHOR_RIGHT) > 0; int count = 0; for(int i = 0; i < 4; i++) { if(globalAnchors[i] && splitAnchors[i]) { count++; } } if(count >= globalCount) { return split; } else { if(split.getParent() instanceof SplitContainer) { split = (SplitContainer) split.getParent(); } else { return split; // last split container } } } } /** builds an array used to find anchors of a component relative to its ancestor container */ /* private static boolean [] findAnchors(Component comp, Container container){ Rectangle r = SwingUtilities.convertRectangle(comp, new Rectangle(0, 0, comp.getWidth(), comp.getHeight()), container); int x = container.getX(); int y = container.getY(); int w = container.getWidth(); int h = container.getHeight(); boolean [] anchors = new boolean [4]; anchors[0] = Math.abs( y - r.y) < 5; anchors[1] = Math.abs(x - r.x) < 5; anchors[2] = Math.abs(y + h - r.y - r.height) < 30; anchors[3] = Math.abs(x + w - r.x - r.width) < 5; return anchors; } */ /** Horizontally divide split and resize the new split * * @since 2004/04/24 * */ private static void hSplitAndResize(Component base, Component left, Component right, double proportion) { Container parent = base.getParent(); SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(parent, base, newSplit); newSplit.setLeftComponent(left); newSplit.setRightComponent(right); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportion)); } /** Vertically divide split and resize the new split * * @since 2004/04/24 * */ private static void vSplitAndResize(Component base, Component top, Component bottom, double proportion) { Container parent = base.getParent(); SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(parent, base, newSplit); newSplit.setTopComponent(top); newSplit.setBottomComponent(bottom); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportion)); } /** look up the split hierarchy to find which borders a component is touching * * @param base the component to find anchors for * @param ancestorContainer the top level ancestor used to stop searching */ public static int findAnchors(Component base, Container ancestorContainer) { int contact = AnchorConstraints.ANCHOR_TOP | AnchorConstraints.ANCHOR_LEFT | AnchorConstraints.ANCHOR_BOTTOM | AnchorConstraints.ANCHOR_RIGHT; Component comp = base.getParent(); Component child = base; while(comp != null && comp != ancestorContainer && contact != 0) { if(comp instanceof SplitContainer) { SplitContainer sc = (SplitContainer) comp; if(sc.getOrientation() == JSplitPane.VERTICAL_SPLIT) { if(sc.getTopComponent() == child) { contact = contact & (~ AnchorConstraints.ANCHOR_BOTTOM); // not at bottom } else { contact = contact & (~ AnchorConstraints.ANCHOR_TOP); // not on top } } else { if(sc.getLeftComponent() == child) { contact = contact & (~ AnchorConstraints.ANCHOR_RIGHT); // not right } else { contact = contact & (~ AnchorConstraints.ANCHOR_LEFT); // not left } } } child = comp; comp = comp.getParent(); } return contact; } /** Tries to find the best position to insert an hidden dockable, and insert it * @deprecated use getInsertionDockingAction / applyDockingAction instead */ public static SingleDockableContainer insertDockable(Container relativeAncestorContainer, Dockable dockable, RelativeDockablePosition position) { if(position == null) { // for safety position = new RelativeDockablePosition(0, 0.8, 0.5, 0.2); } SingleDockableContainer dockableContainer = null; if(relativeAncestorContainer.getComponentCount() == 0) { // empty docking panel dockableContainer = DockableContainerFactory.getFactory().createDockableContainer(dockable, DockableContainerFactory.ParentType.PARENT_DESKTOP); // default central insertion relativeAncestorContainer.add((Component) dockableContainer, BorderLayout.CENTER); relativeAncestorContainer.invalidate(); // 2005/05/04 relativeAncestorContainer.validate(); relativeAncestorContainer.repaint(); } else { dockableContainer = DockableContainerFactory.getFactory().createDockableContainer(dockable, DockableContainerFactory.ParentType.PARENT_SPLIT_CONTAINER); // convert relative positionning to current positionning (depending // on the current size of dockingPanel) int x = (int) (position.getX() * relativeAncestorContainer.getWidth()); int y = (int) (position.getY() * relativeAncestorContainer.getHeight()); int w = (int) (position.getWidth() * relativeAncestorContainer.getWidth()); int h = (int) (position.getHeight() * relativeAncestorContainer.getHeight()); int centerX = x + w / 2; int centerY = y + h / 2; SplitContainer split = findBestContainer(relativeAncestorContainer, position); if(split != null) { // ok we've found one /*Rectangle splitRect = SwingUtilities.convertRectangle(split, new Rectangle(0, 0, split.getWidth(), split.getHeight()), relativeAncestorContainer);*/ //int contacts = findAnchors(split, relativeAncestorContainer); int contacts = position.getAnchors(); // we use the anchors that // were computed on closing // heuristics : try to find an anchor, and which component(left/right) // is nearer of center /*boolean anchoredTop = Math.abs( y - splitRect.y) < 5; boolean anchoredLeft = Math.abs(x - splitRect.x) < 5; boolean anchoredBottom = Math.abs(y + h - splitRect.y - splitRect.height) < 30; boolean anchoredRight = Math.abs(x + w - splitRect.x - splitRect.width) < 5;*/ boolean anchoredTop = (contacts & AnchorConstraints.ANCHOR_TOP) > 0; boolean anchoredLeft = (contacts & AnchorConstraints.ANCHOR_LEFT) > 0; boolean anchoredBottom = (contacts & AnchorConstraints.ANCHOR_BOTTOM) > 0; boolean anchoredRight = (contacts & AnchorConstraints.ANCHOR_RIGHT) > 0; // System.out.println("anchors : " + anchoredTop + ", "+ anchoredLeft + ", " // + anchoredBottom + ", " + anchoredRight); Component left = split.getLeftComponent(); Component right = split.getRightComponent(); Point leftCenter = SwingUtilities.convertPoint(left, left.getWidth() / 2, left.getHeight() / 2, relativeAncestorContainer); Point rightCenter = SwingUtilities.convertPoint(right, right.getWidth() / 2, right.getHeight() / 2, relativeAncestorContainer); int leftDist = (leftCenter.x - x) * (leftCenter.x - x) + (leftCenter.y - y) * (leftCenter.y); int rightDist = (rightCenter.x - x) * (rightCenter.x - x) + (rightCenter.y - y) * (rightCenter.y); Point bestCenter; Component bestComp; if(leftDist < rightDist) { bestCenter = leftCenter; bestComp = left; } else { bestCenter = rightCenter; bestComp = right; } //2006/09/12 /* If the split matches the size of the component, then * we'll have to split it (and not split one of its children) */ float splitWidthRatio = Math.abs(1 - split.getWidth() / (float) w); float splitHeightRatio = Math.abs(1 - split.getHeight() / (float) h); /** this will happen only when anchors are not too strict (like top+right) * for wider anchors (left-top-right) this ration is not used as * superflous */ if(split.getOrientation() == JSplitPane.VERTICAL_SPLIT) { Component top = split.getTopComponent(); Component bottom = split.getBottomComponent(); int topH = top.getHeight(); int bottomH = bottom.getHeight(); // proportions used when splitting a vertical split vertically float proportionTopH = h / (float) topH; float proportionBottomH = h / (float) bottomH; if(proportionTopH >= 0.6f) { // not too big proportionTopH = 0.6f; } if(proportionBottomH >= 0.6f) { // not too big proportionBottomH = 0.6f; } // proportions used when splitting a vertical split horizontally int splitW = split.getWidth(); float proportionW = w / (float) splitW; if(proportionW >= 0.8f) { // not too big proportionW = 0.8f; } if(anchoredTop) { if(anchoredLeft) { if(anchoredBottom) { // TLB = full left SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setLeftComponent((Component) dockableContainer); newSplit.setRightComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionW)); } else { // Top + left if(splitWidthRatio < 0.1f && split.getHeight() > h) {//2006/09/12 // almost the same width, but the split is taller : we split it // vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setTopComponent((Component) dockableContainer); newSplit.setBottomComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, h / (float) split.getHeight())); } else { SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, top, newSplit); newSplit.setLeftComponent((Component) dockableContainer); newSplit.setRightComponent(top); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionW)); } } } else if(anchoredRight) { // TR if(anchoredBottom) { // TRB = full right SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setRightComponent((Component) dockableContainer); newSplit.setLeftComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionW)); } else { if(splitWidthRatio < 0.1f && split.getHeight() > h) { // 2006/09/12 // almost the same width, but the split is taller : we split it // vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setTopComponent((Component) dockableContainer); newSplit.setBottomComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, h / (float) split.getHeight())); } else { SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, top, newSplit); newSplit.setLeftComponent(top); newSplit.setRightComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionW)); } } } else { // just anchored top SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, top, newSplit); newSplit.setTopComponent((Component) dockableContainer); newSplit.setBottomComponent(top); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionTopH)); } } else if(anchoredBottom) { // but not anchoredTop if(anchoredLeft) { //BL if(anchoredRight) { //BLR = full bottom SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, bottom, newSplit); newSplit.setTopComponent(bottom); newSplit.setBottomComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionBottomH)); } else { if(splitWidthRatio < 0.1f && split.getHeight() > h) { // 2006/09/12 // almost the same width, but the split is taller : we split it // vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setBottomComponent((Component) dockableContainer); newSplit.setTopComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - h / (float) split.getHeight())); } else { SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, bottom, newSplit); newSplit.setLeftComponent((Component) dockableContainer); newSplit.setRightComponent(bottom); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionW)); } } } else if(anchoredRight) { // BR if(splitWidthRatio < 0.1f && split.getHeight() > h) { // 2006/09/12 // almost the same width, but the split is taller : we split it // vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setBottomComponent((Component) dockableContainer); newSplit.setTopComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - h / (float) split.getHeight())); } else { SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, bottom, newSplit); newSplit.setLeftComponent(bottom); newSplit.setRightComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionW)); } } else { // just anchored bottom SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, bottom, newSplit); newSplit.setTopComponent(bottom); newSplit.setBottomComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionBottomH)); } } else if(anchoredLeft) { // not anchored on top / bottom if(anchoredRight) { //2005/10/10 // left + right on a vertical split, means we have to insert a new component // in between int yTop = y; int yBottom = split.getHeight() - y - h; int splitTop = top.getHeight(); int splitBottom = bottom.getHeight(); SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit); if(bestComp == top) { newSplit.setTopComponent(bestComp); newSplit.setBottomComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(split, (split.getHeight() - yBottom) / (float) split.getHeight())); SwingUtilities.invokeLater(new SplitResizer(newSplit, yTop / (float) split.getHeight())); } else { newSplit.setBottomComponent(bestComp); newSplit.setTopComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(split, yTop / (float) split.getHeight())); SwingUtilities.invokeLater(new SplitResizer(newSplit, h / (float) splitBottom)); } } else {// only left SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit); newSplit.setRightComponent(bestComp); newSplit.setLeftComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionW)); } } else if(anchoredRight) { SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit); newSplit.setLeftComponent(bestComp); newSplit.setRightComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionW)); } else { // not anchored at all, split verticaly and add // todo : check how it's done now for the split-h part and do the same here SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit); if(bestCenter.y < centerY) { newSplit.setTopComponent(bestComp); newSplit.setBottomComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionBottomH)); } else { newSplit.setBottomComponent(bestComp); newSplit.setTopComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionTopH)); } } } else { // horizontal split // proportions used when splitting a horizontal split horizontally float proportionLeftW = w / (float) left.getWidth(); float proportionRightW = w / (float) right.getWidth(); if(proportionLeftW >= 0.8f) { // not too big proportionLeftW = 0.8f; } if(proportionRightW >= 0.8f) { // not too big proportionRightW = 0.8f; } // proportions used when splitting a horizontal split vertically int splitH = split.getHeight(); float proportionH = h / (float) splitH; if(proportionH >= 0.6f) { // not too big proportionH = 0.6f; } if(anchoredTop) { if(anchoredLeft) { if(anchoredBottom) { // TLB = full left SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, left, newSplit); newSplit.setLeftComponent((Component) dockableContainer); newSplit.setRightComponent(left); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionLeftW)); } else if(anchoredRight) { // TLR = full top SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setTopComponent((Component) dockableContainer); newSplit.setBottomComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionH)); } else { // just anchored top/left if(splitWidthRatio < 0.1f && split.getHeight() > h) { // 2006/09/12 // almost the same width, but the split is taller : we split it // vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setTopComponent((Component) dockableContainer); newSplit.setBottomComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, h / (float) split.getHeight())); } else { // otherwise we just split vertically on the left side SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, left, newSplit); newSplit.setTopComponent((Component) dockableContainer); newSplit.setBottomComponent(left); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionH)); } } } else if(anchoredRight) { // Top but not left if(anchoredBottom) { // top + right + bottom == full right SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, right, newSplit); newSplit.setRightComponent((Component) dockableContainer); newSplit.setLeftComponent(right); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionRightW)); } else { // top + right if(splitWidthRatio < 0.1f && split.getHeight() > h) { // 2006/09/12 // almost the same width, but the split is taller : we split it // vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setTopComponent((Component) dockableContainer); newSplit.setBottomComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, h / (float) split.getHeight())); } else { SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, right, newSplit); newSplit.setBottomComponent(right); newSplit.setTopComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionH)); } } } else if(anchoredBottom) { //2005/10/10 // top + bottom : create a horizontal split // as we are inserting a vertical element into a horizontal split // we have to adjust the width on both sides int xLeft = x; int xRight = split.getWidth() - x - w; int splitLeft = left.getWidth(); int splitRight = right.getWidth(); SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit); if(bestComp == left) { newSplit.setLeftComponent(bestComp); newSplit.setRightComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(split, (split.getWidth() - xRight) / (float) split.getWidth())); SwingUtilities.invokeLater(new SplitResizer(newSplit, xLeft / (float) split.getWidth())); } else { newSplit.setRightComponent(bestComp); newSplit.setLeftComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(split, xLeft / (float) split.getWidth())); SwingUtilities.invokeLater(new SplitResizer(newSplit, w / (float) splitRight)); } } else { // just anchored top if(splitWidthRatio < 0.1f && split.getHeight() > h) { // 2006/09/12 // almost the same width, but the split is taller : we split it // vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setTopComponent((Component) dockableContainer); newSplit.setBottomComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, h / (float) split.getHeight())); } else { SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit); newSplit.setTopComponent((Component) dockableContainer); newSplit.setBottomComponent(bestComp); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionH)); } } } else if(anchoredBottom) { // but not anchoredTop if(anchoredLeft) { if(anchoredRight) { // BLR == full bottom SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setTopComponent(split); newSplit.setBottomComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionH)); } else { // bottom + left if(splitWidthRatio < 0.1f && split.getHeight() > h) { // 2006/09/12 // almost the same width, but the split is taller : we split it // vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setBottomComponent((Component) dockableContainer); newSplit.setTopComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - h / (float) split.getHeight())); } else { SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, left, newSplit); newSplit.setBottomComponent((Component) dockableContainer); newSplit.setTopComponent(left); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionH)); } } } else if(anchoredRight) { // bottom + right if(splitWidthRatio < 0.1f && split.getHeight() > h) { // 2006/09/12 // almost the same width, but the split is taller : we split it // vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setBottomComponent((Component) dockableContainer); newSplit.setTopComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - h / (float) split.getHeight())); } else { SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, right, newSplit); newSplit.setTopComponent(right); newSplit.setBottomComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionH)); } } else { // just anchored bottom if(splitWidthRatio < 0.1f && split.getHeight() > h) { // 2006/09/12 // almost the same width, but the split is taller : we split it // vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setBottomComponent((Component) dockableContainer); newSplit.setTopComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - h / (float) split.getHeight())); } else { SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit); newSplit.setTopComponent(bestComp); newSplit.setBottomComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionH)); } } } else if(anchoredLeft) { // not anchored on top / bottom if(anchoredRight) { // left + right... we have to split vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setTopComponent((Component) dockableContainer); newSplit.setBottomComponent(split); // todo : check this case : why is the new component on top SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionH)); } else { // just left if(splitWidthRatio < 0.1f && split.getHeight() > h) { // 2006/09/12 // almost the same width, but the split is taller : we split it // vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setTopComponent((Component) dockableContainer); newSplit.setBottomComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, h / (float) split.getHeight())); } else { SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, left, newSplit); newSplit.setRightComponent(left); newSplit.setLeftComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionLeftW)); } } } else if(anchoredRight) { if(splitWidthRatio < 0.1f && split.getHeight() > h) { // 2006/09/12 // almost the same width, but the split is taller : we split it // vertically SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split.getParent(), split, newSplit); newSplit.setTopComponent((Component) dockableContainer); newSplit.setBottomComponent(split); SwingUtilities.invokeLater(new SplitResizer(newSplit, h / (float) split.getHeight())); } else { SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, right, newSplit); newSplit.setLeftComponent(right); newSplit.setRightComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionRightW)); } } else { // not anchored at all // this part can be improved : // - we know we're into an horizontal split // - we can guess if the component was horizontaly splitted or vertically, // and on which side of the split if was (bestComp) float widthIfSplitH = bestComp.getWidth() / 2; float heightIfSplitH = bestComp.getHeight(); float widthIfSplitV = bestComp.getWidth(); float heightIfSplitV = bestComp.getHeight() / 2; // now which case keeps the best proportions ? float whH = widthIfSplitH / heightIfSplitH; float whV = widthIfSplitV / heightIfSplitV; float whBefore = w / (float) h; if(Math.abs(whBefore - whV) < Math.abs(whBefore - whH)) { // nearer of V SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit); if(bestCenter.y < centerY) { newSplit.setTopComponent(bestComp); newSplit.setBottomComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, 1 - proportionH)); } else { newSplit.setBottomComponent(bestComp); newSplit.setTopComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionH)); } } else { SplitContainer newSplit = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit); if(bestCenter.x < centerX) { newSplit.setLeftComponent(bestComp); newSplit.setRightComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionRightW)); } else { newSplit.setRightComponent(bestComp); newSplit.setLeftComponent((Component) dockableContainer); SwingUtilities.invokeLater(new SplitResizer(newSplit, proportionLeftW)); } } } } } else { // 2004/04/01 (this part was missing) ------------------------------ // one component, but not a split container // heuristics : try to find an anchor boolean anchoredTop = y < 5; boolean anchoredLeft = x < 5; boolean anchoredBottom = Math.abs(y + h - relativeAncestorContainer.getHeight()) < 5; boolean anchoredRight = Math.abs(x + w - relativeAncestorContainer.getWidth()) < 5; Component singleComp = relativeAncestorContainer.getComponent(0); float proportionW = w / (float) relativeAncestorContainer.getWidth(); if(proportionW >= 0.8f) { // not too big proportionW = 0.8f; } float proportionH = h / (float) relativeAncestorContainer.getHeight(); if(proportionH >= 0.6f) { // not too big proportionH = 0.6f; } if(anchoredTop) { if(anchoredLeft) { if(anchoredBottom) { hSplitAndResize(singleComp, (Component) dockableContainer, singleComp, proportionW); } else if(anchoredRight) { // top + left + right == TOP vSplitAndResize(singleComp, (Component) dockableContainer, singleComp, proportionH); } else { // top + left... what should we do ? if(w > h) { vSplitAndResize(singleComp, (Component) dockableContainer, singleComp, proportionH); } else { hSplitAndResize(singleComp, (Component) dockableContainer, singleComp, proportionW); } } } else if(anchoredRight) { // top + right (not left) if(anchoredBottom) { // top + right + bottom == on the right hSplitAndResize(singleComp, singleComp, (Component) dockableContainer, 1 - proportionW); } else { // top + right if(w > h) { // on top vSplitAndResize(singleComp, (Component) dockableContainer, singleComp, proportionH); } else { // on the right hSplitAndResize(singleComp, singleComp, (Component) dockableContainer, 1 - proportionW); } } } else { // top only vSplitAndResize(singleComp, (Component) dockableContainer, singleComp, proportionH); } } else if(anchoredLeft) { //left (but not top) if(anchoredBottom) { // left + bot if(anchoredRight) { // == bottom vSplitAndResize(singleComp, singleComp, (Component) dockableContainer, 1 - proportionH); } else { // left + bottom if(w > h) { // bottom vSplitAndResize(singleComp, singleComp, (Component) dockableContainer, 1 - proportionH); } else { // on the left hSplitAndResize(singleComp, (Component) dockableContainer, singleComp, proportionW); } } } else if(anchoredRight) { // left + right, but not top/bottom... if(centerY < relativeAncestorContainer.getHeight() / 2) { // center is upper part vSplitAndResize(singleComp, (Component) dockableContainer, singleComp, proportionH); } else { // lower part vSplitAndResize(singleComp, singleComp, (Component) dockableContainer, 1 - proportionH); } } else { // left only hSplitAndResize(singleComp, (Component) dockableContainer, singleComp, proportionW); } } else if(anchoredBottom) { // bottom, but not top/left if(anchoredRight) { if(w > h) { // bottom vSplitAndResize(singleComp, singleComp, (Component) dockableContainer, 1 - proportionH); } else { // on the right hSplitAndResize(singleComp, singleComp, (Component) dockableContainer, 1 - proportionW); } } else { // just bottom vSplitAndResize(singleComp, singleComp, (Component) dockableContainer, 1 - proportionH); } } else if(anchoredRight) { // just right hSplitAndResize(singleComp, singleComp, (Component) dockableContainer, 1 - proportionW); } else { // no anchors if(centerY < relativeAncestorContainer.getHeight() / 2) { // center is upper part vSplitAndResize(singleComp, (Component) dockableContainer, singleComp, proportionH); } else { vSplitAndResize(singleComp, singleComp, (Component) dockableContainer, 1 - proportionH); } } } // 2004/04/01 (end of missing part) ------------------------------ } return dockableContainer; //DockingActionEvent action = getInsertionDockingAction(relativeAncestorContainer, dockable, position); //return applyDockingAction(dockable, action); } /** returns a docking action event corresponding to the insertion point and method * of the dockable. */ public static DockingActionEvent getInsertionDockingAction(Container relativeAncestorContainer, Dockable dockable, DockableState dockableState, DockableState newState) { RelativeDockablePosition position = dockableState.getPosition(); DockingDesktop desktop = dockableState.getDesktop(); DockableState.Location initialState = dockableState.getLocation(); DockableState.Location nextState = newState.getLocation(); if(position == null) { // for safety position = new RelativeDockablePosition(0, 0.8, 0.5, 0.2); } SingleDockableContainer dockableContainer = null; if(relativeAncestorContainer.getComponentCount() == 0) { // empty docking panel return new DockingActionAddDockableEvent(desktop, dockable, initialState, nextState, relativeAncestorContainer); } else { // convert relative positionning to current positionning (depending // on the current size of dockingPanel) int x = (int) (position.getX() * relativeAncestorContainer.getWidth()); int y = (int) (position.getY() * relativeAncestorContainer.getHeight()); int w = (int) (position.getWidth() * relativeAncestorContainer.getWidth()); int h = (int) (position.getHeight() * relativeAncestorContainer.getHeight()); int centerX = x + w / 2; int centerY = y + h / 2; SplitContainer split = findBestContainer(relativeAncestorContainer, position); if(split != null) { // ok we've found one Rectangle splitRect = SwingUtilities.convertRectangle(split, new Rectangle(0, 0, split.getWidth(), split.getHeight()), relativeAncestorContainer); // heuristics : try to find an anchor, and which component(left/right) // is nearer of center boolean anchoredTop = Math.abs(y - splitRect.y) < 5; boolean anchoredLeft = Math.abs(x - splitRect.x) < 5; boolean anchoredBottom = Math.abs(y + h - splitRect.y - splitRect.height) < 30/*5*/; boolean anchoredRight = Math.abs(x + w - splitRect.x - splitRect.width) < 5; Component left = split.getLeftComponent(); Component right = split.getRightComponent(); Point leftCenter = SwingUtilities.convertPoint(left, left.getWidth() / 2, left.getHeight() / 2, relativeAncestorContainer); Point rightCenter = SwingUtilities.convertPoint(right, right.getWidth() / 2, right.getHeight() / 2, relativeAncestorContainer); int leftDist = (leftCenter.x - x) * (leftCenter.x - x) + (leftCenter.y - y) * (leftCenter.y); int rightDist = (rightCenter.x - x) * (rightCenter.x - x) + (rightCenter.y - y) * (rightCenter.y); Point bestCenter; Component bestComp; if(leftDist < rightDist) { bestCenter = leftCenter; bestComp = left; } else { bestCenter = rightCenter; bestComp = right; } if(split.getOrientation() == JSplitPane.VERTICAL_SPLIT) { Component top = split.getTopComponent(); Component bottom = split.getBottomComponent(); int topH = top.getHeight(); int bottomH = bottom.getHeight(); // proportions used when splitting a vertical split vertically float proportionTopH = h / (float) topH; float proportionBottomH = h / (float) bottomH; if(proportionTopH >= 0.6f) { // not too big proportionTopH = 0.6f; } if(proportionBottomH >= 0.6f) { // not too big proportionBottomH = 0.6f; } // proportions used when splitting a vertical split horizontally int splitW = split.getWidth(); float proportionW = w / (float) splitW; if(proportionW >= 0.8f) { // not too big proportionW = 0.8f; } if(anchoredTop) { if(anchoredLeft) { if(anchoredBottom) { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, split, DockingConstants.SPLIT_LEFT, proportionW); } else { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, top, DockingConstants.SPLIT_LEFT, proportionW); } } else if(anchoredRight) { if(anchoredBottom) { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, split, DockingConstants.SPLIT_RIGHT, 1 - proportionW); } else { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, top, DockingConstants.SPLIT_RIGHT, 1 - proportionW); } } else { // just anchored top return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, top, DockingConstants.SPLIT_TOP, proportionTopH); } } else if(anchoredBottom) { // but not anchoredTop if(anchoredLeft) { if(anchoredRight) { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bottom, DockingConstants.SPLIT_BOTTOM, 1 - proportionBottomH); } else { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bottom, DockingConstants.SPLIT_LEFT, proportionW); } } else if(anchoredRight) { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bottom, DockingConstants.SPLIT_RIGHT, 1 - proportionW); } else { // just anchored bottom return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bottom, DockingConstants.SPLIT_BOTTOM, 1 - proportionBottomH); } } else if(anchoredLeft) { // not anchored on top / bottom if(anchoredRight) { //2005/10/10 // left + right on a vertical split, means we have to insert a new component // in between int yTop = y; int yBottom = split.getHeight() - y - h; int splitTop = top.getHeight(); int splitBottom = bottom.getHeight(); /*SplitContainer newSplit = new SplitContainer(JSplitPane. VERTICAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit);*/ if(bestComp == top) { float hParent = (split.getHeight() - yBottom) / (float) split.getHeight(); float hChild = yTop / (float) split.getHeight(); return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bestComp, DockingConstants.SPLIT_BOTTOM, hChild, hParent); } else { float hChild = h / (float) splitBottom; float hParent = yTop / (float) split.getHeight(); return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bestComp, DockingConstants.SPLIT_TOP, hChild, hParent); } } else {// only left return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bestComp, DockingConstants.SPLIT_LEFT, proportionW); } } else if(anchoredRight) { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bestComp, DockingConstants.SPLIT_RIGHT, 1 - proportionW); } else { // not anchored at all, split verticaly and add SplitContainer newSplit = new SplitContainer(JSplitPane.VERTICAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit); if(bestCenter.y < centerY) { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bestComp, DockingConstants.SPLIT_BOTTOM, 1 - proportionBottomH); } else { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bestComp, DockingConstants.SPLIT_TOP, proportionTopH); } } } else { // horizontal split // proportions used when splitting a horizontal split horizontally float proportionLeftW = w / (float) left.getWidth(); float proportionRightW = w / (float) right.getWidth(); if(proportionLeftW >= 0.8f) { // not too big proportionLeftW = 0.8f; } if(proportionRightW >= 0.8f) { // not too big proportionRightW = 0.8f; } // proportions used when splitting a horizontal split vertically int splitH = split.getHeight(); float proportionH = h / (float) splitH; if(proportionH >= 0.6f) { // not too big proportionH = 0.6f; } if(anchoredTop) { if(anchoredLeft) { if(anchoredBottom) { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, left, DockingConstants.SPLIT_LEFT, proportionLeftW); } else if(anchoredRight) { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, split, DockingConstants.SPLIT_TOP, proportionH); } else { // just anchored top/left return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, left, DockingConstants.SPLIT_TOP, proportionH); } } else if(anchoredRight) { if(anchoredBottom) { // top + right + bottom return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, right, DockingConstants.SPLIT_RIGHT, 1 - proportionRightW); } else { // top + right return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, right, DockingConstants.SPLIT_TOP, proportionH); } } else if(anchoredBottom) { //2005/10/10 // top + bottom : create a horizontal split // as we are inserting a vertical element into a horizontal split // we have to adjust the width on both sides int xLeft = x; int xRight = split.getWidth() - x - w; int splitLeft = left.getWidth(); int splitRight = right.getWidth(); /*SplitContainer newSplit = new SplitContainer(JSplitPane. HORIZONTAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit);*/ if(bestComp == left) { float parentW = (split.getWidth() - xRight) / (float) split.getWidth(); float childW = xLeft / (float) split.getWidth(); return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bestComp, DockingConstants.SPLIT_RIGHT, childW, parentW); } else { float parentW = xLeft / (float) split.getWidth(); float childW = w / (float) splitRight; return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bestComp, DockingConstants.SPLIT_LEFT, childW, parentW); } } else { // just anchored top return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bestComp, DockingConstants.SPLIT_TOP, proportionH); } } else if(anchoredBottom) { // but not anchoredTop if(anchoredLeft) { if(anchoredRight) { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, split, DockingConstants.SPLIT_BOTTOM, 1 - proportionH); } else { // bottom + left return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, left, DockingConstants.SPLIT_BOTTOM, 1 - proportionH); } } else if(anchoredRight) { // bottom + right return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, right, DockingConstants.SPLIT_BOTTOM, 1 - proportionH); } else { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bestComp, DockingConstants.SPLIT_BOTTOM, 1 - proportionH); } } else if(anchoredLeft) { // not anchored on top / bottom return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, left, DockingConstants.SPLIT_LEFT, proportionLeftW); } else if(anchoredRight) { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, right, DockingConstants.SPLIT_RIGHT, 1 - proportionRightW); } else { // not anchored at all, split verticaly and add /*SplitContainer newSplit = new SplitContainer(JSplitPane. VERTICAL_SPLIT); DockingUtilities.replaceChild(split, bestComp, newSplit);*/ if(bestCenter.y < centerY) { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bestComp, DockingConstants.SPLIT_BOTTOM, 1 - proportionH); } else { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, bestComp, DockingConstants.SPLIT_TOP, proportionH); } } } } else { // 2004/04/01 (this part was missing) ------------------------------ // one component, but not a split container // heuristics : try to find an anchor boolean anchoredTop = y < 5; boolean anchoredLeft = x < 5; boolean anchoredBottom = Math.abs(y + h - relativeAncestorContainer.getHeight()) < 5; boolean anchoredRight = Math.abs(x + w - relativeAncestorContainer.getWidth()) < 5; Component singleComp = relativeAncestorContainer.getComponent(0); float proportionW = w / (float) relativeAncestorContainer.getWidth(); if(proportionW >= 0.8f) { // not too big proportionW = 0.8f; } float proportionH = h / (float) relativeAncestorContainer.getHeight(); if(proportionH >= 0.6f) { // not too big proportionH = 0.6f; } if(anchoredTop) { if(anchoredLeft) { if(anchoredBottom) { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_LEFT, proportionW); } else if(anchoredRight) { // top + left + right == TOP return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_TOP, proportionH); } else { // top + left... what should we do ? if(w > h) { // vsplit return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_TOP, proportionH); } else { // hsplit return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_LEFT, proportionW); } } } else if(anchoredRight) { // top + right (not left) if(anchoredBottom) { // top + right + bottom == on the right return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_RIGHT, 1 - proportionW); } else { // top + right if(w > h) { // on top return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_TOP, proportionH); } else { // on the right return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_RIGHT, 1 - proportionW); } } } else { // top only return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_TOP, proportionH); } } else if(anchoredLeft) { //left (but not top) if(anchoredBottom) { // left + bot if(anchoredRight) { // == bottom return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_BOTTOM, 1 - proportionH); } else { // left + bottom if(w > h) { // bottom return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_BOTTOM, 1 - proportionH); } else { // on the left return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_LEFT, proportionW); } } } else if(anchoredRight) { // left + right, but not top/bottom... if(centerY < relativeAncestorContainer.getHeight() / 2) { // center is upper part return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_TOP, proportionH); } else { // lower part return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_BOTTOM, 1 - proportionH); } } else { // left only return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_LEFT, proportionW); } } else if(anchoredBottom) { // bottom, but not top/left if(anchoredRight) { if(w > h) { // bottom return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_BOTTOM, 1 - proportionH); } else { // on the right return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_RIGHT, 1 - proportionW); } } else { // just bottom return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_BOTTOM, 1 - proportionH); } } else if(anchoredRight) { // just right return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_RIGHT, 1 - proportionW); } else { // no anchors if(centerY < relativeAncestorContainer.getHeight() / 2) { // center is upper part return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_TOP, proportionH); } else { return new DockingActionSplitComponentEvent(desktop, dockable, initialState, nextState, singleComp, DockingConstants.SPLIT_BOTTOM, 1 - proportionH); } } } } } public static SingleDockableContainer applyDockingAction(Dockable dockable, DockingActionEvent action) { SingleDockableContainer dockableContainer; switch(action.getActionType()) { case DockingActionEvent.ACTION_ADD_DOCKABLE: DockingActionAddDockableEvent addAction = (DockingActionAddDockableEvent) action; dockableContainer = DockableContainerFactory.getFactory().createDockableContainer(dockable, DockableContainerFactory.ParentType.PARENT_DESKTOP); Container relativeAncestorContainer = addAction.getParentContainer(); // default central insertion relativeAncestorContainer.add((Component) dockableContainer, BorderLayout.CENTER); relativeAncestorContainer.invalidate(); // 2005/05/04 relativeAncestorContainer.validate(); relativeAncestorContainer.repaint(); return dockableContainer; case DockingActionEvent.ACTION_SPLIT_COMPONENT: dockableContainer = DockableContainerFactory.getFactory().createDockableContainer(dockable, DockableContainerFactory.ParentType.PARENT_SPLIT_CONTAINER); DockingActionSplitComponentEvent splitAction = (DockingActionSplitComponentEvent) action; Component base = splitAction.getBase(); float div = splitAction.getDividorLocation(); DockingConstants.Split splitPosition = splitAction.getSplitPosition(); float parentDiv = splitAction.getParentDividorLocation(); switch(splitPosition.value()) { case DockingConstants.INT_SPLIT_TOP: vSplitAndResize(base, (Container) dockableContainer, base, div); break; case DockingConstants.INT_SPLIT_LEFT: hSplitAndResize(base, (Container) dockableContainer, base, div); break; case DockingConstants.INT_SPLIT_BOTTOM: vSplitAndResize(base, base, (Container) dockableContainer, div); break; case DockingConstants.INT_SPLIT_RIGHT: hSplitAndResize(base, base, (Container) dockableContainer, div); break; } if(parentDiv != - 1 && base.getParent() instanceof SplitContainer) { SplitContainer parent = (SplitContainer) base.getParent(); new SplitResizer(parent, parentDiv); } return dockableContainer; default: throw new IllegalArgumentException("Action type not managed : " + action.getActionType()); } } }vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ShadowBorder.java000066400000000000000000000063031243334202400312620ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import javax.swing.border.*; import java.awt.Component; import java.awt.Graphics; import java.awt.Insets; import java.awt.*; import javax.swing.*; /** A border using a shadow on right-bottom sides. * *

* Two types of border can be drawn : full shadow border and half shadow border. *

    *
  • full shadow border paints darker lines on top and left to define a rectangular shape * (this is the kind of border used by DockableContainers (DockViews). * half shadow border paints only a shadow (nothing on top and right) : it is used for * DockedTabbedPane contents. *
* * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public class ShadowBorder implements Border { private static Insets INSETS_FULL = new Insets(3, 2, 5, 5); private static Insets INSETS_HALF = new Insets(1, 1, 5, 5); private static Image shadowImage = new ImageIcon(ShadowBorder.class.getResource("shadow.png")).getImage(); static int shadowW = shadowImage.getWidth(null); static int shadowH = shadowImage.getHeight(null); private Color highlight = UIManager.getColor("VLDocking.highlight"); private Color shadow = UIManager.getColor("VLDocking.shadow"); private boolean paintTopLeft = true; private Insets insets; /* Constructs a full shadow border */ public ShadowBorder() { this(true); } /** Constructs a full shadow border (if paintTopLeft is true) or a half shadow border * (is false). * */ public ShadowBorder(boolean paintTopLeft) { this.paintTopLeft = paintTopLeft; insets = paintTopLeft ? INSETS_FULL : INSETS_HALF; } public boolean isBorderOpaque() { return false; } public void paintBorder(Component component, Graphics graphics, int x, int y, int w, int h) { // top corner graphics.drawImage(shadowImage, x + w - 5, y, x + w, y + 5, shadowW - 5, 0, shadowW, 5, null); // vertical graphics.drawImage(shadowImage, x + w - 5, y + 5, x + w, y + h - 5, shadowW - 5, 5, shadowW, shadowH - 5, null); // bottom-right corner graphics.drawImage(shadowImage, x + w - 5, y + h - 5, x + w, y + h, shadowW - 5, shadowH - 5, shadowW, shadowH, null); // horizontal graphics.drawImage(shadowImage, x + 5, y + h - 5, x + w - 5, y + h, 5, shadowH - 5, shadowW - 5, shadowH, null); // bottom left corner graphics.drawImage(shadowImage, x, y + h - 5, x + 5, y + h, 0, shadowH - 5, 5, shadowH, null); if(paintTopLeft) { graphics.setColor(highlight); graphics.drawRect(x + 1, y + 2, w - 7, 1); // graphics.drawRect(x + 1, y + 2, 1, h - 7); graphics.drawLine(x + 1, y + 2, x + 1, y + h - 5); graphics.setColor(shadow); graphics.drawRect(x, y + 1, w - 5, h - 6); } } public Insets getBorderInsets(Component component) { return insets; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ShapePainterStrategy.java000066400000000000000000000021351243334202400330040ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; /** Contract for a shape painter (during drag and drop operation) * * @author Lilian Chamontin, VLSolutions * @since 3.0 */ interface ShapePainterStrategy { /** show the drag cursor */ public void showDragCursor(); /** show the stop-drag cursor (drag not enabled)*/ public void showStopDragCursor(); /** show the stop-drag cursor (drag not enabled)*/ public void showSwapDragCursor(); /** show the float (detached) cursor */ public void showFloatCursor(); public void repaint(); public void startDrag(DockableDragSource source); public void endDrag(); } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/SingleDockableContainer.java000066400000000000000000000023461243334202400334130ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; /** A SingleDockableContainer is a DockableContainer that can display * a single Dockable component. *

* The components is usually displayed with decorations * (a title bar, docking state management buttons, a drop shadow, ...). *

* This interface is meant for API Extenders in order to provide new kinds of * SingleDockableContainers (if the default implementation, DockView hasn't * got enough features or to provide a different look and feel). * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public interface SingleDockableContainer extends DockableContainer { /** Returns the dockable this container is displaying */ public Dockable getDockable(); } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/SplitContainer.java000066400000000000000000000307351243334202400316430ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import javax.swing.*; import java.awt.*; import java.awt.geom.*; import com.vlsolutions.swing.docking.event.*; /** A Specialized JSplitPane which accepts drag and drop of DockableContainer. *

* The split container should be used only by the DockingDesktop. *

* It is a SplitPane with bug workarounds and a custom UI (in fact : no UI painting at all, * by default). * * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public class SplitContainer extends JSplitPane implements DockDropReceiver { private static final long serialVersionUID = 1L; // this is for debugging purpose and will be removed. private static Color[] colors = {Color.RED, Color.BLUE, Color.CYAN, Color.GREEN, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.WHITE, Color.YELLOW}; private static int colorindex = - 1; private static final boolean DEBUG = false; private static final String uiClassID = "DockingSplitPaneUI"; /** Constructs a vertically splitted SplitContainer */ public SplitContainer() { this(VERTICAL_SPLIT); } /** Constructs a SplitContainer with the given JSplitPane orientation. */ public SplitContainer(int orientation) { super(orientation); setBorder(null); if(DEBUG) { Color c = colors[(++colorindex % colors.length)]; setBorder(BorderFactory.createLineBorder(c, 2)); } } /** Overriden for custom UI delegation */ public String getUIClassID() { return uiClassID; } /** Returns a readable String representing this SplitContainer */ public String toString() { if(getOrientation() == HORIZONTAL_SPLIT) { return "SplitContainer[HORIZONTAL, " + getTopComponent() + " / " + getBottomComponent() + ']'; } else { return "SplitContainer[VERTICAL, " + getTopComponent() + " / " + getBottomComponent() + ']'; } } /** Returns a suitable name for when this container is the main child of a Tab (TabbedDockableContainer) */ public String getTabName() { Component left = getLeftComponent(); if(left instanceof SingleDockableContainer) { return ((SingleDockableContainer) left).getDockable().getDockKey().getTabName(); } else if(left instanceof SplitContainer) { return ((SplitContainer) left).getTabName(); } else { return null; } } /** {@inheritDoc} */ public void processDockableDrag(DockDragEvent event) { scanContainer(event, false); } /** {@inheritDoc} */ public void processDockableDrop(DockDropEvent event) { scanContainer(event, true); } private void scanContainer(DockEvent event, boolean drop) { // reject operation if the source is an ancestor of this view. if(event.getDragSource().getDockableContainer().isAncestorOf(this)) { // this is possible for compound containers (as they contain sub-dockables) // in that case, you cannnot drop a compound into one of its children // 2007/01/08 if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).delegateDrag(); } return; } /* Dock is available : * - on borders of the two components * - on the center of the 2 components (meaning : tab'em) */ Point p = event.getMouseEvent().getPoint(); Rectangle compBounds = getLeftComponent().getBounds(); if(compBounds.contains(p)) { scanComponent(getLeftComponent(), event, drop, p, compBounds); } else { getRightComponent().getBounds(compBounds); if(compBounds.contains(p)) { scanComponent(getRightComponent(), event, drop, p, compBounds); } else { // we are elsewhere : reject if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).rejectDrag(); } } } } // workaround bug #4276222 private boolean isPainted; private boolean hasProportionalLocation; private double proportionalLocation; /** Overriden for a bug workaround*/ public void setDividerLocation(double proportionalLocation) { if(! isPainted) { hasProportionalLocation = true; this.proportionalLocation = proportionalLocation; } else { if(proportionalLocation < 0) { // safety checks to avoid exceptions proportionalLocation = 0; } else if(proportionalLocation > 1) { proportionalLocation = 1; } else { super.setDividerLocation(proportionalLocation); } } } public void setDividerLocation(int location) { super.setDividerLocation(location); if(! DockingPreferences.isLightWeightUsageEnabled()) { // ugly repaint trick due to incorrect repaint on linux/mac systems final Window w = SwingUtilities.getWindowAncestor(this); if(w != null) { SwingUtilities.invokeLater(new Runnable() { public void run() { w.repaint(); } }); } } } /** overriden for a bug workaround reason */ public void paint(Graphics g) { if(! isPainted) { isPainted = true; if(hasProportionalLocation) { setDividerLocation(proportionalLocation); doLayout(); } } super.paint(g); } /** Resest recursively the left and right components to their preferred size * if possible. (same contract as JSplitPane's). *

* If contained components are SplitContainers, their are also reset to their * preferredSize. * */ public void resetToPreferredSizes() { super.resetToPreferredSizes(); if(getLeftComponent() instanceof SplitContainer) { ((SplitContainer) getLeftComponent()).resetToPreferredSizes(); } if(getRightComponent() instanceof SplitContainer) { ((SplitContainer) getRightComponent()).resetToPreferredSizes(); } } /** Replaces the child component by a sub-split pane. * @param child one or the two components of this split pane * @param newComp the new component to add * @param position where to put comp / child (i.e if SPLIT_TOP, * a vertical splitpane will be created and comp will be on top of it * (and child at bottom). */ public void split(Component newComp, Component child, DockingConstants.Split position) { SplitContainer split; if(position == DockingConstants.SPLIT_TOP || position == DockingConstants.SPLIT_BOTTOM) { split = new SplitContainer(JSplitPane.VERTICAL_SPLIT); } else /*if (position == DockingConstants.SPLIT_LEFT || position == DockingConstants.SPLIT_RIGHT)*/{ split = new SplitContainer(JSplitPane.HORIZONTAL_SPLIT); } if(getLeftComponent() == child) { remove(child); setLeftComponent(split); if(position == DockingConstants.SPLIT_TOP || position == DockingConstants.SPLIT_LEFT) { split.setLeftComponent(newComp); // for splitpane, left == top split.setRightComponent(child); } else { split.setLeftComponent(child); // for splitpane, left == top split.setRightComponent(newComp); } } else { remove(child); setRightComponent(split); if(position == DockingConstants.SPLIT_TOP || position == DockingConstants.SPLIT_LEFT) { split.setLeftComponent(newComp); // for splitpane, left == top split.setRightComponent(child); } else { split.setLeftComponent(child); // for splitpane, left == top split.setRightComponent(newComp); } } } private void scanComponent(Component comp, DockEvent event, boolean drop, Point p, Rectangle compBounds) { int distTop = p.y - compBounds.y; int distLeft = p.x - compBounds.x; int min = Math.min(distTop, distLeft); int distRight = compBounds.x + compBounds.width - p.x; int distBottom = compBounds.y + compBounds.height - p.y; int min2 = Math.min(distBottom, distRight); min = Math.min(min, min2); Dockable dockable = event.getDragSource().getDockable(); DockableState.Location splitState = DockingUtilities.getDockableLocationFromHierarchy(this); DockableState.Location dockableState = dockable.getDockKey().getLocation(); if(min == distTop) { // dock on top if(drop) { event.setDockingAction(new DockingActionSplitComponentEvent(event.getDesktop(), dockable, dockableState, splitState, comp, DockingConstants.SPLIT_TOP, 0.5f)); ((DockDropEvent) event).acceptDrop(); event.getDesktop().splitComponent(comp, event.getDragSource().getDockable(), DockingConstants.SPLIT_TOP); } else { Rectangle2D r2d = new Rectangle2D.Float(compBounds.x, compBounds.y, compBounds.width, 20); event.setDockingAction(new DockingActionSplitComponentEvent(event.getDesktop(), dockable, dockableState, splitState, comp, DockingConstants.SPLIT_TOP, 0.5f)); ((DockDragEvent) event).acceptDrag(r2d); } } else if(min == distLeft) { if(drop) { event.setDockingAction(new DockingActionSplitComponentEvent(event.getDesktop(), dockable, dockableState, splitState, comp, DockingConstants.SPLIT_LEFT, 0.5f)); ((DockDropEvent) event).acceptDrop(); event.getDesktop().splitComponent(comp, event.getDragSource().getDockable(), DockingConstants.SPLIT_LEFT); } else { Rectangle2D r2d = new Rectangle2D.Float(compBounds.x, compBounds.y, 20, compBounds.height); event.setDockingAction(new DockingActionSplitComponentEvent(event.getDesktop(), dockable, dockableState, splitState, comp, DockingConstants.SPLIT_LEFT, 0.5f)); event.setDockingAction(new DockingActionSplitComponentEvent(event.getDesktop(), dockable, dockable.getDockKey().getLocation(), splitState, comp, DockingConstants.SPLIT_TOP, 0.5f)); ((DockDragEvent) event).acceptDrag(r2d); } } else if(min == distBottom) { if(drop) { event.setDockingAction(new DockingActionSplitComponentEvent(event.getDesktop(), dockable, dockableState, splitState, comp, DockingConstants.SPLIT_BOTTOM, 0.5f)); ((DockDropEvent) event).acceptDrop(); event.getDesktop().splitComponent(comp, event.getDragSource().getDockable(), DockingConstants.SPLIT_BOTTOM); } else { Rectangle2D r2d = new Rectangle2D.Float(compBounds.x, compBounds.y + compBounds.height - 20, compBounds.width, 20); event.setDockingAction(new DockingActionSplitComponentEvent(event.getDesktop(), dockable, dockableState, splitState, comp, DockingConstants.SPLIT_BOTTOM, 0.5f)); ((DockDragEvent) event).acceptDrag(r2d); } } else { // right if(drop) { event.setDockingAction(new DockingActionSplitComponentEvent(event.getDesktop(), dockable, dockableState, splitState, comp, DockingConstants.SPLIT_RIGHT, 0.5f)); ((DockDropEvent) event).acceptDrop(); event.getDesktop().splitComponent(comp, event.getDragSource().getDockable(), DockingConstants.SPLIT_RIGHT); } else { Rectangle2D r2d = new Rectangle2D.Float(compBounds.x + compBounds.width - 20, compBounds.y, 20, compBounds.height); event.setDockingAction(new DockingActionSplitComponentEvent(event.getDesktop(), dockable, dockableState, splitState, comp, DockingConstants.SPLIT_RIGHT, 0.5f)); ((DockDragEvent) event).acceptDrag(r2d); } } } } /* Utility class, resizes a splitcontainer after its size is known (needs an invokelater after * having added it). * allows us to avoid the nasty resizing of a splitpane when a component * is added on the right/bottom (it will then take most of the split surface, * which is not good when we add a small dockable to the right of a big dockable */ class SplitResizer implements Runnable { SplitContainer split; int location; double doubleloc; boolean isDouble; SplitResizer(SplitContainer split, int location) { this.split = split; this.location = location; isDouble = false; } SplitResizer(SplitContainer split, double location) { this.split = split; this.doubleloc = location; isDouble = true; } public void run() { // used as invokeLater, as the size of the splitpane is not known // when split is first inserted. if(isDouble) { split.setDividerLocation(doubleloc); } else { // clamp resizing to the half width/height of the splitpane int maxWidth = split.getWidth() / 2; int maxHeight = split.getHeight() / 2; if(location < 0) { //meaning it's a resize of the opposite component if(split.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) { location = Math.max(maxWidth, split.getWidth() + location); } else { location = Math.max(maxHeight, split.getHeight() + location); } } else { if(split.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) { location = Math.min(maxWidth, location); } else { location = Math.min(maxHeight, location); } } split.setDividerLocation(location); } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/TabFactory.java000066400000000000000000000030631243334202400307350ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; /** A factory that replaces DockViews (with title headers) by tabbed panes with a single tab. *

* This factory provides a unified GUI for single AND tabbed components (with the exception of * auto-hide and single-floating that still use the standard title bars). *

* It is still in an early stage and will be improved in future releases, depending on its * adoption. * * @author Lilian Chamontin, VLSolutions * @since 2.1.3 * */ public class TabFactory extends DefaultDockableContainerFactory { public SingleDockableContainer createDockableContainer(Dockable dockable, ParentType parentType) { switch(parentType) { case PARENT_TABBED_CONTAINER: return new TabbedDockView(dockable); case PARENT_DESKTOP: return new MaximizedDockViewAsTab(dockable);//MaximizedDockView(dockable); case PARENT_SPLIT_CONTAINER: return new DockViewAsTab(dockable); case PARENT_DETACHED_WINDOW: return new DetachedDockView(dockable); default: throw new RuntimeException("Wrong dockable container type"); } } }vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/TabbedContainerActions.java000066400000000000000000000162201243334202400332430ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Icon; import javax.swing.KeyStroke; import javax.swing.UIManager; /** An utility class providing default implementation of usefull actions for pop-up * menus in tab container selectors. *

* * @author Lilian Chamontin, VLSolutions * *@update 2005/10/07 Lilian Chamontin : added the attach action for floating tabs */ @SuppressWarnings("unused") public class TabbedContainerActions { // label resources taken from BasicInternalFrameUI... private static final String CLOSE_TEXT = UIManager.getString("DockTabbedPane.closeButtonText"); private static final String ICONIFY_TEXT = UIManager.getString("DockTabbedPane.minimizeButtonText"); private static final String RESTORE_TEXT = UIManager.getString("DockTabbedPane.restoreButtonText"); private static final String MAXIMIZE_TEXT = UIManager.getString("DockTabbedPane.maximizeButtonText"); private static final String FLOAT_TEXT = UIManager.getString("DockTabbedPane.floatButtonText"); private static final String ATTACH_TEXT = UIManager.getString("DockTabbedPane.attachButtonText"); private static final Icon CLOSE_ICON = UIManager.getIcon("DockTabbedPane.menu.close"); private static final Icon CLOSE_ALL_ICON = UIManager.getIcon("DockTabbedPane.closeAll"); private static final Icon CLOSE_OTHER_ICON = UIManager.getIcon("DockTabbedPane.closeAllOther"); private static final Icon ICONIFY_ICON = UIManager.getIcon("DockTabbedPane.menu.hide"); private static final Icon MAXIMIZE_ICON = UIManager.getIcon("DockTabbedPane.menu.maximize"); private static final Icon FLOAT_ICON = UIManager.getIcon("DockTabbedPane.menu.float"); private static final Icon ATTACH_ICON = UIManager.getIcon("DockTabbedPane.menu.attach"); private TabbedContainerActions() {} /** returns an action suitable for closing a dockable contained in a tab. *

* Action properties : The icon is provided, and also the standard localized "close" message. */ public static Action createCloseAction(final Dockable dockable, final DockingDesktop desktop) { AbstractAction action = new AbstractAction(CLOSE_TEXT) { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { desktop.close(dockable); } }; action.putValue(AbstractAction.SMALL_ICON, CLOSE_ICON); KeyStroke ks = (KeyStroke) UIManager.get("DockingDesktop.closeActionAccelerator"); if(ks != null) { action.putValue(AbstractAction.ACCELERATOR_KEY, ks); } return action; } /** returns an action suitable for closing every dockable contained in a tab. *

* Action properties : The icon is provided, and also an unlocalized "Close all documents" message. */ public static Action createCloseAllAction(final Dockable base, final DockingDesktop desktop) { AbstractAction action = new AbstractAction("Close all documents") { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { desktop.closeAllDockablesInTab(base); } }; action.putValue(AbstractAction.SMALL_ICON, CLOSE_ALL_ICON); return action; } /** returns an action suitable for closing every dockable contained in a tab excepted the current one. *

* Action properties : The icon is provided, and also an unlocalized "Close all other documents" message. */ public static Action createCloseAllOtherAction(final Dockable exception, final DockingDesktop desktop) { AbstractAction action = new AbstractAction("Close all other documents") { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { desktop.closeAllOtherDockablesInTab(exception); } }; action.putValue(AbstractAction.SMALL_ICON, CLOSE_OTHER_ICON); return action; } /** returns an action suitable for maximizing a dockable contained in a tab. *

* Action properties : The icon is provided, and also a localized "Maximize" message. */ public static Action createMaximizeTabAction(final Dockable dockable, final DockingDesktop desktop) { AbstractAction action = new AbstractAction(MAXIMIZE_TEXT) { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { desktop.maximize(dockable); } }; action.putValue(AbstractAction.SMALL_ICON, MAXIMIZE_ICON); KeyStroke ks = (KeyStroke) UIManager.get("DockingDesktop.maximizeActionAccelerator"); if(ks != null) { action.putValue(AbstractAction.ACCELERATOR_KEY, ks); } return action; } /** returns an action suitable for hiding a dockable contained in a tab. *

* Action properties : The icon is provided, and also a localized "Iconify" message. */ public static Action createHideTabAction(final Dockable dockable, final DockingDesktop desktop) { AbstractAction action = new AbstractAction(ICONIFY_TEXT) { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { desktop.setAutoHide(dockable, true); } }; action.putValue(AbstractAction.SMALL_ICON, ICONIFY_ICON); KeyStroke ks = (KeyStroke) UIManager.get("DockingDesktop.dockActionAccelerator"); if(ks != null) { action.putValue(AbstractAction.ACCELERATOR_KEY, ks); } return action; } /** returns an action suitable for floating (detach) a dockable contained in a tab. *

* Action properties : The icon is provided, and a default "Detach" message. */ public static Action createFloatTabAction(final Dockable dockable, final DockingDesktop desktop) { AbstractAction action = new AbstractAction(FLOAT_TEXT) { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { desktop.setFloating(dockable, true); } }; action.putValue(AbstractAction.SMALL_ICON, FLOAT_ICON); KeyStroke ks = (KeyStroke) UIManager.get("DockingDesktop.floatActionAccelerator"); if(ks != null) { action.putValue(AbstractAction.ACCELERATOR_KEY, ks); } return action; } /** returns an action suitable for attaching a dockable contained in a floating tab. *

* Action properties : The icon is provided, and a default "Attach" message. * @since 2.0.1 */ public static Action createAttachTabAction(final Dockable dockable, final DockingDesktop desktop) { AbstractAction action = new AbstractAction(ATTACH_TEXT) { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { desktop.setFloating(dockable, false); } }; action.putValue(AbstractAction.SMALL_ICON, ATTACH_ICON); KeyStroke ks = (KeyStroke) UIManager.get("DockingDesktop.floatActionAccelerator"); if(ks != null) { action.putValue(AbstractAction.ACCELERATOR_KEY, ks); } return action; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/TabbedDockView.java000066400000000000000000000043561243334202400315220ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; import com.vlsolutions.swing.docking.event.DockDragEvent; import com.vlsolutions.swing.docking.event.DockDropEvent; import com.vlsolutions.swing.docking.event.DockEvent; import java.awt.Component; import javax.swing.SwingUtilities; import javax.swing.UIManager; /** A DockView that can be nested into a TabbedDockableContainer * * @author Lilian Chamontin, VLSolutions */ public class TabbedDockView extends DockView { private static final long serialVersionUID = 1L; public TabbedDockView(Dockable dockable) { super(dockable, false); } protected void scanDrop(DockEvent event, boolean drop) { DockableState.Location location = dockable.getDockKey().getLocation(); if(location == DockableState.Location.DOCKED) { super.scanDrop(event, drop); } else if(location == DockableState.Location.FLOATING) { // don't allow drop for floating tabs : only when child of a compound dockable if(DockingUtilities.isChildOfCompoundDockable(dockable)) { super.scanDrop(event, drop); } else { if(drop) { ((DockDropEvent) event).rejectDrop(); } else { ((DockDragEvent) event).delegateDrag(); } } } } public void setVisible(boolean visible) { super.setVisible(visible); if(visible) { if(UIManager.getBoolean("TabbedContainer.requestFocusOnTabSelection")) { // this is a workaround to get focus on a tab when it's selected // obviously, this relies in the fact that the parent of this dockView is // the tab container. SwingUtilities.invokeLater(new Runnable() { public void run() { if(getDockable() != null) { Component comp = getDockable().getComponent(); if(comp != null) { comp.requestFocus(); } } } }); } } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/TabbedDockableContainer.java000066400000000000000000000033361243334202400333530ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking; /** Interface describing a container that can be used to display more than * one Dockable in a Tabbed Pane fashion. *

* This interface is meant for API Extenders in order to provide new kinds of * TabbedDockableContainers (the default implementation is DockTabbedPane). * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public interface TabbedDockableContainer extends DockableContainer { /** Returns the currently selected (front) dockable */ public Dockable getSelectedDockable(); /** Change the tab selection to display this dockable */ public void setSelectedDockable(Dockable dockable); /** Returs the current tab count (which is also the current dockable count) */ public int getTabCount(); /** Returns the dockable at the index tab */ public Dockable getDockableAt(int index); /** Adds a dockable to the given index tab. */ public void addDockable(Dockable dockable, int index); /** Removes a dockable from the tabs */ public void removeDockable(Dockable dockable); /** Remove the dockable at specified index tab */ public void removeDockable(int index); /** Returns the index of the given dockable */ public int indexOfDockable(Dockable dockable); } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/animation/000077500000000000000000000000001243334202400300115ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/animation/AnimationEvent.java000066400000000000000000000031751243334202400336030ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.animation; import java.awt.*; /** An Event describing the state of an animation * * @see AnimationListener * @see ComponentAnimator * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public class AnimationEvent { /** state identifying the beginning of an animation */ public static final int ANIMATION_START = 0; /** state identifying a change in the animation (the component has changed of bounds) */ public static final int ANIMATION_FRAME = 1; /** state identifying the end of an animation */ public static final int ANIMATION_END = 2; private Component source; private int state; /** Event Constructor. * @param source the animated component * @param state the state of animation (ANIMATION_START , ANIMATION_FRAME or ANIMATION_END) * */ public AnimationEvent(Component source, int state) { this.source = source; this.state = state; } /** returns the state of the animation (ANIMATION_START, ANIMATION_FRAME or ANIMATION_END) */ public int getState() { return state; } /** returns the source of animation */ public Object getSource() { return source; } } AnimationListener.java000066400000000000000000000021711243334202400342230ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/animation/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.animation; /** The AnimationListener interface is used to notify listeners about the state * of an animation process (animation start and end). *

* This interface is used by ComponentAnimator, generally to block * events management during animation phase. * * @see ComponentAnimator * @see AnimationEvent * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public interface AnimationListener { /** This method is invoked when the animation state change. *

Changes are relative to animation start, sequence(frame) and end. * */ public void animation(AnimationEvent e); } ComponentAnimator.java000066400000000000000000000146571243334202400342470ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/animation/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.animation; import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.util.ArrayList; /** Utility class used to perform move/resize animation for awt/swing components. *

* This class moves/resizes a Component given a start and end Rectangle and * a duration. *

* Movements and listeners notifications are processed in the Swing Event Thread. * * @author Lilian Chamontin, vlsolutions. * @version 1.0 */ public class ComponentAnimator { /** The animated component */ protected Component comp; /** the component's start bounds */ protected Rectangle startBounds; /** the component's end bounds */ protected Rectangle endBounds; /** the animation duration in seconds */ protected float duration; /** animation start time System.currentTimeMillis() */ private long start; /** time elapsed since the beginnig of animation */ protected float elapsed = 0; private Timer timer; private ArrayList listeners = new ArrayList(3); /** Single-shot animator (use another ComponentAnimator for a new animation). * * * @param comp the component to animate * @param startBounds initial bounds of the component * @param endBounds end bounds of the component * @param duration duration of animation, expressed in seconds * @param listener single listener used for animation notification */ public ComponentAnimator(Component comp, Rectangle startBounds, Rectangle endBounds, float duration, AnimationListener listener) { this.comp = comp; this.startBounds = startBounds; this.endBounds = endBounds; this.duration = duration; addAnimationListener(listener); start(); } /** Reusable component animator. * To start an animation, don't forget to call the {@link #start() start() }method. * */ public ComponentAnimator(Component comp, Rectangle startBounds, Rectangle endBounds, float duration) { this.comp = comp; this.startBounds = startBounds; this.endBounds = endBounds; this.duration = duration; } /** Starts the animation. *

The component is setBoundsed to startBounds and made visible, * than a Swing timer is started to process the animation (refresh rate is 100 ms). *

the ANIMATION_START event is then fired to all listeners. */ public void start() { if(duration == 0) { // heavy weight == no animation fireAnimationEvent(new AnimationEvent(comp, AnimationEvent.ANIMATION_START)); // already the end comp.setBounds(endBounds.x, endBounds.y, endBounds.width, endBounds.height); comp.invalidate(); comp.validate(); comp.repaint(); fireAnimationEvent(new AnimationEvent(comp, AnimationEvent.ANIMATION_END)); } else { comp.setBounds(startBounds.x, startBounds.y, startBounds.width, startBounds.height); comp.validate(); comp.setVisible(true); timer = new Timer(100, new AnimationActionListener()); start = System.currentTimeMillis(); timer.start(); fireAnimationEvent(new AnimationEvent(comp, AnimationEvent.ANIMATION_START)); } } /** Cancels the animation (the component is not reset to its initial location/size) */ public void cancel() { timer.stop(); } /** Adds a new listener to the animator * @param listener the listener */ public void addAnimationListener(AnimationListener listener) { if(listener != null && ! listeners.contains(listener)) { listeners.add(listener); } } /** loops over the listeners to fire animation event */ private void fireAnimationEvent(AnimationEvent e) { for(int i = 0; i < listeners.size(); i++) { ((AnimationListener) listeners.get(i)).animation(e); } } /** Returns the duration of the animation * * @return the duration of the animation, in seconds */ public float getDuration() { return duration; } /** Sets the duration of the animation. *

Warning : do not change this value during an animation * * @param duration the new duration in seconds */ public void setDuration(float duration) { this.duration = duration; } /** Returns the end bounds of the components. * * @return the end bounds of the components. */ public Rectangle getEndBounds() { return endBounds; } /** Sets the end bounds of the component. *

Warning : do not change end bounds during an animation. * * @param endBounds */ public void setEndBounds(Rectangle endBounds) { this.endBounds = endBounds; } /** Returns the start bounds of the component. * * @return the start bounds of the component (those of when animation starts). */ public Rectangle getStartBounds() { return startBounds; } /** Sets the start bounds of the component for animation. *

Warning :do not change start bounds during an animation * @param startBounds the start bounds of the component. */ public void setStartBounds(Rectangle startBounds) { this.startBounds = startBounds; } /** Inner action listener to hide actionPerformed from the public API. */ private class AnimationActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { long time = System.currentTimeMillis(); elapsed = (time - start) / 1000f; if(elapsed < duration) { float f1 = (duration - elapsed) / duration; float f2 = elapsed / duration; Rectangle newBounds = new Rectangle(); newBounds.x = (int) (startBounds.x * f1 + endBounds.x * f2); newBounds.y = (int) (startBounds.y * f1 + endBounds.y * f2); newBounds.width = (int) (startBounds.width * f1 + endBounds.width * f2); newBounds.height = (int) (startBounds.height * f1 + endBounds.height * f2); comp.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height); comp.validate(); fireAnimationEvent(new AnimationEvent(comp, AnimationEvent.ANIMATION_FRAME)); } else { // the end comp.setBounds(endBounds.x, endBounds.y, endBounds.width, endBounds.height); comp.validate(); timer.stop(); fireAnimationEvent(new AnimationEvent(comp, AnimationEvent.ANIMATION_END)); } } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/animation/package.html000066400000000000000000000005351243334202400322750ustar00rootroot00000000000000

Swing Components Animation.

The animation package provides classes and interface requiered in component animations for the docking framework.

There is not much animation for now (only auto-expand / auto-hide features), but this could change in future versions (think about animated docking...). vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/000077500000000000000000000000001243334202400271535ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/DockDragEvent.java000066400000000000000000000072331243334202400325030ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import java.awt.event.*; import java.awt.*; import com.vlsolutions.swing.docking.*; /** An event describing a drag operation occuring for docking purpose. *

* This event is used by API extenders to manage drag and drop action related to * docking. This is not meant to be used by User Applications. *

* Standard processing of dragging is (ignoring DockableStateChange events) : *

    *
  • the users starts a drag gesture from a DockableDragSource *
  • the mouse reaches a component implementing DockDropReceiver *
  • a DockDragEvent is created and passed to the DockDropReceiver *
  • the receiver accepts that drag with {@link #acceptDrag(Shape)} *
  • the shape is used to give a feeback to the user *
* * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public class DockDragEvent extends DockEvent { private boolean acceptDrag = false; // when accept drag is false, indicates if the docking should check ancestors private boolean delegateDrag = false; private Shape dropShape; /** Creates an event based on a drag source and a mouse event. *

The mouse coordinates are converted into the receiver's coordinates.*/ public DockDragEvent(DockingDesktop desktop, DockableDragSource source, MouseEvent event) { super(desktop, source, event); } /** returns true if drag is accepted. * * @return true if drag is accepted */ public boolean isDragAccepted() { return acceptDrag; } /** If drag is not accepted, this method will be invoked to evaluate * a delegating event processing. *

* This is useful for nested DropReceivers (like TabbedDockableContainers) */ public boolean isDragDelegated() { return ! acceptDrag && delegateDrag; } /** Returns the shape to display if drag is accepted. *

* This method will be invoked only if isDragAccepted returns true *

* As this method can be called on every mouse drag over a component, it is * a good practice to reuse the same shape as lond a possible (do not create a * new Shape at every invocation). * */ public Shape getDropShape() { return dropShape; } /** Used by a DockDropReceiver to indicate that the drag operation is accepted * (mouse is over a droppable zone). *

* As of version 2.1, please note that you also have to invoke #setDockingAction() * to specify the action associated with the drag shape. * * @param dropShape the shape (in drop component coordinates) showing the drop zone, * which will be displayed on the glasspane of the DockingPanel. * */ public void acceptDrag(Shape dropShape) { this.acceptDrag = true; this.dropShape = dropShape; } /** Used to reject the drag (e.g. when trying to drop a component onto itself) */ public void rejectDrag() { this.acceptDrag = false; this.delegateDrag = false; } /** Rejects the drag, but allows the docking system to search for othet drop receiver * in ancestors. *

* for example, a TabbedDockableContainer that doesn't allow drops on its * borders can delegates this management to its container. */ public void delegateDrag() { this.acceptDrag = false; this.delegateDrag = true; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/DockDropEvent.java000066400000000000000000000073061243334202400325330ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import java.awt.event.*; import com.vlsolutions.swing.docking.*; import javax.swing.*; /** An event send to a dockDropReceiver to complete a drop operation *

* This event is used by API extenders to manage drag and drop action related to * docking. This is not meant to be used by User Applications. * *

* The dockDropReceiver can accept or reject the drop. *

* If the drop is accepted, the receiver must process the docking operation, * (usually by invoking a docking method on the desktop). * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public class DockDropEvent extends DockEvent { private DockingDesktop desk; private boolean accepted; public DockDropEvent(DockingDesktop desk, DockableDragSource source, MouseEvent event) { super(desk, source, event); this.desk = desk; } /** shortcut for acceptDrop(true). *

* If the drop is accepted, the receiver must process the docking operation, * (usually by invoking a docking method on the desktop). *

* As of version 2.1, a DockingActionEvent has been added to the DockEvent class, adding * a "semantic" description of the docking operation. The DropReceiver must call * setDockingAction() before acceptDrop(). *

* It is still the responsability of the drop receiver to process the docking operation. * */ public void acceptDrop() { acceptDrop(true); } /** notifies the event manager that docking is accepted. *

* If the drop is accepted, the receiver must process the docking operation, * (usually by invoking a docking method on the desktop). * * @param remove if true, the docking desktop will remove the dragged dockable * from its containment hierarchy. If false, it is the responsibility of the * DockDropReceiver to remove (or simply move) the dragged dockable. *

for example, accepting drop without removing the component is saving * a lot of processing for TabbedDockableContainers when the dragged component * already belongs to their tabs. * */ public void acceptDrop(boolean remove) { this.accepted = true; if(remove) { DockableState state = desk.getContext().getDockableState(source.getDockable()); DockingDesktop sourceDesktop; if(state == null) { // this should happen only with whole tabs drags as they don't have any state // associated with them (bug ?) if(source instanceof TabbedDockableContainer) { Dockable d1 = ((TabbedDockableContainer) source).getDockableAt(0); state = desk.getContext().getDockableState(d1); sourceDesktop = state.getDesktop(); } else { throw new RuntimeException("unmanaged dockable drag source : " + source); } } else { sourceDesktop = state.getDesktop(); } if(sourceDesktop != null) { sourceDesktop.dropRemove(source); } } } /** It is still time to reject a drop, although the standard way is by denying the * previous drag operation. */ public void rejectDrop() { UIManager.getLookAndFeel().provideErrorFeedback(desk); } /** Indicates if the drop operation is accepted. *

* Once rejected (with rejectDrop, it is not possible to re-accept it * */ public boolean isDropAccepted() { return accepted; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/DockEvent.java000066400000000000000000000054241243334202400317050ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import java.awt.event.*; import com.vlsolutions.swing.docking.*; /** Abstract superclass of drag and drop docking events. *

This class holds a reference to the source of the event and its mouse event. * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public abstract class DockEvent { /** The drag source */ protected DockableDragSource source; /** The docking desktop which is the destination of the drag and drop gesture */ protected DockingDesktop desktop; /** The MouseEvent, in target's coordinates */ protected MouseEvent event; /** The action corresponding to the drag and drop gesture * (actions can be seen as allowed docking gestures) */ protected DockingActionEvent action; /** Constructor for dock events. * * @param targetDesktop the desktop which will receive the drop * @param source the source of drag operation * @param event the mouse event which is the cause of this DockEvent. */ public DockEvent(DockingDesktop targetDesktop, DockableDragSource source, MouseEvent event) { this.desktop = targetDesktop; this.source = source; this.event = event; } /** Returns the MouseEvent which is the cause of this DockEvent. *

* note that mouse coordinates are converted into the target's coordinates. * @return a mouse event */ public MouseEvent getMouseEvent() { return event; } /** Returns a reference to the drag source of this event. * * @return the drag source (the component actually dragged) */ public DockableDragSource getDragSource() { return source; } /** Returns a reference of the desktop in which the docking event takes place. *

* As of version 2.1, this method returns the "target" desktop (the one in which the drop will occur) *

* To get a reference of the "source" desktop, use the DockableState information provided by * the DockingContext. * */ public DockingDesktop getDesktop() { return desktop; } /** Returns the DockingActionEvent corresponding to the drag and drop gesture */ public DockingActionEvent getDockingAction() { return action; } /** Set the docking action corresponding to this drag and drop gesture. * */ public void setDockingAction(DockingActionEvent actionEvent) { this.action = actionEvent; } } DockableSelectionEvent.java000066400000000000000000000023711243334202400343160ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import com.vlsolutions.swing.docking.Dockable; /** An event for tracking selection changes of dockables. *

* Useful for example when * the developper wants to enable or disable actions depending on the dockable * which takes the keyboard focus. * *

implementation note : works with keyboard focus events. * * @author Lilian Chamontin, VLSolutions * @since 2.0 * @see DockableSelectionListener */ public class DockableSelectionEvent { private Dockable selectedDockable; public DockableSelectionEvent(Dockable selectedDockable) { this.selectedDockable = selectedDockable; } /** Returns the currently selected Dockable */ public Dockable getSelectedDockable() { return selectedDockable; } } DockableSelectionListener.java000066400000000000000000000021551243334202400350220ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; /** This interface describes a listener for dockable selection changes. * *

The notification is currently based on keyboard focus policy (the event is * triggered when a new dockable grabs the keyboard focus). * * @author Lilian Chamontin, VLSolutions * @since 2.0 * @see DockableSelectionEvent * @see com.vlsolutions.swing.docking.DockingDesktop#addDockableSelectionListener(DockableSelectionListener) */ public interface DockableSelectionListener { /** This method is invoked when a new dockable is selected. */ public void selectionChanged(DockableSelectionEvent e); } DockableStateChangeEvent.java000066400000000000000000000034321243334202400345560ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import com.vlsolutions.swing.docking.*; /** An event triggered after a change of dockable state. *

Events are triggered when a component is : *

    *
  • Docked (added to the desktop) *
  • set in Auto-hide mode (collapsed as a border button) *
  • closed (removed from the desktop) *
  • maximized (the only one visible) *
  • floating (detached from the desktop) *
* *

It is also possible to track changes before they occurs with * the DockableStateWillChangeEvent, which is triggered before the change is * processed (this event is vetoable). * * @see DockableStateWillChangeEvent * @see DockableStateChangeListener * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public class DockableStateChangeEvent { private DockableState previousState, newState; public DockableStateChangeEvent(DockableState previousState, DockableState newState) { this.previousState = previousState; this.newState = newState; } /** returns the previous state of the dockable, or null if the component * wasn't known to the docking desktop before. */ public DockableState getPreviousState() { return previousState; } /** returns the new state of the dockable */ public DockableState getNewState() { return newState; } } DockableStateChangeListener.java000066400000000000000000000026401243334202400352620ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; /** Interface implemented by classes that need to be notified of * a state change of a dockable. *

* Events are triggered when a Dockable component is : *

    *
  • Docked (added to the desktop) *
  • set in Auto-hide mode (collapsed as a border button) *
  • closed (removed from the desktop) *
  • maximized (the only one visible) *
  • floating (detached from the desktop) *
*

* * * @see DockableStateChangeEvent * @see DockableStateWillChangeEvent * @see com.vlsolutions.swing.docking.DockingDesktop#addDockableStateChangeListener(DockableStateChangeListener) * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public interface DockableStateChangeListener { /** this method will be called after a dockable component has changed of state * (closed, hidden, docked) */ public void dockableStateChanged(DockableStateChangeEvent event); } DockableStateWillChangeEvent.java000066400000000000000000000044021243334202400354040ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import com.vlsolutions.swing.docking.*; /** An event triggered before a change of dockable state. *

Events are triggered when a component is : *

    *
  • Docked (added to the desktop) *
  • set in Auto-hide mode (collapsed as a border button) *
  • closed (removed from the desktop) *
  • maximized *
  • floating (detached from its window) *
* *

Note that event are not triggered by drag-dock moves (they don't correspond * to a state change). If you need to track such changes, use a Swing AncestorListener, * or override the addNotify method of your dockable component. * *

It is also possible to track changes after they occur with * the DockableStateChangeEvent . * * @see javax.swing.event.AncestorListener * @see DockableStateWillChangeListener * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public class DockableStateWillChangeEvent { private DockableState currentState, futureState; private boolean isAccepted; public DockableStateWillChangeEvent(DockableState currentState, DockableState futureState) { this.currentState = currentState; this.futureState = futureState; this.isAccepted = true; } /** this method will return null when the event is triggered for initial docking * */ public DockableState getCurrentState() { return currentState; } /** Returns the future (proposed) state of the dockable. if cancel() is called on the event, * this state change will be vetoed. *@see #cancel() */ public DockableState getFutureState() { return futureState; } /** Refuse the change of dockable state. *

The docking action is cancelled. * */ public void cancel() { isAccepted = false; } public boolean isAccepted() { return isAccepted; } } DockableStateWillChangeListener.java000066400000000000000000000027021243334202400361110ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; /** Interface implemented by classes that need to be notified of * a state change of a dockable before it is processed. *

* Events are triggered before a Dockable component is : *

    *
  • docked (added to the desktop) *
  • set in Auto-hide mode (collapsed as a border button) *
  • closed (removed from the desktop) *
  • maximized *
  • floating (detached) *
*

Those event are vetoable : invoking their cancel method * will stop the state change processing. * * * @see com.vlsolutions.swing.docking.DockingDesktop#addDockableStateWillChangeListener(DockableStateWillChangeListener) * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public interface DockableStateWillChangeListener { /** invoked before a dockable state change. * @param event a vetoable state change event. * */ public void dockableStateWillChange(DockableStateWillChangeEvent event); } DockingActionAddDockableEvent.java000066400000000000000000000034451243334202400355210ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import com.vlsolutions.swing.docking.Dockable; import com.vlsolutions.swing.docking.DockableState; import com.vlsolutions.swing.docking.DockingDesktop; import java.awt.Container; /** A DockingActionEvent describing the first insertion of a dockable either inside a desktop * docking panel (main panel) or into a compoundDockable (nested) container. * * @author Lilian Chamontin, VLSolutions * @since 2.1 */ public class DockingActionAddDockableEvent extends DockingActionDockableEvent { private Container parentContainer; /** Constructor for a DockingActionAddDockableEvent * @param parentContainer the container (DockingPanel or CompoundDockingPanel) into which this * dockable is goint to be added. */ public DockingActionAddDockableEvent(DockingDesktop desktop, Dockable dockable, DockableState.Location initialLocation, DockableState.Location nextLocation, Container parentContainer) { super(desktop, dockable, initialLocation, nextLocation, ACTION_ADD_DOCKABLE); this.parentContainer = parentContainer; } /** Returns the parent container into which this dockable will be added */ public Container getParentContainer() { return parentContainer; } public String toString() { return "DockingActionAddDockableEvent "; } } DockingActionCloseEvent.java000066400000000000000000000022321243334202400344420ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import com.vlsolutions.swing.docking.Dockable; import com.vlsolutions.swing.docking.DockableState; import com.vlsolutions.swing.docking.DockingDesktop; /** A DockingActionEvent describing the closing of a dockable * * @author Lilian Chamontin, VLSolutions * @since 2.1 */ public class DockingActionCloseEvent extends DockingActionDockableEvent { public DockingActionCloseEvent(DockingDesktop desktop, Dockable dockable, DockableState.Location initialLocation) { super(desktop, dockable, initialLocation, DockableState.Location.CLOSED, ACTION_CLOSE); } public String toString() { return "DockingActionCloseEvent"; } } DockingActionCreateTabEvent.java000066400000000000000000000030601243334202400352270ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import com.vlsolutions.swing.docking.Dockable; import com.vlsolutions.swing.docking.DockableState; import com.vlsolutions.swing.docking.DockingDesktop; /** A DockingActionEvent describing a tab insertion (or movement). * * @author Lilian Chamontin, VLSolutions * @since 2.1 */ public class DockingActionCreateTabEvent extends DockingActionDockableEvent { private Dockable base; private int order; public DockingActionCreateTabEvent(DockingDesktop desktop, Dockable dockable, DockableState.Location initialLocation, DockableState.Location nextLocation, Dockable base, int order) { super(desktop, dockable, initialLocation, nextLocation, ACTION_CREATE_TAB); this.base = base; this.order = order; } /** Returns the dockable used as a reference to create a tab (may already belong to a tab)*/ public Dockable getBase() { return base; } /** Returns the order of insertion in the tabbed container */ public int getOrder() { return order; } public String toString() { return "DockingActionCreateTabEvent"; } } DockingActionDockableEvent.java000066400000000000000000000025071243334202400351060ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import com.vlsolutions.swing.docking.Dockable; import com.vlsolutions.swing.docking.DockableState; import com.vlsolutions.swing.docking.DockingDesktop; /** A DockingActionEvent involving a single dockable as source of the action. * * * @author Lilian Chamontin, VLSolutions * @since 2.1 */ public abstract class DockingActionDockableEvent extends DockingActionEvent { private Dockable dockable; public DockingActionDockableEvent(DockingDesktop desktop, Dockable dockable, DockableState.Location initialLocation, DockableState.Location nextLocation, int actionType) { super(desktop, initialLocation, nextLocation, actionType); this.dockable = dockable; } public Dockable getDockable() { return dockable; } public void setDockable(Dockable dockable) { this.dockable = dockable; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/DockingActionEvent.java000066400000000000000000000076241243334202400335450ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import com.vlsolutions.swing.docking.DockableState; import com.vlsolutions.swing.docking.DockingDesktop; /** An abstract event class describing a docking action. *

* This event is used to explain a dockable action : it doesn't contain any information * about the current state of a dockable, but describes precisely what we want to do * with it (for example, detach it, or left-split another dockable). *

* The DockingActionDockableEvent abstract subclass is used as a superclass for all events * associated to a single dockable. *

* Concrete sub classes are used for every type of docking action (split, tab...) * * @since 2.1 * * @author Lilian Chamontin, VLSolutions */ public abstract class DockingActionEvent implements Cloneable { /* action descriptors : allow for fast switch/case tests */ /** Field associated to a closing action */ public static final int ACTION_CLOSE = 0; /** Field associated to an addDockable action */ public static final int ACTION_ADD_DOCKABLE = 1; /** Field associated to a split dockable action */ public static final int ACTION_SPLIT_DOCKABLE = 2; /** Field associated to a split component action */ public static final int ACTION_SPLIT_COMPONENT = 3; /** Field associated to a multipurpose (API internals) splut container action */ public static final int ACTION_SPLIT_DOCKABLE_CONTAINER = 4; /** Field associated to a createTab action */ public static final int ACTION_CREATE_TAB = 5; /** A multipurpose action used to describe maximize, hide and detach actions */ public static final int ACTION_STATE_CHANGE = 6; private DockableState.Location initialLocation; private DockableState.Location nextLocation; private int actionType; private DockingDesktop desktop; /** Constructs a new DockingActionEvent * * @param targetDesktop the desktop that will receive the action . * @param initialState the initial (before action) DockableState (DockableState.STATE_FLOATING...) * @param nextState the next (after action) DockableState (DockableState.STATE_DOCKED...) * @param actionType a field defining the type of action used (ACTION_CLOSE...) */ public DockingActionEvent(DockingDesktop targetDesktop, DockableState.Location initialLocation, DockableState.Location nextLocation, int actionType) { this.desktop = targetDesktop; this.initialLocation = initialLocation; this.nextLocation = nextLocation; this.actionType = actionType; } /** Returns one of the DockableState states reflecting the state of the dockable before the action */ public DockableState.Location getInitialLocation() { return initialLocation; } /** Returns one of the DockableState states reflecting the state of the dockable after the action */ public DockableState.Location getNextLocation() { return nextLocation; } /** Returns a field describing the action (ACTION_CLOSE...). */ public int getActionType() { return actionType; } /** Returns the desktop used as a receiver (target) of the docking action. *

* The desktop used as a source (on multi-desktop applications) can be retrieved by asking for * the current dockable state (to the DockingContext). */ public DockingDesktop getDesktop() { return desktop; } /** Overriden clone method */ public Object clone() { try { return super.clone(); } catch(CloneNotSupportedException e) { e.printStackTrace(); throw new RuntimeException(e); } } } DockingActionListener.java000066400000000000000000000027771243334202400341760ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; /** A listener to docking actions. *

* This listener can be used to be notified of docking actions and to react to them (including * vetoing). * * @author Lilian Chamontin, VLSolutions * @since 2.1 */ public interface DockingActionListener { /** Invoked before a docking action is processed, to give a chance to the * listener to react to it and cancel it if needed. * * @return true if action can be processed, false if it should be cancelled * */ public boolean acceptDockingAction(DockingActionEvent event); /** Invoked once a docking action has been performed. * * @param event the event corresponding to the docking action. Subclasses of * DockingActionEvent are used to reflect different types of action * (DockingActionCloseEvent when a dockable is closed, * DockingActionSplitDockableEvent when a dockable is moved ...). */ public void dockingActionPerformed(DockingActionEvent event); } DockingActionSimpleStateChangeEvent.java000066400000000000000000000030331243334202400367350ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import com.vlsolutions.swing.docking.Dockable; import com.vlsolutions.swing.docking.DockableState; import com.vlsolutions.swing.docking.DockingDesktop; /** An event describing a basic state change. *

* Baic state changes include : *

    *
  • Maximize/Restore *
  • Float (just detach : attach is expressed with split/addDockable/createTab events) *
  • Hide (just hide : show is expressed with split/addDockable/createTab events) *
* * @author Lilian Chamontin, VLSolutions */ public class DockingActionSimpleStateChangeEvent extends DockingActionDockableEvent { /** Constructs a new event */ public DockingActionSimpleStateChangeEvent(DockingDesktop desktop, Dockable dockable, DockableState.Location initiallocation, DockableState.Location nextLocation) { super(desktop, dockable, initiallocation, nextLocation, ACTION_STATE_CHANGE); } public String toString() { return "DockingActionSimpleStateChangeEvent (" + getInitialLocation().name() + " -> " + getNextLocation().name(); } } DockingActionSplitComponentEvent.java000066400000000000000000000060201243334202400363520ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import com.vlsolutions.swing.docking.Dockable; import com.vlsolutions.swing.docking.DockableState; import com.vlsolutions.swing.docking.DockingConstants; import com.vlsolutions.swing.docking.DockingDesktop; import java.awt.Component; /** A DockingActionEvent describing a split action (from a base component (splitcontainer, tab...)). * * @author Lilian Chamontin, VLSolutions * @since 2.1 */ public class DockingActionSplitComponentEvent extends DockingActionDockableEvent { private Component base; private float dividorLocation; private float parentDividorLocation; private DockingConstants.Split splitPosition; /** Constructs a new event */ public DockingActionSplitComponentEvent(DockingDesktop desktop, Dockable dockable, DockableState.Location initialLocation, DockableState.Location nextLocation, Component base, DockingConstants.Split splitPosition, float dividorLocation) { super(desktop, dockable, initialLocation, nextLocation, ACTION_SPLIT_COMPONENT); this.base = base; this.dividorLocation = dividorLocation; this.parentDividorLocation = - 1; this.splitPosition = splitPosition; } /** Constructs a new event. *

* This version of the constructor also contains resizing information for the parent of * thhe splitted component. */ public DockingActionSplitComponentEvent(DockingDesktop desktop, Dockable dockable, DockableState.Location initialLocation, DockableState.Location nextLocation, Component base, DockingConstants.Split splitPosition, float dividorLocation, float parentDividorLocation) { super(desktop, dockable, initialLocation, nextLocation, ACTION_SPLIT_COMPONENT); this.base = base; this.dividorLocation = dividorLocation; this.parentDividorLocation = parentDividorLocation; this.splitPosition = splitPosition; } /** Returns the dockable which will be used as a base for the splitting */ public Component getBase() { return base; } public float getDividorLocation() { return dividorLocation; } /** returns a dividor location value for the parent split container, or -1 if not needed *

* This value is used to express inserting a component with same orientation of the * parent split container (like : transform A|B into [A|child]|B : we need to adjust * A|child dividor, and also [] | B dividor). */ public float getParentDividorLocation() { return parentDividorLocation; } public DockingConstants.Split getSplitPosition() { return splitPosition; } public String toString() { return "DockingActionSplitComponentEvent"; } } DockingActionSplitDockableContainerEvent.java000066400000000000000000000035301243334202400377620ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import com.vlsolutions.swing.docking.DockableState; import com.vlsolutions.swing.docking.DockingConstants; import com.vlsolutions.swing.docking.DockingDesktop; import java.awt.Component; import java.awt.Container; /** A split event : split a base component in two, and puts a dockable container * in the other split position. * * @author Lilian Chamontin, VLSolutions * @since 2.1 */ public class DockingActionSplitDockableContainerEvent extends DockingActionEvent { private Container dockableContainer; private DockingConstants.Split position; private float location; private Component base; /** Constructs a new event */ public DockingActionSplitDockableContainerEvent(DockingDesktop desk, DockableState.Location initialLocation, DockableState.Location nextLocation, Component base, Container dockableContainer, DockingConstants.Split position, float location) { super(desk, initialLocation, nextLocation, ACTION_SPLIT_DOCKABLE); this.base = base; this.dockableContainer = dockableContainer; this.position = position; this.location = location; } public Container getDockableContainer() { return dockableContainer; } public DockingConstants.Split getSplitPosition() { return position; } public float getLocation() { return location; } public Component getBase() { return base; } } DockingActionSplitDockableEvent.java000066400000000000000000000036541243334202400361260ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.event; import com.vlsolutions.swing.docking.Dockable; import com.vlsolutions.swing.docking.DockableState; import com.vlsolutions.swing.docking.DockingConstants; import com.vlsolutions.swing.docking.DockingDesktop; /** A DockingActionEvent describing a split action (from a base dockable). * * * @author Lilian Chamontin, VLSolutions * @since 2.1 */ public class DockingActionSplitDockableEvent extends DockingActionDockableEvent { private Dockable base; private float dividorLocation; private DockingConstants.Split splitPosition; /** Constructs a new event */ public DockingActionSplitDockableEvent(DockingDesktop desktop, Dockable dockable, DockableState.Location initialLocation, DockableState.Location nextLocation, Dockable base, DockingConstants.Split splitPosition, float dividorLocation) { super(desktop, dockable, initialLocation, nextLocation, ACTION_SPLIT_DOCKABLE); this.base = base; this.dividorLocation = dividorLocation; this.splitPosition = splitPosition; } /** Returns the dockable which will be used as a base for the splitting */ public Dockable getBase() { return base; } public float getDividorLocation() { return dividorLocation; } public DockingConstants.Split getSplitPosition() { return splitPosition; } public String toString() { return "DockingActionSplitDockableEvent [base:" + base.getDockKey() + ", dockable:" + getDockable().getDockKey() + "]"; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/event/package.html000066400000000000000000000051101243334202400314310ustar00rootroot00000000000000

Events Package of the VLDocking Framework.

This package contains event and listeners classes of the docking framework.

There are two types of events :

  • Drag and Drop events, used for docking processing.
  • State-change event, used for notifications.

Drag and Drop events

Those events are used by the docking framework to process Docking operations.

They shoud not be used by User Applications, only by API extenders.

This category contains :

  • DockEvent : the ancestor
  • DockDragEvent : an event transmitted to DockDropReceivers in order to know if Drag is allowed and which shape should be drawn.
  • DockDropEvent : when a DockDragEvent is accepted, and mouse button released, a DockDropEvent is transmitted to a DockDropReceiver. It is its responsibility to call the appropriate methods of DockingDesktop in order to change the docking position of the dragged component.

DockableState events

Those events are used for notification purpose, in order to allow the User Application to track configuration changes on the docking desktop.

Note : there are 3 states :

  • docked : component is visible on the docking desktop
  • hidden : iconified in an auto-hide border of the docking desktop
  • closed : not visible
A state change is triggered only when a Dockable changes of state.
Keep in mind that multiple changes of docking position do not trigger multiple state change events (only the initial docking triggers the event).

This category contains :

  • DockableStateWillChangeEvent : a vetoable state change is triggered before state change (for example before a docked component is closed).
    The User application can cancel the event to veto the change.
  • DockableStateChangeEvent : a non-vetoable state change is triggered after the state change (for example, after a hidden component is closed), in order to let the user application know about the state change.

The workflow of event delivering is the following

  Dockable in state S1 (docked/hidden/closed)

   "stateChange" requested
      event manager : triggers DockableStateWillChangeEvents
      if (event.isAccepted()){
        process state change
        ...
        Dockable in state S2 != S1 (docked/hidden/closed)
        event manager : triggers DockableStateChangeEvents

      } // else don't change state

vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/overview.html000066400000000000000000000016461243334202400305750ustar00rootroot00000000000000

VLDocking Framework.

This javadoc directory represents the API documentation of the VLDocking Framework.

Original javadoc website is VLDocking on google code

Getting Started

To fully understand the principles of docking please read the following documents :
  • {@link com.vldocking.swing.docking main package summary}
  • online developer's tutorial
  • and the javadoc of main classes ({@link com.vldocking.swing.docking.DockingDesktop DockingDesktop} / {@link com.vldocking.swing.docking.DockKey DockKey} / {@link com.vldocking.swing.docking.Dockable Dockable}).

For those who would like to extend the API, please read this javadoc and don't hesitate to contact me on the VLDocking google groups mailing list for explanations. vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/package.html000066400000000000000000000176711243334202400303270ustar00rootroot00000000000000

The VLDocking Framework for JFC "Swing" applications.

Goals.

The VLDocking Framework provides a means to add docking capabilities into a Swing application with minor modification of the components hierarchy (only decoration of existing components and containers and adding of a new root container).

Audience.

This javadoc is targetted to :

  • API Users : developpers of "User Applications"
  • API Extenders : developpers that want to extend the framework, add new kinds of containers, or change the look and feel of existing ones.

You will find in this documentation references of those targets, indicating you if you have to read such document or not, depending on your goals (developping a "User Application" or extending the API).

For API Users

Basic Description

The VL Docking Framework is a set of Swing Components that is used to enhance any Swing Application by providing Docking capabilities to user components :

A user component can be any Swing JComponent (usualy a JPanel or a JScrollPane).

Docking functions are built upon the following classes :

  • DockingDesktop : the root container of a docking-enabled application
  • Dockable : an interface implemented (usually) by components that need docking capabilities.
  • DockableContainers : specialized containers with drag and drop extensions (come in two flavors, SingleDockableContainer and TabbedDockabeContainer).
  • DockKey : a JavaBeans object fully describing the dockable (use for save/load, and for DockableContainers customization) : name, icon, tooltip, docking features.

The DockingDesktop class.

There is usually only one DockingDesktop associated to a Window.

For developpers used to JInternalFrame API, the DockingDesktop is equivalent to the JDesktopPane : a layered pane capable of managing and displaying multiple components, with overlapping when needed.

The desktop is composed of :

  • 4 auto-hide zones (on borders ) displaying buttons that are used to activate or hide their Dockable.
  • a central zone, for visible Dockables (or "docked" components).

The central zone contains a DockableContainer that can be recursively splitted in two (horizontally or vertically) to add more DockableContainers. Each split acts as a JSplitPane, and can be resized by the end-user or with the API.

The Dockable interface

The Dockable is implemented by dockable component providers or, simply by components that want to benefit of the docking features.

If you already have a working application (without docking) and want to use the docking framework, take your GUI major components, have them implement the Dockable interface (only 2 methods) and you will be able to add them to the docking desktop.

Alternatively, you can use DockablePanel which is a JPanel container implementing Dockable.

The DockableContainer, SingleDockableContainer and TabbedDockableContainer interfaces.

These interfaces are implemented by containers of Dockables. Usually you will not interact with them (except if you want to extend the framework).

The DockKey class

This one is important because it fully describes the Docking presentation of your dockables, and their behaviour.

A DockKey is used in 3 situations :

  • the DockingDesktop needs a unique key to identify a dockable (for read/write operations)
  • the DockableContainer displaying a Dockable wants information about the dockable : a name, an icon, ...
  • and finally, the DockingDesktop and DockableContainer only allow docking features associated to that DockKey (maximizeable, closeable, hidable...).

So keep in mind that each dockable must have a unique DockKey (it's a kind of primary key) and that the key, as a javabean, is used to decorate the dockable container.

Listeners : most DockKey properties are bound, and changing their value will have an immediate effect on the DockingDesktop : for example, you can change the icon property of a key and it will be propagated to the DockableContainer's title bar of its dockable.


Getting Started

It's easy, just follow the steps below, or have a look at the tutorial on the online tutorial .

Creating a small sample application :

Here is a working code showing a simple frame with dockable buttons.

import com.vldocking.swing.docking.*;
import javax.swing.*;
import java.awt.*;

public class DemoFrame extends JFrame {
  // our docking desktop
  DockingDesktop desk = new DockingDesktop();

  public DemoFrame(){
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    getContentPane().add(desk);

    // first, create 4 dockable buttons (inner class below)
    DockableButton button1 = new DockableButton("Dockable 1");
    DockableButton button2 = new DockableButton("Dockable 2");
    DockableButton button3 = new DockableButton("Dockable 3");
    DockableButton button4 = new DockableButton("Dockable 4");
    // first button at center
    desk.addDockable(button1);

    // second and third button splitted vertically on the left of center
    // first parameter is the "reference", second is the added dockable
    desk.split(button1, button2, DockingConstants.SPLIT_LEFT);
    desk.split(button2, button3, DockingConstants.SPLIT_BOTTOM);

    // add the fourth button as a tab on the 3rd :
    desk.createTab(button3, button4, 1);

    SwingUtilities.invokeLater(
        new Runnable() {
      public void run() {
        setSize(800,600);
        validate();
        setVisible(true); // realize on the event dispatch thread

      }
    });
  }
  public static void main(String [] args){
    new DemoFrame();
  }

  // our basic dockable object
  class DockableButton extends JButton implements Dockable {
     DockKey key;
     public DockableButton(String label){
        super(label);
        this.key = new DockKey(label); // most simple dockkey constructor
        setPreferredSize(new Dimension(200,200));
     }

    public DockKey getDockKey() {
      return key;
    }

    public Component getComponent() {
      return this;
    }
  }
}

But of course, there's more in the docking framework than this. For example you can also :

  • hide a component on a border
  • attract user attention by a blinking dockable title
  • adjust the width and height of the dockables
  • read and write a desktop configuration from/to an XML stream
  • ...
You can read more about these features in the tutorial on https://code.google.com/p/vldocking/w/list.

Browsing the API

The subset of classes of this package needed to understand and use the Docking Framework is limited to the following classes :

  • DockingPanel : the panel that contains the users components is also the main interface to docking functions.
  • Dockable : the interface implemented by dockable objects
  • DockKey : the key of a Dockable, an object that describes a user component (icon, text, tooltip)

Extending the API

This API has been developed with extension in mind.

To Fully understand its principles, you will have to browse the entire javadoc and read the API extension tutorial on VLDocking google code. vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ui/000077500000000000000000000000001243334202400264475ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ui/AutoHideButtonPanelUI.java000066400000000000000000000053701243334202400334330ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ui; import com.vlsolutions.swing.docking.AutoHideButtonPanel; import com.vlsolutions.swing.docking.DockingConstants; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicPanelUI; /** The UI associated with the AutoHideButtonPanel. *

* This UI uses the following properties : *

    *
  • UIManager.getBorder("AutoHideButtonPanel.topBorder") *
  • UIManager.getBorder("AutoHideButtonPanel.bottomBorder") *
  • UIManager.getBorder("AutoHideButtonPanel.leftBorder") *
  • UIManager.getBorder("AutoHideButtonPanel.rightBorder") *
*

* These borders are used accordingly to the border zone (TOP, LEFT..) of the used * AutoHideButtonPanel. * * @see DockingUISettings * @author Lilian Chamontin, VLSolutions * */ public class AutoHideButtonPanelUI extends BasicPanelUI implements PropertyChangeListener { private static AutoHideButtonPanelUI instance = new AutoHideButtonPanelUI(); public static ComponentUI createUI(JComponent c) { return instance; } public AutoHideButtonPanelUI() {} public void installUI(JComponent comp) { super.installUI(comp); installBorder((AutoHideButtonPanel) comp); comp.addPropertyChangeListener(AutoHideButtonPanel.PROPERTY_BORDERZONE, this); } public void uninstallUI(JComponent comp) { super.uninstallUI(comp); comp.setBorder(null); comp.removePropertyChangeListener(this); } protected void installBorder(AutoHideButtonPanel btnPanel) { switch(btnPanel.getBorderZone()) { case DockingConstants.INT_HIDE_TOP: btnPanel.setBorder(UIManager.getBorder("AutoHideButtonPanel.topBorder")); break; case DockingConstants.INT_HIDE_BOTTOM: btnPanel.setBorder(UIManager.getBorder("AutoHideButtonPanel.bottomBorder")); break; case DockingConstants.INT_HIDE_LEFT: btnPanel.setBorder(UIManager.getBorder("AutoHideButtonPanel.leftBorder")); break; case DockingConstants.INT_HIDE_RIGHT: btnPanel.setBorder(UIManager.getBorder("AutoHideButtonPanel.rightBorder")); break; } } public void propertyChange(PropertyChangeEvent e) { installBorder((AutoHideButtonPanel) e.getSource()); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ui/AutoHideButtonUI.java000066400000000000000000000117231243334202400324520ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ui; import com.vlsolutions.swing.docking.AutoHideButton; import com.vlsolutions.swing.docking.DockingConstants; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicLabelUI; /** The UI delegate for AutoHideButtons. *

* This UI uses the following properties : *

    *
  • UIManager.getBorder("AutoHideButton.expandBorderTop") *
  • UIManager.getBorder("AutoHideButton.expandBorderLeft") *
  • UIManager.getBorder("AutoHideButton.expandBorderBottom") *
  • UIManager.getBorder("AutoHideButton.expandBorderRight") *
*

* Feel free to provide different borders they will be used accordingly to the * positionning of the button (TOP, LEFT..) * * @see DockingUISettings * @author Lilian Chamontin, VLSolutions */ public class AutoHideButtonUI extends BasicLabelUI implements PropertyChangeListener { protected static AutoHideButtonUI instance = new AutoHideButtonUI(); public AutoHideButtonUI() {} /** * Creates a new DockingSplitPaneUI instance */ public static ComponentUI createUI(JComponent x) { return instance; } public void installUI(JComponent comp) { super.installUI(comp); AutoHideButton btn = (AutoHideButton) comp; installBorder(btn); btn.addPropertyChangeListener(AutoHideButton.PROPERTY_ZONE, this); //Font f = UIManager.getFont("MenuItem.font"); Font f = UIManager.getFont("AutoHideButton.font"); if(f != null) { btn.setFont(f); } else { btn.setFont(new Font("Dialog", Font.PLAIN, 10)); } } public void uninstallUI(JComponent comp) { super.uninstallUI(comp); comp.setBorder(null); comp.removePropertyChangeListener(AutoHideButton.PROPERTY_ZONE, this); } public void propertyChange(PropertyChangeEvent e) { if(e.getPropertyName().equals(AutoHideButton.PROPERTY_ZONE)) { installBorder((AutoHideButton) e.getSource()); } else { super.propertyChange(e); } } protected void installBorder(AutoHideButton btn) { switch(btn.getZone()) { case DockingConstants.INT_HIDE_TOP: btn.setBorder(UIManager.getBorder("AutoHideButton.expandBorderTop")); break; case DockingConstants.INT_HIDE_LEFT: btn.setBorder(UIManager.getBorder("AutoHideButton.expandBorderLeft")); break; case DockingConstants.INT_HIDE_BOTTOM: btn.setBorder(UIManager.getBorder("AutoHideButton.expandBorderBottom")); break; case DockingConstants.INT_HIDE_RIGHT: btn.setBorder(UIManager.getBorder("AutoHideButton.expandBorderRight")); break; } } /** Overriden to paint properly the button on vertical sides. */ public void paint(Graphics g, JComponent comp) { AutoHideButton btn = (AutoHideButton) comp; int zone = btn.getZone(); if(zone == DockingConstants.INT_HIDE_TOP || zone == DockingConstants.INT_SPLIT_BOTTOM) { super.paint(g, comp); } else { // vertical button : we have to rely on a custom paint if(btn.isOpaque()) { g.setColor(btn.getBackground()); g.fillRect(0, 0, btn.getWidth(), btn.getHeight()); } double pid2 = Math.PI / 2d; Graphics2D g2 = ((Graphics2D) g.create()); g2.setFont(btn.getFont()); g2.setColor(btn.getForeground()); FontMetrics fm = btn.getFontMetrics(btn.getFont()); Icon icon = btn.getIcon(); Insets i = btn.getInsets(); String text = btn.getText(); // 2005/07/12 added text != null controls if(zone == DockingConstants.INT_HIDE_LEFT) { g2.translate(0, btn.getHeight()); g2.rotate(- pid2); if(icon != null) { icon.paintIcon(btn, g2, i.bottom, i.left); if(text != null) { g2.drawString(text, i.bottom + icon.getIconWidth() + btn.getIconTextGap(), i.left + btn.getWidth() / 2 + fm.getAscent() / 2 /* fm.getAscent()*/); } } else { if(text != null) { g2.drawString(text, i.bottom, i.left + btn.getWidth() / 2 + fm.getAscent() / 2); } } } else { g2.translate(btn.getWidth(), 0); g2.rotate(pid2); if(icon != null) { icon.paintIcon(btn, g2, 1, 1); if(text != null) { g2.drawString(text, i.top + icon.getIconWidth() + btn.getIconTextGap(), btn.getWidth() / 2 + fm.getAscent() / 2); } } else { if(text != null) { g2.drawString(text, i.top, btn.getWidth() / 2 + fm.getAscent() / 2); } } } } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ui/AutoHideExpandPanelUI.java000066400000000000000000000026551243334202400334020ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ui; import com.vlsolutions.swing.docking.AutoHideExpandPanel; import javax.swing.JComponent; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicPanelUI; /** The UI delegate for the AutoHideExpandPanel component. *

* This class is mostly a placeholder in the case the developper would like * to provide a custom replacement for the expand panel look and feel. * * @author Lilian Chamontin, VLSolutions */ public class AutoHideExpandPanelUI extends BasicPanelUI { private static AutoHideExpandPanelUI instance = new AutoHideExpandPanelUI(); public AutoHideExpandPanelUI() {} public static ComponentUI createUI(JComponent c) { return instance; } public void installUI(JComponent comp) { super.installUI(comp); AutoHideExpandPanel panel = (AutoHideExpandPanel) comp; panel.resetBorders(); } public void uninstallUI(JComponent comp) { super.uninstallUI(comp); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ui/DetachedDockViewUI.java000066400000000000000000000035651243334202400327160ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ui; import java.awt.Color; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicPanelUI; /** The UI of the "detached" (floating) dockview. * * @see com.vlsolutions.swing.docking.DockView * @see com.vlsolutions.swing.docking.DetachedDockView * @author Lilian Chamontin, VLSolutions * @since 2.0 */ public class DetachedDockViewUI extends BasicPanelUI { /* Note that this is not a subclass of DockViewUI, (to avoid border management problems due to ancestor listener) */ private static DetachedDockViewUI instance = new DetachedDockViewUI(); @SuppressWarnings("unused") private Color highlight = UIManager.getColor("VLDocking.highlight"); public DetachedDockViewUI() {} /** Creates a UI for the given component (shared instance) */ public static ComponentUI createUI(JComponent c) { return instance; } /** Installs the component's UI */ public void installUI(JComponent c) { super.installUI(c); c.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); /* //BorderFactory.createCompoundBorder( //BorderFactory.createEmptyBorder(1,0,0,0), BorderFactory.createMatteBorder(0, 1,1,1, Color.GRAY)); */ } /** Uninstalls the component's UI */ public void uninstallUI(JComponent c) { super.uninstallUI(c); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ui/DockViewTitleBarUI.java000066400000000000000000000543361243334202400327250ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ui; import com.vlsolutions.swing.docking.DockKey; import com.vlsolutions.swing.docking.DockViewTitleBar; import com.vlsolutions.swing.docking.Dockable; import com.vlsolutions.swing.docking.DockableState; import com.vlsolutions.swing.docking.DockingDesktop; import com.vlsolutions.swing.docking.DockingUtilities; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Font; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.Rectangle; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.event.AncestorEvent; import javax.swing.event.AncestorListener; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.PanelUI; /** A UI for the {@link com.vlsolutions.swing.docking.DockViewTitleBar}. * * @author Lilian Chamontin, VLSolutions * @author Andrew Carlson, HypnoRabbit Studios * @since 2.0 * @update 2006/12/01 Lilian Chamontin : added client property support for dockKey, and react to visibleTitleBar * @update 2007/01/08 Lilian Chamontin : added support for autohide/dock disabled when hidden */ public class DockViewTitleBarUI extends PanelUI implements PropertyChangeListener { /* hack to use custom painting except on mac os (ugly opacity effects) */ private static boolean useCustomPaint = System.getProperty("os.name").toLowerCase().indexOf("mac os") < 0; private static Color panelColor = UIManager.getColor("Panel.background"); @SuppressWarnings("unused") private static Color highlight = UIManager.getColor("VLDocking.highlight"); @SuppressWarnings("unused") private static Color shadow = UIManager.getColor("VLDocking.shadow"); private static Icon closeIcon = UIManager.getIcon("DockViewTitleBar.close"); private static Icon closeIconRollover = UIManager.getIcon("DockViewTitleBar.close.rollover"); private static Icon closeIconPressed = UIManager.getIcon("DockViewTitleBar.close.pressed"); private static Icon maximizeIcon = UIManager.getIcon("DockViewTitleBar.maximize"); private static Icon maximizeIconRollover = UIManager.getIcon("DockViewTitleBar.maximize.rollover"); private static Icon maximizeIconPressed = UIManager.getIcon("DockViewTitleBar.maximize.pressed"); private static Icon restoreIcon = UIManager.getIcon("DockViewTitleBar.restore"); private static Icon restoreIconRollover = UIManager.getIcon("DockViewTitleBar.restore.rollover"); private static Icon restoreIconPressed = UIManager.getIcon("DockViewTitleBar.restore.pressed"); private static Icon hideIcon = UIManager.getIcon("DockViewTitleBar.hide"); private static Icon hideIconRollover = UIManager.getIcon("DockViewTitleBar.hide.rollover"); private static Icon hideIconPressed = UIManager.getIcon("DockViewTitleBar.hide.pressed"); private static Icon dockIcon = UIManager.getIcon("DockViewTitleBar.dock"); private static Icon dockIconRollover = UIManager.getIcon("DockViewTitleBar.dock.rollover"); private static Icon dockIconPressed = UIManager.getIcon("DockViewTitleBar.dock.pressed"); private static Icon floatIcon = UIManager.getIcon("DockViewTitleBar.float"); private static Icon floatIconRollover = UIManager.getIcon("DockViewTitleBar.float.rollover"); private static Icon floatIconPressed = UIManager.getIcon("DockViewTitleBar.float.pressed"); private static Icon attachIcon = UIManager.getIcon("DockViewTitleBar.attach"); private static Icon attachIconRollover = UIManager.getIcon("DockViewTitleBar.attach.rollover"); private static Icon attachIconPressed = UIManager.getIcon("DockViewTitleBar.attach.pressed"); // label resources taken from BasicInternalFrameUI... private static final String CLOSE_TEXT = UIManager.getString("DockViewTitleBar.closeButtonText"); private static final String ICONIFY_TEXT = UIManager.getString("DockViewTitleBar.minimizeButtonText"); private static final String RESTORE_TEXT = UIManager.getString("DockViewTitleBar.restoreButtonText"); private static final String MAXIMIZE_TEXT = UIManager.getString("DockViewTitleBar.maximizeButtonText"); private static final String FLOAT_TEXT = UIManager.getString("DockViewTitleBar.floatButtonText"); private static final String ATTACH_TEXT = UIManager.getString("DockViewTitleBar.attachButtonText"); private static Color selectedTitleColor = UIManager.getColor("InternalFrame.activeTitleBackground"); private static Color selectedTextColor = UIManager.getColor("InternalFrame.activeTitleForeground"); private static Color notSelectedTitleColor = UIManager.getColor("InternalFrame.inactiveTitleBackground"); private static Color notSelectedTextColor = UIManager.getColor("InternalFrame.inactiveTitleForeground"); // flags to hide/show buttons in the title bar (they are always visible in the contextual menu, but might // take too much space on the titles (for example a minimum set could be hide/float/close // as maximize is accessed by double click) private boolean isCloseButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isCloseButtonDisplayed"); private boolean isHideButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isHideButtonDisplayed"); private boolean isDockButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isDockButtonDisplayed"); private boolean isMaximizeButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isMaximizeButtonDisplayed"); private boolean isRestoreButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isRestoreButtonDisplayed"); private boolean isFloatButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isFloatButtonDisplayed"); private boolean isAttachButtonDisplayed = UIManager.getBoolean("DockViewTitleBar.isAttachButtonDisplayed"); protected DockViewTitleBar titleBar; /* This ancestor listener is required as buttons may change according to container hierarchy. * The first example is when a dockable is added to a floating + compund dockable, the attach * button (which usually becomes visible as the dockable is in the floating state) has to be hidden * (tech choice : we don't want to allow attaching a single child of a compound dockable) * */ private AncestorListener ancestorListener = new AncestorListener() { public void ancestorAdded(AncestorEvent event) { configureButtons(titleBar); } public void ancestorMoved(AncestorEvent event) {} public void ancestorRemoved(AncestorEvent event) {} }; public DockViewTitleBarUI(DockViewTitleBar tb) { this.titleBar = tb; } public static ComponentUI createUI(JComponent c) { return new DockViewTitleBarUI((DockViewTitleBar) c); } public void installUI(JComponent c) { super.installUI(c); installTitleBorder(c); BoxLayout box = new BoxLayout(titleBar, BoxLayout.X_AXIS); titleBar.setLayout(box); titleBar.setOpaque(true); titleBar.addPropertyChangeListener(this); titleBar.addAncestorListener(ancestorListener); installButtons(); installLabel(); Dockable d = titleBar.getDockable(); if(d != null) { titleBar.getDockable().getDockKey().addPropertyChangeListener(this); configureButtons(titleBar); } c.setCursor(Cursor.getDefaultCursor()); // needs this to avoid artifacts with floating dockable borders. } protected void layoutTitleBar() { titleBar.removeAll(); titleBar.add(Box.createHorizontalStrut(4)); // keep the label not to close to the border titleBar.add(titleBar.getTitleLabel()); titleBar.add(Box.createHorizontalGlue()); int height = UIManager.getInt("DockViewTitleBar.height"); if(height > 0) { titleBar.add(Box.createRigidArea(new Dimension(4, height))); // fixed height } titleBar.add(titleBar.getHideOrDockButton()); titleBar.add(titleBar.getFloatButton()); titleBar.add(titleBar.getMaximizeOrRestoreButton()); titleBar.add(titleBar.getCloseButton()); // simple layout hook for extenders titleBar.finishLayout(); titleBar.revalidate(); } public void uninstallUI(JComponent c) { super.uninstallUI(c); uninstallTitleBorder(c); titleBar.removePropertyChangeListener(this); titleBar.removeAncestorListener(ancestorListener); Dockable d = titleBar.getDockable(); if(d != null) { d.getDockKey().removePropertyChangeListener(this); } } /** Installs default on the titlebar label */ protected void installLabel() { JLabel titleLabel = titleBar.getTitleLabel(); Font f = UIManager.getFont("DockViewTitleBar.titleFont"); titleLabel.setFont(f); titleLabel.setForeground(notSelectedTextColor); titleBar.setBackground(notSelectedTitleColor); // adjust minimum size because of BoxLayout usage (doesn't allow resize under minimum size) //titleLabel.setMinimumSize(new Dimension(30, titleLabel.getPreferredSize().height)); } /** Installs the default background of the title bar */ protected void installBackground() { titleBar.setBackground(notSelectedTitleColor); } /** configure the title bar buttons */ protected void installButtons() { JButton closeButton = titleBar.getCloseButton(); JButton dockButton = titleBar.getHideOrDockButton(); JButton maximizeButton = titleBar.getMaximizeOrRestoreButton(); JButton floatButton = titleBar.getFloatButton(); // temporary workaround for nimbus look and feel : nimbus adds a large border // around buttons which doesn't follow other LAF behaviour. Border emptyBorder = BorderFactory.createEmptyBorder(0, 2, 0, 2); closeButton.setBorder(emptyBorder); dockButton.setBorder(emptyBorder); maximizeButton.setBorder(emptyBorder); floatButton.setBorder(emptyBorder); //Insets buttonMargin = new Insets(3, 5, 3, 5); Insets buttonMargin = new Insets(0, 2, 0, 2); closeButton.setMargin(buttonMargin); dockButton.setMargin(buttonMargin); maximizeButton.setMargin(buttonMargin); floatButton.setMargin(buttonMargin); dockButton.setRolloverEnabled(true); dockButton.setBorderPainted(false); dockButton.setFocusable(false); dockButton.setContentAreaFilled(false); closeButton.setRolloverEnabled(true); closeButton.setBorderPainted(false); closeButton.setFocusable(false); closeButton.setContentAreaFilled(false); maximizeButton.setRolloverEnabled(true); maximizeButton.setBorderPainted(false); maximizeButton.setFocusable(false); maximizeButton.setContentAreaFilled(false); floatButton.setRolloverEnabled(true); floatButton.setBorderPainted(false); floatButton.setFocusable(false); floatButton.setContentAreaFilled(false); } /** Listen to property changes in the DockKey or the title bar */ public void propertyChange(PropertyChangeEvent e) { String pName = e.getPropertyName(); //System.out.println("property change " + pName); if(pName.equals("dockable")) { Dockable old = (Dockable) e.getOldValue(); if(old != null) { old.getDockKey().removePropertyChangeListener(this); } Dockable newDockable = ((Dockable) e.getNewValue()); if(newDockable != null) { configureButtons(titleBar); newDockable.getDockKey().addPropertyChangeListener(this); } } else if(pName.equals(DockKey.PROPERTY_AUTOHIDEABLE)) { boolean isAutoHideable = ((Boolean) e.getNewValue()).booleanValue(); boolean isMaximized = titleBar.getDockable().getDockKey().getLocation() == DockableState.Location.MAXIMIZED; if(isAutoHideable) { if(! isMaximized) { titleBar.getHideOrDockButton().setVisible(true); configureHideButton(titleBar.getHideOrDockButton()); } } else { titleBar.getHideOrDockButton().setVisible(false); } } else if(pName.equals(DockKey.PROPERTY_MAXIMIZABLE)) { boolean isMaximizeable = ((Boolean) e.getNewValue()).booleanValue(); boolean isHidden = titleBar.getDockable().getDockKey().getLocation() == DockableState.Location.HIDDEN; if(isMaximizeable) { if(! isHidden) { titleBar.getMaximizeOrRestoreButton().setVisible(true); configureMaximizeButton(titleBar.getMaximizeOrRestoreButton()); } } else { titleBar.getMaximizeOrRestoreButton().setVisible(false); } } else if(pName.equals(DockKey.PROPERTY_CLOSEABLE)) { boolean isCloseable = ((Boolean) e.getNewValue()).booleanValue(); boolean isMaximized = titleBar.getDockable().getDockKey().getLocation() == DockableState.Location.MAXIMIZED; if(isCloseable) { if(! isMaximized) { titleBar.getCloseButton().setVisible(true); configureCloseButton(titleBar.getCloseButton()); } } else { titleBar.getCloseButton().setVisible(false); } } else if(pName.equals(DockKey.PROPERTY_FLOATABLE)) { boolean isFloatable = ((Boolean) e.getNewValue()).booleanValue(); boolean isMaximized = titleBar.getDockable().getDockKey().getLocation() == DockableState.Location.MAXIMIZED; if(isFloatable) { if(! isMaximized) { titleBar.getFloatButton().setVisible(true); configureFloatButton(titleBar.getFloatButton()); } } else { titleBar.getFloatButton().setVisible(false); } } else if(pName.equals(DockKey.PROPERTY_DOCKABLE_STATE)) { configureButtons(titleBar); } else if(pName.equals("active")) { boolean isActive = ((Boolean) e.getNewValue()).booleanValue(); if(isActive) { titleBar.getTitleLabel().setForeground(selectedTextColor); titleBar.setBackground(selectedTitleColor); } else { titleBar.getTitleLabel().setForeground(notSelectedTextColor); titleBar.setBackground(notSelectedTitleColor); } titleBar.repaint(); } else if(pName.equals("titlebar.notification")) { boolean notification = ((Boolean) e.getNewValue()).booleanValue(); if(notification) { titleBar.setBackground(UIManager.getColor("DockingDesktop.notificationColor")); titleBar.setOpaque(true); } else { if(titleBar.isActive()) { titleBar.setBackground(selectedTitleColor); } else { titleBar.setBackground(notSelectedTitleColor); } titleBar.setOpaque(false); } titleBar.repaint(); } else if(pName.equals(DockKey.PROPERTY_NAME)) { titleBar.repaint(); } else if(pName.equals("clientProperty.visibleTitleBar")) { // 2006/12/01 boolean v = Boolean.TRUE.equals(e.getNewValue()); titleBar.setVisible(v); } } /** Update the buttons to track state changes (for example, the maximize button can become "restore" * when the view is maximized. */ protected void configureButtons(DockViewTitleBar tb) { layoutTitleBar(); DockKey key = tb.getDockable().getDockKey(); DockableState.Location location = key.getLocation(); JButton closeButton = titleBar.getCloseButton(); JButton maxBtn = titleBar.getMaximizeOrRestoreButton(); JButton hideBtn = titleBar.getHideOrDockButton(); JButton floatBtn = titleBar.getFloatButton(); switch(location) { case DOCKED: if(key.isCloseEnabled() && isCloseButtonDisplayed) { closeButton.setVisible(true); configureCloseButton(closeButton); } else { closeButton.setVisible(false); } if(key.isMaximizeEnabled() && isMaximizeButtonDisplayed) { maxBtn.setVisible(true); configureMaximizeButton(maxBtn); } else { maxBtn.setVisible(false); } boolean isChildOfMaximizedContainer = false; DockingDesktop desk = titleBar.getDesktop(); if(desk != null) { Dockable max = desk.getMaximizedDockable(); if(max != null && max.getComponent().getParent().isAncestorOf(titleBar)) { isChildOfMaximizedContainer = true; } } if(key.isAutoHideEnabled() && isHideButtonDisplayed && ! isChildOfMaximizedContainer) { hideBtn.setVisible(true); configureHideButton(hideBtn); } else { hideBtn.setVisible(false); } if(key.isFloatEnabled() && isFloatButtonDisplayed && ! isChildOfMaximizedContainer) { floatBtn.setVisible(true); configureFloatButton(floatBtn); } else { floatBtn.setVisible(false); } titleBar.revalidate(); break; case HIDDEN: if(key.isCloseEnabled() && isCloseButtonDisplayed) { closeButton.setVisible(true); configureCloseButton(closeButton); } else { closeButton.setVisible(false); } // maximize not allowed when in autohide mode maxBtn.setVisible(false); boolean isChildOfCompound = DockingUtilities.isChildOfCompoundDockable(tb.getDockable()); // idem for float if(key.isFloatEnabled() && isFloatButtonDisplayed && ! isChildOfCompound) { floatBtn.setVisible(true); configureFloatButton(floatBtn); } else { floatBtn.setVisible(false); } // hide becomes dock if(isChildOfCompound) { //tb.getParent().getParent() instanceof AutoHideExpandPanel // V2.1 : only when not nested hideBtn.setVisible(false); } else { if(isDockButtonDisplayed && key.isAutoHideEnabled()) { // 2007/01/08 hideBtn.setVisible(true); configureDockButton(hideBtn); } else { hideBtn.setVisible(false); } } titleBar.revalidate(); break; case MAXIMIZED: closeButton.setVisible(false); floatBtn.setVisible(false); // maxBtn becomes restore if(isRestoreButtonDisplayed) { configureRestoreButton(maxBtn); maxBtn.setVisible(true); } else { maxBtn.setVisible(false); } hideBtn.setVisible(false); titleBar.revalidate(); break; case FLOATING: closeButton.setVisible(false); maxBtn.setVisible(false); hideBtn.setVisible(false); if(DockingUtilities.isChildOfCompoundDockable(tb.getDockable())) { // cannot attach a compound dockable directly floatBtn.setVisible(false); } else { floatBtn.setVisible(isAttachButtonDisplayed); configureAttachButton(floatBtn); } break; default: // not interesting } } /** installs the icons and tooltip suitable for a close button */ protected void configureCloseButton(JButton btn) { btn.setIcon(closeIcon); btn.setRolloverIcon(closeIconRollover); btn.setPressedIcon(closeIconPressed); btn.setRolloverSelectedIcon(closeIconRollover); btn.setToolTipText(CLOSE_TEXT); } /** installs the icons and tooltip suitable for a maximize button */ protected void configureMaximizeButton(JButton btn) { btn.setIcon(maximizeIcon); btn.setRolloverIcon(maximizeIconRollover); btn.setPressedIcon(maximizeIconPressed); btn.setRolloverSelectedIcon(maximizeIconRollover); btn.setToolTipText(MAXIMIZE_TEXT); } /** installs the icons and tooltip suitable for a restore button. */ protected void configureRestoreButton(JButton btn) { btn.setIcon(restoreIcon); btn.setRolloverIcon(restoreIconRollover); btn.setPressedIcon(restoreIconPressed); btn.setRolloverSelectedIcon(restoreIconRollover); btn.setToolTipText(RESTORE_TEXT); } /** installs the icons and tooltip suitable for a hide button */ protected void configureHideButton(JButton btn) { btn.setIcon(hideIcon); btn.setRolloverIcon(hideIconRollover); btn.setPressedIcon(hideIconPressed); btn.setRolloverSelectedIcon(hideIconRollover); btn.setToolTipText(ICONIFY_TEXT); } /** installs the icons and tooltip suitable for a dock button */ protected void configureDockButton(JButton btn) { btn.setIcon(dockIcon); btn.setRolloverIcon(dockIconRollover); btn.setPressedIcon(dockIconPressed); btn.setRolloverSelectedIcon(dockIconRollover); btn.setToolTipText(RESTORE_TEXT); } /** installs the icons and tooltip suitable for a float button */ protected void configureFloatButton(JButton btn) { btn.setIcon(floatIcon); btn.setRolloverIcon(floatIconRollover); btn.setPressedIcon(floatIconPressed); btn.setRolloverSelectedIcon(floatIconRollover); btn.setToolTipText(FLOAT_TEXT); } /** installs the icons and tooltip suitable for an attach button */ protected void configureAttachButton(JButton btn) { btn.setIcon(attachIcon); btn.setRolloverIcon(attachIconRollover); btn.setPressedIcon(attachIconPressed); btn.setRolloverSelectedIcon(attachIconRollover); btn.setToolTipText(ATTACH_TEXT); } /** installs the border of the title bar */ protected void installTitleBorder(JComponent c) { Border b = UIManager.getBorder("DockViewTitleBar.border"); c.setBorder(b); } /** uninstalls the icons and tooltip suitable for a close button */ protected void uninstallTitleBorder(JComponent c) { c.setBorder(null); } /** Custom title bar painting : uses a gradient from the background color * to the control highlight color. */ public void paint(Graphics g, JComponent c) { DockViewTitleBar tb = (DockViewTitleBar) c; if(useCustomPaint) { Graphics2D g2 = (Graphics2D) g.create(); g2.setColor(panelColor); g2.fillRect(0, 0, tb.getWidth(), tb.getHeight()); // emptyborder doesn't repaint //TODO: Optimize Look and Feel specific color selecting Insets i = tb.getInsets(); if(tb.isActive()) { if(UIManager.getLookAndFeel().getName().contains("Substance")) { g2.setColor(UIManager.getColor("controlLtHighlight")); //Active substance } else { g2.setColor(UIManager.getColor("controlShadow")); //Active other } } else { g2.setColor(UIManager.getColor("Panel.background")); } Rectangle r = tb.getTitleLabel().getBounds(); int w = r.x + r.width; g2.fillRect(i.left, i.top, w, tb.getHeight() - i.top - i.bottom); // gradient paint after the label text (to ensure readability) if(tb.isActive()) { if(UIManager.getLookAndFeel().getName().contains("Substance")) { g2.setPaint(new GradientPaint(i.left + w, 0, UIManager.getColor("controlLtHighlight"), tb.getWidth(), 0, UIManager.getColor("controlHighlight"))); //Active substance } else { g2.setPaint(new GradientPaint(i.left + w, 0, UIManager.getColor("controlShadow"), tb.getWidth(), 0, UIManager.getColor("controlHighlight"))); //Active other } } else { g2.setPaint(new GradientPaint(i.left + w, 0, UIManager.getColor("Panel.background"), tb.getWidth(), 0, UIManager.getColor("controlHighlight"))); //panelColor)); } g2.fillRect(i.left + w, i.top, tb.getWidth() - w - i.left - i.right, tb.getHeight() - i.top - i.bottom); g2.dispose(); } super.paint(g, c); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ui/DockViewUI.java000066400000000000000000000073001243334202400312630ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ui; import java.awt.Container; import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.event.AncestorEvent; import javax.swing.event.AncestorListener; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.PanelUI; import com.vlsolutions.swing.docking.DockView; import com.vlsolutions.swing.docking.SplitContainer; import com.vlsolutions.swing.docking.TabbedDockableContainer; /** * This is the UI delegate for the DockView class. * *

* Default behaviour in to install a shadow border on the dockview, but this can * be replaced by overriding the 3 installXXXDockableBorder methods. * * @author Lilian Chamontin, VLSolutions * * @since 2.0 */ public class DockViewUI extends PanelUI { /** * Ancestor listener used to install different borders depending on the * usage of the dock view (docked, maximized, tabbed). */ protected ViewAncestorListener ancestorListener = new ViewAncestorListener(); private static DockViewUI instance = new DockViewUI(); public DockViewUI() { } public static ComponentUI createUI(JComponent c) { return instance; } public void installUI(JComponent c) { super.installUI(c); DockView v = (DockView) c; Container parent = c.getParent(); if (parent instanceof TabbedDockableContainer) { installTabbedDockableBorder(v); } else if (parent instanceof SplitContainer) { installSingleDockableBorder(v); } else { installMaximizedDockableBorder(v); } c.addAncestorListener(ancestorListener); } public void uninstallUI(JComponent c) { super.uninstallUI(c); c.removeAncestorListener(ancestorListener); } /** * Installs a border when the DockView target is a SingleDockableContainer * (not nested in a tabbed container ) * *

* default is a shadowed border. */ protected void installSingleDockableBorder(DockView v) { Border b = UIManager.getBorder("DockView.singleDockableBorder"); v.setBorder(b); } /** * Installs a border when the DockView target is included in a * TabbedDockableContainer. * *

* Default is a shadow border without top and left shadows * */ protected void installTabbedDockableBorder(DockView v) { Border b = UIManager.getBorder("DockView.tabbedDockableBorder"); v.setBorder(b); } /** * Installs a border when the DockView target is unique on the desktop * (mamimized, or alone) * *

* Default is a shadow border without top and left shadows * */ protected void installMaximizedDockableBorder(DockView v) { Border b = UIManager.getBorder("DockView.maximizedDockableBorder"); v.setBorder(b); } class ViewAncestorListener implements AncestorListener { public void ancestorAdded(AncestorEvent ancestorEvent) { DockView v = (DockView) ancestorEvent.getComponent(); Container parent = v.getParent(); if (parent instanceof TabbedDockableContainer) { installTabbedDockableBorder(v); } else if (parent instanceof SplitContainer) { installSingleDockableBorder(v); } else { installMaximizedDockableBorder(v); } } public void ancestorMoved(AncestorEvent ancestorEvent) { } public void ancestorRemoved(AncestorEvent ancestorEvent) { } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ui/DockingSplitPaneUI.java000066400000000000000000000112071243334202400327470ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ui; import javax.swing.plaf.basic.*; import javax.swing.*; import javax.swing.plaf.*; import java.awt.*; import java.awt.image.*; /** A specific UI for removing border effects of the JSplitPanes used for docking. * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * */ public class DockingSplitPaneUI extends BasicSplitPaneUI { Color shadow = UIManager.getColor("VLDocking.shadow"); Color highlight = UIManager.getColor("VLDocking.highlight"); TexturePaint tp = null; private static boolean drawDelimitors = UIManager.getBoolean("SplitContainer.drawDotsDelimitors"); private static boolean useCustomImages = UIManager.getBoolean("SplitContainer.useCustomImages"); private static BufferedImage horizontalImage = (BufferedImage) UIManager.get("SplitContainer.hImage"); private static BufferedImage verticalImage = (BufferedImage) UIManager.get("SplitContainer.vImage"); private static int dividerSize = UIManager.getInt("SplitContainer.dividerSize"); private static boolean isSplitResizingEnabled = UIManager.getBoolean("SplitContainer.isResizingEnabled"); public DockingSplitPaneUI() {} /** if true, the UI will paint shadowed dots along the split pane divider, * if false, the divider will remain empty. Default is false * @deprecated use UIManager.put("SplitContainer.drawDotsDelimitors", Boolean) instead */ public static void setDrawDelimitors(boolean draw) { drawDelimitors = draw; } /** * Creates a new DockingSplitPaneUI instance */ public static ComponentUI createUI(JComponent x) { return new DockingSplitPaneUI(); } public void installUI(JComponent comp) { super.installUI(comp); ((JSplitPane) comp).setDividerSize(dividerSize); comp.setEnabled(isSplitResizingEnabled); } protected void installDefaults() { super.installDefaults(); divider.setBorder(null); } /** * Creates the default divider. */ public BasicSplitPaneDivider createDefaultDivider() { DockingSplitPaneDivider bd = new DockingSplitPaneDivider(this); return bd; } class DockingSplitPaneDivider extends BasicSplitPaneDivider { private static final long serialVersionUID = 1L; DockingSplitPaneDivider(BasicSplitPaneUI ui) { super(ui); } public void paint(Graphics g) { Dimension size = getSize(); Color bgColor = getBackground(); if(bgColor != null) { g.setColor(bgColor); g.fillRect(0, 0, size.width, size.height); } if(useCustomImages) { Graphics2D g2 = (Graphics2D) g.create(); BufferedImage image = getOrientation() == JSplitPane.HORIZONTAL_SPLIT ? verticalImage : horizontalImage; int width = image.getWidth(); int height = image.getHeight(); // Create a texture paint from the buffered image Rectangle r = new Rectangle(0, 0, width, height); if(tp == null) { tp = new TexturePaint(image, r); } if(getOrientation() == JSplitPane.HORIZONTAL_SPLIT) { g2.setPaint(tp); g2.fillRect(size.width / 2 - width / 2, 0, width, size.height); } else { g2.setPaint(tp); g2.fillRect(0, size.height / 2 - height / 2, size.width, height); } } else if(drawDelimitors) { // special case : custom integrated dots delimitors if(tp == null) { // Create a buffered image texture patch of size 5x5 BufferedImage bi = new BufferedImage(4, 4, BufferedImage.TYPE_INT_RGB); Graphics2D big = bi.createGraphics(); // Render into the BufferedImage graphics to create the texture big.setColor(getBackground()); big.fillRect(0, 0, 4, 4); big.setColor(highlight); big.fillRect(1, 1, 1, 1); big.setColor(shadow); big.fillRect(2, 2, 1, 1); // Create a texture paint from the buffered image Rectangle r = new Rectangle(0, 0, 4, 4); tp = new TexturePaint(bi, r); big.dispose(); } // g.setColor(shadow); Graphics2D g2 = (Graphics2D) g.create(); // Add the texture paint to the graphics context. g2.setPaint(tp); if(getOrientation() == JSplitPane.HORIZONTAL_SPLIT) { g2.fillRect(size.width / 2 - 2, 0, 4, size.height); } else { g2.fillRect(0, size.height / 2 - 2, size.width, 4); } } //paintDragRectangle(g); super.paint(g); } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ui/DockingUISettings.java000066400000000000000000001032261243334202400326530ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ui; import java.awt.Color; import java.awt.Toolkit; import java.awt.event.KeyEvent; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.KeyStroke; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.Border; import com.vlsolutions.swing.toolbars.ToolBarPanelBorder; /** * Central class to manage Look and feel settings for the docking framework. *

* There are two ways of modifying the look and feel of the docking framework : *

    *
  • provide a subclass of DockingUISettings and override the installXXX * methods *
  • directly put UI properties (UIManager.put(key,value)) awaited by the * desktop UI delegates. Those are described below. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
UI propertytypeeffect
DockView.singleDockableBorderBorderborder used when the DockView is docked alone (not in a tab)
DockView.tabbedDockableBorderBorderborder used when the DockView is contained in a tabbed pane
DockView.maximizedDockableBorderBorderborder used when the DockView is maxmized
AutoHideButtonUIclass nameUI delegate for the AutoHideButton
AutoHideButtonPanelUIclass nameUI delegate for the AutoHideButtonPanel
AutoHideExpandPanelUIclass nameUI delegate for the AutoHideExpandPanel
AutoHideButton.expandBorderTopBorderBorder of the autohide button when it is on top of the desktop
AutoHideButton.expandBorderBottomBorderBorder of the autohide button when it is at bottom of the desktop
AutoHideButton.expandBorderLeftBorderBorder of the autohide button when it is on the left of the desktop
AutoHideButton.expandBorderRightBorderBorder of the autohide button when it is on the right of the desktop
AutoHideButtonPanel.topBorderBorderBorder of the AutoHideButtonPanel when it is on top of the desktop
AutoHideButtonPanel.bottomBorderBorderBorder of the AutoHideButtonPanel when it is at bottom of the desktop
AutoHideButtonPanel.leftBorderBorderBorder of the AutoHideButtonPanel when it is on the left of the desktop
AutoHideButtonPanel.rightBorderBorderBorder of the AutoHideButtonPanel when it is on the right of the desktop
DockViewUIclass nameUI delegate for DockView
DetachedDockViewUIclass nameUI delegate for DetachedDockView
DockViewTitleBarUIclass nameUI delegate for DockViewTitleBar
DockViewTitleBar.heightintHeight of the title bars. If set to 0, then every title bar will compute * its preferred size (based on fonts and icons)
DockViewTitleBar.closeButtonTextStringText of the close button
DockViewTitleBar.minimizeButtonTextStringText of the minimize (hide) button
DockViewTitleBar.maximizeButtonTextStringText of the maximize button
DockViewTitleBar.restoreButtonTextStringText of the restore button(opposite of maximize)
DockViewTitleBar.floatButtonTextStringText of the float button (detach)
DockViewTitleBar.attachButtonTextStringText of the attach button(opposite of float)
DockViewTitleBar.titleFontFontFont used by the title bar
DockViewTitleBar.isCloseButtonDisplayedbooleandisplay or not the close button in the title bar (still accessible from * pop-up menu)
DockViewTitleBar.isHideButtonDisplayedbooleandisplay or not the hide button in the title bar
DockViewTitleBar.isDockButtonDisplayedbooleandisplay or not the dock button in the title bar
DockViewTitleBar.isMaximizeButtonDisplayedbooleandisplay or not the maximize button in the title bar
DockViewTitleBar.isRestoreButtonDisplayedbooleandisplay or not the restore button in the title bar
DockViewTitleBar.isFloatButtonDisplayedbooleandisplay or not the float button in the title bar
DockViewTitleBar.isAttachButtonDisplayedbooleandisplay or not the attach button in the title bar
DockViewTitleBar.borderBorderBorder of the title bar
DockingSplitPaneUIclass nameUI delegate for SplitContainer component
SplitContainer.dividerSizeintDivider size of the split panes
TabbedDockableContainer.tabPlacementint (SwingConstants.TOP / BOTTOM)Global tab style
DockTabbedPane.closeButtonTextStringText for the close button in tab
DockTabbedPane.minimizeButtonTextStringText for the minimize button in tab
DockTabbedPane.restoreButtonTextStringText for the restore button in tab
DockTabbedPane.maximizeButtonTextStringText for the maximize button in tab
DockTabbedPane.floatButtonTextStringText for the float button in tab
DockTabbedPane.attachButtonTextStringText for the attach button in tab (when floating)
TabbedContainer.requestFocusOnTabSelectionbooleanAutomatically puts focus on the selected tabbed component (default false) *
TabbedPane.otherIconsGapintGap between text and close icon in closeable tab
TabbedPane.inBetweenOtherIconsGapintGap between two icons
DockViewTitleBar.closeIconIcon for the close button
DockViewTitleBar.close.rolloverIconIcon for the close button
DockViewTitleBar.close.pressedIconIcon for the close button
DockViewTitleBar.dockIconIcon for the dock button
DockViewTitleBar.dock.rolloverIconIcon for the dock button
DockViewTitleBar.dock.pressedIconIcon for the dock button
DockViewTitleBar.hideIconIcon for the hide button
DockViewTitleBar.hide.rolloverIconIcon for the hide button
DockViewTitleBar.hide.pressedIconIcon for the hide button
DockViewTitleBar.maximizeIconIcon for the maximize button
DockViewTitleBar.maximize.rolloverIconIcon for the maximize button
DockViewTitleBar.maximize.pressedIconIcon for the maximize button
DockViewTitleBar.restoreIconIcon for the restore button
DockViewTitleBar.restore.rolloverIconIcon for the restore button
DockViewTitleBar.restore.pressedIconIcon for the restore button
DockViewTitleBar.floatIconIcon for the float button
DockViewTitleBar.float.rolloverIconIcon for the float button
DockViewTitleBar.float.pressedIconIcon for the float button
DockViewTitleBar.attachIconIcon for the attach button
DockViewTitleBar.attach.rolloverIconIcon for the attach button
DockViewTitleBar.attach.pressedIconIcon for the attach button
DockViewTitleBar.menu.closeIconIcon for the close button, in pop-up menu
DockViewTitleBar.menu.hideIconIcon for the hide button, in pop-up menu
DockViewTitleBar.menu.maximizeIconIcon for the maximize button, in pop-up menu
DockViewTitleBar.menu.restoreIconIcon for the restore button, in pop-up menu
DockViewTitleBar.menu.dockIconIcon for the dock button, in pop-up menu
DockViewTitleBar.menu.floatIconIcon for the float button, in pop-up menu
DockViewTitleBar.menu.attachIconIcon for the attach button, in pop-up menu
DockTabbedPane.closeIconIcon for the close button, in tabs
DockTabbedPane.close.rolloverIconIcon for the close button, in tabs
DockTabbedPane.close.pressedIconIcon for the close button, in tabs
DockTabbedPane.menu.closeIconIcon for the close button, in tab pop-up menu
DockTabbedPane.menu.hideIconIcon for the hide button, in tab pop-up menu
DockTabbedPane.menu.maximizeIconIcon for the maximize button, in tab pop-up menu
DockTabbedPane.menu.floatIconIcon for the float button, in tab pop-up menu
DockTabbedPane.menu.attachIconIcon for the attach button, in tab pop-up menu (when floating)
DockTabbedPane.menu.closeAllIconIcon for the "close all" button, in tab pop-up menu
DockTabbedPane.menu.closeAllOtherIconIcon for the "close all other" button, in tab pop-up menu
DockingDesktop.closeActionAcceleratorKeyStrokeKeyStroke for close action (on selected dockable)
DockingDesktop.maximizeActionAcceleratorKeyStrokeKeyStroke for maximize/restore action (on selected dockable)
DockingDesktop.dockActionAcceleratorKeyStrokeKeyStroke for hide/dock action (on selected dockable)
DockingDesktop.floatActionAcceleratorKeyStrokeKeyStroke for float/attach action (on selected dockable)
DockingDesktop.notificationColorColorblinking color for notifications
DockingDesktop.notificationBlinkCountintmaximum number of blinking for notifications
DragControler.stopDragCursor"ImageCursor image used when a drag and drop move is not allowed
DragControler.detachCursor"ImageCursor image used when a drag and drop move will detach the dockable
DragControler.dragCursor"ImageCursor image used when a drag and drop move is allowed(not leading to a * detached dockable)
DragControler.swapDragCursorImageCursor image used when doing a drag and drop with Ctrl key (hot swap)
DragControler.isDragAndDropEnabledBooleanGlobal switch to turn on/off drag and drop support in vldocking (default * set to true)
DragControler.paintBackgroundUnderDragRectBooleanGlobal switch to turn on/off background painting under drag shapes (which * can be slow on some linux distributions) (default set to true)
ToolBarGripperUIclass nameUI delegate for the toolbar "gripper"
ToolBarPanel.topBorderBorderBorder used when a toolbar in on the top of a container
ToolBarPanel.leftBorderBorderBorder used when a toolbar in on the left of a container
ToolBarPanel.bottomBorderBorderBorder used when a toolbar in at the bottom of a container
ToolBarPanel.rightBorderBorderBorder used when a toolbar in on the right of a container
FloatingDialog.dialogBorderBorderBorder used for the FloatingDialog
FloatingDialog.titleBorderBorderBorder used for the title (drag header) of the FloatingDialog
FloatingContainer.followParentWindowBooleanif true, the floating dialogs will follow the movements of their parent * window on screen
FloatingContainer.paintDragShapeBooleanif true, a drag outline shape will follow the mouse when dragging
* * @author Lilian Chamontin, VLSolutions */ public class DockingUISettings { static DockingUISettings instance = null; /** Field for installing settings only once */ protected boolean isSettingsInstalled = false; private Color shadow = UIManager.getColor("controlShadow"); private Color highlight = UIManager.getColor("controlLtHighlight"); @SuppressWarnings("unused") private Color darkShadow = UIManager.getColor("controlDkShadow"); public DockingUISettings() { } /** * returns the singleton instance used to store and install UI settings for * the framework */ public static DockingUISettings getInstance() { // give a chance to subclassers to install their own subclass instance if (instance == null) { instance = new DockingUISettings(); } return instance; } /** * Allows replacement of the settings instance (used to override global look * and feel settings of the framework. *

* This method must be called before DockingDesktop is referenced, as the * settings are statically installed at that moment. */ public static void setInstance(DockingUISettings newInstance) { instance = newInstance; } /** * Installs the UI settings. This is executed only once, and automatically * called at DockingDesktop class loading in case it was not called by the * application. */ public void installUI() { if (!isSettingsInstalled) { installColors(); installAutoHideSettings(); installBorderSettings(); installDockViewSettings(); installDockViewTitleBarSettings(); installSplitContainerSettings(); installCloseableTabs(); installTabbedContainerSettings(); installIcons(); installAccelerators(); installDesktopSettings(); installFloatingSettings(); installToolBarSettings(); isSettingsInstalled = true; } } /** * Allows updating of the ui after a look and feel change. *

* The Docking framework uses references of UI elements from this class to * install its UI according to the look and feel. When Laf is changed, and * before calling SwingUtilities.updateComponentTreeUI(topLevelComponent), * invoke updateUI() in order to reset everything. *

* Calling this method after * SwingUtilities.updateComponentTreeUI(topLevelComponent) is unspecified * (some things will be updated, others not). */ public void updateUI() { isSettingsInstalled = false; installUI(); } /** installs the borders */ public void installBorderSettings() { // this is for the "flat style" (comment this line, or put a FALSE to // revert to "shadow style" // flat style is the default (outside : empty 1 pix / inside : // hightlight-top-left + shadow-bottom-right Border innerFlatSingleBorder = BorderFactory.createCompoundBorder( BorderFactory.createMatteBorder(1, 1, 0, 0, highlight), BorderFactory.createMatteBorder(0, 0, 1, 1, shadow)); Border flatSingleBorder = BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder(1, 1, 1, 1), innerFlatSingleBorder); UIManager.put("DockView.singleDockableBorder", flatSingleBorder); UIManager.put("DockView.tabbedDockableBorder", null); UIManager.put("DockView.maximizedDockableBorder", null); } /** installs the autohide related properties */ public void installAutoHideSettings() { UIManager.put("AutoHideButtonUI", "com.vlsolutions.swing.docking.ui.AutoHideButtonUI"); UIManager.put("AutoHideButtonPanelUI", "com.vlsolutions.swing.docking.ui.AutoHideButtonPanelUI"); UIManager.put("AutoHideExpandPanelUI", "com.vlsolutions.swing.docking.ui.AutoHideExpandPanelUI"); UIManager.put("AutoHideButton.expandBorderTop", BorderFactory .createCompoundBorder( BorderFactory.createCompoundBorder(BorderFactory .createMatteBorder(1, 1, 0, 1, shadow), BorderFactory.createMatteBorder(1, 1, 0, 1, highlight)), BorderFactory .createEmptyBorder(0, 6, 0, 6))); UIManager.put("AutoHideButton.expandBorderBottom", BorderFactory .createCompoundBorder( BorderFactory.createCompoundBorder(BorderFactory .createMatteBorder(0, 1, 1, 1, shadow), BorderFactory.createMatteBorder(0, 1, 1, 1, highlight)), BorderFactory .createEmptyBorder(0, 6, 0, 6))); UIManager.put("AutoHideButton.expandBorderLeft", BorderFactory .createCompoundBorder( BorderFactory.createCompoundBorder(BorderFactory .createMatteBorder(1, 1, 1, 0, shadow), BorderFactory.createMatteBorder(1, 1, 1, 0, highlight)), BorderFactory .createEmptyBorder(6, 0, 6, 0))); UIManager.put("AutoHideButton.expandBorderRight", BorderFactory .createCompoundBorder( BorderFactory.createCompoundBorder(BorderFactory .createMatteBorder(1, 0, 1, 1, shadow), BorderFactory.createMatteBorder(1, 0, 1, 1, highlight)), BorderFactory .createEmptyBorder(6, 0, 6, 0))); UIManager.put("AutoHideButtonPanel.topBorder", BorderFactory .createCompoundBorder( BorderFactory.createEmptyBorder(1, 0, 0, 0), BorderFactory.createMatteBorder(0, 0, 1, 0, shadow))); UIManager.put("AutoHideButtonPanel.bottomBorder", BorderFactory .createCompoundBorder( BorderFactory.createEmptyBorder(0, 0, 1, 0), BorderFactory.createMatteBorder(1, 0, 0, 0, shadow))); UIManager.put("AutoHideButtonPanel.leftBorder", BorderFactory .createCompoundBorder( BorderFactory.createEmptyBorder(0, 1, 0, 1), BorderFactory.createMatteBorder(0, 0, 0, 1, shadow))); UIManager.put("AutoHideButtonPanel.rightBorder", BorderFactory .createCompoundBorder( BorderFactory.createEmptyBorder(0, 1, 0, 1), BorderFactory.createMatteBorder(0, 1, 0, 0, shadow))); UIManager.put("AutoHideButton.font", UIManager.get("MenuItem.font")); // 2006/01/23 } /** installs the DockView related properties */ public void installDockViewSettings() { UIManager.put("DockViewUI", "com.vlsolutions.swing.docking.ui.DockViewUI"); UIManager.put("DetachedDockViewUI", "com.vlsolutions.swing.docking.ui.DetachedDockViewUI"); } /** installs the DockVieTitleBar related properties */ public void installDockViewTitleBarSettings() { UIManager.put("DockViewTitleBarUI", "com.vlsolutions.swing.docking.ui.DockViewTitleBarUI"); UIManager.put("DockViewTitleBar.height", new Integer(20)); UIManager.put("DockViewTitleBar.closeButtonText", UIManager.getString("InternalFrameTitlePane.closeButtonText")); UIManager.put("DockViewTitleBar.minimizeButtonText", UIManager .getString("InternalFrameTitlePane.minimizeButtonText")); UIManager .put("DockViewTitleBar.restoreButtonText", UIManager .getString("InternalFrameTitlePane.restoreButtonText")); UIManager.put("DockViewTitleBar.maximizeButtonText", UIManager .getString("InternalFrameTitlePane.maximizeButtonText")); UIManager.put("DockViewTitleBar.floatButtonText", "Detach"); UIManager.put("DockViewTitleBar.attachButtonText", "Attach"); // font to be used in the title bar UIManager.put("DockViewTitleBar.titleFont", UIManager.get("InternalFrame.titleFont")); // are buttons displayed or just accessible from the contextual menu ? // setting one of these flags to false hide the button from the title // bar // setting to true not necessarily shows the button, as it then depends // on the DockKey allowed states. UIManager.put("DockViewTitleBar.isCloseButtonDisplayed", Boolean.TRUE); UIManager.put("DockViewTitleBar.isHideButtonDisplayed", Boolean.TRUE); UIManager.put("DockViewTitleBar.isDockButtonDisplayed", Boolean.TRUE); UIManager.put("DockViewTitleBar.isMaximizeButtonDisplayed", Boolean.TRUE); UIManager .put("DockViewTitleBar.isRestoreButtonDisplayed", Boolean.TRUE); UIManager.put("DockViewTitleBar.isFloatButtonDisplayed", Boolean.TRUE); UIManager.put("DockViewTitleBar.isAttachButtonDisplayed", Boolean.TRUE); UIManager.put("DockViewTitleBar.border", BorderFactory.createMatteBorder(0, 0, 1, 0, shadow)); } /** installs the splitpanes related properties */ public void installSplitContainerSettings() { UIManager.put("DockingSplitPaneUI", "com.vlsolutions.swing.docking.ui.DockingSplitPaneUI"); UIManager.put("SplitContainer.dividerSize", new Integer(4)); UIManager.put("SplitContainer.isResizingEnabled", Boolean.TRUE); // 2007/08/11 } /** installs the tabbed pane related properties */ public void installTabbedContainerSettings() { @SuppressWarnings("unused") final String prefix = "/com/vldocking/swing/docking/"; UIManager.put("TabbedDockableContainer.tabPlacement", new Integer( SwingConstants.TOP)); UIManager.put("DockTabbedPane.closeButtonText", UIManager.getString("InternalFrameTitlePane.closeButtonText")); UIManager.put("DockTabbedPane.minimizeButtonText", UIManager .getString("InternalFrameTitlePane.minimizeButtonText")); UIManager .put("DockTabbedPane.restoreButtonText", UIManager .getString("InternalFrameTitlePane.restoreButtonText")); UIManager.put("DockTabbedPane.maximizeButtonText", UIManager .getString("InternalFrameTitlePane.maximizeButtonText")); UIManager.put("DockTabbedPane.floatButtonText", "Detach"); UIManager.put("DockTabbedPane.attachButtonText", "Attach");// 2005/10/07 UIManager.put("JTabbedPaneSmartIcon.font", UIManager.getFont("TabbedPane.font")); // 2006/01/23 // set to true to set focus directly into a tabbed component when it // becomes // selected UIManager.put("TabbedContainer.requestFocusOnTabSelection", Boolean.FALSE); } /** installs the closable tabs properties */ public void installCloseableTabs() { // this one is already provided by the look and feel // UIManager.put("TabbedPane.textIconGap", new Integer(4)); UIManager.put("TabbedPane.otherIconsGap", new Integer(8)); UIManager.put("TabbedPane.inBetweenOtherIconsGap", new Integer(4)); UIManager.put("TabbedPane.alternateTabIcons", Boolean.FALSE); } /** installs icons used by the framework */ @SuppressWarnings("unused") public void installIcons() { final String prefix = "/com/vlsolutions/swing/docking/"; Icon closeIcon = new ImageIcon(getClass().getResource( prefix + "close16v2.png")); Icon closeRolloverIcon = new ImageIcon(getClass().getResource( prefix + "close16v2rollover.png")); Icon closePressedIcon = new ImageIcon(getClass().getResource( prefix + "close16v2pressed.png")); Icon closeTabIcon = new ImageIcon(getClass().getResource( prefix + "close16tab.png")); Icon closeTabRolloverIcon = new ImageIcon(getClass().getResource( prefix + "close16tabRollover.png")); Icon closeTabPressedIcon = new ImageIcon(getClass().getResource( prefix + "close16tabPressed.png")); Icon hideIcon = new ImageIcon(getClass().getResource( prefix + "hide16v2.png")); Icon hideRolloverIcon = new ImageIcon(getClass().getResource( prefix + "hide16v2rollover.png")); Icon maximizeIcon = new ImageIcon(getClass().getResource( prefix + "maximize16v2.png")); Icon maximizeRolloverIcon = new ImageIcon(getClass().getResource( prefix + "maximize16v2rollover.png")); Icon restoreIcon = new ImageIcon(getClass().getResource( prefix + "restore16v2.png")); Icon restoreRolloverIcon = new ImageIcon(getClass().getResource( prefix + "restore16v2rollover.png")); Icon dockRolloverIcon = new ImageIcon(getClass().getResource( prefix + "dock16v2rollover.png")); Icon floatIcon = new ImageIcon(getClass().getResource( prefix + "float16v2.png")); Icon floatRolloverIcon = new ImageIcon(getClass().getResource( prefix + "float16v2rollover.png")); Icon floatPressedIcon = new ImageIcon(getClass().getResource( prefix + "float16v2pressed.png")); Icon attachIcon = new ImageIcon(getClass().getResource( prefix + "attach16v2.png")); Icon attachRolloverIcon = new ImageIcon(getClass().getResource( prefix + "attach16v2rollover.png")); Icon attachPressedIcon = new ImageIcon(getClass().getResource( prefix + "attach16v2pressed.png")); UIManager.put("DockViewTitleBar.close", closeIcon); UIManager.put("DockViewTitleBar.close.rollover", closeRolloverIcon); UIManager.put("DockViewTitleBar.close.pressed", closePressedIcon); UIManager.put("DockViewTitleBar.dock", new ImageIcon(getClass() .getResource(prefix + "dock16v2.png"))); UIManager.put("DockViewTitleBar.dock.rollover", dockRolloverIcon); UIManager.put("DockViewTitleBar.dock.pressed", new ImageIcon(getClass() .getResource(prefix + "dock16v2pressed.png"))); UIManager.put("DockViewTitleBar.hide", hideIcon); UIManager.put("DockViewTitleBar.hide.rollover", hideRolloverIcon); UIManager.put("DockViewTitleBar.hide.pressed", new ImageIcon(getClass() .getResource(prefix + "hide16v2pressed.png"))); UIManager.put("DockViewTitleBar.maximize", maximizeIcon); UIManager.put("DockViewTitleBar.maximize.pressed", new ImageIcon( getClass().getResource(prefix + "maximize16v2pressed.png"))); UIManager.put("DockViewTitleBar.maximize.rollover", maximizeRolloverIcon); UIManager.put("DockViewTitleBar.restore", restoreIcon); UIManager.put("DockViewTitleBar.restore.pressed", new ImageIcon( getClass().getResource(prefix + "restore16v2pressed.png"))); UIManager.put("DockViewTitleBar.restore.rollover", restoreRolloverIcon); UIManager.put("DockViewTitleBar.float", floatIcon); UIManager.put("DockViewTitleBar.float.rollover", floatRolloverIcon); UIManager.put("DockViewTitleBar.float.pressed", floatPressedIcon); UIManager.put("DockViewTitleBar.attach", attachIcon); UIManager.put("DockViewTitleBar.attach.rollover", attachRolloverIcon); UIManager.put("DockViewTitleBar.attach.pressed", attachPressedIcon); UIManager.put("DockViewTitleBar.menu.close", closeRolloverIcon); UIManager.put("DockViewTitleBar.menu.hide", hideRolloverIcon); UIManager.put("DockViewTitleBar.menu.maximize", maximizeRolloverIcon); UIManager.put("DockViewTitleBar.menu.restore", restoreRolloverIcon); UIManager.put("DockViewTitleBar.menu.dock", dockRolloverIcon); UIManager.put("DockViewTitleBar.menu.float", floatRolloverIcon); UIManager.put("DockViewTitleBar.menu.attach", attachRolloverIcon); UIManager.put("DockTabbedPane.close", closeIcon); UIManager.put("DockTabbedPane.close.rollover", closeRolloverIcon); UIManager.put("DockTabbedPane.close.pressed", closePressedIcon); UIManager.put("DockTabbedPane.unselected_close", null); // 2005/11/14 UIManager.put("DockTabbedPane.unselected_close.rollover", closeRolloverIcon); UIManager.put("DockTabbedPane.unselected_close.pressed", closePressedIcon); UIManager.put("DockTabbedPane.menu.close", closeRolloverIcon); UIManager.put("DockTabbedPane.menu.hide", hideRolloverIcon); UIManager.put("DockTabbedPane.menu.maximize", maximizeRolloverIcon); UIManager.put("DockTabbedPane.menu.float", floatRolloverIcon); UIManager.put("DockTabbedPane.closeAll", new ImageIcon(getClass() .getResource(prefix + "closeAll16.png"))); UIManager.put("DockTabbedPane.closeAllOther", new ImageIcon(getClass() .getResource(prefix + "closeAllOther16.png"))); UIManager.put("DockTabbedPane.menu.attach", attachRolloverIcon); // 2005/10/07 } /** installs the eyboard shortcuts */ public void installAccelerators() { int MENU_SHORTCUT_MASK = Toolkit.getDefaultToolkit() .getMenuShortcutKeyMask(); // this returns CTRL_MASK or META_MASK depending on the platform // (win/mac os) UIManager.put("DockingDesktop.closeActionAccelerator", KeyStroke.getKeyStroke(KeyEvent.VK_F4, MENU_SHORTCUT_MASK)); // toggle maximize/restore UIManager .put("DockingDesktop.maximizeActionAccelerator", KeyStroke .getKeyStroke(KeyEvent.VK_ESCAPE, KeyEvent.SHIFT_MASK)); // toggle autohide/dock UIManager.put("DockingDesktop.dockActionAccelerator", KeyStroke .getKeyStroke(KeyEvent.VK_BACK_SPACE, MENU_SHORTCUT_MASK)); UIManager.put("DockingDesktop.floatActionAccelerator", KeyStroke.getKeyStroke(KeyEvent.VK_F5, MENU_SHORTCUT_MASK)); } /** installs the DockinDesktop related properties */ public void installDesktopSettings() { UIManager.put("DockingDesktop.notificationColor", Color.ORANGE); UIManager.put("DockingDesktop.notificationBlinkCount", new Integer(5)); UIManager.put( "DragControler.stopDragCursor", new ImageIcon(getClass().getResource( "/com/vlsolutions/swing/docking/stopdragcursor.gif")) .getImage()); UIManager.put( "DragControler.detachCursor", new ImageIcon(getClass().getResource( "/com/vlsolutions/swing/docking/detachCursor.png")) .getImage()); UIManager.put("DragControler.dragCursor", new ImageIcon(getClass() .getResource("/com/vlsolutions/swing/docking/dragcursor.gif")) .getImage()); UIManager.put( "DragControler.swapDragCursor", new ImageIcon(getClass().getResource( "/com/vlsolutions/swing/docking/swapdragcursor.gif")) .getImage()); UIManager.put("DragControler.isDragAndDropEnabled", Boolean.TRUE); UIManager.put("DragControler.paintBackgroundUnderDragRect", Boolean.FALSE); } /** installs the FloatingDialog related properties */ public void installFloatingSettings() { // Border border = BorderFactory.createMatteBorder(1,1,1,1, darkShadow); // Border titleBorder = BorderFactory.createMatteBorder(0,0,1,0, // highlight); Border border = null;// BorderFactory.createEmptyBorder(1,1,1,1); Border titleBorder = null;// BorderFactory.createMatteBorder(0,0,1,0, // shadow); UIManager.put("FloatingDialog.dialogBorder", border); UIManager.put("FloatingDialog.titleBorder", titleBorder); UIManager.put("FloatingContainer.followParentWindow", Boolean.TRUE); UIManager.put("FloatingContainer.paintDragShape", Boolean.TRUE); } /** installs the toolbar related properties */ public void installToolBarSettings() { UIManager.put("ToolBarGripperUI", "com.vlsolutions.swing.toolbars.ToolBarGripperUI"); // borders to use with toolbarpanels depending on their position UIManager.put("ToolBarPanel.topBorder", new ToolBarPanelBorder( ToolBarPanelBorder.TOP_PANEL)); UIManager.put("ToolBarPanel.leftBorder", new ToolBarPanelBorder( ToolBarPanelBorder.LEFT_PANEL)); UIManager.put("ToolBarPanel.bottomBorder", new ToolBarPanelBorder( ToolBarPanelBorder.BOTTOM_PANEL)); UIManager.put("ToolBarPanel.rightBorder", new ToolBarPanelBorder( ToolBarPanelBorder.RIGHT_PANEL)); } private void installColors() { Color shadow = UIManager.getColor("controlShadow"); Color highlight = UIManager.getColor("controlLtHighlight"); if (shadow == null) { shadow = Color.GRAY; } if (highlight == null) { highlight = shadow.brighter(); } UIManager.put("VLDocking.shadow", shadow); UIManager.put("VLDocking.highlight", highlight); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ui/package.html000066400000000000000000000010571243334202400307330ustar00rootroot00000000000000

UI Package of the docking framework.

This package contains classes related to UI management (look and feel classes).

Customizing the UI of the Docking Framework

Since Version 2.0, almost every visual property of the Docking Framework is stored with DockingUISettings in the form or UI properties.

There properties can be Fonts, Colors, Borders, or UI delegates class names.

The complete list of properties can be found in the DockingUISettings class. vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ws/000077500000000000000000000000001243334202400264635ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ws/WSDesktop.java000066400000000000000000000732471243334202400312260ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ws; import com.vlsolutions.swing.docking.AutoHidePolicy; import com.vlsolutions.swing.docking.DockableState; import com.vlsolutions.swing.docking.DockingConstants; import com.vlsolutions.swing.docking.RelativeDockablePosition; import com.vlsolutions.swing.docking.SplitContainer; import java.awt.Rectangle; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import javax.swing.JSplitPane; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; /** A desktop part of a workspace. *

* Use this object to define the layout of a DockingDesktop. This layout can be applied later * to that desktop through the Workspace.apply(DockingContext ctx) method. *

* The API is a subset of the one of DockingDesktop : limited to layout building. * you can addDockable(), split(), createTab(), addHiddenDockable(), addFloatingDockable(), see these * method description for further information. *

* Node : WSDesktop doens't support layout updates : you should use it to build a layout, but not to * move dockables around. (if you add a dockable somewhere, don't add it elsewhere later as removal isn't * fully implemented). *

* In a WSDesktop, dockables are identified by a WSDockKey (a limited version of DockKey) : this is to allow * you to create workspaces with dockables that haven't been constructed yet (lazy loading). *

*Example : *

 *  Workspace w = new Workspace();
 *  WSDesktop desk = w.getDesktop(0); // gets the default (single) desktop
 * // define some dockable keys
 *  WSDockKey editorKey = new WSDockKey("editor");
 *  WSDockKey treeKey, tableKey, imgToolKey // other dockable keys
 *
 * // now define a workspace layout
 *  desk.addDockable(editorKey); // initial dockable
 *  desk.split(editorKey, treeKey, DockingConstants.SPLIT_LEFT, 0.5);  // splitted
 *  desk.split(treeKey, tableKey, DockingConstants.SPLIT_TOP, 0.7);  // tree is also splitted
 *
 *  desk.createTab(tableKey, imgToolsKey, 0);  // tableKey is transformed into a tabbed container
 * // and that's it
 * // ...
 * // later
 * //
 * DockingContext ctx = ... // your real desktop
 * w.apply(ctx); // applies the workspace to this desktop
 * // now the dektops are loaded as specified in the 'w' workspace
 *
* * @author Lilian Chamontin, VLSolutions * @since 2.1.2 */ @SuppressWarnings({"rawtypes", "unchecked", "unused"}) public class WSDesktop { /** The name of this desktop (which must match the name of a real desktop if more than one desktops are used ) */ private String desktopName; /** root node for desktop (<=> DockingPanel) */ private TopLevelNode mainNode = new TopLevelNode(); /** Map of Nodes (key : WSDockKey, value : Node)*/ private HashMap nodesByKey = new HashMap(); /** 4 borders of this desktop */ private ArrayList[] borders = new ArrayList[4]; /** <=> floating windows */ private ArrayList floatingNodes = new ArrayList(); private WSDockKey maximizedDockable = null; /** groups of tabs (used to re-tab autohidden dockable)*/ protected HashMap> tabbedGroups = new HashMap(); // / /** Constructs a WSDesktop with "default" as name */ public WSDesktop() { this("default"); } /** Constructs a WSDesktop with a given name */ public WSDesktop(String desktopName) { this.desktopName = desktopName; for(int i = 0; i < borders.length; i++) { borders[i] = new ArrayList(); } } /** removes all information stored into this desktop, which becomes ready to * be reused. */ public void clear() { mainNode = new TopLevelNode(); nodesByKey.clear(); for(int i = 0; i < borders.length; i++) { borders[i].clear(); } floatingNodes.clear(); maximizedDockable = null; } /** Adds the first dockable to this desktop. This method will fail if called more than once */ public void addDockable(WSDockKey key) { if(mainNode.child != null) { throw new IllegalArgumentException("this workspace isn't empty"); } mainNode.setChild(new SingleDockableNode(key)); } /** Sets the maximized dockable of this desktop, (or null if no dockable maximized). *

* Don't forget that this dockable MUST ALSO BE in the DOCKED state (added to the desktop * in a split, tab or compound node) otherwise the missing restore information will cause * unwanted behaviour, or exceptions. */ public void setMaximizedDockable(WSDockKey max) { this.maximizedDockable = max; } private SingleDockableNode getNode(WSDockKey key) { return (SingleDockableNode) nodesByKey.get(key); } /** Splits a dockable (with a given split location) * * @param base the dockable to be splitted * @param newDockable the new dockable * @param split the orientation of split * @param splitLocation where the split divisor is (always relative from the top/left dockable, so * split(a, b, SPLIT_TOP, 0.1f) and split(a, b, SPLIT_BOTTOM, 0.1f) have the same dividor location (somewhere near * the top of the split). */ public void split(WSDockKey base, WSDockKey newDockable, DockingConstants.Split split, double splitLocation) { Node baseNode = getNode(base); if(baseNode == null) { throw new IllegalArgumentException("base dockable not found " + base); } SplitNode splitNode = new SplitNode(); replaceChild(baseNode.parent, baseNode, splitNode); switch(split.value()) { case DockingConstants.INT_SPLIT_TOP: splitNode.setTop(new SingleDockableNode(newDockable)); splitNode.setBottom(baseNode); splitNode.isHorizontal = false; break; case DockingConstants.INT_SPLIT_LEFT: splitNode.setLeft(new SingleDockableNode(newDockable)); splitNode.setRight(baseNode); splitNode.isHorizontal = true; break; case DockingConstants.INT_SPLIT_BOTTOM: splitNode.setBottom(new SingleDockableNode(newDockable)); splitNode.setTop(baseNode); splitNode.isHorizontal = false; break; case DockingConstants.INT_SPLIT_RIGHT: splitNode.setRight(new SingleDockableNode(newDockable)); splitNode.setLeft(baseNode); splitNode.isHorizontal = true; break; } splitNode.location = splitLocation; } /** Creates a tab containing baseTab and newTab (if baseTab is already into a Tab, then * newTab will just be added at the "order" position. */ public void createTab(WSDockKey baseTab, WSDockKey newTab, int order) { SingleDockableNode baseTabNode = getNode(baseTab); if(baseTabNode == null) { throw new IllegalArgumentException("base dockable not found " + baseTab); } if(baseTabNode.parent instanceof TabNode) { // already in a tab TabNode parent = (TabNode) baseTabNode.parent; parent.addTab(order, new SingleDockableNode(newTab)); } else { // replace parent by a tab TabNode gParent = new TabNode(); replaceChild(baseTabNode.parent, baseTabNode, gParent); gParent.addTab(0, baseTabNode); gParent.addTab(order, new SingleDockableNode(newTab)); } } /** Adds a dockable into a compound dockable */ public void addDockable(WSDockKey compoundDockable, WSDockKey childDockable) { SingleDockableNode node = getNode(compoundDockable); Node parent = node.parent; CompoundDockableNode cnode = new CompoundDockableNode(compoundDockable); replaceChild(parent, node, cnode); cnode.setNestedNode(new SingleDockableNode(childDockable)); } /** Adds a new dockable (and stores its return-to-docked position) */ public void addHiddenDockable(WSDockKey dockable, RelativeDockablePosition dockedPosition) { int zone; if(dockable.getAutoHideBorder() == null) { zone = AutoHidePolicy.getPolicy().getDefaultHideBorder().value(); } else { zone = dockable.getAutoHideBorder().value(); } ArrayList border = borders[zone]; border.add(new HiddenNode(new SingleDockableNode(dockable), dockedPosition)); } /** Adds a new floating dockable * * @param dockable the dockable to add as floating * @param windowRect rectangle defining the window (relative to screen) of the floating dockable * @param returnPosition where to put the dockable when returning to the desktop * */ public void setFloating(WSDockKey dockable, Rectangle windowRect, RelativeDockablePosition returnPosition) { FloatingNode f = new FloatingNode(new SingleDockableNode(dockable), windowRect, returnPosition); floatingNodes.add(f); } /** Returns the name of this desktop (which must match the name of a real desktop if more than one desktops are used ) */ public String getDesktopName() { return desktopName; } /** Updates the name of this workspace desktop */ public void setDesktopName(String name) { this.desktopName = name; } /** Package method : used to encode this desktop into an XML stream */ void writeDesktopNode(PrintWriter out) { out.println(""); out.println(""); if(mainNode.child != null) { xmlWriteComponent(mainNode.child, out); } if(maximizedDockable != null) { out.println(""); out.println(""); out.println(""); } out.println(""); for(int i = 0; i < borders.length; i++) { xmlWriteBorder(i, borders[i], out); } // finish with the floating dockables for(int i = 0; i < floatingNodes.size(); i++) { FloatingNode f = (FloatingNode) floatingNodes.get(i); xmlWriteFloating(f, out); } // and the tab groups xmlWriteTabGroups(out); out.println(""); } private void xmlWriteComponent(Node node, PrintWriter out) { if(node instanceof SplitNode) { xmlWriteSplit((SplitNode) node, out); } else if(node instanceof TabNode) { xmlWriteTab((TabNode) node, out); } else if(node instanceof SingleDockableNode) { xmlWriteDockable((SingleDockableNode) node, out); } } private void xmlWriteSplit(SplitNode splitNode, PrintWriter out) { double location = splitNode.location; int orientation = splitNode.isHorizontal ? JSplitPane.HORIZONTAL_SPLIT : JSplitPane.VERTICAL_SPLIT; out.println(""); xmlWriteComponent(splitNode.getLeft(), out); xmlWriteComponent(splitNode.getRight(), out); out.println(""); } private void xmlWriteTab(TabNode tabNode, PrintWriter out) { out.println(""); for(int i = 0; i < tabNode.tabs.size(); i++) { xmlWriteDockable(tabNode.getTab(i), out); } out.println(""); } private void xmlWriteDockable(SingleDockableNode dockable, PrintWriter out) { boolean isCompound = dockable instanceof CompoundDockableNode; if(isCompound) { out.println(""); } else { out.println(""); } WSDockKey key = dockable.key; out.println(""); if(isCompound) { CompoundDockableNode d = (CompoundDockableNode) dockable; if(d.nestedNode != null) { // compound panels cannont have more than one child (split/tab/single) xmlWriteComponent(d.nestedNode, out); } } out.println(""); } private void xmlWriteBorder(int zone, ArrayList border, PrintWriter out) { if(border.size() > 0) { out.println(""); for(int i = 0; i < border.size(); i++) { HiddenNode node = (HiddenNode) border.get(i); xmlWriteBorderDockable(node, out); } out.println(""); } } private void xmlWriteBorderDockable(HiddenNode node, PrintWriter out) { RelativeDockablePosition position = node.position; SingleDockableNode child = node.node; boolean isCompound = child instanceof CompoundDockableNode; if(isCompound) { out.println(""); } else { out.println(""); } WSDockKey key = child.key; out.println(""); out.println(""); if(isCompound) { CompoundDockableNode d = (CompoundDockableNode) child; if(d.nestedNode != null) { // compound panels cannont have more than one child (split/tab/single) xmlWriteComponent(d.nestedNode, out); } } out.println(""); } private void replaceChild(Node parent, Node child, Node newChild) { if(parent instanceof TopLevelNode) { TopLevelNode t = ((TopLevelNode) parent); if(t.child == child) { t.setChild(newChild); } else { throw new IllegalArgumentException("child not found in top level node " + child); } } else if(parent instanceof CompoundDockableNode) { CompoundDockableNode c = ((CompoundDockableNode) parent); if(c.nestedNode == child) { c.setNestedNode(newChild); } else { throw new IllegalArgumentException("child not found in compound " + child); } } else if(parent instanceof SplitNode) { SplitNode split = (SplitNode) parent; if(split.left == child) { split.setLeft(newChild); } else if(split.right == child) { split.setRight(newChild); } else { throw new IllegalArgumentException("child not found in split " + child); } } else if(parent instanceof TabNode) { TabNode tab = (TabNode) parent; for(int i = 0; i < tab.tabs.size(); i++) { Node n = tab.getTab(i); if(n == child) { tab.replaceTab(i, (SingleDockableNode) newChild); break; } } throw new IllegalArgumentException("child not found in tabs " + child); } else if(parent instanceof HiddenNode) { HiddenNode h = (HiddenNode) parent; if(h.node == child) { h.setChild((SingleDockableNode) newChild); } else { throw new IllegalArgumentException("child not found in hidden dockable " + child); } } else if(parent instanceof FloatingNode) { FloatingNode f = (FloatingNode) parent; if(f.child == child) { f.setChild(newChild); } else { throw new IllegalArgumentException("child not found in floating dockable " + child); } } else { throw new IllegalArgumentException("wrong type for parent " + parent); } } private void xmlWriteFloating(FloatingNode node, PrintWriter out) { Rectangle r = node.windowRect; out.println(""); if(node.child instanceof TabNode) { TabNode tab = (TabNode) node.child; for(int i = 0; i < tab.tabs.size(); i++) { SingleDockableNode n = tab.getTab(i); xmlWriteFloatingDockable(n, out, node.returnPosition); } } else { // single xmlWriteFloatingDockable((SingleDockableNode) node.child, out, node.returnPosition); } out.println(""); } private void xmlWriteFloatingDockable(SingleDockableNode dockable, PrintWriter out, RelativeDockablePosition returnPosition) { boolean isCompound = dockable instanceof CompoundDockableNode; if(isCompound) { out.println(""); } else { out.println(""); } WSDockKey key = dockable.key; out.println(""); out.println(""); out.println(""); // @todo : see how to implement that if(isCompound) { CompoundDockableNode d = (CompoundDockableNode) dockable; if(d.nestedNode != null) { // compound panels cannont have more than one child (split/tab/single) xmlWriteComponent(d.nestedNode, out); } } out.println(""); } private void xmlWriteTabGroups(PrintWriter out) { ArrayList uniqueGroups = new ArrayList(); ArrayList processedDockables = new ArrayList(); Iterator it = tabbedGroups.keySet().iterator(); while(it.hasNext()) { WSDockKey d = it.next(); if(! processedDockables.contains(d)) { processedDockables.add(d); LinkedList tabList = tabbedGroups.get(d); Iterator listIt = tabList.iterator(); while(listIt.hasNext()) { WSDockKey d2 = listIt.next(); if(! processedDockables.contains(d2)) { processedDockables.add(d2); } } uniqueGroups.add(tabList); } } out.println(""); for(int i = 0; i < uniqueGroups.size(); i++) { out.println(""); LinkedList group = (LinkedList) uniqueGroups.get(i); Iterator listIt = group.iterator(); while(listIt.hasNext()) { WSDockKey d = (WSDockKey) listIt.next(); xmlWriteDockableTab(d, out); } out.println(""); } out.println(""); } private void xmlWriteDockableTab(WSDockKey key, PrintWriter out) { out.println(""); out.println(""); out.println(""); } void readDesktopNode(Element root) throws SAXNotRecognizedException, SAXException { NodeList children = root.getChildNodes(); for(int i = 0, len = children.getLength(); i < len; i++) { org.w3c.dom.Node child = children.item(i); xmlBuildRootNode(child); } } private void xmlBuildRootNode(org.w3c.dom.Node node) throws SAXNotRecognizedException, SAXException { if(node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { Element elt = (Element) node; String name = elt.getNodeName(); if(name.equals("DockingPanel")) { // only one child at most NodeList children = elt.getChildNodes(); for(int i = 0, len = children.getLength(); i < len; i++) { xmlBuildDockingPanelNode(elt.getChildNodes().item(i)); } } else if(name.equals("Border")) { int zone = Integer.parseInt(elt.getAttribute("zone")); NodeList children = elt.getElementsByTagName("Dockable"); for(int i = 0, len = children.getLength(); i < len; i++) { xmlBuildAutoHideNode(zone, (Element) children.item(i)); } } else if(name.equals("Floating")) { int x = Integer.parseInt(elt.getAttribute("x")); int y = Integer.parseInt(elt.getAttribute("y")); int width = Integer.parseInt(elt.getAttribute("width")); int height = Integer.parseInt(elt.getAttribute("height")); NodeList children = elt.getElementsByTagName("Dockable"); xmlBuildFloatingNode(children, new Rectangle(x, y, width, height)); //2005/10/10 /* for (int i = 0, len = children.getLength(); i < len; i++) { xmlBuildFloatingNode((Element)children.item(i), new Rectangle(x, y, width, height)); }*/ } else if(name.equals("TabGroups")) { NodeList children = elt.getElementsByTagName("TabGroup"); xmlBuildTabGroup(children); //2005/10/10 } else { throw new SAXNotRecognizedException(name); } } } private void xmlBuildDockingPanelNode(org.w3c.dom.Node node) throws SAXException { if(node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { Node child = xmlCreateComponent((Element) node, DockableState.Location.DOCKED); if(node != null) { mainNode.setChild(child); } } } private Node xmlCreateComponent(Element elt, DockableState.Location dockableLocation) throws SAXException { if(elt.getNodeName().equals("Split")) { SplitNode split = xmlBuildSplitContainer(elt, dockableLocation); return split; } else if(elt.getNodeName().equals("Dockable")) { SingleDockableNode sdc = xmlGetDockable(elt); if(sdc instanceof CompoundDockableNode) { // check for children and build them xmlBuildCompoundDockable((CompoundDockableNode) sdc, elt, dockableLocation); } return sdc; } else if(elt.getNodeName().equals("TabbedDockable")) { TabNode tdc = xmlBuildTabbedDockableContainer(elt, dockableLocation); return tdc; } else if(elt.getNodeName().equals("MaximizedDockable")) { // this should be the last element from DockingPanel node SingleDockableNode sdc = xmlGetDockable(elt); setMaximizedDockable(sdc.key); return null; } else { throw new SAXNotRecognizedException(elt.getNodeName()); } } private SingleDockableNode xmlGetDockable(Element dockableElt) { Element key = (Element) dockableElt.getElementsByTagName("Key").item(0); String name = key.getAttribute("dockName"); WSDockKey wsKey = new WSDockKey(name); SingleDockableNode sdn = (SingleDockableNode) nodesByKey.get(wsKey); if(sdn == null) { String compound = dockableElt.getAttribute("compound"); if("true".equals(compound)) { sdn = new CompoundDockableNode(wsKey); } else { sdn = new SingleDockableNode(wsKey); } } return sdn; } private void xmlBuildCompoundDockable(CompoundDockableNode cdn, Element elt, DockableState.Location dockableLocation) throws SAXException { /* a compound dockable can hold a sub dockable (or split/tabs) */ NodeList children = elt.getChildNodes(); for(int i = 0, len = children.getLength(); i < len; i++) { org.w3c.dom.Node node = children.item(i); if(node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { if(elt.getNodeName().equals("Key")) { // ignore : it's the key of the compound dockable } else { Node comp = xmlCreateComponent(elt, dockableLocation); cdn.nestedNode = comp; return; // no more than a single child } } } } private SplitNode xmlBuildSplitContainer(Element elt, DockableState.Location dockableLocation) throws SAXException { int orientation = Integer.parseInt(elt.getAttribute("orientation")); String loc = elt.getAttribute("location"); double location = 0.5; if(loc != null && ! loc.equals("")) { location = Double.parseDouble(loc); } SplitNode split = new SplitNode(); split.isHorizontal = orientation == SplitContainer.HORIZONTAL_SPLIT; split.location = location; boolean left = true; for(int i = 0; i < elt.getChildNodes().getLength(); i++) { org.w3c.dom.Node child = elt.getChildNodes().item(i); if(child.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { Node comp = xmlCreateComponent((Element) child, dockableLocation); if(left) { split.setLeft(comp); left = false; } else { split.setRight(comp); } } } return split; } private TabNode xmlBuildTabbedDockableContainer(Element elt, DockableState.Location dockableLocation) throws SAXException { TabNode tdc = new TabNode(); int index = 0; for(int i = 0; i < elt.getChildNodes().getLength(); i++) { org.w3c.dom.Node child = elt.getChildNodes().item(i); if(child.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { SingleDockableNode sdn = xmlGetDockable((Element) child); tdc.addTab(index++, sdn); // we don't update the tab group as it is done in a separate pass (xmlBuildTabGroups()) if(sdn instanceof CompoundDockableNode) { // check for children and build them is needed xmlBuildCompoundDockable((CompoundDockableNode) sdn, (Element) child, dockableLocation); } } } return tdc; } private void xmlBuildAutoHideNode(int zone, Element dockableElt) throws SAXException { Element hideElt = (Element) dockableElt.getElementsByTagName("RelativePosition").item(0); float x = Float.parseFloat(hideElt.getAttribute("x")); float y = Float.parseFloat(hideElt.getAttribute("y")); float w = Float.parseFloat(hideElt.getAttribute("w")); float h = Float.parseFloat(hideElt.getAttribute("h")); RelativeDockablePosition position = new RelativeDockablePosition(x, y, w, h); SingleDockableNode dockable = xmlGetDockable(dockableElt); borders[zone].add(new HiddenNode(dockable, position)); if(dockable instanceof CompoundDockableNode) { // check for children and build them xmlBuildCompoundDockable((CompoundDockableNode) dockable, dockableElt, DockableState.Location.HIDDEN); } } private void xmlBuildFloatingNode(NodeList dockables, Rectangle rectangle) throws SAXException { // @todo not optimal.. we should refactor it oustide this method FloatingNode floating = null; SingleDockableNode baseDockable = null; // used when there are tabs for(int i = 0; i < dockables.getLength(); i++) { Element dockableElt = (Element) dockables.item(i); Element hideElt = (Element) dockableElt.getElementsByTagName("RelativePosition").item(0); float x = Float.parseFloat(hideElt.getAttribute("x")); float y = Float.parseFloat(hideElt.getAttribute("y")); float w = Float.parseFloat(hideElt.getAttribute("w")); float h = Float.parseFloat(hideElt.getAttribute("h")); RelativeDockablePosition position = new RelativeDockablePosition(x, y, w, h); SingleDockableNode dockable = xmlGetDockable(dockableElt); if(i == 0) { baseDockable = dockable; floating = new FloatingNode(baseDockable, rectangle, position); floatingNodes.add(floating); } Element previousState = (Element) dockableElt.getElementsByTagName("PreviousState").item(0); int istate = Integer.parseInt(previousState.getAttribute("state")); // @todo : see how to manage this value if(i > 0) { createTab(baseDockable.key, dockable.key, i); } if(dockable instanceof CompoundDockableNode) { // check for children and build them xmlBuildCompoundDockable((CompoundDockableNode) dockable, dockableElt, DockableState.Location.FLOATING); } } } private void xmlBuildTabGroup(NodeList group) { for(int i = 0; i < group.getLength(); i++) { Element groupElt = (Element) group.item(i); NodeList dockables = groupElt.getElementsByTagName("Dockable"); SingleDockableNode base = null; for(int j = 0; j < dockables.getLength(); j++) { Element dockableElt = (Element) dockables.item(j); SingleDockableNode d = xmlGetDockable(dockableElt); if(j == 0) { base = d; } else { addToTabbedGroup(base.key, d.key); } } } } /** Registers a dockable as belonging to a tab group. *

It is used to have a memory of grouped (tabbed) dockables in order to keep the * group together when dockable are restored from auto-hide mode. *

This method is generally called by the tabbed container management, and not directly * by the developper. * *

However, there is a case where calling this method can be usefull : * when, at startup, a desktop is built with multiple hidden dockables, and the developper wants * them to be grouped in a tab container when they are restored to the desktop. * * @param base an already tabbed dockable * @param newTab a dockable to add to the tab group * *@since 1.1.2 */ public void addToTabbedGroup(WSDockKey base, WSDockKey newTab) { /* this method is called when a dockable is added to a dockableTabbedContainer */ LinkedList group = tabbedGroups.get(base); if(group == null) { group = new LinkedList(); group.add(base); tabbedGroups.put(base, group); } group.add(newTab); tabbedGroups.put(newTab, group); } // ------- inner classes used to handle dockable layout /** abstract node into the layout */ private abstract class Node { Node parent; } /** a node describing a tab */ private class TabNode extends Node { ArrayList tabs = new ArrayList(); SingleDockableNode getTab(int index) { return (SingleDockableNode) tabs.get(index); } void addTab(int index, SingleDockableNode tab) { tabs.add(index, tab); tab.parent = this; } private void replaceTab(int index, SingleDockableNode node) { tabs.set(index, node); node.parent = this; } } /** a node containing a single dockable */ private class SingleDockableNode extends Node { WSDockKey key; SingleDockableNode(WSDockKey key) { this.key = key; nodesByKey.put(key, this); } } /** a single node that contains a whole dockable hierarchy */ private class CompoundDockableNode extends SingleDockableNode { Node nestedNode; CompoundDockableNode(WSDockKey key) { super(key); } void setNestedNode(Node nested) { nested.parent = this; nestedNode = nested; } } /** a node that represents a split */ private class SplitNode extends Node { void setTop(Node node) { this.left = node; node.parent = this; } void setBottom(Node node) { this.right = node; node.parent = this; } void setLeft(Node node) { this.left = node; node.parent = this; } void setRight(Node node) { this.right = node; node.parent = this; } Node getTop() { return left; } Node getBottom() { return right; } Node getLeft() { return left; } Node getRight() { return right; } Node left, right; private double location; // proportional location (0-1) boolean isHorizontal; } /** a node describing a auto-hide dockable */ private class HiddenNode extends Node { private SingleDockableNode node; private RelativeDockablePosition position; HiddenNode(SingleDockableNode node, RelativeDockablePosition position) { this.node = node; node.parent = this; this.position = position; } void setChild(SingleDockableNode child) { child.parent = this; this.node = child; } } /** used as root node for main and hidden hierarchies */ private class TopLevelNode extends Node { Node child; void setChild(Node child) { this.child = child; child.parent = this; } } /** top container for floating dockables */ private class FloatingNode extends Node { private Node child; private Rectangle windowRect; private RelativeDockablePosition returnPosition; FloatingNode(Node child, Rectangle windowRect, RelativeDockablePosition returnPosition) { this.windowRect = windowRect; this.returnPosition = returnPosition; setChild(child); } void setChild(Node child) { this.child = child; child.parent = this; } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ws/WSDockKey.java000066400000000000000000000040771243334202400311410ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ws; import com.vlsolutions.swing.docking.DockingConstants; /** Defines a key associated to a dockable in a workspace. * * The internal "key" will have to match the one of a DockKey when the * worspace is applied to a DockingContext. * *

example : * if your application uses a dockable with DockKey k = new DockKey("testDockable");
* than your corresponding WSDockKey will be wsdk = new WSDockKey("testDockable"); *

* Design note : We use this class insted of DockKey because sometimes dockkeys are lazily * created (at dockable creation) and thus aren't already available when specifying a * workspace. * * @author Lilian Chamontin, VLSolutions */ public class WSDockKey { private String key; // must match DockKey#key private DockingConstants.Hide autoHideBorder; public WSDockKey(String key) { this.key = key; } public String toString() { return key; } /** returns this object's hashcode */ public int hashCode() { return key.hashCode(); } public boolean equals(Object o) { if(o instanceof WSDockKey) { return key.equals(((WSDockKey) o).key); } return false; } /** returns the inner key of this object (which must match a DockKey's 'key' instance variable) */ public String getKey() { return key; } /** Returns the autohide border of this dockable, or null if not set*/ public DockingConstants.Hide getAutoHideBorder() { return autoHideBorder; } /** Updates the autohide border property */ public void setAutoHideBorder(DockingConstants.Hide border) { this.autoHideBorder = border; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ws/Workspace.java000066400000000000000000000144361243334202400312740ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ws; import com.vlsolutions.swing.docking.DockingContext; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.util.ArrayList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** A logical organization of dockables. Used to define and save desktop layouts (xml loading in not supported yet). *

* A Workspace is composed of WSDesktop elements (one per involved desktop). *

* Each WSDesktop supports an API similar to the DockingDesktop (addDockable, split, createTab), where * arguments are simple DockKeys (and not Dockables). * *

Currently this version doesn't support dockable removal : you can create a workspace, but shouldn't alter its * layout by moving already positionned dockables elsewhere (e.g. workspace will fail if you install a dockable * on an auto-hide border, then add is as a docked tab later). * * * @author Lilian Chamontin, VLSolutions * @since 2.1.2 */ public class Workspace { private ArrayList desktops = new ArrayList(); /** Creates a workspace with a single default WSDesktop */ public Workspace() { desktops.add(new WSDesktop()); } /** Removes the contained desktops */ public void clear() { desktops.clear(); } /** Adds a new desktop to this workspace */ public void addDesktop(WSDesktop desktop) { desktops.add(desktop); } /** Return the number of desktops contained in this workspace (default is 1 ) */ public int getDesktopCount() { return desktops.size(); } /** Returns the index-th desktop contained */ public WSDesktop getDesktop(int index) { return (WSDesktop) desktops.get(index); } /** Returns a desktop identified by its name or null if not found */ public WSDesktop getDesktop(String desktopName) { if(desktops.size() == 1) { return (WSDesktop) desktops.get(0); } for(int i = 0; i < desktops.size(); i++) { WSDesktop d = (WSDesktop) desktops.get(i); if(d.getDesktopName().equals(desktopName)) { return d; } } return null; } /** Applies this workspace to the given docking context (this is equivalent as loading a * workspace file from DockingContext.readXML() : it removes every dockable from the context and * associated desktops, and clears their dockable states, then it reloads the dockables as specified * by this workspace layout. */ public void apply(DockingContext dockingContext) throws WorkspaceException { ByteArrayOutputStream outb = new ByteArrayOutputStream(); PrintWriter out = new PrintWriter(outb); out.println(""); out.println(""); for(int i = 0; i < desktops.size(); i++) { WSDesktop desktop = (WSDesktop) desktops.get(i); desktop.writeDesktopNode(out); } out.println(""); out.close(); byte[] bytes = outb.toByteArray(); //System.out.println(new String(bytes)); ByteArrayInputStream is = new ByteArrayInputStream(bytes); try { dockingContext.readXML(is); } catch(Exception ex) { throw new WorkspaceException(ex); } finally { try { is.close(); } catch(Exception ignore) { } } } /** Loads and configures this workspace from a given docking context. *

* The workspace is then ready to be applied or saved as a stream. * @since 2.1.3 * @see #apply(DockingContext) */ public void loadFrom(DockingContext context) throws WorkspaceException { try { ByteArrayOutputStream out = new ByteArrayOutputStream(); context.writeXML(out); out.close(); byte[] bytes = out.toByteArray(); //System.out.println(new String(bytes)); ByteArrayInputStream is = new ByteArrayInputStream(bytes); readXML(is); is.close(); } catch(Exception e) { throw new WorkspaceException(e); } } /** Saves the workspace layout into an XML stream. *

* The workspace is composed of every desktop layouts associated * with this workspace (desktops are identified by their 'desktopName' property). * *

* The stream is not closed at the end of the operation. * * @see #readXML(InputStream) * */ public void writeXML(OutputStream stream) throws IOException { PrintWriter out = new PrintWriter(stream); out.println(""); out.println(""); for(int i = 0; i < desktops.size(); i++) { WSDesktop desktop = (WSDesktop) desktops.get(i); desktop.writeDesktopNode(out); } out.println(""); out.flush(); } public void readXML(InputStream in) throws ParserConfigurationException, IOException, SAXException { // remove all dockable states for(int i = 0; i < desktops.size(); i++) { WSDesktop desk = (WSDesktop) desktops.get(i); desk.clear(); } DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(in); Element root = doc.getDocumentElement(); if(root.getNodeName().equals("DockingDesktop")) { // this is an old desktop file, missing the VLDocking root node (VLDocking 2.0 format) // so we noly have a single desktop WSDesktop desk = getDesktop(0); // only one desk.readDesktopNode(root); } else { NodeList desktopChildren = root.getChildNodes(); for(int i = 0, len = desktopChildren.getLength(); i < len; i++) { Node node = desktopChildren.item(i); if(node instanceof Element) { Element deskChild = (Element) node; WSDesktop desk = getDesktop(deskChild.getAttribute("name")); desk.readDesktopNode(deskChild); } } } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ws/WorkspaceButton.java000066400000000000000000000044271243334202400324670ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ws; import com.vlsolutions.swing.docking.DockingContext; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Icon; import javax.swing.JButton; /** A simple button that applies a workspace to a given Docking context when pressed . * * @author Lilian Chamontin, VLSolutions * @since 2.1.3 * */ public class WorkspaceButton extends JButton { private static final long serialVersionUID = 1L; private Workspace workspace; private DockingContext ctx; private ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { try { applyWorkspace(); } catch(WorkspaceException ex) { ex.printStackTrace(); } } }; /** default constructor */ public WorkspaceButton() { addActionListener(actionListener); } /** constructor with a menu text */ public WorkspaceButton(String text) { super(text); addActionListener(actionListener); } /** constructor with a menu text and an icon */ public WorkspaceButton(String text, Icon icon) { super(text, icon); addActionListener(actionListener); } /** Invoked when the button is pressed : applies the workspace to the associated context */ public void applyWorkspace() throws WorkspaceException { workspace.apply(ctx); } /** Returns the workspace used by this button */ public Workspace getWorkspace() { return workspace; } /** updates the workspace to be used by this button */ public void setWorkspace(Workspace workspace) { this.workspace = workspace; } /** Returns the docking context used by this button */ public DockingContext getDockingContext() { return ctx; } /** Updates the docking context used by this button */ public void setDockingContext(DockingContext ctx) { this.ctx = ctx; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ws/WorkspaceException.java000066400000000000000000000020021243334202400331350ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ws; /** An exception raised when a workspace operation has gone wrong (can encapsulate * another exception). * * @author Lilian Chamontin, VLSolutions */ public class WorkspaceException extends Exception { private static final long serialVersionUID = 1L; public WorkspaceException(String message) { super(message); } public WorkspaceException(Exception cause) { super(cause); } public WorkspaceException(String message, Exception cause) { super(message, cause); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/docking/ws/WorkspaceMenuItem.java000066400000000000000000000044561243334202400327410ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.docking.ws; import com.vlsolutions.swing.docking.DockingContext; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Icon; import javax.swing.JMenuItem; /** A simple menu item that applies a workspace to a given Docking context when selected . * * @author Lilian Chamontin, VLSolutions * @since 2.1.3 */ public class WorkspaceMenuItem extends JMenuItem { private static final long serialVersionUID = 1L; private Workspace workspace; private DockingContext ctx; private ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { try { applyWorkspace(); } catch(WorkspaceException ex) { ex.printStackTrace(); } } }; /** Default constructor */ public WorkspaceMenuItem() { addActionListener(actionListener); } /** constructor with a menu text */ public WorkspaceMenuItem(String text) { super(text); addActionListener(actionListener); } /** constructor with a menu text and an icon */ public WorkspaceMenuItem(String text, Icon icon) { super(text, icon); addActionListener(actionListener); } /** Invoked when the button is pressed : applies the workspace to the associated context */ public void applyWorkspace() throws WorkspaceException { workspace.apply(ctx); } /** Returns the workspace used by this menu item */ public Workspace getWorkspace() { return workspace; } /** updates the workspace to be used by this menu item */ public void setWorkspace(Workspace workspace) { this.workspace = workspace; } /** Returns the docking context used by this menu item */ public DockingContext getDockingContext() { return ctx; } /** Updates the docking context used by this menu item */ public void setDockingContext(DockingContext ctx) { this.ctx = ctx; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/tabbedpane/000077500000000000000000000000001243334202400265015ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/tabbedpane/JTabbedPaneSmartIcon.java000066400000000000000000000255261243334202400332750ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.tabbedpane; import java.awt.Component; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import javax.swing.Icon; import javax.swing.JTabbedPane; import javax.swing.UIManager; /** An Icon allowing the use of closeable tabs by simulating the entire tabpane tab-painting. * *

* As JTabbedPanes cannot use any JComponents as tab selectors (the access if protected and we just have * a label, an icon and a tooltip), we have to rely on tricks to bypass them. * * * * @author Lilian Chamontin, VLSolutions * @update 2005/11/01 Lilian Chamontin : fixed NPE when otherIcons == null (tabs without smart icons) * @update 2005/11/08 Lilian Chamontin : fixed bug related to event management when multiple other-icons are used * (big thanks to Emmanuel GAUVRIT). * @update 2005/11/21 Lilian Chamontin : enhanced width calculation of the icon size. */ public class JTabbedPaneSmartIcon implements Icon, Cloneable { /* Implementation : This icon is larger than standard icons : it also paints the tab title and optional buttons. * Inner Event management (with JTabbedPaneSmartIconManager) allows simulation of action on the buttons. * */ /** The traditional tab selector icon */ private Icon icon; /** calculated used width (icon + label + other icons) + gaps */ private int width; /** x location where the other icons are drawn*/ private int otherIconsOffset; /** tab height */ private int height; /** the traditional tab selector label */ private String label; /** the traditional tab selector tooltip text*/ private String tooltipText; /** local tooltip text : the one to use during mouse movements (depends on the mouse position, * and can be either the tab selector tooltip text or one of the smart buttons included into this icon). */ private String localTooltipText; // list of additional icons (presented as buttons) private SmartIconJButton[] otherIcons; /** currently pressed inner button */ private SmartIconJButton pressedButton; /** currently rolled-over inner button */ private SmartIconJButton rolloverButton; /** gap between the icon and the text*/ private int textIconGap; /** gap between the text and the following icons*/ private int otherIconsGap; private boolean antialiased = false; /* The container this icon is for (required to calculate proper widths and heights) */ private JTabbedPane container; private int inBetweenOtherIconsGap; /** Constructs a new smart icon with a given set of additional buttons */ public JTabbedPaneSmartIcon(Icon icon, String label, SmartIconJButton[] otherIcons) { this.icon = icon; this.label = label; this.otherIcons = otherIcons; this.textIconGap = UIManager.getInt("TabbedPane.textIconGap"); this.otherIconsGap = UIManager.getInt("TabbedPane.otherIconsGap"); this.inBetweenOtherIconsGap = UIManager.getInt("TabbedPane.inBetweenOtherIconsGap"); invalidateSize(); try { //mimic the unofficial aa settings of Swing this.antialiased = "true".equals(System.getProperty("swing.aatext")); } catch(SecurityException ignore) { // for untrusted web start apps failing gracefully } } public SmartIconJButton getSmartButton(int index) { return otherIcons[index]; } public void setSmartButton(int index, SmartIconJButton btn) { otherIcons[index] = btn; invalidateSize(); } /** Creates a shalow copy of this icon */ public JTabbedPaneSmartIcon copy() { return (JTabbedPaneSmartIcon) clone(); } /** {@inheritDoc} */ public Object clone() { try { return super.clone(); } catch(CloneNotSupportedException ignore) { ignore.printStackTrace(); return null; } } /** Update the tooltip of this icon */ public void setTooltipText(String tooltip) { this.tooltipText = tooltip; } /** Return the tooltip of this icon */ public String getTooltipText() { return this.tooltipText; } /** Return the local tooltip of this icon (the one associated with inner mouse movements)*/ public String getLocalTooltipText() { return this.localTooltipText; } /** Update the label to be displayed on the tab */ public void setLabel(String label) { this.label = label; invalidateSize(); } /** Return the tab label */ public String getLabel() { return this.label; } /** Update the main icon (left) to be displayed on the tab */ public void setIcon(Icon icon) { this.icon = icon; invalidateSize(); } /** Return the tab icon */ public Icon getIcon() { return this.icon; } private void invalidateSize() { this.width = this.height = - 1; } /** Specify which container will use this icon. *

If the icon is shared between containers, please provide at least one as * this allows the icon to properly estimate its dimension. */ public void setIconForTabbedPane(JTabbedPane container) { this.container = container; } /** paints the icon (and the associated label and sub-icons) */ public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2 = (Graphics2D) g; Object renderingValue = null; if(this.antialiased) { renderingValue = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } if(icon != null) { icon.paintIcon(c, g, x, y); } Font f = UIManager.getFont("JTabbedPaneSmartIcon.font"); // 2006/01/23 if(f != null) { g.setFont(f); } // reevaluate the width with correct graphics object, in case something has changed FontMetrics fm = g.getFontMetrics(); int iconsOffset = otherIconsOffset; if(icon != null) { g.drawString(label, x + icon.getIconWidth() + textIconGap, y + height - fm.getDescent()); } else { g.drawString(label, x, y + height - fm.getDescent()); } if(otherIcons != null) { //2005/11/01 for(int i = 0; i < otherIcons.length; i++) { otherIcons[i].paintIcon(c, g, x + iconsOffset, y + height / 2 - otherIcons[i].getIconHeight() / 2); iconsOffset += otherIcons[i].getIconWidth(); if(i < otherIcons.length - 1) { iconsOffset += inBetweenOtherIconsGap; } } } if(antialiased) { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, renderingValue); } } private SmartIconJButton findButtonAt(Point p) { int start = otherIconsOffset; if(otherIcons != null) { //2005/11/01 for(int i = 0; i < otherIcons.length; i++) { SmartIconJButton btn = otherIcons[i]; if(p.x >= start && p.x < start + btn.getIconWidth()) { if(p.y >= height / 2 - btn.getIconHeight() / 2 && p.y < height / 2 + btn.getIconHeight() / 2) { return btn; } else { return null; } } start += btn.getIconWidth(); // bug corrected thanks to Emmanuel GAUVRIT 2005/11/08 if(i < otherIcons.length - 1) { start += inBetweenOtherIconsGap; } } } return null; } /** Returns the width of this icon */ public int getIconWidth() { if(width == - 1) { if(container == null) { throw new NullPointerException("container for this smart icon not specified with setIconForTabbedPane()"); } // reevaluate the width with correct graphics object, in case something has changed //Font f = UIManager.getFont("DockTabbedPane.font"); // 2006/01/23 Font f = UIManager.getFont("JTabbedPaneSmartIcon.font"); // 2006/01/23 FontMetrics fm = container.getFontMetrics(f); this.width = 0; if(icon != null) { width = icon.getIconWidth(); } width += textIconGap + fm.stringWidth(label) + otherIconsGap; this.otherIconsOffset = width; @SuppressWarnings("unused") int iconsOffset = otherIconsOffset; if(otherIcons != null) { for(int i = 0; i < otherIcons.length; i++) { width += otherIcons[i].getIconWidth(); // additional width for icons if(i < otherIcons.length - 1) { width += inBetweenOtherIconsGap; } } } } return width; } /** Returns the height of this icon */ public int getIconHeight() { if(height == - 1) { if(icon != null) { height = icon.getIconHeight(); } else { height = 16; // standard height (as if there was an icon) : should be calculated instead of fixed } } return height; } /** Process the mouse pressed event. *

* Mouse coordinates are given relative to this icon */ public boolean onMousePressed(MouseEvent e) { // find the icon under the point SmartIconJButton btn = findButtonAt(e.getPoint()); if(btn != null && btn.isEnabled()) { btn.setPressed(true); pressedButton = btn; return true; } return false; } /** Process the mouse released event. *

* Mouse coordinates are given relative to this icon */ public boolean onMouseReleased(final MouseEvent e) { if(pressedButton != null && pressedButton.isEnabled()) { pressedButton.setPressed(false); final SmartIconJButton btn = findButtonAt(e.getPoint()); if(btn == pressedButton) { btn.fireAction(new ActionEvent(e.getSource(), ActionEvent.ACTION_PERFORMED, "")); return true; } } return false; } /** Process the mouse exited event. *

* Mouse coordinates are given relative to this icon */ public boolean onMouseExited(MouseEvent e) { // reset all rollover states if(rolloverButton != null) { rolloverButton.setRollover(false); rolloverButton = null; localTooltipText = tooltipText; return true; } rolloverButton = null; return false; } /** Process the mouse moved event. *

* Mouse coordinates are given relative to this icon */ public boolean onMouseMoved(MouseEvent e) { // check for a rollover effect SmartIconJButton btn = findButtonAt(e.getPoint()); boolean shouldRepaint = false; if(btn != null) { String tip = btn.getTooltipText(); if(tip != null) { if(! tip.equals(localTooltipText)) { this.localTooltipText = tip; shouldRepaint = true; } } else if(localTooltipText != tooltipText) { this.localTooltipText = tooltipText; shouldRepaint = true; } if(btn == rolloverButton) { // still on the same button } else { // another button if(rolloverButton != null) { rolloverButton.setRollover(false); } rolloverButton = btn; rolloverButton.setRollover(true); shouldRepaint = true; } } else if(rolloverButton != null) { rolloverButton.setRollover(false); rolloverButton = null; localTooltipText = tooltipText; shouldRepaint = true; } return shouldRepaint; } } JTabbedPaneSmartIconManager.java000066400000000000000000000267651243334202400345170ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/tabbedpane/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.tabbedpane; import java.awt.Component; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import javax.swing.Icon; import javax.swing.JTabbedPane; /** This class is the interface between a JTabbedPane and a smart icon. *

* As JTabbedPanes cannot use any JComponents as tab selectors (the access if protected and we just have * a label, an icon and a tooltip), we have to rely on tricks to bypass them. *

* This class is used (with a mouse listener) to forward events into the smart icon. which is responsible * for faking an enhanced tab selector (including label and optional buttons). * * * @author Lilian Chamontin, VLSolutions */ public class JTabbedPaneSmartIconManager implements MouseListener, MouseMotionListener { private JTabbedPane tabbedPane; private JTabbedPaneSmartIcon pressedIcon; private int pressedTab; // the tab associated to the pressed icon private JTabbedPaneSmartIcon movedIcon; private int movedTab; /** Constructs a new tabbedPane manager for a given JTabbedPane */ public JTabbedPaneSmartIconManager(JTabbedPane tabbedPane) { this.tabbedPane = tabbedPane; tabbedPane.addMouseListener(this); tabbedPane.addMouseMotionListener(this); } /** MouseListener implementation, use to track mouse behaviour inside the tab selector bounds * and forward them to the appropriate smart icon. */ public void mouseReleased(MouseEvent e) { checkTabCount(); // forward the event to the pressed smart icon if(pressedIcon != null) { Point p = e.getPoint(); final Rectangle r = tabbedPane.getBoundsAt(pressedTab); if (r == null) { return; } Point iPoint = convertPointToIcon(r, p, pressedIcon); final MouseEvent eSmart = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), e.getModifiers(), iPoint.x, iPoint.y, e.getClickCount(), e.isPopupTrigger(), e.getButton()); try { if(pressedIcon.onMouseReleased(eSmart)) { tabbedPane.repaint(r.x, r.y, r.width, r.height); // no choice but trigger a repaint } } catch(Exception ignore) { // bug database : 5075526 this is to remove the stack trace } pressedIcon = null; } } private Point convertPointToIcon(Rectangle r, Point p, Icon icon) { int x = p.x - (r.x + r.width / 2 - icon.getIconWidth() / 2); int y = p.y - (r.y + r.height / 2 - icon.getIconHeight() / 2); return new Point(x, y); } /** MouseListener implementation, use to track mouse behaviour inside the tab selector bounds * and forward them to the appropriate smart icon. */ public void mousePressed(MouseEvent e) { // where is the mouse pressed ? Point p = e.getPoint(); this.pressedIcon = null; // reset the pressed state int targetTab = findTabAt(p); if(targetTab != - 1) { Icon icon = tabbedPane.getIconAt(targetTab); if(icon instanceof JTabbedPaneSmartIcon) { JTabbedPaneSmartIcon smartIcon = (JTabbedPaneSmartIcon) icon; // convert point into smartIcon coordinates // get the tab bounds Rectangle r = tabbedPane.getBoundsAt(targetTab); if (r == null) { return; } // as the icon is the only thing visible, we consider it centered in the tab // (which is the default paint behaviour of BasicTabbedPaneUI, and should be okay // with most look and feels. int x = p.x - (r.x + r.width / 2 - icon.getIconWidth() / 2); int y = p.y - (r.y + r.height / 2 - icon.getIconHeight() / 2); if(x >= 0 && y >= 0 && x < icon.getIconWidth() && y < icon.getIconHeight()) { // forward the event to the smart icon MouseEvent eSmart = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), e.getModifiers(), x, y, e.getClickCount(), e.isPopupTrigger(), e.getButton()); if(smartIcon.onMousePressed(eSmart)) { tabbedPane.repaint(r.x, r.y, r.width, r.height); // no choice but trigger a repaint } pressedIcon = smartIcon; pressedTab = targetTab; } } } } /** verify if the tab count hasn't changed. *

* There is always the risk that the last tab has been removed (and movedTab will be * out of bounds) * */ private void checkTabCount() { if(movedTab >= tabbedPane.getTabCount()) { // too late : tab has been removed movedTab = - 1; movedIcon = null; } if(pressedTab >= tabbedPane.getTabCount()) { pressedTab = - 1; pressedIcon = null; } } private int findTabAt(Point p) { int x = p.x; int y = p.y; for(int i = 0; i < tabbedPane.getTabCount(); i++) { Rectangle bounds = tabbedPane.getBoundsAt(i); if(bounds != null && bounds.contains(x, y)) { return i; } } return - 1; } /** MouseListener implementation, use to track mouse behaviour inside the tab selector bounds * and forward them to the appropriate smart icon. */ public void mouseMoved(MouseEvent e) { checkTabCount(); // where is the mouse moved ? Point p = e.getPoint(); int targetTab = findTabAt(p); if(targetTab != - 1) { Icon icon = tabbedPane.getIconAt(targetTab); if(icon instanceof JTabbedPaneSmartIcon) { JTabbedPaneSmartIcon smartIcon = (JTabbedPaneSmartIcon) icon; if(movedIcon != null && movedIcon != smartIcon) { // trigger a mouseExit from the movedIcon Rectangle prevRect = tabbedPane.getBoundsAt(movedTab); if (prevRect == null) { return; } Point iPoint = convertPointToIcon(prevRect, p, movedIcon); MouseEvent eSmart = new MouseEvent((Component) e.getSource(), MouseEvent.MOUSE_EXITED, e.getWhen(), e.getModifiers(), iPoint.x, iPoint.y, e.getClickCount(), e.isPopupTrigger(), e.getButton()); if(movedIcon.onMouseExited(eSmart)) { String tip = movedIcon.getLocalTooltipText(); if(tip != null && ! tip.equals(tabbedPane.getToolTipTextAt(targetTab))) { tabbedPane.setToolTipTextAt(targetTab, tip); } // tabbedPane.repaint(prevRect.x, prevRect.y, prevRect.width, prevRect.height); tabbedPane.revalidate(); tabbedPane.repaint(); } movedIcon = null; movedTab = - 1; } // convert point into smartIcon coordinates // get the tab bounds Rectangle r = tabbedPane.getBoundsAt(targetTab); if (r == null) { return; } Point iPoint = convertPointToIcon(r, p, icon); if(iPoint.x >= 0 && iPoint.y >= 0 && iPoint.x < icon.getIconWidth() && iPoint.y < icon.getIconHeight()) { // forward the event to the smart icon MouseEvent eSmart = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), e.getModifiers(), iPoint.x, iPoint.y, e.getClickCount(), e.isPopupTrigger(), e.getButton()); if(smartIcon.onMouseMoved(eSmart)) { String tip = smartIcon.getLocalTooltipText(); if(tip != null && ! tip.equals(tabbedPane.getToolTipTextAt(targetTab))) { tabbedPane.setToolTipTextAt(targetTab, tip); } tabbedPane.revalidate(); tabbedPane.repaint(); // tabbedPane.repaint(r.x, r.y, r.width, r.height); } movedIcon = smartIcon; movedTab = targetTab; } else { // in tab, but not on icon if(movedIcon != null) { // trigger a mouseExit from the movedIcon Rectangle prevRect = tabbedPane.getBoundsAt(movedTab); if (prevRect == null) { return; } iPoint = convertPointToIcon(prevRect, p, movedIcon); MouseEvent eSmart = new MouseEvent((Component) e.getSource(), MouseEvent.MOUSE_EXITED, e.getWhen(), e.getModifiers(), iPoint.x, iPoint.y, e.getClickCount(), e.isPopupTrigger(), e.getButton()); if(movedIcon.onMouseExited(eSmart)) { String tip = movedIcon.getLocalTooltipText(); if(tip != null && ! tip.equals(tabbedPane.getToolTipTextAt(targetTab))) { tabbedPane.setToolTipTextAt(targetTab, tip); } tabbedPane.revalidate(); tabbedPane.repaint(); // tabbedPane.repaint(prevRect.x, prevRect.y, prevRect.width, prevRect.height); } } movedIcon = null; movedTab = - 1; } } else { // not a smart icon ? if(movedIcon != null) { // trigger a mouseExit from the movedIcon Rectangle prevRect = tabbedPane.getBoundsAt(movedTab); if (prevRect == null) { return; } Point iPoint = convertPointToIcon(prevRect, p, movedIcon); MouseEvent eSmart = new MouseEvent((Component) e.getSource(), MouseEvent.MOUSE_EXITED, e.getWhen(), e.getModifiers(), iPoint.x, iPoint.y, e.getClickCount(), e.isPopupTrigger(), e.getButton()); if(movedIcon.onMouseExited(eSmart)) { String tip = movedIcon.getLocalTooltipText(); if(tip != null && ! tip.equals(tabbedPane.getToolTipTextAt(targetTab))) { tabbedPane.setToolTipTextAt(targetTab, tip); } tabbedPane.revalidate(); tabbedPane.repaint(); // tabbedPane.repaint(prevRect.x, prevRect.y, prevRect.width, prevRect.height); } movedIcon = null; movedTab = - 1; } } } else { // not on a tab if(movedIcon != null) { // trigger a mouseExit from the movedIcon Rectangle prevRect = tabbedPane.getBoundsAt(movedTab); if (prevRect == null) { return; } Point iPoint = convertPointToIcon(prevRect, p, movedIcon); MouseEvent eSmart = new MouseEvent((Component) e.getSource(), MouseEvent.MOUSE_EXITED, e.getWhen(), e.getModifiers(), iPoint.x, iPoint.y, e.getClickCount(), e.isPopupTrigger(), e.getButton()); if(movedIcon.onMouseExited(eSmart)) { String tip = movedIcon.getLocalTooltipText(); if(tip != null && ! tip.equals(tabbedPane.getToolTipTextAt(movedTab))) { tabbedPane.setToolTipTextAt(movedTab, tip); } tabbedPane.revalidate(); tabbedPane.repaint(); // tabbedPane.repaint(prevRect.x, prevRect.y, prevRect.width, prevRect.height); } movedIcon = null; movedTab = - 1; } } } /** MouseListener implementation, use to track mouse behaviour inside the tab selector bounds * and forward them to the appropriate smart icon. */ public void mouseExited(MouseEvent e) { checkTabCount(); if(movedIcon != null) { Point p = e.getPoint(); // trigger a mouseExit from the movedIcon Rectangle prevRect = tabbedPane.getBoundsAt(movedTab); if (prevRect == null) { return; } Point iPoint = convertPointToIcon(prevRect, p, movedIcon); MouseEvent eSmart = new MouseEvent((Component) e.getSource(), MouseEvent.MOUSE_EXITED, e.getWhen(), e.getModifiers(), iPoint.x, iPoint.y, e.getClickCount(), e.isPopupTrigger(), e.getButton()); if(movedIcon.onMouseExited(eSmart)) { String tip = movedIcon.getLocalTooltipText(); if(tip != null && ! tip.equals(tabbedPane.getToolTipTextAt(movedTab))) { tabbedPane.setToolTipTextAt(movedTab, tip); } tabbedPane.repaint(prevRect.x, prevRect.y, prevRect.width, prevRect.height); } movedIcon = null; movedTab = - 1; } } /** MouseListener implementation, not used. */ public void mouseEntered(MouseEvent e) {} /** MouseMotionListener implementation, not used. */ public void mouseDragged(MouseEvent e) {} /** MouseListener implementation, not used. */ public void mouseClicked(MouseEvent e) {} } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/tabbedpane/SmartIconJButton.java000066400000000000000000000154421243334202400325570ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.tabbedpane; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.GrayFilter; import javax.swing.Icon; import javax.swing.ImageIcon; /** A sub component of JTabbedPaneSmartIcon, used to describe a button included in a tabbedpane. *

* As JTabbedPanes cannot use any JComponents as tab selectors (the access if protected and we just have * a label, an icon and a tooltip), we have to rely on tricks to bypass them. *

* This trick, the SmartIconJButton is an icon faking the behaviour of a button. It uses an Action * for reacting to clicks and manages a set of images (default, rollover, pressed, disabled) to * behave like a rollover button. * * @author Lilian Chamontin, VLSolutions */ public class SmartIconJButton implements Icon, PropertyChangeListener { /** The action triggered when the clicks on the icon */ protected Action action; /** the default icon (enabled/visible)*/ protected Icon defaultIcon; /** the icon for the rollover effect*/ protected Icon rolloverIcon; /** the icno for the pressed effect */ protected Icon pressedIcon; /** the icon for the disabled effect */ protected Icon disabledIcon; /** the tooltip associated with the button */ protected String tooltipText; /* internal state variables*/ private boolean isRollover, isPressed, isEnabled, isVisible; /** Constructs a new button with an action. * * The button is enabled and visible. */ public SmartIconJButton(Action action) { this.action = action; defaultIcon = (Icon) action.getValue(AbstractAction.SMALL_ICON); tooltipText = (String) action.getValue(AbstractAction.SHORT_DESCRIPTION); isVisible = true; isEnabled = action.isEnabled(); action.addPropertyChangeListener(this); } /** Update the default icon property */ public void setIcon(Icon icon) { this.defaultIcon = icon; } /** Returns the default icon */ public Icon getIcon() { return defaultIcon; } /** Update the rollover icon property */ public void setRolloverIcon(Icon icon) { this.rolloverIcon = icon; } /** Returns the rollover icon */ public Icon getRolloverIcon() { return rolloverIcon; } /** Update the pressed icon property */ public void setPressedIcon(Icon icon) { this.pressedIcon = icon; } /** Returns the pressed icon */ public Icon getPressedIcon() { return pressedIcon; } /** Update the disabled icon property */ public void setDisabledIcon(Icon icon) { this.disabledIcon = icon; } /** Returns the disabled icon */ public Icon getDisabledIcon() { return disabledIcon; } /** Update the rollover state */ public void setRollover(boolean isRollover) { this.isRollover = isRollover; } /** Update the enabled state */ public void setEnabled(boolean isEnabled) { this.isEnabled = isEnabled; } /** Update the visible state */ public void setVisible(boolean isVisible) { this.isVisible = isVisible; } /** Update the pressed state */ public void setPressed(boolean isPressed) { this.isPressed = isPressed; } /** Returns the rollover state*/ public boolean isRollover() { return isRollover; } /** Returns the pressed state*/ public boolean isPressed() { return isPressed; } /** Returns the enabled state*/ public boolean isEnabled() { return isEnabled; } /** Returns the visible state*/ public boolean isVisible() { return isVisible; } /** paints the appropriate icon according to its internal state (pressed, rollover...) */ public void paintIcon(java.awt.Component c, java.awt.Graphics g, int x, int y) { if(! isVisible) { return; } else if(isEnabled) { if(isPressed) { if(pressedIcon != null) { pressedIcon.paintIcon(c, g, x, y); } else { defaultIcon.paintIcon(c, g, x + 1, y + 1); } } else if(isRollover) { if(rolloverIcon != null) { rolloverIcon.paintIcon(c, g, x, y); } else { defaultIcon.paintIcon(c, g, x - 1, y - 1); // "push" effect } } else { // just the default if(defaultIcon != null) { defaultIcon.paintIcon(c, g, x, y); } } } else { // disabled if(disabledIcon == null) { disabledIcon = createDisabledIcon(); } disabledIcon.paintIcon(c, g, x, y); } } private Icon createDisabledIcon() { if(defaultIcon instanceof ImageIcon) { Image i = GrayFilter.createDisabledImage(((ImageIcon) defaultIcon).getImage()); return new ImageIcon(i); } else { BufferedImage bi = new BufferedImage(defaultIcon.getIconWidth(), defaultIcon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); Graphics g = bi.createGraphics(); g.setColor(new Color(0, 0, 0, 0)); g.fillRect(0, 0, defaultIcon.getIconWidth(), defaultIcon.getIconHeight()); defaultIcon.paintIcon(null, g, 0, 0); g.dispose(); Image i = GrayFilter.createDisabledImage(bi); return new ImageIcon(i); } } public int getIconWidth() { int w = 0; if(defaultIcon != null) { w = Math.max(w, defaultIcon.getIconWidth()); } if(rolloverIcon != null) { w = Math.max(w, rolloverIcon.getIconWidth()); } if(pressedIcon != null) { w = Math.max(w, pressedIcon.getIconWidth()); } return w; } public int getIconHeight() { int h = 0; if(defaultIcon != null) { h = Math.max(h, defaultIcon.getIconHeight()); } if(rolloverIcon != null) { h = Math.max(h, rolloverIcon.getIconHeight()); } if(pressedIcon != null) { h = Math.max(h, pressedIcon.getIconHeight()); } return h; } /** triggers the associated action */ public void fireAction(ActionEvent e) { action.actionPerformed(e); } public String getTooltipText() { return tooltipText; } public void setTooltipText(String tooltip) { this.tooltipText = tooltip; } /** Do not call directly as it a side effect of listening to the action changes. */ public void propertyChange(PropertyChangeEvent evt) { // track changes in the Action String prop = evt.getPropertyName(); if(prop.equals(AbstractAction.SHORT_DESCRIPTION)) { setTooltipText((String) evt.getNewValue()); } else if(prop.equals(AbstractAction.SMALL_ICON)) { setIcon((Icon) evt.getNewValue()); } else if(prop.equals("enabled")) { setEnabled(((Boolean) evt.getNewValue()).booleanValue()); } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/tabbedpane/package.html000066400000000000000000000007151243334202400307650ustar00rootroot00000000000000 The extended TabbedPane component for VLDocking.

This package contains classes allowing to embed buttons into the tabs of a jtabbedpane.

Although it supports any number of tabs, the current implementation for the docking framework only uses one : a close rollover button located on the right of the tab's label. vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/000077500000000000000000000000001243334202400262415ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/BackgroundPainter.java000066400000000000000000000015171243334202400325120ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.Graphics; import javax.swing.JComponent; /** An interface implemented by objects which can paint toolbar backgrounds. * * * @author Lilian Chamontin, VLSolutions * @since 2.1.4 */ public interface BackgroundPainter { public void paintBackground(JComponent component, Graphics g); } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/RolloverIcon.java000066400000000000000000000033601243334202400315230ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import javax.swing.GrayFilter; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.UIManager; /** A custom Icon to have a nice rollover effect for toolbar icons. *

* This icon uses a gray version of the provided image and paints it under the original one. * * @author Lilian Chamontin, VLSolutions */ public class RolloverIcon implements Icon { private int shadowWidth = 1; private int shadowHeight = 1; private Icon icon, shadowIcon; public RolloverIcon(Icon icon) { this.icon = icon; shadowIcon = new ImageIcon(GrayFilter.createDisabledImage(((ImageIcon) icon).getImage())); } public int getIconHeight() { return icon.getIconWidth(); } public int getIconWidth() { return icon.getIconHeight(); } public void paintIcon(Component c, Graphics g, int x, int y) { Color highlight = UIManager.getColor("VLDocking.highlight"); @SuppressWarnings("unused") Color shadow = UIManager.getColor("VLDocking.shadow"); g.setColor(highlight); g.fillRect(x, y, getIconWidth(), getIconHeight()); shadowIcon.paintIcon(c, g, x + shadowWidth - 1, y + shadowHeight - 1); icon.paintIcon(c, g, x - 1, y - 1); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/RoundedBorder.java000066400000000000000000000025161243334202400316460ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import java.awt.Insets; import javax.swing.UIManager; import javax.swing.border.Border; /** A simple rounded border. * * Can be used anywhere a rounded border is needed (no specific purpose). * * @author Lilian Chamontin, VLSolutions */ public class RoundedBorder implements Border { private Insets insets = new Insets(2, 2, 2, 2); private Color shadow = UIManager.getColor("controlShadow"); public RoundedBorder() {} public boolean isBorderOpaque() { return false; } public void paintBorder(Component component, Graphics graphics, int x, int y, int w, int h) { graphics.setColor(shadow); graphics.drawRoundRect(x, y, w - 1, h - 1, 9, 9); } public Insets getBorderInsets(Component component) { return insets; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/ToolBarButtonBorder.java000066400000000000000000000062441243334202400330060ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.Component; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import javax.swing.AbstractButton; import javax.swing.ImageIcon; import javax.swing.border.Border; /** A border suitable for toolbar buttons. *

* Paints a nice button effect with rounded corners. * * @author Lilian Chamontin, vlsolutions. * @version 1.0 * @since 2.0 */ public class ToolBarButtonBorder implements Border { private boolean pressed; public ToolBarButtonBorder() {} private static Image borderImage = new ImageIcon(ToolBarButtonBorder.class.getResource("toolbarbuttonborder.png")).getImage(); private static Image pressedBorderImage = new ImageIcon(ToolBarButtonBorder.class.getResource("toolbarbuttonborder_pressed.png")).getImage(); static int borderWidth = borderImage.getWidth(null); static int borderHeight = borderImage.getHeight(null); @SuppressWarnings("unused") private boolean paintTopLeft = true; private Insets insets = new Insets(2, 2, 2, 2); public boolean isBorderOpaque() { return false; } public void paintBorder(Component component, Graphics graphics, int x, int y, int w, int h) { Image img; if(pressed) { img = pressedBorderImage; } else { img = borderImage; } // top right corner graphics.drawImage(img, x + w - 5, y, x + w, y + 5, borderWidth - 5, 0, borderWidth, 5, null); // vertical right graphics.drawImage(img, x + w - 5, y + 5, x + w, y + h - 5, borderWidth - 5, 5, borderWidth, borderHeight - 5, null); // bottom-right corner graphics.drawImage(img, x + w - 5, y + h - 5, x + w, y + h, borderWidth - 5, borderHeight - 5, borderWidth, borderHeight, null); // horizontal bottom graphics.drawImage(img, x + 5, y + h - 5, x + w - 5, y + h, 5, borderHeight - 5, borderWidth - 5, borderHeight, null); // bottom left corner graphics.drawImage(img, x, y + h - 5, x + 5, y + h, 0, borderHeight - 5, 5, borderHeight, null); // horizontal top graphics.drawImage(img, x + 5, y, x + w - 5, y + 5, 5, 0, borderHeight - 5, 5, null); // vertical left graphics.drawImage(img, x, y + 5, x + 5, y + h - 5, 0, 5, 5, borderHeight - 5, null); // top left corner graphics.drawImage(img, x, y, x + 5, y + 5, 0, 0, 5, 5, null); } public Insets getBorderInsets(Component component) { if(component instanceof AbstractButton) { AbstractButton btn = (AbstractButton) component; Insets i = btn.getMargin(); i.top += insets.top; i.left += insets.left; i.right += insets.right; i.bottom += insets.bottom; return i; } else { return insets; } } public boolean isPressed() { return pressed; } public void setPressed(boolean pressed) { this.pressed = pressed; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/ToolBarConstraints.java000066400000000000000000000047371243334202400327110ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; /** Constraints to be used with the ToolBarLayout. *

* Depending on the orientation of the layout, the two integers majorOrder and minorOrder * express the opposite measures : *

    *
  • in an horizontal layout, majorOrder is the ROW, and minorOrder is the COLUMN *
  • in a vertical layout, majorOrder is the COLUMN, and minorOrder is the ROW *
*

* Example : To layout two toolbars horizontally on an horizontal layout, use the following constraints * (0,0) and (0,1) (the column is the minor order on an horizontal layout). *

* to layout them in a row (one above the other), use the constraints (0,0) and (1,0) (the row * is the major order on an horizontal layout). * * @author Lilian Chamontin, VLSolutions */ public class ToolBarConstraints { /** The major order is the row index for horizontal toolbars, and the column index for * vertical toolbars. */ public int majorOrder; /** The minor order is the column index for horizontal toolbars, and the row index for * vertical toolbars. */ public int minorOrder; /** Set to -1/0/+1 during drag/drop phase to allow insertion between rows/columns. * Do not use it outside drag and drop operations. */ /* package protected */int majorOffset = 0; /** Set to -1/0-31 during drag/drop phase to allow insertion between rows/columns * Do not use it outside drag and drop operations. */ /* package protected */int minorOffset = 0; /** Constructs a new ToolBarConstraints at (0,0) */ public ToolBarConstraints() {} /** Constructs a new ToolBarConstraints at (majorOrder,minorOrder). *

* the majorOrder is the ROW for an horizontal layout, and the columns for a vertical layout. */ public ToolBarConstraints(int majorOrder, int minorOrder) { this.majorOrder = majorOrder; this.minorOrder = minorOrder; } /** Returns a description of these constraints. */ public String toString() { return "ToolBarConstraints[" + majorOrder + ", " + minorOrder + "]"; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/ToolBarContainer.java000066400000000000000000000157241243334202400323220ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.BorderLayout; import java.awt.Component; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.HashMap; import javax.swing.JPanel; import javax.swing.SwingConstants; import javax.swing.UIManager; import java.awt.FlowLayout; /** The container for toolbar panels. *

* The layout used is BorderLayout and the CENTER component is dedicated to the user * (the other 4 places (NORTH, EAST, WEST and SOUTH are used to display the toolbar panels)). * *


* The ToolBarContainer is a JPanel with a BorderLayout, containing a user component and a maximum of four * ToolBarPanels. *

* *

* Loading and saving toolbar configurations is done with the {@link ToolBarIO} utility class, and works if * VLToolbars are registered (given a name and made know to their container by {@link #registerToolBar(VLToolBar)} ). * * @author Lilian Chamontin, VLSolutions * @update 2006/09/09 Support for LTR/RTL orientation */ @SuppressWarnings({"rawtypes", "unchecked"}) public class ToolBarContainer extends JPanel { private static final long serialVersionUID = 1L; private Map componentsByContraints = new HashMap(); // this is private in borderlayout, so we need to keep a copy here private Map contraintsByComponents = new HashMap(); private Map toolBarsByName = new HashMap(); public ToolBarContainer() { setLayout(new BorderLayout()); } /** Registers a new ToolBar. *

* Registering is used when reading a xml configuration */ public void registerToolBar(VLToolBar toolbar) { if(toolbar.getName() == null) { throw new IllegalArgumentException("This toolbar hasn't got a name : cannot be registered"); } toolBarsByName.put(toolbar.getName(), toolbar); } /** Unregisters a ToolBar. *

* Registering is used when reading a xml configuration */ public void unregisterToolBar(VLToolBar toolbar) { if(toolbar.getName() == null) { return; } toolBarsByName.remove(toolbar.getName()); } /** Returns the registered toolbar associated with the given name, or null if not found */ public VLToolBar getToolBarByName(String name) { return (VLToolBar) toolBarsByName.get(name); } /** Returns the list of currently registered toolbars. * *

(eturns a new list at each invocation.) */ public List getRegisteredToolBars() { return new ArrayList(toolBarsByName.values()); } /** Overriden to track component constraints */ public void add(Component comp, Object constraints) { super.add(comp, constraints); componentsByContraints.put(constraints, comp); contraintsByComponents.put(comp, constraints); if(comp instanceof ToolBarPanel) { ToolBarPanel panel = (ToolBarPanel) comp; if(constraints.equals(BorderLayout.EAST) || constraints.equals(BorderLayout.WEST)) { panel.setOrientation(SwingConstants.VERTICAL); } // install the UI border if(constraints.equals(BorderLayout.NORTH)) { panel.setBorder(UIManager.getBorder("ToolBarPanel.topBorder")); } else if(constraints.equals(BorderLayout.WEST)) { panel.setBorder(UIManager.getBorder("ToolBarPanel.leftBorder")); } else if(constraints.equals(BorderLayout.EAST)) { panel.setBorder(UIManager.getBorder("ToolBarPanel.rightBorder")); } else if(constraints.equals(BorderLayout.SOUTH)) { panel.setBorder(UIManager.getBorder("ToolBarPanel.bottomBorder")); } } } /** Overriden to keep track of component constraints */ public void remove(Component comp) { super.remove(comp); Object constraints = contraintsByComponents.remove(comp); componentsByContraints.remove(constraints); } /** Overriden to keep track of component constraints */ public void remove(int index) { Component comp = getComponent(index); super.remove(index); Object constraints = contraintsByComponents.remove(comp); componentsByContraints.remove(constraints); } /** Overriden to keep track of component constraints */ public void removeAll() { super.removeAll(); componentsByContraints.clear(); contraintsByComponents.clear(); } /** Returns the component for a given BorderLayout constraints */ public Component getComponentAt(Object constraints) { return (Component) componentsByContraints.get(constraints); } /** Returns the ToolBarPanel for a given BorderLayout constraints */ public ToolBarPanel getToolBarPanelAt(Object constraints) { return (ToolBarPanel) getComponentAt(constraints); } /** Returns the BorderLayout constraints of the given component */ public Object getConstraints(Component comp) { return contraintsByComponents.get(comp); } /** Creates a default ToolBarContainer with preinstalled toolbar panels on the borders with * the LEADING alignment. *

* The toolbarPanels are then accessible with getToolBarPanelAt(constraints) where constraints values * are BorderLayout.NORTH, EAST, WEST and SOUTH. */ public static ToolBarContainer createDefaultContainer(boolean topToolbar, boolean leftToolBar, boolean bottomToolBar, boolean rightToolBar) { return createDefaultContainer(topToolbar, leftToolBar, bottomToolBar, rightToolBar, FlowLayout.LEADING); } /** Creates a default ToolBarContainer with preinstalled toolbar panels on the borders with * the specified alignment * The value of the alignment argument must be one of * FlowLayout.LEFT, FlowLayout.RIGHT, * FlowLayout.CENTER, FlowLayout.LEADING, or * FlowLayout.TRAILING. *

* The toolbarPanels are then accessible with getToolBarPanelAt(constraints) where constraints values * are BorderLayout.NORTH, EAST, WEST and SOUTH. * *@author KDMurthy, Marathon Project. */ public static ToolBarContainer createDefaultContainer(boolean topToolbar, boolean leftToolBar, boolean bottomToolBar, boolean rightToolBar, int alignment) { ToolBarContainer container = new ToolBarContainer(); if(topToolbar) { ToolBarPanel panel = new ToolBarPanel(alignment); panel.setVisible(false); container.add(panel, BorderLayout.NORTH); } if(leftToolBar) { ToolBarPanel panel = new ToolBarPanel(alignment); panel.setVisible(false); container.add(panel, BorderLayout.WEST); } if(bottomToolBar) { ToolBarPanel panel = new ToolBarPanel(alignment); panel.setVisible(false); container.add(panel, BorderLayout.SOUTH); } if(rightToolBar) { ToolBarPanel panel = new ToolBarPanel(alignment); panel.setVisible(false); container.add(panel, BorderLayout.EAST); } return container; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/ToolBarGripper.java000066400000000000000000000045521243334202400320050ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import javax.swing.JComponent; import javax.swing.SwingConstants; import javax.swing.UIManager; /** The component used to have a "grip" action on a toolbar (Drag and Drop support) * * @author Lilian Chamontin, VLSolutions * @since 2.0 */ public class ToolBarGripper extends JComponent { private static final long serialVersionUID = 1L; private static final String uiClassID = "ToolBarGripperUI"; /** Id for the orientation property */ public static final String PROPERTY_ORIENTATION = "ORIENTATION"; private int orientation = SwingConstants.HORIZONTAL; private boolean collapsible = true; private boolean collapsed = false; public ToolBarGripper() { this(SwingConstants.HORIZONTAL); } public ToolBarGripper(int orientation) { setOrientation(orientation); updateUI(); } public void setOrientation(int orientation) { int old = this.orientation; this.orientation = orientation; firePropertyChange(PROPERTY_ORIENTATION, old, orientation); // not used by the framwork, but might be usefull for someone } /** Returns the orientation of this gripper (SwingConstants.HORIZONTAL/VERTICAL) */ public int getOrientation() { return this.orientation; } /** * Resets the UI property to a value from the current look and feel. * * @see JComponent#updateUI */ public void updateUI() { setUI(UIManager.getUI(this)); } /** {@inheritDoc} * @since 2.0 */ public String getUIClassID() { return uiClassID; } /** Return true is this toolbar can be collapsed (default is true)*/ public boolean isCollapsible() { return collapsible; } public void setCollapsible(boolean collapsible) { this.collapsible = collapsible; } /** Return true is this toolbar is currently collapsed */ public boolean isCollapsed() { return collapsed; } public void setCollapsed(boolean collapsed) { this.collapsed = collapsed; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/ToolBarGripperUI.java000066400000000000000000000052651243334202400322450ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.SwingConstants; import javax.swing.plaf.ComponentUI; /** The default UI for the toolbar gripper. * * @author Lilian Chamontin, VLSolutions */ public class ToolBarGripperUI extends ComponentUI { /** the "grip" (an alpha blended dot image, 3*3 pixels, hightlighted underneath ) */ protected static Image gripImage = new ImageIcon(ToolBarGripperUI.class.getResource("gripper.png")).getImage(); protected static Image gripExpandHImage = new ImageIcon(ToolBarGripperUI.class.getResource("grip_expand_h.png")).getImage(); protected static Image gripExpandVImage = new ImageIcon(ToolBarGripperUI.class.getResource("grip_expand_v.png")).getImage(); /** Constructs a new gripper UI */ public ToolBarGripperUI() {} public static ComponentUI createUI(JComponent c) { return new ToolBarGripperUI(); } /** installs the UI and sets the preferred size of the gripper */ public void installUI(JComponent comp) { super.installUI(comp); comp.setPreferredSize(new Dimension(4, 4)); } /** Paints gripper dots */ public void paint(Graphics g, JComponent comp) { ToolBarGripper gripper = (ToolBarGripper) comp; Insets insets = gripper.getInsets(); if(gripper.getOrientation() == SwingConstants.HORIZONTAL) { int dots = (gripper.getHeight()) / 4 - 1; int dotsSize = dots * 4; int top = insets.top + gripper.getHeight() / 2 - dotsSize / 2; int centerX = insets.left + (gripper.getWidth() - insets.left - insets.right) / 2; for(int i = 0; i < dots; i++) { g.drawImage(gripImage, centerX - 1, top + i * 4 + 1, null); } if(gripper.isCollapsed()) { int centerY = gripper.getHeight() / 2; g.drawImage(gripExpandHImage, 0, centerY - 4, null); } } else { int dots = (gripper.getWidth()) / 4 - 1; for(int i = 0; i < dots; i++) { g.drawImage(gripImage, insets.left + i * 4 + 2, insets.top, null); } if(gripper.isCollapsed()) { int centerX = gripper.getWidth() / 2; g.drawImage(gripExpandVImage, centerX - 4, 0, null); } } super.paint(g, comp); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/ToolBarIO.java000066400000000000000000000173111243334202400307010ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; /** A utility class used to save and restore toolbars to/from an XML configuration. * * @author Lilian Chamontin, VLSolutions */ public class ToolBarIO { /** The main container */ private ToolBarContainer container; /** Constructs a new ToolBarIO utility based on the given container */ public ToolBarIO(ToolBarContainer container) { this.container = container; } /** Saves the current toolbar configuration into an XML stream. *

* The stream is not closed at the end of the operation. * * @see #readXML(InputStream) * */ public void writeXML(OutputStream stream) throws IOException { PrintWriter out = new PrintWriter(stream); out.println(""); out.println(""); xmlWriteContainer(out); out.println(""); out.flush(); } private void xmlWriteContainer(PrintWriter out) { out.println(""); Component[] comps = container.getComponents(); for(int i = 0; i < comps.length; i++) { Object constraints = container.getConstraints(comps[i]); if(constraints.equals(BorderLayout.NORTH)) { ToolBarPanel panel = container.getToolBarPanelAt(constraints); xmlWriteToolBarPanel(out, panel, "top"); } else if(constraints.equals(BorderLayout.WEST)) { ToolBarPanel panel = container.getToolBarPanelAt(constraints); xmlWriteToolBarPanel(out, panel, "left"); } else if(constraints.equals(BorderLayout.SOUTH)) { ToolBarPanel panel = container.getToolBarPanelAt(constraints); xmlWriteToolBarPanel(out, panel, "bottom"); } else if(constraints.equals(BorderLayout.EAST)) { ToolBarPanel panel = container.getToolBarPanelAt(constraints); xmlWriteToolBarPanel(out, panel, "right"); } } out.println(""); } private void xmlWriteToolBarPanel(PrintWriter out, ToolBarPanel panel, String position) { out.println(""); ToolBarPanelLayout layout = (ToolBarPanelLayout) panel.getLayout(); Component[] children = layout.getComponents(); // toolbars only for(int i = 0; i < children.length; i++) { VLToolBar tb = (VLToolBar) children[i]; ToolBarConstraints tc = layout.getConstraints(tb); out.println(""); } out.println(""); } /** Reads an XML encoded stream as the toolbar configuration. *

* When the method returns, the container is totally reconfigured with possibly different * toolbars at different positions. *

* Note : The VLToolBars of the stream must be registered with * the {@link ToolBarContainer#registerToolBar(VLToolBar) registerToolBar} method, * prior readXML. *

Also note that the container must already contain its ToolBarPanels before reading * the configuration. * *

* Dismisses all visible toolbars. *

* The stream is not closed at the end of the operation. * @see #writeXML(OutputStream) * @see ToolBarContainer#registerToolBar(VLToolBar) * @return a descriptor of the reading operation(useful for example to know the registered toolbars, that weren't * loaded (missing) from the input file). * */ public ToolBarIOReadInfo readXML(InputStream in) throws ParserConfigurationException, IOException, SAXException { ToolBarIOReadInfo tri = new ToolBarIOReadInfo(); // first clear the toolbar panels Component[] comps = container.getComponents(); for(int i = 0; i < comps.length; i++) { Object constraints = container.getConstraints(comps[i]); if(constraints.equals(BorderLayout.NORTH)) { ((Container) comps[i]).removeAll(); } else if(constraints.equals(BorderLayout.WEST)) { ((Container) comps[i]).removeAll(); } else if(constraints.equals(BorderLayout.SOUTH)) { ((Container) comps[i]).removeAll(); } else if(constraints.equals(BorderLayout.EAST)) { ((Container) comps[i]).removeAll(); } } DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(in); Element root = doc.getDocumentElement(); NodeList children = root.getChildNodes(); for(int i = 0, len = children.getLength(); i < len; i++) { Node child = children.item(i); xmlReadRootNode(child, tri); } tri.setRegisteredToolbars(container.getRegisteredToolBars()); tri.finishLoading(); container.revalidate(); return tri; } private void xmlReadRootNode(Node node, ToolBarIOReadInfo tri) throws SAXException { if(node.getNodeType() == Node.ELEMENT_NODE) { Element elt = (Element) node; String name = elt.getNodeName(); if(name.equals("Container")) { NodeList children = node.getChildNodes(); for(int i = 0, len = children.getLength(); i < len; i++) { Node child = children.item(i); xmlReadContainerNode(child, tri); } } else { throw new SAXNotRecognizedException(name); } } } private void xmlReadContainerNode(Node node, ToolBarIOReadInfo tri) throws SAXException { if(node.getNodeType() == Node.ELEMENT_NODE) { Element elt = (Element) node; String name = elt.getNodeName(); if(name.equals("ToolBarPanel")) { String position = elt.getAttribute("position"); ToolBarPanel tp = null; if(position.equals("top")) { tp = container.getToolBarPanelAt(BorderLayout.NORTH); } else if(position.equals("left")) { tp = container.getToolBarPanelAt(BorderLayout.WEST); } else if(position.equals("bottom")) { tp = container.getToolBarPanelAt(BorderLayout.SOUTH); } else if(position.equals("right")) { tp = container.getToolBarPanelAt(BorderLayout.EAST); } NodeList children = elt.getElementsByTagName("ToolBar"); for(int i = 0, len = children.getLength(); i < len; i++) { xmlReadToolBarPanelNode(tp, (Element) children.item(i), tri); } tp.revalidate(); } else { throw new SAXNotRecognizedException(name); } } } private void xmlReadToolBarPanelNode(ToolBarPanel panel, Element toolbarElt, ToolBarIOReadInfo tri) { String toolbarName = toolbarElt.getAttribute("name"); int major = Integer.parseInt(toolbarElt.getAttribute("major")); int minor = Integer.parseInt(toolbarElt.getAttribute("minor")); boolean collapsed = Boolean.valueOf(toolbarElt.getAttribute("collapsed")).booleanValue(); //2.0.6b ToolBarConstraints tc = new ToolBarConstraints(major, minor); VLToolBar tb = container.getToolBarByName(toolbarName); if(tb != null) { tb.setCollapsed(collapsed); // 2.0.6b panel.add(tb, tc); tri.notifyToolbarInstalled(tb); } else { // If the ToolBar is not registered ignore it tri.notifyUnknownToolbarFound(toolbarName); } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/ToolBarIOReadInfo.java000066400000000000000000000041201243334202400323030ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.util.ArrayList; import java.util.List; /** Descriptor of the loading operation of toolbars. * *

returns useful informations such as the toolbars registered and successfully loaded, and * the ones not loaded. * * @author Lilian Chamontin, VLSolutions */ @SuppressWarnings({"rawtypes", "unchecked"}) public class ToolBarIOReadInfo { List notInstalledToolBarList; List installedToolBarList = new ArrayList(); List unknownToolBarNames = new ArrayList(); List registeredToolbars; public ToolBarIOReadInfo() {} /** returns the list of toolbars that were successfully loaded from the toolbarIO operation */ public List getInstalledToolbars() { return installedToolBarList; } /** returns the list of toolbars that weren't loaded from the stream (but registered) */ public List getNotInstalledToolbars() { return notInstalledToolBarList; } /** Return the list of toolbars names (String) found in the stream but not registered * (these toolbars cannot be loaded, so the API can only report their name). */ public List getUnknownToolbarNames() { return unknownToolBarNames; } void notifyToolbarInstalled(VLToolBar tb) { installedToolBarList.add(tb); } void setRegisteredToolbars(List registered) { this.registeredToolbars = registered; } /** invoked on completion of loading */ void finishLoading() { this.notInstalledToolBarList = new ArrayList(registeredToolbars); notInstalledToolBarList.removeAll(installedToolBarList); } void notifyUnknownToolbarFound(String toolbarName) { unknownToolBarNames.add(toolbarName); } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/ToolBarPanel.java000066400000000000000000000134421243334202400314320ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.Component; import java.awt.FlowLayout; import java.awt.Graphics; import java.util.ArrayList; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JToolBar; import javax.swing.JToolBar.Separator; import javax.swing.SwingConstants; /** The toolbar panel is able to receive multiple toolbars and arrange them in * many columns or rows (depending on the horizontal/vertical orientation). * *


* The ToolBarPanel is a JPanel with a ToolBarPanelLayout. It support horizontal and vertical orientation, * and can contain one or more VLToolbars (with given ToolBarContraints for positionning). *

* @author Lilian Chamontin, VLSolutions * @update 2006/09/09 Support for LTR and RTL component orientation */ @SuppressWarnings({"rawtypes", "unchecked"}) public class ToolBarPanel extends JPanel { private static final long serialVersionUID = 1L; private int orientation = SwingConstants.HORIZONTAL; /** an optionnal background painter */ private BackgroundPainter painter; /** * Constructs a new toobar panel with a LEADING alignment. */ public ToolBarPanel() { this(FlowLayout.LEADING); } /** * Constructs a new ToolBarPanel with the specified * alignment. * @param align the alignment value * The value of the alignment argument must be one of * FlowLayout.LEFT, FlowLayout.RIGHT, * FlowLayout.CENTER, FlowLayout.LEADING, or * FlowLayout.TRAILING. * */ public ToolBarPanel(int align) { this(align, null); } /** * Constructs a new ToolBarPanel with the specified * alignment and background painter. * @param align the alignment value * The value of the alignment argument must be one of * FlowLayout.LEFT, FlowLayout.RIGHT, * FlowLayout.CENTER, FlowLayout.LEADING, or * FlowLayout.TRAILING. * @param painter the background painter. * @since 2.1.4 */ public ToolBarPanel(int align, BackgroundPainter painter) { setLayout(new ToolBarPanelLayout(this, align)); this.painter = painter; } /** Adds a new toolbar respecting the given positionning constraints. */ public void add(JToolBar toolbar) { add(toolbar, 0); setVisible(true); } /** Adds a new JToolBar to the Panel at the given row. Multiple VLToolBars * are constructed using Separators in the original JToolBar */ public void add(JToolBar toolbar, int major) { toolbar.setOrientation(orientation); VLToolBar[] bars = getVLToolBarsFromJToolBar(toolbar); for(int i = 0; i < bars.length; i++) { ToolBarConstraints toolBarConstraints = new ToolBarConstraints(major, i); add(bars[i], toolBarConstraints); } } /** * Helper function to convert a JToolBar into multiple VLToolBar objects. The JToolBar * is split at the separator boundary to create VLToolbars * @param bar, the JToolBar object * @return array of VLToolBar objects */ private VLToolBar[] getVLToolBarsFromJToolBar(JToolBar bar) { ArrayList vlBars = new ArrayList(); Component[] components = bar.getComponents(); VLToolBar current = new VLToolBar(); for(int i = 0; i < components.length; i++) { if(components[i] instanceof JButton) { JButton button = (JButton) components[i]; if(button.getIcon() != null) button.setText(null); current.add(button); } else if(components[i] instanceof Separator) { vlBars.add(current); current = new VLToolBar(); } else { System.err.println("Don't know how to handle this component " + components[i].getClass()); } } vlBars.add(current); return (VLToolBar[]) vlBars.toArray(new VLToolBar[vlBars.size()]); } /** Adds a new toolbar respecting the given positionning constraints. */ public void add(VLToolBar toolbar, ToolBarConstraints constraints) { toolbar.setOrientation(orientation); super.add(toolbar, constraints); setVisible(true); } public void remove(Component comp) { super.remove(comp); if(getComponentCount() == 0) { setVisible(false); } } /* Updates the orientation of this toolbar. Valid values are SwingConstants.HORIZONTAL and VERTICAL*/ public void setOrientation(int orientation) { if(this.orientation != orientation) { this.orientation = orientation; updateOrientation(); revalidate(); } } /** Returns the orientation of this toolbarpanel */ public int getOrientation() { return this.orientation; } /** Propagates the orientation to the contained toolbars */ private void updateOrientation() { for(int i = 0; i < getComponentCount(); i++) { VLToolBar tb = (VLToolBar) getComponent(i); tb.setOrientation(orientation); } } /** Overriden for optional background painting */ public void paintComponent(Graphics g) { if(painter != null) { painter.paintBackground(this, g); } super.paintComponent(g); } /** Returns the optional background painter for this toolbar panel (may be null) *@since 2.1.4 */ public BackgroundPainter getBackgroundPainter() { return painter; } /** Updates the optional background painter for this toolbar panel * @param painter the new painer (may be null) * @since 2.1.4 */ public void setPainter(BackgroundPainter painter) { this.painter = painter; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/ToolBarPanelBorder.java000066400000000000000000000101731243334202400325660ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.Component; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import javax.swing.ImageIcon; import javax.swing.border.Border; /** This is an optional class that can be used as a border for toolbar panels. * * @author Lilian Chamontin, VLSolutions */ public class ToolBarPanelBorder implements Border { public static final int TOP_PANEL = 0; public static final int LEFT_PANEL = 1; public static final int BOTTOM_PANEL = 2; public static final int RIGHT_PANEL = 3; private static Image borderImage = new ImageIcon(ToolBarButtonBorder.class.getResource("toolbarpanelborder.png")).getImage(); static int borderWidth = borderImage.getWidth(null); static int borderHeight = borderImage.getHeight(null); private Insets insets; private int panelPosition; public ToolBarPanelBorder() { this(TOP_PANEL); } public ToolBarPanelBorder(int panelPosition) { this.panelPosition = panelPosition; switch(panelPosition) { case TOP_PANEL: insets = new Insets(1, 1, 4, 1); break; case LEFT_PANEL: insets = new Insets(1, 1, 1, 4); break; case BOTTOM_PANEL: insets = new Insets(4, 1, 1, 1); break; case RIGHT_PANEL: insets = new Insets(1, 4, 1, 1); break; } } public boolean isBorderOpaque() { return false; } public void paintBorder(Component component, Graphics graphics, int x, int y, int w, int h) { switch(panelPosition) { case TOP_PANEL: // horizontal bottom graphics.drawImage(borderImage, x, y + h - 5, x + w, y + h, 5, borderHeight - 5, borderWidth - 5, borderHeight, null); // bottom-right corner /* graphics.drawImage(borderImage, x+ w -SIDE, y+h-SIDE, x+w, y+h, borderWidth-SIDE,borderHeight-SIDE, borderWidth, borderWidth, null); // bottom left graphics.drawImage(borderImage, x, y+h-SIDE, x+SIDE, y+h, 0, borderHeight-SIDE, SIDE, borderHeight, null);*/ break; case LEFT_PANEL: // vertical right graphics.drawImage(borderImage, x + w - 5, y, x + w, y + h, borderWidth - 5, 5, borderWidth, borderHeight - 5, null); break; case BOTTOM_PANEL: // horizontal top graphics.drawImage(borderImage, x, y, x + w, y + 5, 5, 0, borderHeight - 5, 5, null); break; case RIGHT_PANEL: // vertical left graphics.drawImage(borderImage, x, y, x + 5, y + h, 0, 5, 5, borderHeight - 5, null); break; } /* // top right corner graphics.drawImage(borderImage, x+ w -5, y, x+w, y+5, borderWidth-5,0, borderWidth, 5, null); // vertical right graphics.drawImage(borderImage, x+ w -5, y+5, x+w, y+h-5, borderWidth-5,5, borderWidth, borderHeight-5, null); // bottom-right corner graphics.drawImage(borderImage, x+ w -5, y+h-5, x+w, y+h, borderHeight-5,borderWidth-5, borderWidth, borderHeight, null); // horizontal bottom graphics.drawImage(borderImage, x+5, y+h-5, x+w-5, y+h, 5,borderHeight-5, borderWidth-5, borderHeight, null); // bottom left corner graphics.drawImage(borderImage, x, y+h-5, x+5, y+h, 0, borderHeight-5, 5, borderHeight, null); // horizontal top graphics.drawImage(borderImage, x+5, y, x+w-5, y+5, 5,0, borderHeight-5, 5, null); // vertical left graphics.drawImage(borderImage, x, y+5, x+5, y+h-5, 0,5, 5, borderHeight-5, null); // top left corner graphics.drawImage(borderImage, x, y, x+5, y+5, 0,0, 5, 5, null); */ } public Insets getBorderInsets(Component component) { return insets; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/ToolBarPanelLayout.java000066400000000000000000000435271243334202400326370ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Insets; import java.awt.LayoutManager2; import java.awt.Point; import java.awt.Rectangle; import java.util.ArrayList; import java.util.Collections; import javax.swing.SwingConstants; /** The layout of a VLToolBarPanel * * @author Lilian Chamontin, VLSolutions * @update 2006/09/09 Support for LTR and RTL component orientation */ @SuppressWarnings({"rawtypes", "unchecked"}) public class ToolBarPanelLayout implements LayoutManager2 { private ToolBarPanel panel; private ArrayList componentInfos = new ArrayList(); private int gap = 3; // gap in pixels between components private int align = FlowLayout.LEADING; public ToolBarPanelLayout(ToolBarPanel panel, int align) { this.panel = panel; this.align = align; } public ToolBarPanelLayout(ToolBarPanel panel) { this(panel, FlowLayout.LEADING); } /** Returns the alignment of this layout (FlowLayout.LEADING, TRAILING...) */ public int getAlign() { return align; } public void setAlign(int align) { this.align = align; } private int getAlignedX(Container target) { int left = 0; boolean ltr = target.getComponentOrientation().isLeftToRight(); int width = preferredLayoutSize(target).width; switch(align) { case FlowLayout.LEFT: left += ltr ? 0 : target.getSize().width - width; break; case FlowLayout.CENTER: left += (target.getSize().width - width) / 2; break; case FlowLayout.RIGHT: left += ltr ? target.getSize().width - width : 0; break; case FlowLayout.LEADING: break; case FlowLayout.TRAILING: left += target.getSize().width - width; break; } return left; } public float getLayoutAlignmentX(Container target) { return 0.5F; } public float getLayoutAlignmentY(Container target) { return 0.5F; } public void invalidateLayout(Container target) {} public Dimension maximumLayoutSize(Container target) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } public void addLayoutComponent(Component comp, Object constraints) { if(constraints == null) { throw new NullPointerException(); } else { ToolBarConstraints tc = (ToolBarConstraints) constraints; componentInfos.add(new ComponentInfo(comp, tc)); reorderComponents(); } } public ToolBarConstraints getConstraints(Component comp) { for(int i = 0; i < componentInfos.size(); i++) { ComponentInfo ci = (ComponentInfo) componentInfos.get(i); if(ci.comp == comp) { return ci.constraints; } } return null; } public void removeLayoutComponent(Component comp) { for(int i = 0; i < componentInfos.size(); i++) { ComponentInfo ci = (ComponentInfo) componentInfos.get(i); if(ci.comp == comp) { componentInfos.remove(i); return; } } } public void addLayoutComponent(String name, Component comp) {} public Dimension minimumLayoutSize(Container parent) { ToolBarPanel panel = (ToolBarPanel) parent; boolean isHorizontal = panel.getOrientation() == SwingConstants.HORIZONTAL; synchronized(parent.getTreeLock()) { Dimension dim = new Dimension(0, 0); int majorCount = getMajorCount(); for(int i = 0; i < majorCount; i++) { Dimension minorDim = new Dimension(0, 0); ArrayList minorList = getMinorComponents(i); for(int j = 0; j < minorList.size(); j++) { ComponentInfo ci = (ComponentInfo) minorList.get(j); Dimension d = ci.comp.getPreferredSize(); if(ci.comp.isVisible()) { if(isHorizontal) { minorDim.width += d.width; minorDim.height = Math.max(minorDim.height, d.height); if(j > 0) { minorDim.width += gap; } } else { minorDim.width = Math.max(minorDim.width, d.width); minorDim.height += d.height; if(j > 0) { minorDim.height += gap; } } } } if(isHorizontal) { dim.width = Math.max(dim.width, minorDim.width); dim.height += minorDim.height; } else { dim.width += minorDim.width; dim.height = Math.max(dim.height, minorDim.height); } } Insets insets = parent.getInsets(); dim.width += insets.left + insets.right; dim.height += insets.top + insets.bottom; return dim; } } public Dimension preferredLayoutSize(Container parent) { return minimumLayoutSize(parent); } /** Returns and ordered array of the contained components */ public Component[] getComponents() { Component[] comps = new Component[componentInfos.size()]; for(int i = 0; i < componentInfos.size(); i++) { ComponentInfo ci = (ComponentInfo) componentInfos.get(i); comps[i] = ci.comp; } return comps; } public void layoutContainer(Container target) { ToolBarPanel panel = (ToolBarPanel) target; boolean isHorizontal = panel.getOrientation() == SwingConstants.HORIZONTAL; boolean ltr = target.getComponentOrientation().isLeftToRight(); synchronized(target.getTreeLock()) { Collections.sort(componentInfos); Insets insets = target.getInsets(); if(isHorizontal) { int top = insets.top; int majorCount = getMajorCount(); for(int i = 0; i < majorCount; i++) { int left = insets.left + getAlignedX(target); int maxHeight = 0; ArrayList minorList = getMinorComponents(i); /*for (int j=0; j < minorList.size(); j++){ ComponentInfo ci = (ComponentInfo) minorList.get(j); Component comp = ci.comp; if (comp.isVisible()){ Dimension d = comp.getPreferredSize(); comp.setBounds(left, top, d.width, d.height); left += d.width + gap; maxHeight = Math.max(maxHeight, d.height); } }*/ if(ltr) { for(int j = 0; j < minorList.size(); j++) { ComponentInfo ci = (ComponentInfo) minorList.get(j); Dimension d = layoutHorizMinor(ci, left, top); if(d != null) { left += d.width + gap; maxHeight = Math.max(maxHeight, d.height); } } } else { for(int j = minorList.size() - 1; j >= 0; j--) { ComponentInfo ci = (ComponentInfo) minorList.get(j); Dimension d = layoutHorizMinor(ci, left, top); if(d != null) { left += d.width + gap; maxHeight = Math.max(maxHeight, d.height); } } } top += maxHeight; } } else { int majorCount = getMajorCount(); /*int left = insets.left; for (int i=0; i < majorCount; i++){ int top = insets.top; int maxWidth = 0; ArrayList minorList = getMinorComponents(i); for (int j=0; j < minorList.size(); j++){ ComponentInfo ci = (ComponentInfo) minorList.get(j); Component comp = ci.comp; if (comp.isVisible()){ Dimension d = comp.getPreferredSize(); comp.setBounds(left, top, d.width, d.height); top += d.height + gap; maxWidth = Math.max(maxWidth, d.width); } } left += maxWidth;*/ int left = insets.left; if(ltr) { for(int i = 0; i < majorCount; i++) { int maxWidth = layoutVertMajor(insets, left, i); left += maxWidth; } } else { for(int i = majorCount - 1; i >= 0; i--) { int maxWidth = layoutVertMajor(insets, left, i); left += maxWidth; } } } } } private Dimension layoutHorizMinor(ComponentInfo ci, int left, int top) { Component comp = ci.comp; if(comp.isVisible()) { Dimension d = comp.getPreferredSize(); comp.setBounds(left, top, d.width, d.height); return d; } return null; } private int layoutVertMajor(Insets insets, int left, int i) { int top = insets.top; int maxWidth = 0; ArrayList minorList = getMinorComponents(i); for(int j = 0; j < minorList.size(); j++) { ComponentInfo ci = (ComponentInfo) minorList.get(j); Component comp = ci.comp; if(comp.isVisible()) { Dimension d = comp.getPreferredSize(); comp.setBounds(left, top, d.width, d.height); top += d.height + gap; maxWidth = Math.max(maxWidth, d.width); } } return maxWidth; } private void reorderComponents() { Collections.sort(componentInfos); /* Usefull state dumps : I'll let them here for some time. System.out.println("---------------------------------------------------"); System.out.println("List of components : ----BEFORE ------"); for (int i=0; i < componentInfos.size(); i++){ ComponentInfo ci = (ComponentInfo)componentInfos.get(i); System.out.println(ci.constraints + " = " + ci.comp); } //*/ // first, insert new major orders for(int i = 0; i < componentInfos.size(); i++) { ComponentInfo ci = (ComponentInfo) componentInfos.get(i); if(ci.constraints.majorOffset < 0) { ci.constraints.majorOffset = 0; for(int j = i + 1; j < componentInfos.size(); j++) { ComponentInfo next = (ComponentInfo) componentInfos.get(j); next.constraints.majorOrder++; } } else if(ci.constraints.majorOffset > 0) { ci.constraints.majorOffset = 0; for(int j = i; j < componentInfos.size(); j++) { // also increase the current one ComponentInfo next = (ComponentInfo) componentInfos.get(j); next.constraints.majorOrder++; } } } // next, insert new minor orders for(int i = 0; i < componentInfos.size(); i++) { ComponentInfo ci = (ComponentInfo) componentInfos.get(i); if(ci.constraints.minorOffset < 0) { ci.constraints.minorOffset = 0; for(int j = i + 1; j < componentInfos.size(); j++) { ComponentInfo next = (ComponentInfo) componentInfos.get(j); if(next.constraints.majorOrder == ci.constraints.majorOrder) { next.constraints.minorOrder++; } } } else if(ci.constraints.minorOffset > 0) { ci.constraints.minorOffset = 0; for(int j = i; j < componentInfos.size(); j++) { // also increase the current one ComponentInfo next = (ComponentInfo) componentInfos.get(j); if(next.constraints.majorOrder == ci.constraints.majorOrder) { next.constraints.minorOrder++; } } } } /* System.out.println("List of components : after offsets"); for (int i=0; i < componentInfos.size(); i++){ ComponentInfo ci = (ComponentInfo)componentInfos.get(i); System.out.println(ci.constraints + " = " + ci.comp); }*/ // next, let all major and minor order be consecutive int order = 0; int minorOrder = 0; int lastMajorOrder = - 1; int lastMinorOrder = - 1; for(int i = 0; i < componentInfos.size(); i++) { ComponentInfo ci = (ComponentInfo) componentInfos.get(i); if(lastMajorOrder == - 1) { lastMajorOrder = ci.constraints.majorOrder; lastMinorOrder = ci.constraints.minorOrder; } if(ci.constraints.majorOrder == lastMajorOrder) { ci.constraints.majorOrder = order; if(ci.constraints.minorOrder == lastMinorOrder) { ci.constraints.minorOrder = minorOrder; } else { minorOrder++; lastMinorOrder = ci.constraints.minorOrder; ci.constraints.minorOrder = minorOrder; } } else { // beginning of a new major order++; minorOrder = 0; lastMajorOrder = ci.constraints.majorOrder; lastMinorOrder = ci.constraints.minorOrder; ci.constraints.majorOrder = order; ci.constraints.minorOrder = minorOrder; } } /* System.out.println("List of components : ------AFTER ----"); for (int i=0; i < componentInfos.size(); i++){ ComponentInfo ci = (ComponentInfo)componentInfos.get(i); System.out.println(ci.constraints + " = " + ci.comp); } */ } private ToolBarConstraints getHorizontalInsertionContraintsAt(Component draggedComponent, Point p) { ToolBarConstraints tc = new ToolBarConstraints(); int majorCount = getMajorCount(); for(int i = 0; i < majorCount; i++) { Rectangle bounds = getMinorBounds(i); if(p.y < bounds.y) { // insert before first tc.majorOrder = i; tc.minorOrder = 0; tc.majorOffset = - 1; return tc; } else if(p.y < bounds.y + 5) { // insert before current row tc.majorOrder = i; tc.minorOrder = 0; tc.majorOffset = - 1; return tc; } else if(p.y > bounds.y + bounds.height) { // insert after.. ignore (will be tested on next loop) } else if(p.y > bounds.y + bounds.height - 5) { // insert a new major as we are just below the lower part tc.majorOrder = i; tc.minorOrder = 0; tc.majorOffset = + 1; return tc; } else if(p.x < bounds.x + bounds.width) { // insert inside ArrayList minorList = getMinorComponents(i); for(int j = 0; j < minorList.size(); j++) { ComponentInfo ci = (ComponentInfo) minorList.get(j); Component comp = ci.comp; if(comp.isVisible()) { if(p.x < comp.getX() + comp.getWidth()) { if(comp == draggedComponent) { return null; } else if(p.x < comp.getX() + 10) { // at the beginning of the component tc.majorOrder = i; tc.minorOrder = j; tc.minorOffset = - 1; return tc; } else { // on the component but not at the beginning if(j < minorList.size() - 1) { ComponentInfo next = (ComponentInfo) minorList.get(j + 1); if(next.comp == draggedComponent) { return null; } } tc.majorOrder = i; tc.minorOrder = j; tc.minorOffset = + 1; return tc; } } } } // not possible to reach this point } else { // after last of the row ArrayList minorList = getMinorComponents(i); tc.majorOrder = i; tc.minorOrder = minorList.size(); return tc; } } // not found... so it's after the last tc.majorOrder = majorCount; tc.minorOrder = 0; return tc; } private ToolBarConstraints getVerticalInsertionContraintsAt(Component draggedComponent, Point p) { ToolBarConstraints tc = new ToolBarConstraints(); int majorCount = getMajorCount(); for(int i = 0; i < majorCount; i++) { Rectangle bounds = getMinorBounds(i); if(p.x < bounds.x) { // insert before first tc.majorOrder = i; tc.minorOrder = 0; tc.majorOffset = - 1; return tc; } else if(p.x < bounds.x + 3) { // insert before current row tc.majorOrder = i; tc.minorOrder = 0; tc.majorOffset = - 1; return tc; } else if(p.x > bounds.x + bounds.width) { // insert after.. ignore (will be tested on next loop) } else if(p.x > bounds.x + bounds.width - 3) { // insert a new major as we are just below the lower part tc.majorOrder = i; tc.minorOrder = 0; tc.majorOffset = + 1; return tc; } else if(p.y < bounds.y + bounds.height) { // insert inside ArrayList minorList = getMinorComponents(i); for(int j = 0; j < minorList.size(); j++) { ComponentInfo ci = (ComponentInfo) minorList.get(j); Component comp = ci.comp; if(comp.isVisible()) { if(p.y < comp.getY() + comp.getHeight()) { if(comp == draggedComponent) { return null; } else if(p.y < comp.getY() + 10) { // at the beginning of the component tc.majorOrder = i; tc.minorOrder = j; tc.minorOffset = - 1; return tc; } else { // on the component but not at the beginning if(j < minorList.size() - 1) { ComponentInfo next = (ComponentInfo) minorList.get(j + 1); if(next.comp == draggedComponent) { return null; } } tc.majorOrder = i; tc.minorOrder = j; tc.minorOffset = + 1; return tc; } } } } // not possible to reach this point } else { // after last of the row ArrayList minorList = getMinorComponents(i); tc.majorOrder = i; tc.minorOrder = minorList.size(); return tc; } } // not found... so it's after the last tc.majorOrder = majorCount; tc.minorOrder = 0; return tc; } /** Returns a proposed TooBarContraints for a given insertion point */ public ToolBarConstraints getInsertionContraintsAt(Component draggedComponent, Point p) { boolean isHorizontal = panel.getOrientation() == SwingConstants.HORIZONTAL; if(isHorizontal) { return getHorizontalInsertionContraintsAt(draggedComponent, p); } else { // vertical return getVerticalInsertionContraintsAt(draggedComponent, p); } } private int getMajorCount() { int max = 0; for(int i = 0; i < componentInfos.size(); i++) { ComponentInfo ci = (ComponentInfo) componentInfos.get(i); ToolBarConstraints tc = ci.constraints; if(tc.majorOrder > max) { max = tc.majorOrder; } } return max + 1; } private Rectangle getMinorBounds(int majorOrder) { Rectangle r = new Rectangle(); Rectangle temp = null; for(int i = 0; i < componentInfos.size(); i++) { ComponentInfo ci = (ComponentInfo) componentInfos.get(i); if(ci.constraints.majorOrder == majorOrder) { temp = ci.comp.getBounds(temp); r = r.union(temp); } } return r; } private ArrayList getMinorComponents(int majorOrder) { ArrayList list = new ArrayList(); for(int i = 0; i < componentInfos.size(); i++) { ComponentInfo ci = (ComponentInfo) componentInfos.get(i); if(ci.constraints.majorOrder == majorOrder) { list.add(ci); } } return list; } private class ComponentInfo implements Comparable { Component comp; ToolBarConstraints constraints; ComponentInfo(Component comp, ToolBarConstraints constraints) { this.comp = comp; this.constraints = constraints; } private int getCompareOrder() { int order = constraints.majorOrder * 100000 + constraints.majorOffset * 10000 + constraints.minorOrder * 100 + constraints.minorOffset; return order; } public int compareTo(Object obj) { ComponentInfo ci = (ComponentInfo) obj; return getCompareOrder() - ci.getCompareOrder(); } } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/ToolBarPersistence.java000066400000000000000000000076711243334202400326660ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.BorderLayout; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.Iterator; import java.util.prefs.Preferences; import javax.xml.parsers.ParserConfigurationException; import org.xml.sax.SAXException; /** * This class contains methods to keep a set of toolbars persistent. *

* The class uses the preferences framework of the java runtime, and installs a * shutdown hook to save the toolbars state on application exit. *

* Warning : this class cannot be run from a sandboxed (untrusted) environment * (unsigned applet/ java web start) as it uses classes requiring a SecurityManager * (Preferences API and Runtime shutdown hook). *

* Call loadToolBarLayout() upon application startup, after registering all ToolBars. * * @author Michael Westergaard, revised by Lilian Chamontin. * * @see ToolBarIO */ public class ToolBarPersistence implements Runnable { private final static String TOOLBAR_LAYOUT = "toolbar_layout"; //$NON-NLS-1$ private ToolBarContainer container; private ToolBarIO io; private Preferences prefs; /** * Construct a new set of persistent toolbars. * * @param mainClass the main class of the application. Will be used to * generate a reasonable name for the preferences to store toolbar * configuration * @param container the toolbarcontainer to keep persistent * @throws SecurityException if this class is invoked from an untrusted environment */ public ToolBarPersistence(Object mainClass, ToolBarContainer container) { this.container = container; this.io = new ToolBarIO(container); String nodeName = mainClass.getClass().getName().replaceFirst(mainClass.getClass().getPackage().getName() + ".", ""); //$NON-NLS-1$ //$NON-NLS-2$ prefs = Preferences.userNodeForPackage(mainClass.getClass()).node(nodeName); Runtime.getRuntime().addShutdownHook(new Thread(this)); } protected void handleUnloadedToolBar(VLToolBar toolbar) { ToolBarPanel panel = container.getToolBarPanelAt(BorderLayout.NORTH); if(panel != null) panel.add(toolbar, new ToolBarConstraints()); } /** * Load the toolbar configuration. * * @throws IOException * @throws ParserConfigurationException * @throws SAXException */ @SuppressWarnings("rawtypes") public void loadToolBarLayout() throws IOException, ParserConfigurationException, SAXException { byte data[] = prefs.getByteArray(TOOLBAR_LAYOUT, null); if(data != null) { InputStream in = new ByteArrayInputStream(data); ToolBarIOReadInfo tri = io.readXML(in); Collection unloadedToolBars = tri.getNotInstalledToolbars(); in.close(); for(Iterator i = unloadedToolBars.iterator(); i.hasNext();) { VLToolBar toolbar = (VLToolBar) i.next(); handleUnloadedToolBar(toolbar); } } } /** * Save the toolbar configuration. *

Masks all errors. *

don't call this method directly : it is used by the shudown hook. * * @see java.lang.Runnable#run() */ public void run() { try { saveToolBarLayout(); } catch(Exception exception) { // Mask error as we are quitting anyway } } /** * Save the toolbar configuration. * * @throws IOException */ public void saveToolBarLayout() throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); io.writeXML(out); out.close(); prefs.putByteArray(TOOLBAR_LAYOUT, out.toByteArray()); } }vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/VLButtonUI.java000066400000000000000000000034741243334202400310670ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.Color; import java.awt.Graphics; import java.awt.Insets; import javax.swing.AbstractButton; import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.plaf.basic.BasicToggleButtonUI; /** A UI for toolbar buttons : replaces the look and feel default UI to * have a unified toolbar rendering. * * @author Lilian Chamontin, VLSolutions */ public class VLButtonUI extends BasicToggleButtonUI { private Color highlight = UIManager.getColor("VLDocking.highlight"); public VLButtonUI() {} public void paint(Graphics g, JComponent comp) { AbstractButton btn = (AbstractButton) comp; boolean rollover = btn.getModel().isRollover(); boolean selected = btn.getModel().isSelected(); boolean armed = btn.getModel().isArmed(); btn.setBorderPainted(selected || rollover); if(rollover || selected) { if(armed) { g.translate(1, 1); } else { @SuppressWarnings("unused") Insets i = btn.getInsets(); if(! selected) { // avoid too much effects g.setColor(highlight); g.fillRect(1, 1, btn.getWidth() - 2, btn.getHeight() - 2); } } } Border b = comp.getBorder(); if(b instanceof ToolBarButtonBorder) { ((ToolBarButtonBorder) b).setPressed(selected || armed); } super.paint(g, comp); } }vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/VLToolBar.java000066400000000000000000000416541243334202400307220ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import com.vlsolutions.swing.docking.animation.AnimationEvent; import com.vlsolutions.swing.docking.animation.AnimationListener; import com.vlsolutions.swing.docking.animation.ComponentAnimator; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.JToolBar; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.border.Border; /** A JToolbar suitable for drag and drop purposes. *

* To use the toolbar feature, you must follow this pattern : *

    *
  • The toolbars must be contained initially in a ToolBarPanel (which can contain multiple toolbars) *
  • The ToolBarPanel must be contained in a ToolBarContainer (which can contain as much as 4 ToolBarPanels * , one on each border). *
  • The center component of the ToolBarContainer can be the DockingDesktop, or any user component. *
* *


* The VLToolBar contains buttons and other components, and is included in a ToolBarPanel of a ToolBarContainer . *

*

* Loading and saving toolbar configurations is done with the {@link ToolBarIO} utility class. *

* Toolbars can now be collapsed (to gain space on screen). this property is disabled by default to * keep compatibility with previous releases. For a better usage of collapsing it is better to * set a tooltip text on the toolbar (it will be propagated to the gripper, which will be the only * one component visible when collapsed). * * @author Lilian Chamontin, VLSolutions * @update 2006/02/20 Lilian Chamontin : added support for collapsible toolbars * @update 2006/03/16 Lilian Chamontin : added animation effect when collapsing toolbars * @update 2006/12/01 Lilian Chamontin : added protection againt class cast when dragging */ public class VLToolBar extends JPanel { private static final long serialVersionUID = 1L; private ToolBarGripper gripper = new ToolBarGripper(); private boolean rolloverBorderPainted = true; private boolean rolloverContentAreaFilled = false; private boolean useCustomUI = true; private int orientation = SwingConstants.HORIZONTAL; private MouseListener buttonMouseHandler = new MouseAdapter() { public void mouseEntered(MouseEvent e) { AbstractButton btn = (AbstractButton) e.getSource(); if((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0) { if(rolloverBorderPainted) { btn.setBorderPainted(true); } if(rolloverContentAreaFilled) { btn.setContentAreaFilled(true); } } } public void mouseExited(MouseEvent e) { AbstractButton btn = (AbstractButton) e.getSource(); btn.setBorderPainted(false); } }; /** The mouse listener in charge for toolbar drag and drop */ private GripperHandler gripperListener = new GripperHandler(); /** The border used during DnD to show that the toolbar is selected */ private Border draggedBorder = new ToolBarButtonBorder(); private VLToolBarLayout horizontalLayout = new VLToolBarLayout(true, 0); private VLToolBarLayout verticalLayout = new VLToolBarLayout(false, 0); /** Constructs a toolbar with a null name (this toolbar will not be * able to write its structure in a XML encoder, unless you call setName(String) * with a non null name before saving). * ). */ public VLToolBar() { this(null); } /** Constructs a toolbar with the given name. *

* The name is used when reading/writing XML configuration. It must not be null if * you use this feature. */ public VLToolBar(String name) { setName(name); setLayout(horizontalLayout); gripper.addMouseMotionListener(gripperListener); gripper.addMouseListener(gripperListener); gripper.setPreferredSize(new Dimension(4, 20)); //gripper.setMinimumSize(new Dimension(4, 4)); add(gripper); setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); gripper.setToolTipText(name); } /** Adds a new separator to this toolbar */ public void addSeparator() { Dimension size = (Dimension) (UIManager.get("ToolBar.separatorSize")); JToolBar.Separator sep = new JToolBar.Separator(); sep.setOrientation(orientation); if(orientation == SwingConstants.HORIZONTAL) { sep.setOrientation(SwingConstants.VERTICAL); sep.setPreferredSize(size); add(sep); } else { sep.setOrientation(SwingConstants.HORIZONTAL); sep.setPreferredSize(size); add(sep); } } /** Overriden to track AbstractButton added */ public Component add(Component comp) { if(comp instanceof AbstractButton) { return add((AbstractButton) comp); } else { if(! (comp instanceof ToolBarGripper)) { comp.setVisible(! gripper.isCollapsed()); } return super.add(comp); } } /** Adds a new button to this toolbar */ public Component add(AbstractButton button) { if(useCustomUI) { installButtonUI(button); } button.setVisible(! gripper.isCollapsed()); super.add(button); configureButton(button); installMouseHandler(button); return button; } /** Adds a new button to this toolbar */ public Component add(JButton button) { // this method is here to maintain backward compatibility return add((AbstractButton) button); } /** Install custom UI for this button : a light rollover effet and a custom rounded/shaded border. *

* This method can be overriden to replace the provided "look and feel" which uses the follwing configuration : *

    *
  • install a VLButtonUI *
  • set 2 pixels margins *
  • set a ToolBarButtonBorder. *
*/ public void installButtonUI(AbstractButton button) { button.setMargin(new Insets(2, 2, 2, 2)); button.setUI(new VLButtonUI()); button.setBorder(new ToolBarButtonBorder()); } /** Used internally to add a mouse listener to the button. *

* Can be overriden to implement custom event handling. */ public void installMouseHandler(AbstractButton button) { button.addMouseListener(buttonMouseHandler); } /** This method is invoked upon adding a button to the toolbar. It can be * overriden to provide another look or feel. *

* Default settings are : *

  • setRolloverEnabled(true) *
  • setContentAreaFilled(false); *
  • setOpaque(false) *
  • setBorderPainted(false) *
*/ public void configureButton(AbstractButton button) { button.setRolloverEnabled(true); button.setContentAreaFilled(false); button.setOpaque(false); button.setBorderPainted(false); } /** Updates the rolloverBorderPainted property. *

* If true, when one of the toolbar buttons is rolled-over, its border will be shown. *

* DefaultValue is true */ public void setRolloverBorderPainted(boolean painted) { this.rolloverBorderPainted = painted; } /** Returns the state of the rolloverBorderPainted property */ public boolean isRolloverBorderPainter() { return rolloverBorderPainted; } /** Updates the rolloverContentAreaFilled property. *

* If true, when one of the toolbar buttons is rolled-over, its content will be filled. *

* Default value is false to accomodate with VLButtonUI which paints itself the button * interiors. * */ public void setRolloverContentAreaFilled(boolean filled) { this.rolloverContentAreaFilled = filled; } /** Returns the value of the rolloverContentAreaFilled property */ public boolean isRolloverContentAreaFilled() { return rolloverContentAreaFilled; } /** Updates the useCustomUI property. *

* Default value is true. *

* When set to true the installButtonUI() method will be called when a button is added to this * toolbar. */ public void setUseCustomUI(boolean useCustomUI) { this.useCustomUI = useCustomUI; } /** Return the value of the useCustomUI property */ public boolean isUseCustomUI() { return useCustomUI; } /** Changes the border used during drag and drop of the toolbar. *

* For a better user experience, please note to install an empty border of the * same Insets than this one (otherwise, there will be a size change of the toolbar at the beginning * of the drag and after the drop). */ public void setDraggedBorder(Border border) { this.draggedBorder = border; } /** Returns the border used during drag and drop or the toolbar */ public Border getDraggedBorder() { return this.draggedBorder; } private void gripperDragged(MouseEvent e) { // where are we ? @SuppressWarnings("unused") Component gripper = e.getComponent(); ToolBarPanel panel = (ToolBarPanel) this.getParent(); if(! (panel.getParent() instanceof ToolBarContainer)) { //2006/12/01 // this is a safety for users willing to include toolbar panels outside // a toolbar container (in that case, these toolbars aren't draggable). return; } ToolBarContainer container = (ToolBarContainer) panel.getParent(); Point tbPanelPoint = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), panel); if(panel.contains(tbPanelPoint)) { // we're dragging inside the same ToolbarPanel ToolBarPanelLayout layout = (ToolBarPanelLayout) panel.getLayout(); ToolBarConstraints constraints = layout.getInsertionContraintsAt(this, tbPanelPoint); if(constraints != null) { panel.remove(this); panel.add(this, constraints); panel.revalidate(); } } else { // we're outside this toolbar panel, check if we're above another toolbar // or near an empty one Rectangle containerBounds = container.getBounds(); Rectangle invisiblePanelBounds = new Rectangle(containerBounds); ToolBarPanel topPanel = (ToolBarPanel) container.getComponentAt(BorderLayout.NORTH); invisiblePanelBounds.height = 10; if(checkGripperOnOtherPanel(topPanel, e, invisiblePanelBounds)) { return; } invisiblePanelBounds.y = containerBounds.y + containerBounds.height - 10; ToolBarPanel bottomPanel = (ToolBarPanel) container.getComponentAt(BorderLayout.SOUTH); if(checkGripperOnOtherPanel(bottomPanel, e, invisiblePanelBounds)) { return; } invisiblePanelBounds.y = containerBounds.y; invisiblePanelBounds.height = containerBounds.height; invisiblePanelBounds.width = 10; ToolBarPanel leftPanel = (ToolBarPanel) container.getComponentAt(BorderLayout.WEST); if(checkGripperOnOtherPanel(leftPanel, e, invisiblePanelBounds)) { return; } invisiblePanelBounds.x = containerBounds.x + containerBounds.width - 10; ToolBarPanel rightPanel = (ToolBarPanel) container.getComponentAt(BorderLayout.EAST); if(checkGripperOnOtherPanel(rightPanel, e, invisiblePanelBounds)) { return; } } } private boolean checkGripperOnOtherPanel(ToolBarPanel panel, MouseEvent e, Rectangle invisibleBounds) { if(panel != null && panel != getParent()) { if(panel.isVisible()) { Point panelPoint = SwingUtilities.convertPoint(this, e.getPoint(), panel); if(panel.contains(panelPoint)) { gripperDraggedOnOtherVisiblePanel(panel, panelPoint); return true; } } else { // not visible Point containerPoint = SwingUtilities.convertPoint(this, e.getPoint(), panel.getParent()); if(invisibleBounds.contains(containerPoint)) { ToolBarPanel parent = (ToolBarPanel) getParent(); parent.remove(this); panel.add(this, new ToolBarConstraints(0, 0)); // the panel is not visible == empty panel.revalidate(); if(parent.getComponentCount() == 0) { parent.setVisible(false); // last toolbar : hideit } return true; } } } return false; } private void gripperDraggedOnOtherVisiblePanel(ToolBarPanel panel, Point point) { // we're dragging inside another ToolbarPanel ToolBarPanelLayout layout = (ToolBarPanelLayout) panel.getLayout(); ToolBarConstraints constraints = layout.getInsertionContraintsAt(this, point); if(constraints != null) { ToolBarPanel parent = (ToolBarPanel) getParent(); parent.remove(this); panel.add(this, constraints); panel.revalidate(); } } public String toString() { return "VLToolBar " + getName(); } /** Updates the orientation of this toolbar. *

* This method is called directly by the framework on toolbar installation or * during drag and drop. */ public void setOrientation(int orientation) { if(this.orientation != orientation) { this.orientation = orientation; gripper.setOrientation(orientation); Component[] comps = getComponents(); removeAll(); if(orientation == SwingConstants.HORIZONTAL) { gripper.setPreferredSize(new Dimension(4, 20)); setLayout(horizontalLayout); for(int i = 0; i < comps.length; i++) { if(comps[i] instanceof JToolBar.Separator) { JToolBar.Separator sep = (JToolBar.Separator) comps[i]; sep.setOrientation(SwingConstants.VERTICAL); } add(comps[i]); } } else { gripper.setPreferredSize(new Dimension(20, 4)); setLayout(verticalLayout); // gripper.setIcon(vGripIcon); for(int i = 0; i < comps.length; i++) { if(comps[i] instanceof JSeparator) { JSeparator sep = (JSeparator) comps[i]; sep.setOrientation(SwingConstants.HORIZONTAL); } add(comps[i]); } } revalidate(); } } /** Updates the tooltip of the toolbar, and propagates it to the toolbar gripper. */ public void setToolTipText(String tooltip) { super.setToolTipText(tooltip); gripper.setToolTipText(tooltip); } boolean isInAnimationCycle = false; private void gripperClicked(MouseEvent e) { if(isCollapsible() && ! isInAnimationCycle) { setCollapsed(! gripper.isCollapsed()); } } /** Hides the toolbar (just showing the gripper) */ public void setCollapsed(final boolean collapsed) { if(collapsed) { // added a subtle animation effect to give more polish to the collapsing //2006/03/16 Rectangle bounds = getBounds(); Rectangle newBounds; float animSpeed; if(orientation == SwingConstants.HORIZONTAL) { newBounds = new Rectangle(bounds.x, bounds.y, 20, getHeight()); animSpeed = getWidth() / 800f; // pix / sec } else { newBounds = new Rectangle(bounds.x, bounds.y, getWidth(), 20); animSpeed = getHeight() / 800f; // pix / sec } ComponentAnimator canim = new ComponentAnimator(this, bounds, newBounds, animSpeed); canim.addAnimationListener(new AnimationListener() { public void animation(AnimationEvent e) { if(e.getState() == AnimationEvent.ANIMATION_END) { gripperListener.resetBorder(); finishAnimation(collapsed); } } }); gripperListener.installDragBorder(); canim.start(); } else { // no animation when expanding finishAnimation(collapsed); } } private void finishAnimation(boolean collapsed) { gripper.setCollapsed(collapsed); int maxSize = 20; //2.0.6b Component[] comps = getComponents(); for(int i = 0; i < comps.length; i++) { if(! (comps[i] instanceof ToolBarGripper)) { if(orientation == SwingConstants.HORIZONTAL) { maxSize = Math.max(maxSize, comps[i].getHeight()); } else { maxSize = Math.max(maxSize, comps[i].getWidth()); } comps[i].setVisible(! collapsed); } } if(collapsed) { if(orientation == SwingConstants.HORIZONTAL) { gripper.setPreferredSize(new Dimension(6, maxSize)); } else { gripper.setPreferredSize(new Dimension(maxSize, 6)); } } revalidate(); } /** Returns true if this toolbar is currently collapsed */ public boolean isCollapsed() { return gripper.isCollapsed(); } public boolean isCollapsible() { return gripper.isCollapsible(); } public void setCollapsible(boolean collapsible) { gripper.setCollapsible(collapsible); } private class GripperHandler implements MouseListener, MouseMotionListener { Border oldBorder; public void mouseDragged(MouseEvent e) { gripperDragged(e); } public void mouseReleased(MouseEvent mouseEvent) { resetBorder(); } /** puts back the old border (the one when not selected) */ public void resetBorder() { setBorder(oldBorder); } public void installDragBorder() { oldBorder = getBorder(); setBorder(draggedBorder); } public void mousePressed(MouseEvent mouseEvent) { installDragBorder(); } public void mouseMoved(MouseEvent mouseEvent) {} public void mouseExited(MouseEvent mouseEvent) {} public void mouseEntered(MouseEvent mouseEvent) {} public void mouseClicked(MouseEvent mouseEvent) { gripperClicked(mouseEvent); } } }vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/VLToolBarLayout.java000066400000000000000000000135261243334202400321150ustar00rootroot00000000000000/* VLDocking Framework 3.0 Copyright Lilian Chamontin, 2004-2013 www.vldocking.com vldocking@googlegroups.com ------------------------------------------------------------------------ This software is distributed under the LGPL license The fact that you are presently reading this and using this class means that you have had knowledge of the LGPL license and that you accept its terms. You can read the complete license here : http://www.gnu.org/licenses/lgpl.html */ package com.vlsolutions.swing.toolbars; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager2; import java.util.ArrayList; /** The layout for VLToolBar (supports horizontal and vertical orientation). *

* When used in horizontal orientation, this layout respects the preferred width of * the contained components, and forces the height to the maximum of all the preferred heights. * (so components are vertically streched to have the same height). *

* When used in vertical orientation, this layout respects the preferred height of * the contained components, and forces the width to the maximum of all the preferred widths. * (so components are horizontally streched to have the same width). * * @author Lilian Chamontin, VLSolutions * @update 2006/09/09 Support for LTR and RTL component orientation */ @SuppressWarnings({"rawtypes", "unchecked"}) public class VLToolBarLayout implements LayoutManager2 { private ArrayList components = new ArrayList(); private boolean isHorizontal; private int gap; // gap in pixels between components public VLToolBarLayout() { this(true, 0); } /** Constructs a new Layout. * * @param isHorizontal indicates if the layout will be horizontal or vertical. * * */ public VLToolBarLayout(boolean isHorizontal) { this(isHorizontal, 0); } /** Constructs a new Layout. * @param isHorizontal indicates if the layout will be horizontal or vertical. * @param gap gap in pixels between components * */ public VLToolBarLayout(boolean isHorizontal, int gap) { this.isHorizontal = isHorizontal; this.gap = gap; } public float getLayoutAlignmentX(Container target) { return 0.5F; } public float getLayoutAlignmentY(Container target) { return 0.5F; } public void invalidateLayout(Container target) {} public Dimension maximumLayoutSize(Container target) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } public void addLayoutComponent(Component comp, Object constraints) { if(constraints == null) { components.add(comp); } else { Integer i = (Integer) constraints; components.add(i.intValue(), comp); } } public void removeLayoutComponent(Component comp) { components.remove(comp); } public void addLayoutComponent(String name, Component comp) {} public Dimension minimumLayoutSize(Container parent) { synchronized(parent.getTreeLock()) { Dimension dim = new Dimension(0, 0); int visible = 0; for(int i = 0; i < components.size(); i++) { Component comp = (Component) components.get(i); Dimension d = comp.getPreferredSize(); if(comp.isVisible()) { visible++; if(isHorizontal) { dim.width += d.width; dim.height = Math.max(dim.height, d.height); } else { dim.width = Math.max(dim.width, d.width); dim.height += d.height; } } } // add the gap between components if(isHorizontal) { dim.width += (visible - 1) * gap; } else { dim.height += (visible - 1) * gap; } Insets insets = parent.getInsets(); dim.width += insets.left + insets.right; dim.height += insets.top + insets.bottom; return dim; } } public Dimension preferredLayoutSize(Container parent) { return minimumLayoutSize(parent); } /** overridden to adjust position (x(top) = width(left), y(left) = height(top) */ public void layoutContainer(Container target) { synchronized(target.getTreeLock()) { Dimension toolbarDim = preferredLayoutSize(target); Insets insets = target.getInsets(); if(isHorizontal) { int left = insets.left; /*for (int i = 0; i < components.size(); i++) { Component comp = (Component) components.get(i); if (comp.isVisible()){ Dimension d = comp.getPreferredSize(); comp.setBounds(left, insets.top, d.width, toolbarDim.height - insets.top - insets.bottom); left += d.width + gap; } }*/ if(target.getComponentOrientation().isLeftToRight()) { for(int i = 0; i < components.size(); i++) { left = layoutHorizComponent((Component) components.get(i), toolbarDim, insets, left); } } else { // Right to left Component firstComp = components.size() == 0 ? null : (Component) components.get(0); int endWith = 0; if(firstComp != null && firstComp instanceof ToolBarGripper) { left = layoutHorizComponent(firstComp, toolbarDim, insets, left); endWith = 1; } for(int i = components.size() - 1; i >= endWith; i--) { left = layoutHorizComponent((Component) components.get(i), toolbarDim, insets, left); } } } else { //vertical @SuppressWarnings("unused") int centerX = insets.left + (toolbarDim.width - insets.left - insets.right) / 2; int top = insets.top; for(int i = 0; i < components.size(); i++) { Component comp = (Component) components.get(i); if(comp.isVisible()) { Dimension d = comp.getPreferredSize(); comp.setBounds(insets.left, top, toolbarDim.width - insets.left - insets.right, d.height); top += d.height + gap; } } } } } /* 2006/09/09 */ private int layoutHorizComponent(Component comp, Dimension toolbarDim, Insets insets, int left) { if(comp.isVisible()) { Dimension d = comp.getPreferredSize(); comp.setBounds(left, insets.top, d.width, toolbarDim.height - insets.top - insets.bottom); left += d.width + gap; } return left; } } vldocking-vldocking-3.0.5/src/main/java/com/vlsolutions/swing/toolbars/package.html000066400000000000000000000020761243334202400305270ustar00rootroot00000000000000 The draggable toolbars of VLDocking.

The VLToolBars.

This packages contains an independant set of components allowing multiple draggable toolbars to be positionned around a central component.

Getting Started

Getting started is easy :

  • create a ToolBarContainer (a specialized JPanel with a BorderLayout) using the static factory method ToolBarContainer.createDefaultContainer(...) specifying the borders that will contain your toolbars.
  • add you component at the center : container.add(myComp, BorderLayout.CENTER)
  • get a reference to a ToolBarPanel from the ToolBarContainer : container.getToolBarPanelAt(BorderLayout.NORTH)
  • add one or more VLToolBars to it, using the ToolBarConstraints to specify their relative order.
  • enjoy the results !


An overview of the components used.

vldocking-vldocking-3.0.5/src/main/resources/000077500000000000000000000000001243334202400211775ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/resources/com/000077500000000000000000000000001243334202400217555ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/000077500000000000000000000000001243334202400243565ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/000077500000000000000000000000001243334202400255055ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/000077500000000000000000000000001243334202400271235ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/attach16v2.png000066400000000000000000000004751243334202400315220ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  +)IDATxc`hTOɓ5"Y` }5_IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/attach16v2rollover.png000066400000000000000000000005161243334202400333030ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  TIDATxڝS+0}pj[[Q#~/ܢATW t!Ulg7IR#7{ ?qts+$treyA՘C4*Z/!Q݊H&Rx}OS?uN †144'}0BTI^B94MBB?L|!M"74l/Uk:BIENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/close16.gif000066400000000000000000000015201243334202400310640ustar00rootroot00000000000000GIF89a!,-H*\(0@A !q"Æ-RD(qÏCI`@;vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/close16pressed.gif000066400000000000000000000015441243334202400324600ustar00rootroot00000000000000GIF89a!,AH*TxpC .(1!Ŋ(hq#C =~ $ȉ&3 "˓0/V)ѠM;vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/close16rollover.gif000066400000000000000000000015441243334202400326570ustar00rootroot00000000000000GIF89a!,AH*TxpC .(1aDbQcƍ3:8#H'A,R$ĕIƄ)ѠM;vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/close16tab.png000066400000000000000000000004261243334202400315760ustar00rootroot00000000000000PNG  IHDR w&bKGD pHYs  tIME  WIDATxڝ; 0DEnj9EJct- a}-t wB GFɫvfwVD97Qjc,KSD1a'| U>%' c\x @aպo5&Q n !M)qa>(uD1~.GIT~snN_P^IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/close16tabPressed.png000066400000000000000000000004161243334202400331230ustar00rootroot00000000000000PNG  IHDR w&bKGD pHYs  tIME  IDATx} 0 D6#dַV)ـ)b*ϱJʛ3Jɫ{@#h擷P̜fζAGgLȱS .yWZO83gp9Rsu1>#9Y9f\΅IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/close16tabRollover.png000066400000000000000000000003621243334202400333220ustar00rootroot00000000000000PNG  IHDR w&bKGD pHYs  tIME  '[IDATxڝ "M iQJJ0DL^ΰ6<S%`.`.SQUsqќ݀I]:hVGӻ0l6v!+wZȢu7i=~54BjVj&Y{v|C133ػ6E,{}"ÓCPm0"PIENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/close16v2pressed.png000066400000000000000000000004271243334202400327460ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  CKnIDATxS sNߎV^#=ND%(81c/,bY`*k+'́p*=U-matj(j.VFH!YԛȵVLf)H)S04HZM}?z4Ƭg6O!jZm]PwQIENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/close16v2rollover.png000066400000000000000000000004161243334202400331430ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  IDATxS ͸]---ZR\ydH^я -ZPd/Ĵ. L}9(D!@9-ZTuѺԜ3ۗ5B$t|ء@$[/n3XY7R%aak V IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/close8.png000066400000000000000000000003411243334202400310240ustar00rootroot00000000000000PNG  IHDRbKGD pHYs  tIME snIDATxڅ 0 /LAY!k9-#R2-]F0+ҽgctT)A.P iJx/,K[Ulj[S+m'lYQϑp04F,QIENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/closeAll16.png000066400000000000000000000003261243334202400315370ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME"7?tEXtCommentCopyright VLSolutions dD:IDATxc`Tc``"U M.\ff&Z^J 25^&IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/closeAllOther16.png000066400000000000000000000003121243334202400325340ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME6g!.tEXtCommentCopyright VLSolutions dD.IDATxc`4HlkszN{OzQ{L|MtkǝÞġʜf©ȧģƨŤǺfʯd̫ͯȳӴʹμӾչ]]ԾϺѽ׻ZҽڿXPN)JMGxxtRNS@fbKGDH pHYs  tIME  $iIDATxڅ0 IRh>y~>89dڹ$" |-gÂ&̐!xI5l_ YrPhL0WvN%] ۋVa8gpWten`Eyg0/GZMPwa-y pS8I:?wx]= !"IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/doc-files/000077500000000000000000000000001243334202400307705ustar00rootroot00000000000000attach16v2rollover.png000066400000000000000000000005161243334202400350710ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/doc-filesPNG  IHDRabKGD pHYs  tIME  TIDATxڝS+0}pj[[Q#~/ܢATW t!Ulg7IR#7{ ?qts+$treyA՘C4*Z/!Q݊H&Rx}OS?uN †144'}0BTI^B94MBB?L|!M"74l/Uk:BIENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/doc-files/close16.gif000066400000000000000000000015201243334202400327310ustar00rootroot00000000000000GIF89a!,-H*\(0@A !q"Æ-RD(qÏCI`@;close16v2rollover.png000066400000000000000000000004161243334202400347310ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/doc-filesPNG  IHDRabKGD pHYs  tIME  IDATxS ͸]---ZR\ydH^я -ZPd/Ĵ. L}9(D!@9-ZTuѺԜ3ۗ5B$t|ء@$[/n3XY7R%aak V IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/doc-files/dock16.gif000066400000000000000000000015231243334202400325470ustar00rootroot00000000000000GIF89a!,0H*\H0C  -b<Ç 7Vd8ɓ$;dock16v2rollover.png000066400000000000000000000003651243334202400345470ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/doc-filesPNG  IHDRabKGD pHYs  tIME  ,IWMIDATxc@!lN8U NN C?00J,-B 2  XM\4ۇmCj[O\_,s>F.% +PIENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/doc-files/docking.gif000066400000000000000000001127431243334202400331050ustar00rootroot00000000000000GIF89a,QH:D]b^X8pfkcckmJkkkU7skkssk{sksss{{o{{{{k-HR%T1R1kL\Pqsx{{=cOpcs`s+RZmsZk{xxdx{ʵƹενƽ!)59BBBBJJJJJRRRRZZ`hckJRZbXf%iC] s{{y.wF~hb{{ℜy|ߎڭνֽ޽5GN%a.cFoRd{ޥ11J֜Ƶʜ縷軐ƽƥƵֽ樂便Ωƽνννu眽޽ڵ,,teKc*%aC#BD/jǍ;)rɇ'\Ĕ/Yt L4ot'I% I4hQ-^ 0b֯`ÊKٳhӪ]˶۷pʝKݻeÈw/-`(1C!'R(ǐ#KL˘3k̹ϠCMӨ)KY'Ib)"a"NVC^͛o)N|qȋ'?9ˣ;8±k}O~ϫO~wcq䘑bsG\xrI%P#!/7`oO@ѡP($X&',(c4h#:> BIF& dkL6PF)TViVFlee|}`RF8r!R!,`E ?-DtL5RWT؆g|a^|vqGhK!B!®F@``  PƵ]OxCP!Ee1mE;fСpDX́?LX;mcDN:.|+|7<+=}s/oF`6cmơ6r.n0Lj SⴠC z0)L ‚<:P(J@?`@:iH@)ģx p|al88` w4 }lB 6q 8E)HVE*bQ`" E(dL4q`t(2l F;q HA<"A}_[02~dD9 !K J`|"PTa}C6:(n ?& PATX$vG~9*t`_zG [$?@* '~ @JЂM(@iOӡ$JQV(F7Pv}f3, jB> pQOB)0 a ԁJ0ʣ V`m( }FQX L0L*c#ղV Hq>ǵX!L5 p2,@*|f؁E@*Vkֲ.ֱI,cFֱ,d3[VbճVh7KZ͚Ei?Z֮6k!Kͭnwb ^(>51A jB9[ B*C 1!'{ X OL W{, WT O0PJ@ U0~x }/n}oSb1_x7>1sbW>{ "SjOǯt =kTkҵ^ekG v'<8\A6"tKAj D@-Ta +/R`r#u莬˭vlmy;v7ٝos8-pc,˺;~'.33{<Ϭ];rfV%O9)r-9_.3L77g@0] ]@g!6I(GRc]6Wu[c:k]dٿwsn{~</Mw;񐏼'O;]폏z!A8! p/G魑һP=Yշ}g{={~q{+_~w ~}c~w/?ׯˏ{^'' %\pW Xz@{zh `H{(8{{ȁ }8؁'#,.&3()87X ȃ6;(4=hA zEX+HI؄gNFSzUX{GXPhz[ȄITȁL/( X^?4p|Vz|#{zs|{ph{G|Ȃ}7|~x{RzȇPW {U({M(H耧XzȊ`h (*U ( 耻(8z|X芆Ḣzx%H { p8ᨎ0{؎:XXzb(+(SxiFhvz{Ȁx'9yzINXݗ{}}W7|}(~*,i{~#n˨ @y p .`4@(KI +WѨp%G~g(!|g{(\guw|hY8x98ȗz _i Y(GsGAɕv{ z ])^p ^I8Jǐ y'h"89}GIםy蝲ti\XCxgG|Ig icْbYؓ .ЛLJDɕK؎zLɠ/IkIcq}(o{9iqXk{{%x)y >ژ;Ș4wɣ99Jژө#/ȐNLH|QZ#z_/:iҸۘh Y[٠H~)Չ3~Xy بzȅ)ȈȤΗטN8lz|Ǚ~Wjɘco(8Z{ziIٷY($ʫج'vZෞʖYؑI}#I]+IʏIdJ J*jy'ʦIi'(GIJ9i[};}ٙTʨz۹y#wUJ ( kٸ|E؞ZEJ%j誈*zٯ7FГp Z+ ` [; _Y]{ @^k]+`۶\ t۶a a뵳 d`z zc}+k vn{[˸KrKyKPn[ihKd۹n +[bs˶+x\{x˹[| ;˻c+Yk;˵k+oJ;[{ۿ * ٺR#@Kx9 ۋC[ }!tزڇ.9؋W*%K$|.,j<ʫZ״:ZX>x2Ǿ Ҁ :ėY @Xtlʦ+2{ʤةٗ&zX<[֊dliWʳNL޲X7׍ؤ6ZZlBEvmܷuwo࿅'>vTȕ'gyR@EҺmJwŏ'_{5jִ:p̟Ξ=ÆSv,mg@yG}LQᔶf#pB +B 3P -C-Т .H.H  E2b$g,Fs,Ì2 3R d 6`cI&hI7x 9+R:K;>ȼ46#8Yf9YlFo?GxǞ|NYWH58s3@i4[чqjIyx 6vR45x=RFU:-U ^XoGԏ2 X  ",k_C|t5MqiO}JZ<ִ`,^ pDYD#aM5aQlVІ'ѭn[6^h#Ǭ5 \Muᯂeb Ў#@ #m{ ZD&1n&AȞe;2[dtw}A(<QAxW I qtҍ%|cBeLoƑ7Gա=D'RX֢ Sލ5IAJP=MR>}IL33>ipІ&>ɕ_=WjPR #F hAbmB!;bԈ}SQ*Tm#ĕa@#5׫>qmܠU1Ech@ ~e$ kxC48 g#ЬƎ @Cf6*b6KBLf3'E`>2pH'XDIRi}7N׈_7ѩ+Z aDȐcޏzՎy5dMkȪ=yoK0d4<#'U/ث<ѴAEKq54@ `2X&ߡn$"ZYf>܊&Y(Wn{Р X cB]i LCڭhT:r `gI;! C$#٠ YVYь ?ӢZچMJ?Xjv#TEp(N@Ё` 8ۆҵ?91 ! ,ZMM"f:Ǩ~BLd}~!7:/`(xCp0 aŋlCRXc.aQdFY&.e(s&'î0Ӟ̍2- 0/p+Z1R6b1]tzR%* ֖£цt͏pU+[dHÕ[.4>`vmsof/6 Gۛ|Rc%4!_uR{db;c[y3Kz )m{nkr:I%iDɕ),y24XzcZ ̹&z2?j:?* rY3W7Sq3pp(zp0hSkB &k(B㸨KУ Iܡ|~9q;@@ Q2*6Lba^3'3;"[ix_?Xm[-ЍW)u NťLLB-[kRu\ɽQ֫Mԏy9W`Nu4\ޜݝa؝!s!uZbB\YP}Y]mU$^r\y==\\vԎX*~`H}Sdp8?[h>RecR͜<[M1d1lWGΎuC\3.&.(1[H )\p ʭ[NY,*Gj!xzBY ]`T9-.#]]VcM=V]MU>5~ PXA`mS%mc3.\^y3Jug_^zncWeG/UueܮB.(Υ83guI+U6Ssa7v` Q\er = =J'|!aTuU fi`^e3sc=bە]a#V]៍U]ZkW2VqXSO^4@6_z2yr6`ek&}׹ĵZpSeTUl.`~2_ drp'yRDE9@(RFiSlM g/XҍZ'^9Yam"Y -Nb=^aN&~fEe\nuN͍T6+~CFfFEj]XwETЦnǍב&Alh8g@?ޱh3`-ͮUiF`J o@`QN—]^\cj"եn#F> Mq}dT~nTS-jUq O8ڼ+MhfrW qnU($l.ViԵ SWpo6+6^<׶Tfedƚ8THT@tA7AD'DWtB'T0GGJtKFS8C/JHt%)N(VWi+^ul}bm- X,ViEd%'i V P =N][ ۆ.Bf/aC`` v!R`OBYD&. .l V^tuu_PKgwyKwwIowv_txGY@iX= x؃X'x؆/xxwo؄xxxgx7yyfHqVM ntu̮Y^vNОFmWXY~HzzzzzzjZivz{{/{?{LJnP8QxZ%\W%R1纽Z⊅uQk%ύj6=tMPw}@8~qـiV!le!l)  -ؘvږҼhi$n) "&eX#} Xs8i y(**>}qGwܡ |}}VJ)J'ҧ iqI)YDDlm3tSE H@BKuݢ:y3{T{̍b ~ګjvi@.HZxbG L A'E"h p-guYUlpV UXlL2A@BI uDQIPwBˎG":=NC>cn0 @ .Ϭ_Λfe+sr8‚#(hP]"`eNUMV&FqZ98_@uuዯV_}# ڭ58+䘻 N/l|#:0;A)@ whUnTQl^TC7A j81y+j^5 .|hjC1%~SL/SJjEtdpA(wAq\謁9P:ˬ88Qr #H VsPm|00E¬m`-$XBEm,:$㶷ŭ, IZ1DqHuO-AM7t,=VjϔZV2o2 da0V6,~" x0QOk3Ih A9&`B V y,;e>d"Bm]p@T(#71Cږz$o~C)'U &Ԋ@cMe%d>DA"2SX L d>ٝ>jbprT@̇ = zkWêCá8h!KR~>̓J1$ʲ4NTUI0ŸלJ5QɺNb!*M3}ȫԩ!C9L@ħTc;Nj@ՁU{[| \RZMkW"oQ8T fY.`M\+fY r7 d42 hށl~GGV`} ?|U#e>a*Q-mZߑ|R P<]3rX@6΃ox:{c!@.2d#/9N.{!\C( ;֑ucc.lf5g^6ùt)o,^󱏽#C\.?"ו=@mZ8!^ J4}C ͂K 6+:@&P&JR"! |˭E3jtCU#Ȫ=x\ ;_õ65[Rq)5'ei,8Ytq@$…ފ"02j釿~ԣ1|'?_uq>QO"xPNNe pOۀ" _!U 02/"Cb69X7Ƅ1̌􌍻MUb3a{a* jVGܞ(,UCQ#Swo';K0`rtcX>QR0y*M4erXܬAt@5f[>Q@B=ŨcOTթA./ i؇>&%d?oB?U?igƧ=dhO=xh^AyD[xH 5 M!Ez|Z=InxK*e1_>Z[E ^ \4XJaND>8:YM^ppqOiȂR@] e ZC߹3z[!y̟ WJdK$L$MLePC/VzducBBe\0ÂdԜ%RX@bu&r#V#M#N#祢]y-Z[A[>+`R [09歁ϳIZ}O :&1=ec.fƴuݡUY…V:@3R 0}*f#b#bp^0f,*&+'`0eV` s[mO ӳmi x^s^O#v'wƢy}tN'x>q΢|>K`e7tC2d(_m A僟VXRm}R pu.JiB:siDjy(#/]2aG)[VR50АH @>ia*5k[%>u@[T@}^@!.ekt":R[9?Tdޒ꓂!Znԥ,⥶%2kgP`^(2,,a>i:K_(hJ%Tj%\h]Y/US.DNbG4SFg^Ԭlae#ED> s%6&](az!Q<`tF ^,2yFԵ2!aXfE%e`""fO+FT+Egt:@0$lx5:eZ+^nf..i.bv.~螮..:QQvVKHX qrk*-ha">!*4ѱmۖT3lcaX :oڄ>3:Ě"f"of!ӾrҽcέFgQޞB9T+" 1V+.)6l{.ovfʾoed2 cFnZ/H="8^ +ƟveXR}ӮaC kJ$@8`B 11]1&*d2"ڪo1w1*qI1C g.3N0yd11q1. w!;!7@#q"O2>@%[2́1( I'B&8z,,2-rik =@52 0k2pQ&Sr0�"_2#r0;@2'g3}2ܥ &ﲇ#0@'3\3;1qUʮ-Coזc_--@4D5":rV%r)\;;3' pٱ9{('] /7@}0_.G]9@'c4ICr0k4]#@Hʵ5{2NZmd91 ND≞$Ndƀ4uy1S;5TOTWuT_T 0[a ;2zr̅ts4^])44M&171:{2Bk!Iq`&_3B';76*qPTr=1>0p$7@6hϲp52#Yaa5M`7@b8_j`/b2b^6.vN+^FNqj5FN~daw⌆ljxww/L a&w8p{|{;p}ww|7p{w}7}7;07GO8W81eb2$I6LT$seIW$TIeؔcYOiMxwV _hdUr7BwZ,5IR lHExTG4uGMLE@DoXd&s_6 _\pB@99㹛ǹRncO_ ya׆CO؋Dr3Ks+ޭ"{)*1fwOD4z-:خ@zr8=FH+0C7(C2xCrZw;;;;{sO)+;;f&d/?3&& 2ldl7?{)s)[Qw+]l+L^ku1` ljujm@'p&}c&l&>'>?G~O>SW>_[>g~>ȓrO|*y}mD՗%v^*'oby][CG{lpZ4 ``Rm7D 7R H ۽ч#}<< ^bJ9L,!-~o{.j]#r8'AG?|wӇ$8N,="aI< ش)eK6 0&J,ˢD*5ڔMI2*եGVU*جXlX8 @'Ydh\Ǐ^'b` 6|qbŋ DE֬=#IƣGD:">?wsG#GŢ- Xֹ'|Rqw 'Cq^](v׫s߮:ཇ'/xG-. r2.2Yg?‘69f=И8a/١L8 @}DE p".aN9[+zGqH :$qR$:I'jCd#>2<1$K2!0[y 4pz'rp LOo&}dF*I69Rn.}iSSBMRQ,UOSuUQ[r 5ܣC/2X@ Bt G<41Z5k e+?b̐ xx@z|ݗ~({'~gL+N_bҌl.ˬ"ef%eăh  (eHN&V(eH rfZOVȡTfyh hȥ+sN<꬯֚뭯j6{lzZ+чa]gů;am3VHaX`diHr* iG8!̃r'tn=tTƏ?+7mQ|YXQK̿r?̋[8KVaSpi^({:!u h޾|02ߞѿu ]E$?ކ4DbSb&uA&R ,Zw(nuMGVf]~|^zBb.8Ƹ Lbxm8B2ސ17>[X aGFHþY[)1[ 6X20.Fir˹FOyG? YHCrX]>Ѱ#boaq!Y _1hI21Hx䏄$jZ` Ze,i9K[e.yK_f0Kt+`P;t^fpzΆ6?$V"Юh Tg:ٹNwD=;<9x5| ) @AdV =y'q vCOYWZT(-2эvGIҒԤ)EJOR/F;1*^h Y,N!YB>lne">QC%*Rt9e Zp^XZְh5kZٺVm[ZWupE:yuiOsd. ^ i%բ2~4D}~~kVӮvzwޯ\\z-ֺzd$k};ZtԸ2w"FD*A+(5߸qok,Uz`W?>;8ws^}")?uIo6[}Y9˖.7cnQ|4wR{7*A{i;m\C^n&F%rLA;|'yA|9y[ bP eZײ\l/[X}޴{˪ѵ! ]xG%t>hN'"A}3??~󗟈q*5Q"лG9c ӊb%~\ͬJ/j/ pPw O(x(8I A0AJMWPY0OW0[PkmPqa326Bnލ+ z>K ;n n jfdMkƨA??adA+4QފĎ7Q&t?.:tL1qWV1/L3E@(Anq9AbNFFFIGUQg4 `G 5HHH:;3A@K1L2LDҤ@5$6I$0Mw.I`\1'OI- 2bP R R2QРQk\Fw]{HTHSuI4:AF>!>Nu>3TK" #l ^*hab4xl6j@Km*069&V3T8Jj0V-c`fdh֜iZ+dh*PрB!,!\F UjeQuT |tRH/^sISsw@a3K0ВbL plȲMbj̬,&hApclq ̋r f켨n̕mvȖ,0׼rSLh dLښ l .`gsm2[hyUFVI aI@ Qvk5S^e|o;<UaaU[U066%qѤ>M(o-@jrCpwox!mof@hL`Y1x Bf'roV@ \! j\5R{^t:@T;e@<<4`}rTfU0isKXѢm vǀlfxvlƪWRL mq]e wtSƠmsl"mXf ܤw Ei8@O x6Fwj˵`HIQWH{V|`:ϗζ<ն_V>ssnKtDL2EY R.͖ٖHjp9E i+Cǹ&8'ˈ r8`Pyiϵ j ]Q@R)uHw^5ysDu<_TUKM~MӖ,ndaWG^B|nAQvnA,_arf80/ 2\VFwyQ@Uy=;lS=Km?`a 8m Pk Z.K,+ Ѯ$/TX{:7?:;6_T8UY05Ynv @ oFVjjx,luS^:LS o@0ޭ5W0tz*0L-k:k O^ȠT?遞n |e 7\{ \e`d |n`o-\n u@v}C|^d;`O@#H eqߖ,M-2?ֳ,siux s\L*[E#QpazOOEj+3D5N 96|)<\cb9=c+h!' 2YrCo9&]#6̼x"o=!%V&=m oLqM&ї\Ʉo]/0Jg5#_!\!؝./Β]P~ 6rˏ˅e,>NaM4.e-M !ѐ!N) e}k_+8gq=O)3N!z`z{*3+9;5/KC>O^W^=Xܜ"=ڝ#р(axD@x >-ߕl"=sص1Ы~1yנv;#APؾ3~>$3? ?W7y}6xuaQXt-/uq=%Kv}Vp/ثX9 \M1;M@ LtkxO5ghԯjp+Mzݹ[sO>ZPpvW)Ƶpg aFPBX!euYV e.ƚ)cRxj&jY^;>neWow\>XKĄsO:)C Uw . UZ jEUw=erVV}UPe o Ua#tG`j jbH(a*jhqh::t֙A]((' (Cn6@Jk!%rG@4;3obQF ـ5Z{QUyNY XfBpf5 ȹb_Ge\I\x:ڊP *oj"b"zkj"(d-z$NT$rI}*@Zixf1uURQAWQL} Ђ.@nZZKÃW 拷۷ $x7-Xߴ=߇Է+xvN~:/>o@|ƞN @rA|_ pa@|b q=2Qؑ?o=JT\LQUXSgMYMmTNVJ >DQuMSILja. h :LtW_*g r4 f Kb0)=<CVvY =w7!`OxhY>$b#78HA0vRѐ.3f,4n!81d4#H;jpJ9n)ݘ6*n O%Ԩj0r WšJb; ;FPshd1~ܥK>2`3ɔrZWҘrpן0fv1`հL5E[ҚPNM%%X{0N gsc*&z*r`W:jPz`jSFfŝe:5l-m - H8("v s]|Wז쉌}ï3>èYS7s ;FS1?^rJ֍8)"Y0_s8_,) ̡*f5 ˨zɞnÛ}38V HHEs :uZ)qSu8WW&7'xҝ[^4S_z50%]5r-]e7j24?5RC[}Qsc_u@;H:,k:ay{|:Lү0|Myһ^W}Oa^`۹^E+n0#]~{/I: oh~Ń|i[V90:zP|N\f.7%cs tbUq%{wܷ ɐ  3M&~ E+\EW9#*8+ 0:v>Oa6awcsolg/ auXwlfsD|4o0{t83TXu֖u?,=6 &, #~&8|,-"~j0x肇x`_/&f|XtX|7'^oWpoWf7QzbJ7XrPt%x@_fHm"h9h4*h*( ('8(-(}؇  h=%va39/0%P~إ/X0QXҎp13b1яK 0"F t%P} 1pѶhX>V>eNf8ਇ&~Ȃ(量(7~vh .y7Bjs1 B#938 c9/39y#8 S9:X98I!9r9(/7R7e:#9:d9:cLi2/4/_H%|qȑVT4+$_K5=#ɍIjՆ3WKd9@BB ym9y)9@!T9 A8x{`z9YBC8ySK d.$BAw~}EheYʑ19~}H@I947@DK78Q82`)K !KdA JC8w! J i8I TId8٠ x9TxI+]g Sw7@*DzyGjJzLjH`PNQMJ\41!#ij  sJujvJ @uyztsz ʧPʧ꧄s{ʨ : {: wP<J av4j=h2b;>Ӟr٧ ܠ  }Z ʬ/ 1ڬ 0ڬ @01ڇ1 0 X҃ S+=گj k:%`m=S<8E"&s-HXBi+9qf4 ܐ t ~ ؐ ͐ ͠ > ?K@ D;F? дB[AkQKO`ɐɰ^ ɠT C˵KQ {z҃pS1t;r+t#Xs۷C ˀd>੪+_*>XѸB1Lrh;8#5hhhY P EX+S[؅[K>{~ol+Ӌ { KB>Y+!='㨂{}{?B7)& X{ Z۴R۴00봸[, l<~ ̴[Ȁ,"{м3*+3.* 3l47LO}0 A@qx!Z+ZZ(}Ƙ:`*+9= $= 7pP Lhuwl9 |zǀ rLȋ|~}[$+y[^5jp"+4iI+M_ܐɝp ڹLl׌Ҍi|` Lڬl{PS# ,wp JT*W߄>6艹c5h+{py}0|'}!=$'}"]/%{` ?C-EMGAK$ Cx}V$TI%F%^ _-aMcme],sQ ðzOp Pwmy{}~-؅=؇P k n*2RٌMَٙ]p pm ;qسV}EcKh}ֵM%,%Wc* ;< =ƍͭ }ϝ}M-ؽM-Mm='ڬmXc;T7!xӡm㎻Gs᰺HZKB>[z.>ޤ蕞*.7颮n뫾뽎댾SZ MjN+}Nn4JBI%H3\K2h>1G~` _}Ḏ̾.=)N9@LXĻl>> H-!/#O%o')+?#'^b.ʂАV; eo^>gH=o_JKPOVRU/\Xa_S[0X=r"SW?GUuw4un.K^䏿?%O7:䓨/0[c45Oa}cC}o=6`\d\mA>??J `~@Ro\^e?9*kگaN8iNZ9 ;ذ@/NN"A'(i)pbhc&/6Ps4 ZY+J/q&K]QigO ChQ!>4q͜tY>>/a$p M06.[jy[үE+OAoG赲 4u L!>+l;UЂd8t̜W vREf)h'`g-yhRas67 !^t|z&t5bh<}Oz;TVOV#ש_\yuw/4$GG3lhzs}fK.ڊbnֽeV[K@8包ȳ|L?/5f A(FRkQ]([eZ.A/Aܤz-=%.|㚂ȁRh;"qSFDSI5ԝPTS !BO\#{$i*˓ߔcQҝc"qS ;GM"Ǚ1$-.=Tb,R=f5nֳ,@Yv-fEԢumkIKZʶ)Y[tS3^A~G"٬'ASu[/V- D>0`+׼ /zջ0|{׾/x֕ꖷ=L<7x.Kl&WQ4l2Sz =.E\A=%F;G,bVR9=Ohf2LMSK( eg\۹ 8aKnYOH1DP9 b.K|ob΋t^;O*xWDezʚG0 y X4!#. a"ov4 M#+ȉe8@?B}O[c(fTZHfSd4hׂ!xϼl!Ђ^` i h@ijN!hGJ?F >DMr+wX;sM|i-df<7‘!!\J7/"[16+qf@B+)qn8`U4sכv+Ulsw3I+NAgeeqTf ]#~ lHw^bdUF;|}h;@yw=x;wG<w|x "7u8N#C ,󙩚aT5<Ùţ%u< N^#:HRɞ}րh X3jg $b <uf2l5y7n6sߒ#趒hgs߮?3C:K2Jiz;&K='^*r4DTda;1Ԩ : ,.lB5%ӗ+J$a>&2)[0012$34C3|8x) nJ3YBREÜV4TdW\EWIld)=X ij$ePL؋ھS.?~ɰR\d˵\˴i[p˺˵$ 5!Z4+bɿ>5)˜:DGlFZ+9)(2FB2 k[% R١md3ux}twHxZuHHH8uTCc#hi[4c;2kdSۙC@1`3pJd3p(02!<'Ky\'Mшte]P]ug[g#]MkXTktXQXWskpމW#c4iô6A2 L d55):Q#OqЂ5_t_HM "a"!.xxbhz$ s1L"" H0gTЗ_dԚ8i>XxA;<=> (ADTZ@F~dGndFvS k*3f tN@IRP#'pZ(Qv!;XF:~4D^_`abYMff]i<XM"zFK^|LȬzw2X-RyNԪz-ΚcEZE&[LfFh^h ]Cdh j x h`krn(¢F Hʔ0,C>aN.i!3j:C5X@Jj6"Vej.jj˹fb*F܏"o'+Dt2j;!ڪ ܥzŹ#k@'XEEJ~ɌlǾ3^0;1NllĖeY "@B9FL64!cJ.x~k=!ԗ^*ီFy$vn> ^UEnWU+AY]OƜJ ^[1%ʙjȮ  ԩj.:_ ONX.p , S['7Gq:i?m }aծ1nR)ΪjinV^LS*硻jК8kl.ncctBKa,gDRω.+78V]7W{X7s9_:w:s?)I0`XCOtE?t8D_tDwtIJgtC_tXtHWFotHKtPS/uJHKuRwxȇ<.u]/]^]'0b?vc'v])pFFSSiSlvjvnTXdj_dD4wFwؓIuNmvwxo;ss||HL8w|x~Osu7UI4ixxxxx'yMyxyRmN}}z/O/ׇ^?w?x?s>O7'\BvZVl'mkHٵ!ɈD܃{gr1S@xwuLLuLxLwhG|sgpu'}7WOM|P߇~P~~޷}ܟ|[p|W>'{>7uh+U937>k6bE@ #x,FkA~!|g<w Zt3.4p&i)p^߿}8zOƑGI*7ɏKI~1gN+I3WDZJ |y ց^q֫kK4h[]A| TZ⼋gYXQdi^5ժ}~a9Uq|gV-o9ӜQFM:maj4fij6=8]ٴV-zt~˄iAu2۾4[N0ކ%;|U2#;So~Ɣ8'RFB`'X '2H J*a>h6U]`fY>bh9ԈO,ࢋ, ePa|}GwH2]6dw\g: b|ҙtVjazyt4a&ܙe& v)ny'|s >1xew%NIוe re"dDTPQL*S/arM:*:Ϋkܺ뭭 5p"r!ZqWh  8P; -h D6ؔڱKTx:LeWo]tmskV0k t[lN 0l?p"q֜raW2^,],ܘaү4[r5#8BXL$R;>NSC-uVSY?_[ȸ#!GW&pƕԊa6XN | c:4ݵ ə-//:,:'/y5߾ n5Ŧ}TBLCLmڪlзt0n@71V`:̅.+oeZBSoR9HeU* 2S0Xl oDcqB1XD)`=a:ۏV.1F#YJo\T̊ʁ2-laR"8X#\%+[WFc'84lQ/ r:ԱyR3eO}t)&e2twRĺILB!&i7Fd7Y}rV4z*!F:E ,.), @!k@Q@50dᨵ4X @ICk餁,5aE+ Lӟ4@PJTW-lQ:5ШEyjժbժe6RlaI!LCd:rH~%K|nťUh,  `$c=A3yA>O4&Vh> QQc-X#ѳFhztRPE2jKխ^XlipyF]:QuXؽnvknuCWŽOzU/ uSO2S[ݲ{'󦓽3kM6Mi"2&7*=[ ģJTg-Y֏/D#&!% nB#(Gm-puܠ[5z[|FA`=dL82=-+a4$r1Zd3Ye5fe 뛚,m jȰ`bŎ8!drf2izć>X[1땪? N d_ _n:ժ^5Um|ղ;fU2iC?x?5_L:l_1V~C8]k6,pIge~l>XǠRZ:풘H8"Y% ׉e/<6qx]2\\&('Ʃ&+9&Z@)_[<0N>\:[>T/o[McՏ8#D o#?򋯈[`t>{ϞM?fk?o?DŽ?o_`" *`eEM$D_^ ]f .`b 8|VHC *'` *@ ` `҅ G JB:Р @ b "a F`2BaJ!:ZVjZ2 r!YN[7Eaap@U@@h;Hh@ 71U,fE5m[%b%j"Dḽ[&Zb(b&.n۝Wy]JPȸ8\ɉ0X EDqLj,@+ (Ict,!jH#ph#CH>E)%;`o(a 6^(@ |>4j>Y?=ƕ>c@@#AccB"A:4#U.6Na-yUøI 5aMT$p{9/B0#,E5:F@#4O66^#8D5$Rn`B9RB%C)<|F4@0@OcRC@$Pe47۸MN6ϺbU[]N+%``Wa~afS`B7-f0!1&RJ~O\5FXM%ZFe\M/E(@U,4%6%R.W4ZC4Cl2nV#gL"g8c%P;lDlnGfRJRenfesfs2l&jL"Đf eb5Ef G~_KJ~4 !#FL_e՗oPS}zEu[߹Ug|GbIK3NhL*KJoMJji%4P5Ge:.%QhO^ $9Z%V:r4P6c )Sڨ[>S*19ہd"x{fFVY}ݧ4IN-'Pq (f9)6}}[ed5Нhh)n11I`,,@`I*]vJbp28) B' .E`ߗG }Ys_MFZ$d \ Yբ&r̡oV+z#rpS Vzq&]9kej)K>(3dFn8C XUpNۈqPrkqHjq@vꙪS雀'@`"]bE)Yi~ ea\R~9+b& >u[P╲$E\yyP$Ă,L)̂,̂,)m)-ΞB:CVB,H-*m,&-,Dm>mf-v֦c} YMekjd}f5L-7r"}" !(J.k|[Gi6߆U e(ip Ť+Ik~e+Ynnn7"ۜf/RB&3ĒV6!b:f, Y8.ʎ(Z R or`& /oo6`ov"pگ0 * ;0c0[0 V/I ;$$*%a 𩲮Ȯ ێNU(N,^Gv'ȪWpGޕ֮ ?oPpfz6x & {: ŏ'qTf})~FXxY#fY9'_"M:q*W2"y񱹖[[D$LwFV U :$z + !ikaU)1ppo%+,. /Sټ2.׉ѧy (~!'/'gl5grc#&f|.î,ڧ茮biz1Lf[^٫=w;/f(t}:I}rF5KWȂ)|e{ven)\ڪL ^/ XC]4!j 2Y238/n>rT5k |0+sDǶPBiin=C=#2h4zM{.49"NE]汰}.i0kC&gP疪EC?lH/4ژ1 rA ̀J'sYXc-. %2N[ef1r8흽Λu j"+M`tBvYY٩tn봲fY[IT$BLaOxgy/aǠ܃./yc|Ly~.7|7F{}7~u^8y8.Qwc7.w|_xPxOx73]p~N7{G9yO~x/wP8xw)<`Z;`pk9g`909wy9y99yy ?L*/((Sz[czksz{zzz[zD@z@:z:z {;{3;C{GK{SO{[c{{s{w{;vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/doc-files/dockview.gif000066400000000000000000000230731243334202400332770ustar00rootroot00000000000000GIF89aH9BBBJJRRZZZcck!k)k)s)s)Z1s1{9{B{BJJRZZccksss{{s{{{ƽνޜ,HHp*LpÆJHqŊ/jqǎ ? Irɒ(OLr˖0_l8͛8sɳϟ@ JѣH*]3HJիXjʵׯ`ÊKٳhiQ Kwݺxw߾yP@ 0P#?h`r@3@G0Ө/XpC0dM{C ssw`PabȡH"&*DO@ =eD\=k`B1ddK:yYf<ٔU9eekyIofk&rItwZݼq )(zj{0(*|W`6l r`F8*nx!⬴h Np]30,4߬s<3@f$)d0iiF픡Mi嵤ek[rdkflz.n]G   {&Li78 wJjA j"L+,()ۈv dC'[:gO6u٪j\v l9.Oq&nsuB'y|z/yzM }0 Op&Wl1b&ĬLʺZ\&@Ѐ@3ֱt$E&iiҳE;MjRm-Lᠫln%Tyԁ/@aniz}oOVY*ST! AB؆&Tu dۜHkY)[Zݶ0 e xRaдt%]iktzz@/h>] ,-fR~<9vVs4ll'!@*‚@NH: , 2;X-]KU J;&۹Ԥ.my5d'Oz'_r[7JBbk) Ήz7*^b'@AJ.D'YNΕ tVL72sfv3QWM!lɬ9 Z ('i"/p(/D^} ~HP=X*iJaN1B8A\q9c ґs(U1ҖwLBUe.Slda4$4 >)Zy|$i.4llg uғ hxH(Rͺ02A9@AFs9ˋoRK (+8aP5[a]L42Mo{BԴKX 2>eBksS[@RS8邭l3Y}Z^Xޟpj2;`[taq105E]ѩq@wҼ,@~dXF"6GuVњgBcH,7YRjͩehX۪Bo;˭ˠ+ 'Ȗ(@A,K,+b cP>fEkcwq,~JSd: n3Yir~ߧEmjݖxFrmMS_[ІlUq+aQM|PE?LtWbou.t zrykPPRh oa X3CnLc´4 (j3ഄ^mN"eJgMm: 6x|9袂J5ƍ(K>cB'Bt5K]OD )Y?j\i2[cP{ QӲL2Q뗜ݕ,3rukT[I'S:pV@=P0v-UQ.ŭ궋}FvcEVl>#1 )~v1hV]20?sRn7v@sE77AKVoMvooRFHtHvT&ZZ/&U7ϓBv$qQ{q>qVg5QSEVEE&*chH3 0c80dH @nҴ}1iMLGU~DeBeZug&Mz p6OfG7hgal7qr>)(h*bK#23cwF7s}7SXS3#4AK,ׂ.dTYjZz`4frbCґC9tU'D[lDVaLHg!'QQ(mbr#r?cDc8XmhS;dryw_t_~WWHJU`z- G/%`'e\lvG4vNV'E"!F~|YhRn(XS$#}deoO4QT/DUZNØuZdcIı`_אԔ1=BCUq[PJ{{&w7Ks13?&)"Kx2c^LI>ptYwx9q:?!K1—iJA}8;3q(AoIIPoљ9ٙa!oY 'љ)Y#IіOyIy̙0"A5rYٝɝ)٩޹9ٞ晛YiiṜ)I9YI@j ڠ :ZZ F#j*#$%'j( J.*-:;z/Z906q !I)L:6ڞٚ*FZ)ڥ/F 5bc ]jYonS+z(ڝjZiJܙh'a }uJm+Y \\ꦊtڤsz q rzڪ ^:xʩ*g? zڨGʪƪɧJJjjtu:Ѻ9VZKjJvzH=𩮷J :i41j5 蚥SڱZ{z+[ kڪJI;*BHҩ&۲xzʮɳF۫JTZP[2 *iڰJ. ` l۵㚷w[kpu{۳R; bZ%zQ۟)[g9;;(.{z4dy{:zfK#3[;KK˟뤐[A[{ꪹk<&{{~cJ ۣJʲqzk;ޫ ʚLG [{+J[';۷ڴW!l}wKʿ2ʾ+ +/Loڙ; k +zlj ƹ)Vs[K+tDʋ˲f=z[ǂ; sʿG)[ZKlJ+Y:ȸ*p,;:JܸT9̲"iLkȌKèY L; pYJ.۲kj <6իIxl -\Ū䬹"+˘I+&u 0[5X]#]2Q}Ԙ , =7NXLnۯNtZۇ-kWtOM z|2<&M^̹ŋmp׽$n<+\KsM̳N]*$!&b|j+o`NςݬmD|F\.~g먬$. O}-֬n<[.,Ǐ ߩ%\j}MUƪ׊̻}BZŲne~.u]m+|ju5t/h~л<( ]:|P/qЬ-DODM@ϑݧ=i<)-ioѡ_^/QO=VYN-̺ ɚn=lᯯԃS-^>4{7lFX@I$dhaBF,8pĆgpѣ'/JDbɂ#+fPS&|rC$sR̸2H=LJ&a$hs'R,gUԚD m0Ǝ Qhѳ4u\fS=q& ϘYe+oۃI25mNN=pk t'X  TS\pC!CvwM֭eMU[w O49*8Fbmxѻ:ܬCa.o>ɬk5W˸䚵&Lup/1N+n RԊ.7(lހCCN* [1-OlCRT ,[ODϬؤjJ\;Vu-K]N,D1CK-- *< =d\ HlArC41 =LsQfsӱR̅<-cT.%-QBaD9?LsWc SPHdQWaC+Yb$A*it1t'E0*2234x(]#Vʢڄ;}KGNu5C-+pO 6L9sZ}8"Oӝ64҉LMc_wd46IR3̸e$paeo^iyLSdgU( -v8Awsu"|_s 9J5TbܘW8@qEMJwȝ f`@ 6tRՋ}OR/=qg9VZCTG?\TD:i,湵A.) ܖ@89rcZt'ڱ#[#qNW4č1o\CJ#8; *M=\OlR\Xh+mv 5CqB!I1## uLF N'1$rW s~7KV Zm.v[.i ڂ/V_z.XJn.$ݏE3b6+IMta ͢prJx+U`Ìx7MaXYK&L|3N6H/& odj@$|gGPK'DM䴏'!5:)ʧ<ʸ6"@kD5h0ZL@H4|H"=?/tYxE.&r&hM&s{LטJ2Q4QØ6y0Y2T>BOD>(ĸ:eT#cȭԓT;*-LӾGֻ$4XŖS,X[Z-\-4Uٞ9:]|պ)ɟuUD}Wc@[^?RLeLZqBMcP)UV= 7s%|g &}n7ZRUFKK\jI.)u[ #NߦlqV;Tv+z&:E"nH,Fy $%3ilfX>(]S!mTsY&5kTJ$`[VYx:Mжk[¾7Ep +"#Ew< ;"cRz=(J"N0KTՉ+mG S#s",ZZ-۶R)GW'u2 Z;"޼vZwζcǸE[Kif]# Ԣ 'ڏۜkKU1Jl$⻡~/:X`1[Za׹눦.Ac[I>TjxAk>;Ow3ѓ.Ï7+RE[:vEy.nJ=ռɯ/2 7șvNnGݞbypxX7mȆ[46 I\SEz{ԁ:2o˽6msAN?kh\o~(7PM w.Uc;k@mNEI7j%*g=!qn !˦ 16$ܡN 5֛9oa+jùCӹ"Qx Yѽ;9C0[s&t2SC #Rx#:izʬ[!6E3C,9`?42:B2t8q {Sg;!IB8_*k*B"”+,(>I1dG{ZR5l0T 'ɺss>&*#-ӫ$K'4 L0úl44ޣ3:O8۰C8?RTS6F De{󲵵[D6?93+52pF:,,02![c[soG7C#ԯ3=Ls0$AS3@^B0.SJ#GћgʯRO=0æSV)&5cı(՚CC㰌rz$i{:tң9棵˜!(S l.3HmH.{<~+/#Z$G CsQ9V BFk5kC N? HE2:ȰAsIS/a$&.tEd bS:+ \=s,|:14DHG[l}ET%PP>u6;eADL ClCFFW{o17JI@BK÷rO ?q7|#{»K2s(]yO04&Ԭ5kp<Ĕħ$졯G\ J:͉1ў|DU'CƗ <(ŤE%?4+;k+ˍn:$"GS#D\ cJ2Κl93%e;*2썙S)bF ]+RT1OS̥9%HFғTKTLTMTNTOTP UQUR-US=UTMUU]S$(pUZU[U\U]U^U_U` VaVb-Vc=VdMa}opiVjVkVlVmVnVoVp WqWr-Ws=Wt W(xWyWzW{W|W}W~CWW XX-XX 0#(}XXXXXXXXX YY؆E;float16v2rollover.png000066400000000000000000000005061243334202400347310ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/doc-filesPNG  IHDRabKGD pHYs  tIME  $Z5=IDATxڝS+ r|lEluTst.Gs踼ހ(u aB\]*d/׸k͔V$KO}< |z`j`  (!V86߆uo^w͵i+Xڋ}L`9=P)]hRHN0LQ'1! *C+`+D=^aEXxE^QL&6F+hl{fɂb;rۣKzVk&Dt1& 1 B SB pD +e,mF k1sչG.?(񼧣6<阀0 ^+6@o>IoOˏ~C?c_?nC:|#H Z fz GHp<<v 2ġ d` a(C:TG:` t.nQZb+`RLH( GsFƧ1v80>~cHȆ c!G- #$HDn$&7Nr %(G)R*0>V2`*UYye-o]X1!`.hQ%\X ,*01f|slL:٘1td<GӞg; O|'?)P}!PA2D:QZm(F7юF GOHҒ(?؁sԃ "0B;A.Yz{×eMoӻ#Ϙ2fÙQE-)d0*`'16HNgZug[лff={O k<;PհlbJ׵Bͫf+ b,B-smjS~6umlYlmWL[)K05?| \{#4qeh˜h3* hbҴGAZ c3Ř[]ܪVlhz_{2ū<5BZ~q\ ~pg/a ¤M c#F'ښN KXvu)ش+_c;f1y ƭCp EM?0ry!q]$GwQEWp+ZQ@ JDH$Q(8xk0Z_B ߃O| /l~5Ҧ/Nu;_RZԜoU}jɦ}U,3X`uk×[,׵vy_16czk`oپb0ga!OۗXsZB4oA - E+Ĺ(`"EY _~t]WW5 ˞v.mhՈM!i#Z5MYNJ#/^r 5j4ekNٙKRy+}҆t,2l; N߲o [օ?ng])La y!AV/Uy^1ˣ)!fola~Q}!1OO妎'# b6$qJ{w=ќ7x Dw¡E ՗>:ScL]2 aN\`y~?0喻x/v3=c7 N L(hCx|0{$ |F0`"v?7aVla|V+ZPZ W7WN8aXXZwO%VZ+H%XO -)(U[3%ZXueI؄ | Ty\6ca|9[RKSVv WX|[f Uc ` P^'0n}p~71/N12/h3Xh6È؈18艌hxH-a+hG8 (;h(񀽈h؈H،؋ˈۘHhx8q{ K6g`fYH\RVx|xf{g8`ЅH' L5E UP2 2w( p-+i*M09/Y0)6MQ66IIJ@<;IS;)XZ90T1)^y@T NUTW0g9KIG9K1pɗȖ7 xY]Jٔh5sX`Jјhv yVp˅t 0}R; Б P /QCL<0NP*oyȉƙٜЙ9YIɝy9IDP*i*ELL`)yɟIiZ)ɟVy`y@Kw kЏb`agz|zЙscbIDP ;; /#0P*LXS*N SJRzVUX^_JZڥejahnjSWʦjZxz:{ڧ|zJzzʨ* ZjzzZ 'xdzk0bСKP҆bV`0* MԷ;0 9;=z pA:EzIQ0R܊d:uZ`j:eJVJ튮*:jzʯگ;[{ ۰`uJ SJ.tn1: P ;P Ț s *B@/*<Z'[=rT@:T[R VTZ۵\۵Y`[b;S[fhkkKi۶[rkp{^KNyz۷|{~+;[K{M`CvSx nYpK`f PE  @ P  A.P*"H[LF״NK('Tpƛʋ˼ۼK(ۼһ'׫٫;;[{蛾꫾RW;[k{ۿHtr 2tnb0V`3RK, lO@ `fE% B@k1p*N0< MJ${"Bĉ¼}[)Ĉ"E(J+(Tā;Q|ăBk\Ņ2_|eIfpqsr|tv|{( ȏr)ܼ,)ȃȈ'`:C7mV'd0ePɽON0 # jf` j - ~^~> n")%n+;WK857^:?n1Nl?JLMN.[;NSU;QO];_~jJ+'?P+S WVTyۮR[x.W{N~耞*~y[s.V|+Pо.{.޷N~긮꺾ŞfiώNn~ ŹEE@~0*>߹10N s7Ll2lva3pqo A/n  _O"2__/ ,:6O5CoE =o7OM,0vm'TU?[_Y?0T\V?f`eO]Sa?Z^O_ov?|~vf?V('`*#iM0P+`oO?_ȟʿOMV`۰ ِٿ_O//ٶ 8p[ *DpA J!D)&ܘqĈ7FɌ(M\P%ǐ-E,H̎u'̇BN0(Ҕ.eSQNZUYn͚l\Ŏ%[YiծUD"]xwo_%p†#^né_}r/G}/n !T@r0i4F'0̎'.#Ȼ!<M<[LKj1pOpϿTr\'rA*le+ ;ၢBp0JOE_qoGLH% |rP(TK:j5TLIN "16WNϓsN׫qGGgᝍ)FZ釳鱎:[h8& wmC *!jX+ZH&[bEu!b2 _$\Rw8qˈJaB*J%*g3J 9C)<Φ*8PY-Hk_'ְؕV^;.(’2$D)n t"HHA,9$.#]r0%+LVʘUu@sP,U >vxG[a}.2# Eh)Eek$Ca=`O_ z4@#.Wڅ ȆBь(8%zN_^Ԗb.E]P6KHB41/*H"*ȉv8Nӟbt!9WG65HI/tX37J$ w\GA|+J;Էv k] /z4Zg1[?l{b~$2wӣL򽂰-:W^7W Sc qxBUݪ:X?ϲv՚p+Y"5iF{Iԍ~penCȸWӴ,:ra$F(]3}ƘKգ$9}^qr#tQ֩QTI"Vժ&߈OnWfG*5 MaSkn3s!6}3 #bn/ [) XEm ]&++g b#Usf~V5N@/K}$&vvwbudzV5(Oߪc\+>h^)iJ_vM=Yx0DVm\"WİnoscP \Z *Pw^ nۧsvzHggWSiy gV6M1bB&Kw˫dd mgٗƲsQ5=U{sgtI:೦Xe7wA?Α˻#S+ @s;jq9;k2c2Q9+?c0-*>ZS=/Sa!z9 ܳ@i:({;4oB= |@҂;4u99?*Qߋ#mb3A? /9 +B#L# (@ᾢ:iz>C7!,N:"8+3ģT@:,b R,ES| f8E`& U|EXSLEYų@]E^E_E` FaFb,FcHn Φ$݄N$l͞MKMӜL MKLdLONtOMߔJ ٬N:SR-]S$ԫRFMTLRGR<ROՎ5RLF%K-NT?M)=/}TKJ6MUSR ?M"eUY5R@UZETy UbER4EU+UYcU^TT13PaRgpJWSs-bmvUbmUdaџU,jdiUl{T`C]uWxXtWq X|-X2Ϥքu~eӆ5!M}ViXhXWU]TjדV7,PX}YMYpYWUΑUXyXנ]XX%W-Q5T=םu؞ Y5Yٌ%k=Yڜ]w֣ڔWXZUVگ[hڴ ڶe߁`[uY &bbP5bZfb/MY2aM!>$(7.-_1.^ .Ɋ-P`?6e5>&89c5FcYmc C>JbD.;d>fdL~^a:A\S^S2vbtd-e8Ye.W.dUT>dc?G>b``Yfc.N@a7e5F\_5?V`jb96g^Xd^~mngfiVgtf[甩)di._f}g,a.tVh>cUawv]~gFh;`Jh>h&cO&i+NZ&eo,F vgnhVgdMn%a]~hch0Vi~hi^^deNaZ^~ihVd+_gj`vUlhg\~ˆ&Ⱦ麎뼾^lvm>kņ.fi.mnӖӤjflnn^bnl휆mҞmllifjbnFonoVno3ރ$&oinUlo  o.oeǖ^ nn&jr~m'pwpoq$.N^pvh\\Fr1q*lefr,$/W6r):'srm'r*'nn8m뎥j"7Bg=sCmfjYl;4>75!D7NOI"nAt>`K_uDsUuFwsE!W'o$8KJ.'[VEguMkoJH۰^oWrhojsss~Obض* 3j6 sbTun__`uL@w[.ìm0prpu_T/xdu)hD 䲵]6Hvyvm9˰1]cyisZ9t,١Gg4x7RWw.96G4{.gzgxxzR/w({bSݳw{·q6G|ZoJq({tG|_^&fWJՙtgw vo}FsQ$v0@7Տ}jQWxz?#$wyo^s||x%}azl VA2dˆ.J*V[~6`7?mĺAnBL,7tSџW ;k̜ լ-kήV6tck\מ'>>;۝cGn;鑇>:xg~|鿭u7?c'z( szH}p\gu9 ~u .8]v|-Hn$h"G"I؞ax`r,Rbjew)v)8^oV3g@ tY\*bP.cȞ4*٦I}&6dXb]: 'UR&(}n |ziiR`o'Z稍hR'Bw梨*~马\(*h^k[USF8Ǟ\X`Zc8Z~k ieH:߹bim[+-/ [nJ%v;뼺to6e0 oŮ m !ӻ*"Zmjpnlq:3,p-6k+ qfn3{,L\Kusr?d^O-ug|&[(L>lpNH4k_-HG u݀{mMc&[xbx. 39Z7}6@C,| qv޷}v m7:yi9ӄÍ|^<㾗.EUoo·~m::|w}>vu1/p+'3]w D뜥ʔ/ H{3>z=0bPU.Xk Xf}^<9{7!{c[4%EgOT6)I`jm$fS8OaӚdf9Gٴszt;3 tRNeYA2$g9<@hI7ʓNhEyυrϡ 1:2aj!CE9&Ԣ)NKJD0M/ʖtHԏIs,*@5șZ\&I1g+jZՀ*<*2)P2u: ?ΆSuDMƵz yU~*U۩նRSuܛ\)͛~Uc] J X}AjH uAsY |Dg_' ,6'm=-dZS]Ŭaٜv5M^][,FwMhkŽrnu}K΋t^W{ \~pͥmw֍w]+t(w^n0Ju0~!檷JUmTHS+TwXR1u5fp?ԡ.]c!-H:or2cI~_ieL)q6.1d!XYd<*ә1vꖕ6'oQeA) 7Rd|Coۆ0Pzԥ&uM-SZժN5WYZֶq][ըua-l^z.v-l8ŏ0 fNZN*<p6-q>7ӭuN4|M׸FlsE29\C8:ғ3N:ԣ.SV:֥ i\:S3ye|9څFcl\n;.ӽv;~޻F.57/8#/S<3s4J#Vb%^b9db6n'v"((8)** A!Aab a<b|RG11@#3.#":#46#Bb5FCZ#&N&nc78c)n$9c:b**u@`,-U-ab=cJ_@"A"c "dBBc4:$PJ%&ZE~#FF99b E6AccK!(dQxa-Md@bAAe">OJ4JPR6Evc8(.eG6GrݜI:ߎɖKV~e-6X䀜M$[e3":4eDJ$6f#ivQ8j_2S"HG6UjeңbbL e!QfZMZ b2j[e"eD56&au%)fk>e+` W&Š  I'F|ʧaЧm}2D~|IBcNf&3eO$CB'] h%7]d%9*)Zh` &U&r`o^.g ơ:}gTZBĊS'@ 耲e2F\Rc]2 eiZE*b'R(wZ*bScxDaޖ,gynbKd"~gDfh@F(hZarr&6$h 9iv"&^eff6`qz =BZWΘ'}iz))*Ҩ'FXeީr2g.gRt )%>'R&zgNiIF\a Vr)gLPt**Χ(Pc Bvުt&D"ii7j:Br;zh&c:OD*l)>lH) (rf2s*bVcN␊lr+G"&wj(a*!|Aိ^jb,vLj~kgЊ*Fli+Oj7"頂ժv^)z۾:*hl2>KRl-оmrJê*m1eAj!6m2$D,QVg^,ewBe*+!Mjm{jϩ{nj|@-.(6m r"fv*hf>ucvn$wJZkVlfݬقе !s@bAA:.^vL@䞤ccdc,ڀ,yM\lNrl\z톬]R76p#+Ro)o"oz@/ In򨞪kPBd]b#uzbb.,y&gn.+/Z|zM몥r/"i ) #.f$. ?+mWha>ay0I*OB\ og1Gr9+Ho̺b$#f"&iߪs.RobVC++z.+2L:,2-ײ-ݲ. @ ,or+qS 373?34G4O35W5Gs]6osvT01q͖J2WZJ;3<dz<6xʬι1_>3?XV a&A#!B/B74D4AD)k8-:Wc43~:rFa0IH JP4?&rF A(TO=OKGl~s8kN23MODdVn8 Xu?P=r>t#?XC>4?V5UlڳUE.rTYoYKLZ_V#1\g[]S55$=^[Z'Sߧ[C`bsgWox18?^,SSK6FʡH'd"govP5WS)>;LY#_udo_lvgvr6-lrR6z4Yo2p4gsP*lr~2^ip7XCWN_vfQqWa#wxvhE6*widGL5zS_ax˶rznxvx@c7o3uK@7-8q5?w7!gS3 }7sO2kzoG[LO]ɸ'ϸR8R/5dy3jkc0+9~/a6Wwp8gu\Zr3 S0tCΖScHw93x~9ۄ9L^th^Ec]8[7߉6W x?:7O%:y ngCMy7w9w:]SVx# {nzc'8+;SPlɩFlk\*y 4G}v|KRi}$F~zj:a{R9nKXB,)цrEn(czI{0 Y2lįhBʭ~6,{8+VRGXSYXe4N5d}SN`S:)OHAVpeTY5Yޖ 2D=vwoDksJ$^Ww]6$ ۉ9Z;u[ OQOvXnY%ZhU\Ehq;"Cg~yiSFڡdQ/^Eex>ޛfN:옹WpVWQ P9*/<6QjsIkoZuArXe!;Ϟvħnzu);C/e7']Ez-m;_ךgn?wQ^ wM߱'7՘xo:rǕ7u`:#= ~ٛ_紛{eWM"(}D迪o[JˠyL(9+! f@I3\ ɧ:_LӌG"ml cG8E#DxS!'i/r߻C2e=suhF22p2D]Ę K"HEZ}}r Cjb)B;:{|!fCWᰐ$!==!qI3I,FIed,c?iqw`## FzQ,.6 TLA3ZG\u-3O+Y~3{t"K=#624*L$;IOZz$bN$R(@@8rF9%K{H\>QvP C~2èGͤr,Mh8ӑU]EK:SRJiGWJT3Oܧ?9J=T?lX0²15*:n4)*Ӭ)V:UX4#ESX25gի߉4Tejst)TUzm`Է-ծMk5kRJVU&[J6=,NyҝYxn5-Th>ë\W#.cA1 bN׹=l{yVMeEx'[P ]mxZú ESlk\/{˚7츬Y7%%;Crj^t'J[EY!WŇ!ou^?GD0>}_֊0^quޫ˫ Pg+*9TMCǘ%/d{xf&gb$ɔr\c.sr3>+G3=#&_nXjF3hCkqLZ$m: &IV);t/gF{z<5g0Z֟je#on1+dI_{{mf|ۭ w^ݐre {S6v]9ƹAo$wkZյN/pۈ.-o8k07{'lx_;/2W;o4Gy󛛄)7cM梏zkN2ǹ57GIǡ>yONhS.wwY]$K]_8kN<#߹ܫ%L~1Jڪ1Anso=u9YNaVyooOws~ƏݍDo_m+i+w}{nw{!؍:V;ϳݻi=E4Bw=J.A~wŽڙ{?<{yǶ [yE/*&ҲKЏOᬍO{|.#oSRh.n, F;,͖(f\0fӸt~0l譬`SPEu +GtpN8pXiPpoo^ cPO߰pP0 /ެ MHn4f|K /. ѐѮƲ)Kw.,Os /wK[+K m pkfpjqQqP )p~1ps ]ggPg {c 5Q A _J!,ӱ9ѭOXJ3)PLeQ,}1 3! 6.d2"}v@RqVmQ !c_j sRmLRr arQ2!"oP [q eHrr'/#r%e1-{R i{ M"1r,+;1(!L-' rϰ,? 5/?+G2/g*C*,'y+3 w" 3/O M&(O4p2D+󒁊r1)W1y8#22 9J3'3Y2c0-s-U;lQ221w#rssTJwTJIe>ӯ2BHB?TKmr0CUM/T(tLEHHe2LJӇOJm4NcdM7=2PKHS!W1O )F75MFSG-C9TR1|IWuKA:'*7ųP?BUTT Ws}X)REE/X)YSsMMR$MUNYOd1VOUZ\WHYutC^R]?R\R["RU\fECSEͲW\UPm_4T1;X^G?buT\a5*+sV9U_2xUb3d9/YdU7f-DmN+fuZ];Ld{Zu;N?uc}eKXqPUY\Vd6l]6ieY4+)J-lg/6RVn["YhGXKveOLuj""mg3mou ?VLWVO2g#$Fml5m >qi .6smgArs3UorLp[wb=ptHvUkk J_7xGvUvW6kyWC7FBy/nնxMSlc%c#s)t6h5[;w[Kvjt 3yVjrw{ojdO7֖wW8y{uksw|C͖vN7wtjpδkpxw8qdwfy5!V^K}^_{AE`wRqwqプvpd $Zel18rm8o8]s]Bc5h븍}~g7}4Wi߳v5WfS8c8M'(<޸#oi9~\8e#YaXQWroxYfAQbxH[h,Y>R?yeE pMmys]8eg9E9KYcG9{ٛ#CO! @Yٟ9٠ zZ#z%):5:yUחٍZڥ_cZgkڦosZw{ڧi5ؚswkVv!A&ZڪZګzVD`W~Mx=ﶨ}VaZ皮ڮZگ[zc}8w/[%AA.3[7;۳?C[GK۴O9646Gu*v{۷[۸[ׂM,Jgׂۻ[Ǜۼ[׻;ř5-^n{yF[d\E4[|WHֺmc +e-Q~7\Nh5;1yyý68c?ڣ-g|q\+^}QZU%ɛɟʣ\ʧʫ!A˷˻˿\ǜ̵6bMBPXBiX;Z`/#|"|`!*[W]=%)}+}¹o'jBO¯DOSIb-\}a= =<ҽvݾA{_I^ѽO"R~# =_]JzH?^C"l6TÉBThq"CRh`ۤ줴'Y\ Jf.cʔ͓)a&|dOf:z ѤOJ.ziUXZ ֩حdj+ڱiמeVۮs֍ 6ۀ(M "bTNn|| C'[֨d,Sɜ6Iԉt̟O :J$ڕ;,ARoㅻxu_kwrś\wJ70 '& Xq|d;<v$I*ՋߒجQ:K %MmgUUMt!(u ZuUFFءo\`fbVŘQUb^utg}6l㎢37d=h 8Ђ"N$KJ9B9RX~y ]1*iq}|8sYdBH'C%o9٠U&r (G{ag`ݩb | jJj*(dFH${y;&Y)I,;, ,+6l.+m^[m^vkm̊K~{n[,WڕS!eaMտ oؿr +7,qP*JidO r"Lr&r*r. s2v(o< ; bt }>3t*R_uZou^ vbMva 'GWkсO^&ڝkZ]#2{|O||/|?|Jܛ_&Q2z%k\5՜~~OߏϿ\=={ٓ=G%{;nJp/ jp?p$,61F0B ZBA k(І;au ސBXD H$bD%PL*^qS|b !qcHF41l\XF8Qm9汎{G@1" (p*PA HGBR(`A%/iL'%)iILdA'5iJQf(KIT(cZR%(U P%.[LZ2̴/IiJaR:@1j*b ,p8zh0s&iÆ#Њ)j;9=@9"ꀁ'?ࠚ@+z˲=Q ׋;*fh.X"Ȁ ld=G:u1h-h"ps4X)>`\[QJM>Z5G}D`_ǃ"B\ X0ĎjtID шL?-G^|b!f:Y$f5pIRxzYZBz U`AlF0~ HP UQ֦67v[)_w%戢]+vE&hmh4KEx ]*uJ +Gc 7) -2󀣁 iOӶtuosg^D>!_ 0 8I\eX!~b.Ii/4ĥ[)针b((FmX z,gZz4kVJ+P(U9ґZS&>o   0I%^bDhTmlcRwƂzWazD~hпQK8 &ZXiA , Gд44P֪ RJTiZ[Jˈ.DUJ]%, G"lgϾӝh]pq"LzM0<@\gl"9î60 u~m,WiK.tD@K7S|^b6">`m';:Ob#L@^O_I2Aa@ۈ1Z4^ToykU[]UIP6Gqxֶxb2LI8=^,P\eteafxM mff9wWs?4'ʘ|(EmģL;.iڦ$ν ejeN^qh6t+MVF >3Yzͦ6R@Z e1n5&< ͯ )}hyDB&VZֆ;֒Lkf?"'| pZ2բDiP}ޅy_tGt9+\u+X}Hp\=vʷ5tzmN7㍿3Jd.vy@Iy#oIwjCik t rLlݼ>3y[{ݽ&ۈ#d 8yY -.XMW+UT郪hO"k ؽ$q] ~oIAF\!A_!a/t' C4T!g}Wx֫SO{l_HqOǾ} f{_ ƿ|YY@;vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/dock16.gif000066400000000000000000000015231243334202400307020ustar00rootroot00000000000000GIF89a!,0H*\H0C  -b<Ç 7Vd8ɓ$;vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/dock16pressed.gif000066400000000000000000000015461243334202400322750ustar00rootroot00000000000000GIF89a΄B!,CH" aHp!(B@Ń1j#CS~$cCWn›8 ;vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/dock16rollover.gif000066400000000000000000000015431243334202400324710ustar00rootroot00000000000000GIF89aB!,@H"!Hp!^xQ#Ǝ1~drɊn$Q(6tI;vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/dock16v2.png000066400000000000000000000003621243334202400311710ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  /zpIDATxc``KKK=. 555|\ ޿``xqC>YZa@} 6y&|x8 3000H(Vc !BаVRuz|ޢ},|1!GtIENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/dock16v2pressed.png000066400000000000000000000003761243334202400325640ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  QIDATxc@!lN85T&V]NN޿``xq0w, @R\7u!$<~AP$Q[RF*Cj[#hIB?8,٢;`2B2IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/dock16v2rollover.png000066400000000000000000000003651243334202400327610ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  ,IWMIDATxc@!lN8U NN C?00J,-B 2  XM\4ۇmCj[O\_,s>F.% +PIENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/dragcursor.gif000066400000000000000000000016221243334202400317660ustar00rootroot00000000000000GIF89a !, oH*\ȰÇ#JHŋƎ7B ɓ&EBDɲD-Qt3fJ6Oys$ϒ3gP5se8(ϥ A~*ƫXjʵׯ;vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/float16v2.png000066400000000000000000000005111243334202400313520ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  ɥIDATxڝS+ }؊\ "Et\&T"!J~}͒}Zo\3!>l{X [S(pPJsJY;ð8gPJԍaA# Ę)B*$11Iܜ4ѽyO!~`)a-PSH{4hsC%7Q" O(UIENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/float16v2pressed.png000066400000000000000000000005221243334202400327420ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  50IDATxڝ!0D7 w؊:-q u$ i$aYKw؜ ҵXh]!Ŵںx0󠤊L΍GزnfH2pO}~'۔:IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/maximize16v2pressed.png000066400000000000000000000005021243334202400334560ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  XRgIDATxڥR \k @[VZ{@Kf'M6 =w9 P&P &K fѯ9ߪd(D/fBR*?z t 'R?>jDVDiBVXNxA} 9pgv{J1vnyT0=Jb=RIl|۸rGp0?ªxHIENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/maximize16v2rollover.png000066400000000000000000000004531243334202400336620ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  -GaIDATxڥS 0 5'Yoбܡ( :@%$eSJ4 R&[q6- a=I/ݵwťLa<݀Xv&IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/docking/restore16v2pressed.png000066400000000000000000000005311243334202400333200ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  nmIDATxڥS ExZضmw7w #~f4ބ!9w=WŐCr iQ0G;te''mWG$`G0 bWzT@ PA =pp"@(mD L7T;@ .HC)q > )q >D8ux@}%@G9HZREDEf@5М9Еe(P'& B0n/ ET<`iHqN%(E B )  ڪCi) F`5p@G6@%(BcdBmn_&qY/h ѫ+ RR j FBMG`) C~"1Ă qP4I0 vKhD2{\G"B@`k/' @e:%h PH LD~䤏4FPe CAeQ& zWaiQd+P @iH LAk5IC%> ;uYl˾ۨCB vKpgxCG@T}tZ NPWւC@^حI1i52n?pT2@B!+Ҽ@n]zWU/ d hTM|I1 (ֱ00ؚ`q~ SB.U ! B" rPrLrI{XD5U"| 9B¦̪ZȮz FZձT@ 9ZC 31ka$ySDp*Td"H !ZɌ5CRI *Wްr7N# XX1eC^2%d`4CbL2fJf84y̦6nz 8IrL:vt5  PRGzNgG9JI(GK"DQF*LB?F(JD )N@Ţ"MMHjx*iK`v2Ip .r: jHMnBMQ?bҭTP*S[zӨZU$HQ5իz!]mV3֯ e(UzֶZ$ iAլvuX1׻^kA%aX$B},4RZֱSE${٘r|jg/ٵ.uBi5Ԣv5k; Uvllي[ֶak ׯ-jpRv=s ~u5u[VwVŮX ^v-W[Q7U{߫U }O:%e_ x*-\XmNXK8/| +v~ tēݬ Fxn1u_ 8?Q7/ }D(A&Y/K.{eOyUjy˷K143ќ.l^gjΙuƲkϫk̺έ\dטuh^ ;'nAl./6]hdԞ ld鶷_n{33nKcnSʭZy[7Jo| M /Q\ oxK'/ьw7w{|ލ1r|x sd˜ήo.eJNsӄF ғ3DWӇK}G˱nCx\NdӮmbw;^tDg.]W ov|!nXߩA,XAyO<_o=H>/{s=Ih=ѧMi_B}Qs~_'~ѥk_)>ߓI?/ߟ\~gj~vv Hke7oVmf#$l&⇂.s0} 84'}8ǂ2؃ց%(>1ȃF8g۷QSHUWDjKlMnh[k]:J؅YhkmȀoX=HA((pNa6i(x%+戸fK@`8 %@"m8,pPP@@2Px=P%txPЋ88PH؈_ol8PNpPЊaQ"Pȇ@NHHш8؉8pOx2|(= ؑ!q2 H((`h. 2hO" &hؑ* kaP""(pKpQin5I6Y5=PjiZ2kYX_ѓȐ, bi|)|yxɏ،@d ZDZCqHJ?ѤNP;1TVz7ZZ\ڥ3`b:/Qfh+ln~rqZ$qx*z ѧ~ʠ.Ix%aQ:ZzrѨک<:B1P01!+BcjJP a P+` Iګ:q@ @<'֊*J`Ppʪ<'` pI0Jj*J$Bhѭ7!`B PpJ@! $0PzI 5k(,@J;A `PP0I PUڃ&*1@@ JתJ5[C1Uk 1p?[KXpʶB񭕫1 xaZz[jl+nExo ۶g+kh뻾'ۺj*Zd{G- 2K*I*ʺ<@@ݛ1 B஘kjZު8XP` j$мlJ*̪[K+ ˸;+).0K;vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/toolbars/grip_expand_h.png000066400000000000000000000003701243334202400326470ustar00rootroot00000000000000PNG  IHDRbKGDC pHYs  tIME .*itEXtCommentCopyright VLSolutions dD\IDATx}1@PE>)ve [e(g`d5#ex"@k)QYo`D|I'IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/toolbars/grip_expand_v.png000066400000000000000000000003551243334202400326700ustar00rootroot00000000000000PNG  IHDRbKGDC pHYs  tIME /,tEXtCommentCopyright VLSolutions dDQIDATxڭ͡Pw3IQT6.ڽvFx'Œ,moI>X>f\SN:IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/toolbars/gripper.png000066400000000000000000000002761243334202400315150ustar00rootroot00000000000000PNG  IHDRV(bKGD pHYs  tIME 5ZtEXtCommentCopyright VLSolutions dD"IDATx !4o/w\<8UdpnIENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/toolbars/toolbarbuttonborder.png000066400000000000000000000002551243334202400341360ustar00rootroot00000000000000PNG  IHDR;֕J pHYsiTStIME  $ LIDATxcd@253C{H@<4KE . <@9\,\fgIENDB`toolbarbuttonborder_pressed.png000066400000000000000000000003041243334202400355770ustar00rootroot00000000000000vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/toolbarsPNG  IHDR;֕JbKGD pHYsiTStIMEQIDATxcd@F$oH,MK fA4>'B$s"m}M3I`Tь) HTd*c '(IENDB`vldocking-vldocking-3.0.5/src/main/resources/com/vlsolutions/swing/toolbars/toolbarpanelborder.png000066400000000000000000000002551243334202400337220ustar00rootroot00000000000000PNG  IHDR;֕J pHYsiTStIME  0:cLIDATxcd@F(ǀtpA @TuLd:مL0Q!yzP069 Wh aIENDB`