diff --git a/deps/JTattoo-1.6.10.jar b/deps/JTattoo-1.6.10.jar deleted file mode 100644 index 4ebf735..0000000 Binary files a/deps/JTattoo-1.6.10.jar and /dev/null differ diff --git a/licenses/jtattoo/APACHE-LICENSE-2.0.txt b/licenses/jtattoo/APACHE-LICENSE-2.0.txt new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/licenses/jtattoo/APACHE-LICENSE-2.0.txt @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/licenses/jtattoo/classpath-exception.txt b/licenses/jtattoo/classpath-exception.txt new file mode 100644 index 0000000..30c7acd --- /dev/null +++ b/licenses/jtattoo/classpath-exception.txt @@ -0,0 +1,17 @@ +Classpath is distributed under the terms of the GNU General Public License +with the following clarification and special exception. + +Linking this library statically or dynamically with other modules is making +a combined work based on this library. Thus, the terms and conditions of the +GNU General Public License cover the whole combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent modules, +and to copy and distribute the resulting executable under terms of your +choice, provided that you also meet, for each linked independent module, +the terms and conditions of the license of that module. An independent module +is a module which is not derived from or based on this library. If you modify +this library, you may extend this exception to your version of the library, +but you are not obligated to do so. If you do not wish to do so, delete this +exception statement from your version. diff --git a/licenses/jtattoo/gpl-2.0.txt b/licenses/jtattoo/gpl-2.0.txt new file mode 100644 index 0000000..2f13e52 --- /dev/null +++ b/licenses/jtattoo/gpl-2.0.txt @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/licenses/jtattoo/lgpl-2.0.txt b/licenses/jtattoo/lgpl-2.0.txt new file mode 100644 index 0000000..e3284a4 --- /dev/null +++ b/licenses/jtattoo/lgpl-2.0.txt @@ -0,0 +1,437 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/licenses/jtattoo/license.txt b/licenses/jtattoo/license.txt new file mode 100644 index 0000000..d08ef32 --- /dev/null +++ b/licenses/jtattoo/license.txt @@ -0,0 +1,21 @@ +Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. + +JTattoo is multiple licensed. If your are an open source developer you can use +it under the terms and conditions of the GNU General Public License version 2.0 +or later as published by the Free Software Foundation. + +see: gpl-2.0.txt + +If you pay for a license you will become a registered user who could use the +software under the terms and conditions of the GNU Lesser General Public License +version 2.0 or later with classpath exception as published by the Free Software +Foundation. + +see: lgpl-2.0.txt +see: classpath-exception.txt + +Registered users could also use JTattoo under the terms and conditions of the +Apache License, Version 2.0 as published by the Apache Software Foundation. + +see: APACHE-LICENSE-2.0.txt + \ No newline at end of file diff --git a/resources/com/jtattoo/plaf/hifi/icons/HorRubber.gif b/resources/com/jtattoo/plaf/hifi/icons/HorRubber.gif new file mode 100644 index 0000000..c54e653 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/HorRubber.gif differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/SplitterDownArrow.gif b/resources/com/jtattoo/plaf/hifi/icons/SplitterDownArrow.gif new file mode 100644 index 0000000..cd8dcc1 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/SplitterDownArrow.gif differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/SplitterHorBumps.gif b/resources/com/jtattoo/plaf/hifi/icons/SplitterHorBumps.gif new file mode 100644 index 0000000..bd4d4bd Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/SplitterHorBumps.gif differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/SplitterLeftArrow.gif b/resources/com/jtattoo/plaf/hifi/icons/SplitterLeftArrow.gif new file mode 100644 index 0000000..c7c5438 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/SplitterLeftArrow.gif differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/SplitterRightArrow.gif b/resources/com/jtattoo/plaf/hifi/icons/SplitterRightArrow.gif new file mode 100644 index 0000000..d8bf53a Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/SplitterRightArrow.gif differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/SplitterUpArrow.gif b/resources/com/jtattoo/plaf/hifi/icons/SplitterUpArrow.gif new file mode 100644 index 0000000..e0f490a Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/SplitterUpArrow.gif differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/SplitterVerBumps.gif b/resources/com/jtattoo/plaf/hifi/icons/SplitterVerBumps.gif new file mode 100644 index 0000000..cd6e164 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/SplitterVerBumps.gif differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/VerRubber.gif b/resources/com/jtattoo/plaf/hifi/icons/VerRubber.gif new file mode 100644 index 0000000..3312324 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/VerRubber.gif differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/large/arrow_down_11x10.png b/resources/com/jtattoo/plaf/hifi/icons/large/arrow_down_11x10.png new file mode 100644 index 0000000..d7d3d94 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/large/arrow_down_11x10.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/large/arrow_left_10x11.png b/resources/com/jtattoo/plaf/hifi/icons/large/arrow_left_10x11.png new file mode 100644 index 0000000..713fd1f Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/large/arrow_left_10x11.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/large/arrow_right_10x11.png b/resources/com/jtattoo/plaf/hifi/icons/large/arrow_right_10x11.png new file mode 100644 index 0000000..b9b4fcb Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/large/arrow_right_10x11.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/large/arrow_up_11x10.png b/resources/com/jtattoo/plaf/hifi/icons/large/arrow_up_11x10.png new file mode 100644 index 0000000..8c9ee35 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/large/arrow_up_11x10.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/large/check_symbol_16x15.png b/resources/com/jtattoo/plaf/hifi/icons/large/check_symbol_16x15.png new file mode 100644 index 0000000..26196a8 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/large/check_symbol_16x15.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/large/tree_collapsed_14x14.png b/resources/com/jtattoo/plaf/hifi/icons/large/tree_collapsed_14x14.png new file mode 100644 index 0000000..c5330cb Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/large/tree_collapsed_14x14.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/large/tree_expanded_14x14.png b/resources/com/jtattoo/plaf/hifi/icons/large/tree_expanded_14x14.png new file mode 100644 index 0000000..219bc77 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/large/tree_expanded_14x14.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/medium/arrow_down_9x8.png b/resources/com/jtattoo/plaf/hifi/icons/medium/arrow_down_9x8.png new file mode 100644 index 0000000..d6d03b5 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/medium/arrow_down_9x8.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/medium/arrow_left_8x9.png b/resources/com/jtattoo/plaf/hifi/icons/medium/arrow_left_8x9.png new file mode 100644 index 0000000..8a647aa Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/medium/arrow_left_8x9.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/medium/arrow_right_8x9.png b/resources/com/jtattoo/plaf/hifi/icons/medium/arrow_right_8x9.png new file mode 100644 index 0000000..1c52ab5 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/medium/arrow_right_8x9.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/medium/arrow_up_9x8.png b/resources/com/jtattoo/plaf/hifi/icons/medium/arrow_up_9x8.png new file mode 100644 index 0000000..d180b34 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/medium/arrow_up_9x8.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/medium/check_symbol_14x13.png b/resources/com/jtattoo/plaf/hifi/icons/medium/check_symbol_14x13.png new file mode 100644 index 0000000..74aba00 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/medium/check_symbol_14x13.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/medium/tree_collapsed_11x11.png b/resources/com/jtattoo/plaf/hifi/icons/medium/tree_collapsed_11x11.png new file mode 100644 index 0000000..834ff93 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/medium/tree_collapsed_11x11.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/medium/tree_expanded_11x11.png b/resources/com/jtattoo/plaf/hifi/icons/medium/tree_expanded_11x11.png new file mode 100644 index 0000000..e9fb1bd Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/medium/tree_expanded_11x11.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/small/arrow_down_7x6.png b/resources/com/jtattoo/plaf/hifi/icons/small/arrow_down_7x6.png new file mode 100644 index 0000000..a62df9c Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/small/arrow_down_7x6.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/small/arrow_left_6x7.png b/resources/com/jtattoo/plaf/hifi/icons/small/arrow_left_6x7.png new file mode 100644 index 0000000..2a6dad8 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/small/arrow_left_6x7.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/small/arrow_right_6x7.png b/resources/com/jtattoo/plaf/hifi/icons/small/arrow_right_6x7.png new file mode 100644 index 0000000..511a37a Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/small/arrow_right_6x7.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/small/arrow_up_7x6.png b/resources/com/jtattoo/plaf/hifi/icons/small/arrow_up_7x6.png new file mode 100644 index 0000000..1f08c3b Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/small/arrow_up_7x6.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/small/check_symbol_12x11.png b/resources/com/jtattoo/plaf/hifi/icons/small/check_symbol_12x11.png new file mode 100644 index 0000000..6696f5e Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/small/check_symbol_12x11.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/small/tree_collapsed_9x9.png b/resources/com/jtattoo/plaf/hifi/icons/small/tree_collapsed_9x9.png new file mode 100644 index 0000000..2c12258 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/small/tree_collapsed_9x9.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/small/tree_expanded_9x9.png b/resources/com/jtattoo/plaf/hifi/icons/small/tree_expanded_9x9.png new file mode 100644 index 0000000..b7d3df3 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/small/tree_expanded_9x9.png differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/thumb_hor.gif b/resources/com/jtattoo/plaf/hifi/icons/thumb_hor.gif new file mode 100644 index 0000000..9c88f53 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/thumb_hor.gif differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/thumb_hor_rollover.gif b/resources/com/jtattoo/plaf/hifi/icons/thumb_hor_rollover.gif new file mode 100644 index 0000000..95ed511 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/thumb_hor_rollover.gif differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/thumb_ver.gif b/resources/com/jtattoo/plaf/hifi/icons/thumb_ver.gif new file mode 100644 index 0000000..8476469 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/thumb_ver.gif differ diff --git a/resources/com/jtattoo/plaf/hifi/icons/thumb_ver_rollover.gif b/resources/com/jtattoo/plaf/hifi/icons/thumb_ver_rollover.gif new file mode 100644 index 0000000..c3517a0 Binary files /dev/null and b/resources/com/jtattoo/plaf/hifi/icons/thumb_ver_rollover.gif differ diff --git a/resources/com/jtattoo/plaf/icons/MenuArrow.gif b/resources/com/jtattoo/plaf/icons/MenuArrow.gif new file mode 100644 index 0000000..17b7e29 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/MenuArrow.gif differ diff --git a/resources/com/jtattoo/plaf/icons/MenuLeftArrow.gif b/resources/com/jtattoo/plaf/icons/MenuLeftArrow.gif new file mode 100644 index 0000000..72e394a Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/MenuLeftArrow.gif differ diff --git a/resources/com/jtattoo/plaf/icons/MenuRightArrow.gif b/resources/com/jtattoo/plaf/icons/MenuRightArrow.gif new file mode 100644 index 0000000..17b7e29 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/MenuRightArrow.gif differ diff --git a/resources/com/jtattoo/plaf/icons/SplitterDownArrow.gif b/resources/com/jtattoo/plaf/icons/SplitterDownArrow.gif new file mode 100644 index 0000000..431228b Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/SplitterDownArrow.gif differ diff --git a/resources/com/jtattoo/plaf/icons/SplitterHorBumps.gif b/resources/com/jtattoo/plaf/icons/SplitterHorBumps.gif new file mode 100644 index 0000000..152e12e Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/SplitterHorBumps.gif differ diff --git a/resources/com/jtattoo/plaf/icons/SplitterHorBumpsSmall.gif b/resources/com/jtattoo/plaf/icons/SplitterHorBumpsSmall.gif new file mode 100644 index 0000000..669868d Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/SplitterHorBumpsSmall.gif differ diff --git a/resources/com/jtattoo/plaf/icons/SplitterLeftArrow.gif b/resources/com/jtattoo/plaf/icons/SplitterLeftArrow.gif new file mode 100644 index 0000000..1f9afdd Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/SplitterLeftArrow.gif differ diff --git a/resources/com/jtattoo/plaf/icons/SplitterRightArrow.gif b/resources/com/jtattoo/plaf/icons/SplitterRightArrow.gif new file mode 100644 index 0000000..5a586e5 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/SplitterRightArrow.gif differ diff --git a/resources/com/jtattoo/plaf/icons/SplitterUpArrow.gif b/resources/com/jtattoo/plaf/icons/SplitterUpArrow.gif new file mode 100644 index 0000000..2afe208 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/SplitterUpArrow.gif differ diff --git a/resources/com/jtattoo/plaf/icons/SplitterVerBumps.gif b/resources/com/jtattoo/plaf/icons/SplitterVerBumps.gif new file mode 100644 index 0000000..e828eb4 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/SplitterVerBumps.gif differ diff --git a/resources/com/jtattoo/plaf/icons/SplitterVerBumpsSmall.gif b/resources/com/jtattoo/plaf/icons/SplitterVerBumpsSmall.gif new file mode 100644 index 0000000..7c0bfe9 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/SplitterVerBumpsSmall.gif differ diff --git a/resources/com/jtattoo/plaf/icons/computer_16x16.png b/resources/com/jtattoo/plaf/icons/computer_16x16.png new file mode 100644 index 0000000..d596d20 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/computer_16x16.png differ diff --git a/resources/com/jtattoo/plaf/icons/empty_8x8.png b/resources/com/jtattoo/plaf/icons/empty_8x8.png new file mode 100644 index 0000000..9659f87 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/empty_8x8.png differ diff --git a/resources/com/jtattoo/plaf/icons/floppy_drive_16x16.png b/resources/com/jtattoo/plaf/icons/floppy_drive_16x16.png new file mode 100644 index 0000000..e3d929b Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/floppy_drive_16x16.png differ diff --git a/resources/com/jtattoo/plaf/icons/folder_new_22x22.png b/resources/com/jtattoo/plaf/icons/folder_new_22x22.png new file mode 100644 index 0000000..04f078f Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/folder_new_22x22.png differ diff --git a/resources/com/jtattoo/plaf/icons/folder_up_22x22.png b/resources/com/jtattoo/plaf/icons/folder_up_22x22.png new file mode 100644 index 0000000..9f36b59 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/folder_up_22x22.png differ diff --git a/resources/com/jtattoo/plaf/icons/hard_drive_16x16.png b/resources/com/jtattoo/plaf/icons/hard_drive_16x16.png new file mode 100644 index 0000000..bae21a8 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/hard_drive_16x16.png differ diff --git a/resources/com/jtattoo/plaf/icons/home_22x22.png b/resources/com/jtattoo/plaf/icons/home_22x22.png new file mode 100644 index 0000000..ae41c1e Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/home_22x22.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/arrow_down_11x8.png b/resources/com/jtattoo/plaf/icons/large/arrow_down_11x8.png new file mode 100644 index 0000000..c279cfb Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/arrow_down_11x8.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/arrow_down_inverse_11x8.png b/resources/com/jtattoo/plaf/icons/large/arrow_down_inverse_11x8.png new file mode 100644 index 0000000..214502c Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/arrow_down_inverse_11x8.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/arrow_left_8x11.png b/resources/com/jtattoo/plaf/icons/large/arrow_left_8x11.png new file mode 100644 index 0000000..99fc794 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/arrow_left_8x11.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/arrow_left_inverse_8x11.png b/resources/com/jtattoo/plaf/icons/large/arrow_left_inverse_8x11.png new file mode 100644 index 0000000..7c1e417 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/arrow_left_inverse_8x11.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/arrow_right_8x11.png b/resources/com/jtattoo/plaf/icons/large/arrow_right_8x11.png new file mode 100644 index 0000000..f661de7 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/arrow_right_8x11.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/arrow_right_inverse_8x11.png b/resources/com/jtattoo/plaf/icons/large/arrow_right_inverse_8x11.png new file mode 100644 index 0000000..b68259f Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/arrow_right_inverse_8x11.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/arrow_up_11x8.png b/resources/com/jtattoo/plaf/icons/large/arrow_up_11x8.png new file mode 100644 index 0000000..431da26 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/arrow_up_11x8.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/arrow_up_inverse_11x8.png b/resources/com/jtattoo/plaf/icons/large/arrow_up_inverse_11x8.png new file mode 100644 index 0000000..4ea935d Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/arrow_up_inverse_11x8.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/check_symbol_14x14.png b/resources/com/jtattoo/plaf/icons/large/check_symbol_14x14.png new file mode 100644 index 0000000..1d13612 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/check_symbol_14x14.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/check_symbol_disabled_14x14.png b/resources/com/jtattoo/plaf/icons/large/check_symbol_disabled_14x14.png new file mode 100644 index 0000000..9a54141 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/check_symbol_disabled_14x14.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/closer_12x12.png b/resources/com/jtattoo/plaf/icons/large/closer_12x12.png new file mode 100644 index 0000000..7909acc Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/closer_12x12.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/cup_24x24.png b/resources/com/jtattoo/plaf/icons/large/cup_24x24.png new file mode 100644 index 0000000..500afe7 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/cup_24x24.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/document_24x24.png b/resources/com/jtattoo/plaf/icons/large/document_24x24.png new file mode 100644 index 0000000..1b62bae Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/document_24x24.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/error_48x48.png b/resources/com/jtattoo/plaf/icons/large/error_48x48.png new file mode 100644 index 0000000..ba06bec Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/error_48x48.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/folder_closed_24x24.png b/resources/com/jtattoo/plaf/icons/large/folder_closed_24x24.png new file mode 100644 index 0000000..743f33d Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/folder_closed_24x24.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/folder_opened_24x24.png b/resources/com/jtattoo/plaf/icons/large/folder_opened_24x24.png new file mode 100644 index 0000000..e6a14c2 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/folder_opened_24x24.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/iconizer_12x12.png b/resources/com/jtattoo/plaf/icons/large/iconizer_12x12.png new file mode 100644 index 0000000..84f0eef Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/iconizer_12x12.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/information_48x48.png b/resources/com/jtattoo/plaf/icons/large/information_48x48.png new file mode 100644 index 0000000..9b730e3 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/information_48x48.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/maximizer_12x12.png b/resources/com/jtattoo/plaf/icons/large/maximizer_12x12.png new file mode 100644 index 0000000..92eea1c Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/maximizer_12x12.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/minimizer_12x12.png b/resources/com/jtattoo/plaf/icons/large/minimizer_12x12.png new file mode 100644 index 0000000..54057a8 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/minimizer_12x12.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/pearl_green_32x32.png b/resources/com/jtattoo/plaf/icons/large/pearl_green_32x32.png new file mode 100644 index 0000000..deaefb2 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/pearl_green_32x32.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/pearl_grey_32x32.png b/resources/com/jtattoo/plaf/icons/large/pearl_grey_32x32.png new file mode 100644 index 0000000..303f312 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/pearl_grey_32x32.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/pearl_red_32x32.png b/resources/com/jtattoo/plaf/icons/large/pearl_red_32x32.png new file mode 100644 index 0000000..ff2e35b Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/pearl_red_32x32.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/pearl_yellow_32x32.png b/resources/com/jtattoo/plaf/icons/large/pearl_yellow_32x32.png new file mode 100644 index 0000000..0b2c52c Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/pearl_yellow_32x32.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/question_48x48.png b/resources/com/jtattoo/plaf/icons/large/question_48x48.png new file mode 100644 index 0000000..c2ab531 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/question_48x48.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/tree_collapsed_14x14.png b/resources/com/jtattoo/plaf/icons/large/tree_collapsed_14x14.png new file mode 100644 index 0000000..aa21702 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/tree_collapsed_14x14.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/tree_expanded_14x14.png b/resources/com/jtattoo/plaf/icons/large/tree_expanded_14x14.png new file mode 100644 index 0000000..7fe5970 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/tree_expanded_14x14.png differ diff --git a/resources/com/jtattoo/plaf/icons/large/warning_48x48.png b/resources/com/jtattoo/plaf/icons/large/warning_48x48.png new file mode 100644 index 0000000..ec44645 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/large/warning_48x48.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/arrow_down_9x6.png b/resources/com/jtattoo/plaf/icons/medium/arrow_down_9x6.png new file mode 100644 index 0000000..a516eb0 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/arrow_down_9x6.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/arrow_down_inverse_9x6.png b/resources/com/jtattoo/plaf/icons/medium/arrow_down_inverse_9x6.png new file mode 100644 index 0000000..9ce4185 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/arrow_down_inverse_9x6.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/arrow_left_6x9.png b/resources/com/jtattoo/plaf/icons/medium/arrow_left_6x9.png new file mode 100644 index 0000000..325b645 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/arrow_left_6x9.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/arrow_left_inverse_6x9.png b/resources/com/jtattoo/plaf/icons/medium/arrow_left_inverse_6x9.png new file mode 100644 index 0000000..365c986 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/arrow_left_inverse_6x9.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/arrow_right_6x9.png b/resources/com/jtattoo/plaf/icons/medium/arrow_right_6x9.png new file mode 100644 index 0000000..68cead1 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/arrow_right_6x9.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/arrow_right_inverse_6x9.png b/resources/com/jtattoo/plaf/icons/medium/arrow_right_inverse_6x9.png new file mode 100644 index 0000000..1b55465 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/arrow_right_inverse_6x9.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/arrow_up_9x6.png b/resources/com/jtattoo/plaf/icons/medium/arrow_up_9x6.png new file mode 100644 index 0000000..4001da5 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/arrow_up_9x6.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/arrow_up_inverse_9x6.png b/resources/com/jtattoo/plaf/icons/medium/arrow_up_inverse_9x6.png new file mode 100644 index 0000000..e095a11 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/arrow_up_inverse_9x6.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/check_symbol_12x12.png b/resources/com/jtattoo/plaf/icons/medium/check_symbol_12x12.png new file mode 100644 index 0000000..314a896 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/check_symbol_12x12.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/check_symbol_disabled_12x12.png b/resources/com/jtattoo/plaf/icons/medium/check_symbol_disabled_12x12.png new file mode 100644 index 0000000..19d9ced Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/check_symbol_disabled_12x12.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/closer_12x12.png b/resources/com/jtattoo/plaf/icons/medium/closer_12x12.png new file mode 100644 index 0000000..7909acc Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/closer_12x12.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/cup_20x20.png b/resources/com/jtattoo/plaf/icons/medium/cup_20x20.png new file mode 100644 index 0000000..8e3938b Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/cup_20x20.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/document_20x20.png b/resources/com/jtattoo/plaf/icons/medium/document_20x20.png new file mode 100644 index 0000000..3f268b6 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/document_20x20.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/error_32x32.png b/resources/com/jtattoo/plaf/icons/medium/error_32x32.png new file mode 100644 index 0000000..c1f36b3 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/error_32x32.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/folder_closed_20x20.png b/resources/com/jtattoo/plaf/icons/medium/folder_closed_20x20.png new file mode 100644 index 0000000..ebf935a Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/folder_closed_20x20.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/folder_opened_20x20.png b/resources/com/jtattoo/plaf/icons/medium/folder_opened_20x20.png new file mode 100644 index 0000000..c3c6c0b Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/folder_opened_20x20.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/iconizer_12x12.png b/resources/com/jtattoo/plaf/icons/medium/iconizer_12x12.png new file mode 100644 index 0000000..84f0eef Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/iconizer_12x12.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/information_32x32.png b/resources/com/jtattoo/plaf/icons/medium/information_32x32.png new file mode 100644 index 0000000..a72fa00 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/information_32x32.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/maximizer_12x12.png b/resources/com/jtattoo/plaf/icons/medium/maximizer_12x12.png new file mode 100644 index 0000000..92eea1c Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/maximizer_12x12.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/minimizer_12x12.png b/resources/com/jtattoo/plaf/icons/medium/minimizer_12x12.png new file mode 100644 index 0000000..54057a8 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/minimizer_12x12.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/pearl_green_28x28.png b/resources/com/jtattoo/plaf/icons/medium/pearl_green_28x28.png new file mode 100644 index 0000000..c60b700 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/pearl_green_28x28.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/pearl_grey_28x28.png b/resources/com/jtattoo/plaf/icons/medium/pearl_grey_28x28.png new file mode 100644 index 0000000..c515435 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/pearl_grey_28x28.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/pearl_red_28x28.png b/resources/com/jtattoo/plaf/icons/medium/pearl_red_28x28.png new file mode 100644 index 0000000..fabf91b Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/pearl_red_28x28.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/pearl_yellow_28x28.png b/resources/com/jtattoo/plaf/icons/medium/pearl_yellow_28x28.png new file mode 100644 index 0000000..7ee0777 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/pearl_yellow_28x28.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/question_32x32.png b/resources/com/jtattoo/plaf/icons/medium/question_32x32.png new file mode 100644 index 0000000..8a9eb1a Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/question_32x32.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/tree_collapsed_11x11.png b/resources/com/jtattoo/plaf/icons/medium/tree_collapsed_11x11.png new file mode 100644 index 0000000..c8a0265 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/tree_collapsed_11x11.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/tree_expanded_11x11.png b/resources/com/jtattoo/plaf/icons/medium/tree_expanded_11x11.png new file mode 100644 index 0000000..c08eb74 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/tree_expanded_11x11.png differ diff --git a/resources/com/jtattoo/plaf/icons/medium/warning_32x32.png b/resources/com/jtattoo/plaf/icons/medium/warning_32x32.png new file mode 100644 index 0000000..2a9f5fe Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/medium/warning_32x32.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/arrow_down_7x4.png b/resources/com/jtattoo/plaf/icons/small/arrow_down_7x4.png new file mode 100644 index 0000000..275ac15 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/arrow_down_7x4.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/arrow_down_inverse_7x4.png b/resources/com/jtattoo/plaf/icons/small/arrow_down_inverse_7x4.png new file mode 100644 index 0000000..d6ebca8 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/arrow_down_inverse_7x4.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/arrow_left_4x7.png b/resources/com/jtattoo/plaf/icons/small/arrow_left_4x7.png new file mode 100644 index 0000000..2723c85 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/arrow_left_4x7.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/arrow_left_inverse_4x7.png b/resources/com/jtattoo/plaf/icons/small/arrow_left_inverse_4x7.png new file mode 100644 index 0000000..026ca70 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/arrow_left_inverse_4x7.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/arrow_right_4x7.png b/resources/com/jtattoo/plaf/icons/small/arrow_right_4x7.png new file mode 100644 index 0000000..8d6c8d7 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/arrow_right_4x7.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/arrow_right_inverse_4x7.png b/resources/com/jtattoo/plaf/icons/small/arrow_right_inverse_4x7.png new file mode 100644 index 0000000..15f31e9 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/arrow_right_inverse_4x7.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/arrow_up_7x4.png b/resources/com/jtattoo/plaf/icons/small/arrow_up_7x4.png new file mode 100644 index 0000000..1007bee Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/arrow_up_7x4.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/arrow_up_inverse_7x4.png b/resources/com/jtattoo/plaf/icons/small/arrow_up_inverse_7x4.png new file mode 100644 index 0000000..a8d48b8 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/arrow_up_inverse_7x4.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/check_symbol_10x10.png b/resources/com/jtattoo/plaf/icons/small/check_symbol_10x10.png new file mode 100644 index 0000000..2dbc1a3 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/check_symbol_10x10.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/check_symbol_disabled_10x10.png b/resources/com/jtattoo/plaf/icons/small/check_symbol_disabled_10x10.png new file mode 100644 index 0000000..3bf00da Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/check_symbol_disabled_10x10.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/closer_10x10.png b/resources/com/jtattoo/plaf/icons/small/closer_10x10.png new file mode 100644 index 0000000..60a0346 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/closer_10x10.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/cup_16x16.png b/resources/com/jtattoo/plaf/icons/small/cup_16x16.png new file mode 100644 index 0000000..d76894e Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/cup_16x16.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/document_16x16.png b/resources/com/jtattoo/plaf/icons/small/document_16x16.png new file mode 100644 index 0000000..7b8e301 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/document_16x16.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/folder_closed_16x16.png b/resources/com/jtattoo/plaf/icons/small/folder_closed_16x16.png new file mode 100644 index 0000000..434e927 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/folder_closed_16x16.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/folder_opened_16x16.png b/resources/com/jtattoo/plaf/icons/small/folder_opened_16x16.png new file mode 100644 index 0000000..cd4aa49 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/folder_opened_16x16.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/iconizer_10x10.png b/resources/com/jtattoo/plaf/icons/small/iconizer_10x10.png new file mode 100644 index 0000000..241b874 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/iconizer_10x10.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/maximizer_10x10.png b/resources/com/jtattoo/plaf/icons/small/maximizer_10x10.png new file mode 100644 index 0000000..b4dabaa Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/maximizer_10x10.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/minimizer_10x10.png b/resources/com/jtattoo/plaf/icons/small/minimizer_10x10.png new file mode 100644 index 0000000..e9f9987 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/minimizer_10x10.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/pearl_green_24x24.png b/resources/com/jtattoo/plaf/icons/small/pearl_green_24x24.png new file mode 100644 index 0000000..53ebaab Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/pearl_green_24x24.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/pearl_grey_24x24.png b/resources/com/jtattoo/plaf/icons/small/pearl_grey_24x24.png new file mode 100644 index 0000000..5bb9ccb Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/pearl_grey_24x24.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/pearl_red_24x24.png b/resources/com/jtattoo/plaf/icons/small/pearl_red_24x24.png new file mode 100644 index 0000000..95d856f Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/pearl_red_24x24.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/pearl_yellow_24x24.png b/resources/com/jtattoo/plaf/icons/small/pearl_yellow_24x24.png new file mode 100644 index 0000000..d8edbfd Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/pearl_yellow_24x24.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/tree_collapsed_9x9.png b/resources/com/jtattoo/plaf/icons/small/tree_collapsed_9x9.png new file mode 100644 index 0000000..203d4db Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/tree_collapsed_9x9.png differ diff --git a/resources/com/jtattoo/plaf/icons/small/tree_expanded_9x9.png b/resources/com/jtattoo/plaf/icons/small/tree_expanded_9x9.png new file mode 100644 index 0000000..7818f06 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/small/tree_expanded_9x9.png differ diff --git a/resources/com/jtattoo/plaf/icons/thumb_hor.gif b/resources/com/jtattoo/plaf/icons/thumb_hor.gif new file mode 100644 index 0000000..517489e Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/thumb_hor.gif differ diff --git a/resources/com/jtattoo/plaf/icons/thumb_hor_rollover.gif b/resources/com/jtattoo/plaf/icons/thumb_hor_rollover.gif new file mode 100644 index 0000000..18b5c01 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/thumb_hor_rollover.gif differ diff --git a/resources/com/jtattoo/plaf/icons/thumb_ver.gif b/resources/com/jtattoo/plaf/icons/thumb_ver.gif new file mode 100644 index 0000000..bdeb826 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/thumb_ver.gif differ diff --git a/resources/com/jtattoo/plaf/icons/thumb_ver_rollover.gif b/resources/com/jtattoo/plaf/icons/thumb_ver_rollover.gif new file mode 100644 index 0000000..21c7520 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/thumb_ver_rollover.gif differ diff --git a/resources/com/jtattoo/plaf/icons/view_detail_22x22.png b/resources/com/jtattoo/plaf/icons/view_detail_22x22.png new file mode 100644 index 0000000..bc04746 Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/view_detail_22x22.png differ diff --git a/resources/com/jtattoo/plaf/icons/view_list_22x22.png b/resources/com/jtattoo/plaf/icons/view_list_22x22.png new file mode 100644 index 0000000..99a1eda Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/view_list_22x22.png differ diff --git a/resources/com/jtattoo/plaf/icons/workplace_16x16.png b/resources/com/jtattoo/plaf/icons/workplace_16x16.png new file mode 100644 index 0000000..20416ee Binary files /dev/null and b/resources/com/jtattoo/plaf/icons/workplace_16x16.png differ diff --git a/src/com/jtattoo/plaf/About.java b/src/com/jtattoo/plaf/About.java new file mode 100644 index 0000000..e59fef9 --- /dev/null +++ b/src/com/jtattoo/plaf/About.java @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +/** + * + * @author Michael Hagen + */ + +// TODO: +// - Auf dem Mac scheint es ein Problem mit dem zeichnen des Aluminium Hintergrunds zu geben +// - setMaximizedBounds unter Linux bei multiscreen Umgebungen funktioniert nicht. Aus diesem Grund +// wird in Linux die Toolbar beim maximieren verdeckt (siehe BaseTitlePane maximize) +public class About extends JDialog { + + public static String JTATTOO_VERSION = "Version: 1.6.11"; + + private static final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + private static final Dimension dlgSize = new Dimension(440, 240); + private static final int dlgPosX = (screenSize.width / 2) - (dlgSize.width / 2); + private static final int dlgPosY = (screenSize.height / 2) - (dlgSize.height / 2); + + public About() { + super((JFrame) null, "About JTattoo"); + JPanel contentPanel = new JPanel(null); + JLabel titleLabel = new JLabel("JTattoo " + JTATTOO_VERSION); + titleLabel.setFont(new Font("Arial", Font.BOLD, 24)); + titleLabel.setBounds(0, 20, dlgSize.width - 8, 36); + titleLabel.setHorizontalAlignment(JLabel.CENTER); + contentPanel.add(titleLabel); + + JLabel copyrightLabel = new JLabel("(c) 2002 and later by MH Software-Entwicklung"); + copyrightLabel.setBounds(0, 80, dlgSize.width - 8, 20); + copyrightLabel.setHorizontalAlignment(JLabel.CENTER); + contentPanel.add(copyrightLabel); + + JButton okButton = new JButton("OK"); + okButton.setBounds((dlgSize.width - 80) / 2, 170, 80, 24); + contentPanel.add(okButton); + + setContentPane(contentPanel); + + addWindowListener(new WindowAdapter() { + + public void windowClosing(WindowEvent ev) { + System.exit(0); + } + }); + + okButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent ev) { + System.exit(0); + } + }); + } + + /** Starten der Anwendung + * @param args the command line arguments + */ + public static void main(String args[]) { + try { + UIManager.setLookAndFeel("com.jtattoo.plaf.mcwin.McWinLookAndFeel"); + About dlg = new About(); + dlg.setSize(dlgSize); + dlg.setLocation(dlgPosX, dlgPosY); + dlg.setVisible(true); + } catch (Exception ex) { + ex.printStackTrace(); + } + } +} diff --git a/src/com/jtattoo/plaf/AbstractBorderFactory.java b/src/com/jtattoo/plaf/AbstractBorderFactory.java new file mode 100644 index 0000000..e7c8297 --- /dev/null +++ b/src/com/jtattoo/plaf/AbstractBorderFactory.java @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import javax.swing.border.Border; + +/** + * @author Michael Hagen + */ +public interface AbstractBorderFactory { + + public Border getFocusFrameBorder(); + + public Border getButtonBorder(); + + public Border getToggleButtonBorder(); + + public Border getTextBorder(); + + public Border getSpinnerBorder(); + + public Border getTextFieldBorder(); + + public Border getComboBoxBorder(); + + public Border getTableHeaderBorder(); + + public Border getTableScrollPaneBorder(); + + public Border getScrollPaneBorder(); + + public Border getTabbedPaneBorder(); + + public Border getMenuBarBorder(); + + public Border getMenuItemBorder(); + + public Border getPopupMenuBorder(); + + public Border getInternalFrameBorder(); + + public Border getPaletteBorder(); + + public Border getToolBarBorder(); + + public Border getDesktopIconBorder(); + + public Border getProgressBarBorder(); +} + diff --git a/src/com/jtattoo/plaf/AbstractIconFactory.java b/src/com/jtattoo/plaf/AbstractIconFactory.java new file mode 100644 index 0000000..a2c277b --- /dev/null +++ b/src/com/jtattoo/plaf/AbstractIconFactory.java @@ -0,0 +1,118 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import javax.swing.Icon; + +/** + * @author Michael Hagen + */ +public interface AbstractIconFactory { + + public Icon getOptionPaneErrorIcon(); + + public Icon getOptionPaneWarningIcon(); + + public Icon getOptionPaneInformationIcon(); + + public Icon getOptionPaneQuestionIcon(); + + public Icon getFileChooserUpFolderIcon(); + + public Icon getFileChooserHomeFolderIcon(); + + public Icon getFileChooserNewFolderIcon(); + + public Icon getFileChooserDetailViewIcon(); + + public Icon getFileChooserListViewIcon(); + + public Icon getFileViewComputerIcon(); + + public Icon getFileViewFloppyDriveIcon(); + + public Icon getFileViewHardDriveIcon(); + + public Icon getMenuIcon(); + + public Icon getIconIcon(); + + public Icon getMaxIcon(); + + public Icon getMinIcon(); + + public Icon getCloseIcon(); + + public Icon getPaletteCloseIcon(); + + public Icon getRadioButtonIcon(); + + public Icon getCheckBoxIcon(); + + public Icon getComboBoxIcon(); + + public Icon getTreeOpenIcon(); + + public Icon getTreeCloseIcon(); + + public Icon getTreeLeafIcon(); + + public Icon getTreeCollapsedIcon(); + + public Icon getTreeExpandedIcon(); + + public Icon getMenuArrowIcon(); + + public Icon getMenuCheckBoxIcon(); + + public Icon getMenuRadioButtonIcon(); + + public Icon getUpArrowIcon(); + + public Icon getDownArrowIcon(); + + public Icon getLeftArrowIcon(); + + public Icon getRightArrowIcon(); + + public Icon getSplitterUpArrowIcon(); + + public Icon getSplitterDownArrowIcon(); + + public Icon getSplitterLeftArrowIcon(); + + public Icon getSplitterRightArrowIcon(); + + public Icon getSplitterHorBumpIcon(); + + public Icon getSplitterVerBumpIcon(); + + public Icon getThumbHorIcon(); + + public Icon getThumbVerIcon(); + + public Icon getThumbHorIconRollover(); + + public Icon getThumbVerIconRollover(); +} diff --git a/src/com/jtattoo/plaf/AbstractLookAndFeel.java b/src/com/jtattoo/plaf/AbstractLookAndFeel.java new file mode 100644 index 0000000..3f9356f --- /dev/null +++ b/src/com/jtattoo/plaf/AbstractLookAndFeel.java @@ -0,0 +1,715 @@ +/* + * Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. + * + * JTattoo is multiple licensed. If your are an open source developer you can use + * it under the terms and conditions of the GNU General Public License version 2.0 + * or later as published by the Free Software Foundation. + * + * see: gpl-2.0.txt + * + * If you pay for a license you will become a registered user who could use the + * software under the terms and conditions of the GNU Lesser General Public License + * version 2.0 or later with classpath exception as published by the Free Software + * Foundation. + * + * see: lgpl-2.0.txt + * see: classpath-exception.txt + * + * Registered users could also use JTattoo under the terms and conditions of the + * Apache License, Version 2.0 as published by the Apache Software Foundation. + * + * see: APACHE-LICENSE-2.0.txt + */ +package com.jtattoo.plaf; + +import java.awt.Color; +import java.util.ArrayList; +import javax.swing.*; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.InsetsUIResource; +import javax.swing.plaf.metal.MetalLookAndFeel; +import javax.swing.plaf.metal.MetalTheme; + +/** + * @author Michael Hagen + */ +abstract public class AbstractLookAndFeel extends MetalLookAndFeel { + + // Workaround to avoid a bug in the java 1.3 VM + static { + try { + if (JTattooUtilities.getJavaVersion() < 1.4) { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + } + } catch (Exception ex) { + } + } + + protected static String currentThemeName = "abstractTheme"; + + private static AbstractTheme myTheme = null; + + abstract public AbstractBorderFactory getBorderFactory(); + + abstract public AbstractIconFactory getIconFactory(); + + protected void initSystemColorDefaults(UIDefaults table) { + Object[] systemColors = { + "desktop", getDesktopColor(), // Color of the desktop background + + "activeCaption", getWindowTitleBackgroundColor(), // Color for captions (title bars) when they are active. + "activeCaptionLight", getWindowTitleColorLight(), + "activeCaptionDark", getWindowTitleColorDark(), + "activeCaptionText", getWindowTitleForegroundColor(), // Text color for text in captions (title bars). + "activeCaptionBorder", getWindowBorderColor(), // Border color for caption (title bar) window borders. + + "inactiveCaption", getWindowInactiveTitleBackgroundColor(), // Color for captions (title bars) when not active. + "inactiveCaptionLight", getWindowInactiveTitleColorLight(), // + "inactiveCaptionDark", getWindowInactiveTitleColorDark(), // + "inactiveCaptionText", getWindowInactiveTitleForegroundColor(), // Text color for text in inactive captions (title bars). + "inactiveCaptionBorder", getWindowInactiveBorderColor(), // Border color for inactive caption (title bar) window borders. + + "window", getInputBackgroundColor(), // Default color for the interior of windows, list, tree etc + "windowBorder", getBackgroundColor(), // ??? + "windowText", getControlForegroundColor(), // ??? + + "menu", getMenuBackgroundColor(), // Background color for menus + "menuText", getMenuForegroundColor(), // Text color for menus + "MenuBar.rolloverEnabled", Boolean.TRUE, + "text", getBackgroundColor(), // Text background color + "textText", getControlForegroundColor(), // Text foreground color + "textHighlight", getSelectionBackgroundColor(), // Text background color when selected + "textHighlightText", getSelectionForegroundColor(), // Text color when selected + "textInactiveText", getDisabledForegroundColor(), // Text color when disabled + + "control", getControlBackgroundColor(), // Default color for controls (buttons, sliders, etc) + "controlText", getControlForegroundColor(), // Default color for text in controls + "controlHighlight", getControlHighlightColor(), // Specular highlight (opposite of the shadow) + "controlLtHighlight", getControlHighlightColor(), // Highlight color for controls + "controlShadow", getControlShadowColor(), // Shadow color for controls + "controlDkShadow", getControlDarkShadowColor(), // Dark shadow color for controls + + "scrollbar", getControlBackgroundColor(), // Scrollbar background (usually the "track") + "info", getTooltipBackgroundColor(), // ToolTip Background + "infoText", getTooltipForegroundColor() // ToolTip Text + }; + + for (int i = 0; i < systemColors.length; i += 2) { + table.put((String) systemColors[i], systemColors[i + 1]); + } + } + + protected void initComponentDefaults(UIDefaults table) { + super.initComponentDefaults(table); + + BaseBorders.initDefaults(); + BaseIcons.initDefaults(); + + Object textFieldBorder = getBorderFactory().getTextFieldBorder(); + Object comboBoxBorder = getBorderFactory().getComboBoxBorder(); + Object scrollPaneBorder = getBorderFactory().getScrollPaneBorder(); + Object tableScrollPaneBorder = getBorderFactory().getTableScrollPaneBorder(); + Object tabbedPaneBorder = getBorderFactory().getTabbedPaneBorder(); + Object buttonBorder = getBorderFactory().getButtonBorder(); + Object toggleButtonBorder = getBorderFactory().getToggleButtonBorder(); + Object titledBorderBorder = new UIDefaults.ProxyLazyValue("javax.swing.plaf.BorderUIResource$LineBorderUIResource", new Object[]{getFrameColor()}); + Object menuBarBorder = getBorderFactory().getMenuBarBorder(); + Object popupMenuBorder = getBorderFactory().getPopupMenuBorder(); + Object menuItemBorder = getBorderFactory().getMenuItemBorder(); + Object toolBarBorder = getBorderFactory().getToolBarBorder(); + Object progressBarBorder = getBorderFactory().getProgressBarBorder(); + Object toolTipBorder = new UIDefaults.ProxyLazyValue("javax.swing.plaf.BorderUIResource$LineBorderUIResource", new Object[]{getFrameColor()}); + Object focusCellHighlightBorder = new UIDefaults.ProxyLazyValue("javax.swing.plaf.BorderUIResource$LineBorderUIResource", new Object[]{getFocusCellColor()}); + Object optionPaneBorder = BorderFactory.createEmptyBorder(0, 0, 0, 0); + Object optionPaneMessageAreaBorder = BorderFactory.createEmptyBorder(8, 8, 8, 8); + Object optionPaneButtonAreaBorder = BorderFactory.createEmptyBorder(0, 8, 8, 8); + Object windowBorder = getBorderFactory().getInternalFrameBorder(); + + Color c = getBackgroundColor(); + ColorUIResource progressBarBackground = new ColorUIResource(ColorHelper.brighter(c, 20)); + + // DEFAULTS TABLE + Object[] defaults = { + "controlTextFont", getControlTextFont(), + "systemTextFont ", getSystemTextFont(), + "userTextFont", getUserTextFont(), + "menuTextFont", getMenuTextFont(), + "windowTitleFont", getWindowTitleFont(), + "subTextFont", getSubTextFont(), + "Label.font", getUserTextFont(), + "Label.background", getBackgroundColor(), + "Label.foreground", getForegroundColor(), + "Label.disabledText", getDisabledForegroundColor(), + "Label.disabledShadow", getWhite(), + // Text (Note: many are inherited) + "TextField.border", textFieldBorder, + "TextField.foreground", getInputForegroundColor(), + "TextField.background", getInputBackgroundColor(), + "TextField.disabledForeground", getDisabledForegroundColor(), + "TextField.disabledBackground", getDisabledBackgroundColor(), + "TextField.inactiveForeground", getDisabledForegroundColor(), + "TextField.inactiveBackground", getDisabledBackgroundColor(), + "TextArea.foreground", getInputForegroundColor(), + "TextArea.background", getInputBackgroundColor(), + "TextArea.disabledForeground", getDisabledForegroundColor(), + "TextArea.disabledBackground", getDisabledBackgroundColor(), + "TextArea.inactiveForeground", getDisabledForegroundColor(), + "TextArea.inactiveBackground", getDisabledBackgroundColor(), + "EditorPane.foreground", getInputForegroundColor(), + "EditorPane.background", getInputBackgroundColor(), + "EditorPane.disabledForeground", getDisabledForegroundColor(), + "EditorPane.disabledBackground", getDisabledBackgroundColor(), + "EditorPane.inactiveForeground", getDisabledForegroundColor(), + "EditorPane.inactiveBackground", getDisabledBackgroundColor(), + "FormattedTextField.border", textFieldBorder, + "FormattedTextField.foreground", getInputForegroundColor(), + "FormattedTextField.background", getInputBackgroundColor(), + "FormattedTextField.disabledForeground", getDisabledForegroundColor(), + "FormattedTextField.disabledBackground", getDisabledBackgroundColor(), + "FormattedTextField.inactiveForeground", getDisabledForegroundColor(), + "FormattedTextField.inactiveBackground", getDisabledBackgroundColor(), + "PasswordField.border", textFieldBorder, + "PasswordField.foreground", getInputForegroundColor(), + "PasswordField.background", getInputBackgroundColor(), + "PasswordField.disabledForeground", getDisabledForegroundColor(), + "PasswordField.disabledBackground", getDisabledBackgroundColor(), + "PasswordField.inactiveForeground", getDisabledForegroundColor(), + "PasswordField.inactiveBackground", getDisabledBackgroundColor(), + // Buttons + "Button.background", getButtonBackgroundColor(), + "Button.foreground", getButtonForegroundColor(), + "Button.disabledText", getDisabledForegroundColor(), + "Button.disabledShadow", getWhite(), + "Button.select", getSelectionBackgroundColor(), + "Button.border", buttonBorder, + "Button.frame", getFrameColor(), + "Button.focus", getFocusColor(), + "Button.rolloverColor", getTheme().getRolloverColor(), + "Button.rolloverForeground", getTheme().getRolloverForegroundColor(), + "CheckBox.font", getUserTextFont(), + "CheckBox.background", getBackgroundColor(), + "CheckBox.foreground", getForegroundColor(), + "CheckBox.disabledText", getDisabledForegroundColor(), + "CheckBox.disabledShadow", getWhite(), + "Checkbox.select", getSelectionBackgroundColor(), + "CheckBox.focus", getFocusColor(), + "CheckBox.icon", getIconFactory().getCheckBoxIcon(), + "RadioButton.font", getUserTextFont(), + "RadioButton.background", getBackgroundColor(), + "RadioButton.foreground", getForegroundColor(), + "RadioButton.disabledText", getDisabledForegroundColor(), + "RadioButton.disabledShadow", getWhite(), + "RadioButton.select", getSelectionBackgroundColor(), + "RadioButton.icon", getIconFactory().getRadioButtonIcon(), + "RadioButton.focus", getFocusColor(), + "ToggleButton.background", getButtonBackgroundColor(), + "ToggleButton.foreground", getButtonForegroundColor(), + "ToggleButton.select", getSelectionBackgroundColor(), + "ToggleButton.text", getButtonForegroundColor(), + "ToggleButton.disabledText", getDisabledForegroundColor(), + "ToggleButton.disabledShadow", getWhite(), + "ToggleButton.disabledSelectedText", getDisabledForegroundColor(), + "ToggleButton.disabledBackground", getButtonBackgroundColor(), + "ToggleButton.disabledSelectedBackground", getSelectionBackgroundColor(), + "ToggleButton.focus", getFocusColor(), + "ToggleButton.border", toggleButtonBorder, + // ToolTip + "ToolTip.border", toolTipBorder, + "ToolTip.foreground", getTooltipForegroundColor(), + "ToolTip.background", getTooltipBackgroundColor(), + // Slider + "Slider.border", null, + "Slider.foreground", getFrameColor(), + "Slider.background", getBackgroundColor(), + "Slider.focus", getFocusColor(), + "Slider.focusInsets", new InsetsUIResource(0, 0, 0, 0), + "Slider.trackWidth", 7, + "Slider.majorTickLength", 6, + // Progress Bar + "ProgressBar.border", progressBarBorder, + "ProgressBar.background", progressBarBackground, + "ProgressBar.selectionForeground", getSelectionForegroundColor(), + "ProgressBar.selectionBackground", getForegroundColor(), + // Combo Box + "ComboBox.border", comboBoxBorder, + "ComboBox.background", getInputBackgroundColor(), + "ComboBox.foreground", getInputForegroundColor(), + "ComboBox.selectionBackground", getSelectionBackgroundColor(), + "ComboBox.selectionForeground", getSelectionForegroundColor(), + "ComboBox.selectionBorderColor", getFocusColor(), + "ComboBox.disabledBackground", getDisabledBackgroundColor(), + "ComboBox.disabledForeground", getDisabledForegroundColor(), + "ComboBox.listBackground", getInputBackgroundColor(), + "ComboBox.listForeground", getInputForegroundColor(), + "ComboBox.font", getUserTextFont(), + // Panel + "Panel.foreground", getForegroundColor(), + "Panel.background", getBackgroundColor(), + "Panel.darkBackground", getTheme().getBackgroundColorDark(), + "Panel.lightBackground", getTheme().getBackgroundColorLight(), + "Panel.alterBackground", getTheme().getAlterBackgroundColor(), + "Panel.font", getUserTextFont(), + // RootPane + "RootPane.frameBorder", windowBorder, + "RootPane.plainDialogBorder", windowBorder, + "RootPane.informationDialogBorder", windowBorder, + "RootPane.errorDialogBorder", windowBorder, + "RootPane.colorChooserDialogBorder", windowBorder, + "RootPane.fileChooserDialogBorder", windowBorder, + "RootPane.questionDialogBorder", windowBorder, + "RootPane.warningDialogBorder", windowBorder, + // InternalFrame + "InternalFrame.border", getBorderFactory().getInternalFrameBorder(), + "InternalFrame.font", getWindowTitleFont(), + "InternalFrame.paletteBorder", getBorderFactory().getPaletteBorder(), + "InternalFrame.paletteTitleHeight", 11, + "InternalFrame.paletteCloseIcon", getIconFactory().getPaletteCloseIcon(), + "InternalFrame.icon", getIconFactory().getMenuIcon(), + "InternalFrame.iconifyIcon", getIconFactory().getIconIcon(), + "InternalFrame.maximizeIcon", getIconFactory().getMaxIcon(), + "InternalFrame.altMaximizeIcon", getIconFactory().getMinIcon(), + "InternalFrame.minimizeIcon", getIconFactory().getMinIcon(), + "InternalFrame.closeIcon", getIconFactory().getCloseIcon(), + // Titled Border + "TitledBorder.titleColor", getForegroundColor(), + "TitledBorder.border", titledBorderBorder, + // List + "List.focusCellHighlightBorder", focusCellHighlightBorder, + "List.font", getUserTextFont(), + "List.foreground", getInputForegroundColor(), + "List.background", getInputBackgroundColor(), + "List.selectionForeground", getSelectionForegroundColor(), + "List.selectionBackground", getSelectionBackgroundColor(), + "List.disabledForeground", getDisabledForegroundColor(), + "List.disabledBackground", getDisabledBackgroundColor(), + // ScrollBar + "ScrollBar.background", getControlBackgroundColor(), + "ScrollBar.highlight", getControlHighlightColor(), + "ScrollBar.shadow", getControlShadowColor(), + "ScrollBar.darkShadow", getControlDarkShadowColor(), + "ScrollBar.thumb", getControlBackgroundColor(), + "ScrollBar.thumbShadow", getControlShadowColor(), + "ScrollBar.thumbHighlight", getControlHighlightColor(), + "ScrollBar.width", 17, + "ScrollBar.allowsAbsolutePositioning", Boolean.TRUE, + // ScrollPane + "ScrollPane.border", scrollPaneBorder, + "ScrollPane.foreground", getForegroundColor(), + "ScrollPane.background", getBackgroundColor(), + // Viewport + "Viewport.foreground", getForegroundColor(), + "Viewport.background", getBackgroundColor(), + "Viewport.font", getUserTextFont(), + // Tabbed Pane + "TabbedPane.boder", tabbedPaneBorder, + "TabbedPane.background", getBackgroundColor(), + "TabbedPane.tabAreaBackground", getTabAreaBackgroundColor(), + "TabbedPane.unselectedBackground", getControlColorDark(), + "TabbedPane.foreground", getControlForegroundColor(), + "TabbedPane.selected", getBackgroundColor(), + "TabbedPane.selectedForeground", getTabSelectionForegroundColor(), + "TabbedPane.tabAreaInsets", new InsetsUIResource(5, 5, 5, 5), + "TabbedPane.contentBorderInsets", new InsetsUIResource(0, 0, 0, 0), + "TabbedPane.tabInsets", new InsetsUIResource(1, 6, 1, 6), + "TabbedPane.focus", getFocusColor(), + // TabbedPane ScrollButton + "TabbedPane.selected", getButtonBackgroundColor(), + "TabbedPane.shadow", new ColorUIResource(180, 180, 180), + "TabbedPane.darkShadow", new ColorUIResource(120, 120, 120), + "TabbedPane.highlight", new ColorUIResource(Color.white), + // Tab Colors in Netbeans + "tab_unsel_fill", getControlBackgroundColor(), + "tab_sel_fill", getControlBackgroundColor(), + // Table + "Table.focusCellHighlightBorder", focusCellHighlightBorder, + "Table.scrollPaneBorder", tableScrollPaneBorder, + "Table.foreground", getInputForegroundColor(), + "Table.background", getInputBackgroundColor(), + "Table.gridColor", getGridColor(), + "TableHeader.foreground", getControlForegroundColor(), + "TableHeader.background", getBackgroundColor(), + "TableHeader.cellBorder", getBorderFactory().getTableHeaderBorder(), + // MenuBar + "MenuBar.border", menuBarBorder, + "MenuBar.foreground", getMenuForegroundColor(), + "MenuBar.background", getMenuBackgroundColor(), + // Menu + "Menu.border", menuItemBorder, + "Menu.borderPainted", Boolean.TRUE, + "Menu.foreground", getMenuForegroundColor(), + "Menu.background", getMenuBackgroundColor(), + "Menu.selectionForeground", getMenuSelectionForegroundColor(), + "Menu.selectionBackground", getMenuSelectionBackgroundColor(), + "Menu.disabledForeground", getDisabledForegroundColor(), + "Menu.acceleratorForeground", getMenuForegroundColor(), + "Menu.acceleratorSelectionForeground", getMenuSelectionForegroundColor(), + "Menu.arrowIcon", getIconFactory().getMenuArrowIcon(), + // Popup Menu + "PopupMenu.background", getMenuBackgroundColor(), + "PopupMenu.border", popupMenuBorder, + // Menu Item + "MenuItem.border", menuItemBorder, + "MenuItem.borderPainted", Boolean.TRUE, + "MenuItem.foreground", getMenuForegroundColor(), + "MenuItem.background", getMenuBackgroundColor(), + "MenuItem.selectionForeground", getMenuSelectionForegroundColor(), + "MenuItem.selectionBackground", getMenuSelectionBackgroundColor(), + "MenuItem.disabledForeground", getDisabledForegroundColor(), + "MenuItem.disabledShadow", getWhite(), + "MenuItem.acceleratorForeground", getMenuForegroundColor(), + "MenuItem.acceleratorSelectionForeground", getMenuSelectionForegroundColor(), + "CheckBoxMenuItem.border", menuItemBorder, + "CheckBoxMenuItem.borderPainted", Boolean.TRUE, + "CheckBoxMenuItem.foreground", getMenuForegroundColor(), + "CheckBoxMenuItem.background", getMenuBackgroundColor(), + "CheckBoxMenuItem.selectionForeground", getMenuSelectionForegroundColor(), + "CheckBoxMenuItem.selectionBackground", getMenuSelectionBackgroundColor(), + "CheckBoxMenuItem.disabledForeground", getDisabledForegroundColor(), + "CheckBoxMenuItem.disabledShadow", getWhite(), + "CheckBoxMenuItem.acceleratorForeground", getMenuForegroundColor(), + "CheckBoxMenuItem.acceleratorSelectionForeground", getMenuSelectionForegroundColor(), + "CheckBoxMenuItem.checkIcon", getIconFactory().getMenuCheckBoxIcon(), + "RadioButtonMenuItem.border", menuItemBorder, + "RadioButtonMenuItem.borderPainted", Boolean.TRUE, + "RadioButtonMenuItem.foreground", getMenuForegroundColor(), + "RadioButtonMenuItem.background", getMenuBackgroundColor(), + "RadioButtonMenuItem.selectionForeground", getMenuSelectionForegroundColor(), + "RadioButtonMenuItem.selectionBackground", getMenuSelectionBackgroundColor(), + "RadioButtonMenuItem.disabledForeground", getDisabledForegroundColor(), + "RadioButtonMenuItem.disabledShadow", getWhite(), + "RadioButtonMenuItem.acceleratorForeground", getMenuForegroundColor(), + "RadioButtonMenuItem.acceleratorSelectionForeground", getMenuSelectionForegroundColor(), + "RadioButtonMenuItem.checkIcon", getIconFactory().getMenuRadioButtonIcon(), + // OptionPane. + "OptionPane.errorIcon", getIconFactory().getOptionPaneErrorIcon(), + "OptionPane.informationIcon", getIconFactory().getOptionPaneInformationIcon(), + "OptionPane.warningIcon", getIconFactory().getOptionPaneWarningIcon(), + "OptionPane.questionIcon", getIconFactory().getOptionPaneQuestionIcon(), + "OptionPane.border", optionPaneBorder, + "OptionPane.messageAreaBorder", optionPaneMessageAreaBorder, + "OptionPane.buttonAreaBorder", optionPaneButtonAreaBorder, + // File View + "FileView.directoryIcon", getIconFactory().getTreeOpenIcon(), + "FileView.fileIcon", getIconFactory().getTreeLeafIcon(), + "FileView.computerIcon", getIconFactory().getFileViewComputerIcon(), + "FileView.hardDriveIcon", getIconFactory().getFileViewHardDriveIcon(), + "FileView.floppyDriveIcon", getIconFactory().getFileViewFloppyDriveIcon(), + // File Chooser + "FileChooser.upFolderIcon", getIconFactory().getFileChooserUpFolderIcon(), + "FileChooser.homeFolderIcon", getIconFactory().getFileChooserHomeFolderIcon(), + "FileChooser.newFolderIcon", getIconFactory().getFileChooserNewFolderIcon(), + "FileChooser.listViewIcon", getIconFactory().getFileChooserListViewIcon(), + "FileChooser.detailsViewIcon", getIconFactory().getFileChooserDetailViewIcon(), + "FileChooser.viewMenuIcon", getIconFactory().getFileChooserDetailViewIcon(), + // Separator + "Separator.background", getBackgroundColor(), + "Separator.foreground", getControlForegroundColor(), + // SplitPane + "SplitPane.centerOneTouchButtons", Boolean.TRUE, + "SplitPane.dividerSize", 7, + "SplitPane.border", BorderFactory.createEmptyBorder(), + // Tree + "Tree.background", getInputBackgroundColor(), + "Tree.foreground", getInputForegroundColor(), + "Tree.textForeground", getInputForegroundColor(), + "Tree.textBackground", getInputBackgroundColor(), + "Tree.selectionForeground", getSelectionForegroundColor(), + "Tree.selectionBackground", getSelectionBackgroundColor(), + "Tree.disabledForeground", getDisabledForegroundColor(), + "Tree.disabledBackground", getDisabledBackgroundColor(), + "Tree.openIcon", getIconFactory().getTreeOpenIcon(), + "Tree.closedIcon", getIconFactory().getTreeCloseIcon(), + "Tree.leafIcon", getIconFactory().getTreeLeafIcon(), + "Tree.expandedIcon", getIconFactory().getTreeExpandedIcon(), + "Tree.collapsedIcon", getIconFactory().getTreeCollapsedIcon(), + "Tree.selectionBorderColor", getFocusCellColor(), + "Tree.line", getFrameColor(), // horiz lines + "Tree.hash", getFrameColor(), // legs + + // ToolBar + "JToolBar.isRollover", Boolean.TRUE, + "ToolBar.border", toolBarBorder, + "ToolBar.background", getToolbarBackgroundColor(), + "ToolBar.foreground", getToolbarForegroundColor(), + "ToolBar.dockingBackground", getToolbarBackgroundColor(), + "ToolBar.dockingForeground", getToolbarDockingColor(), + "ToolBar.floatingBackground", getToolbarBackgroundColor(), + "ToolBar.floatingForeground", getToolbarForegroundColor(),}; + table.putDefaults(defaults); + + if (JTattooUtilities.getJavaVersion() >= 1.5) { + table.put("Spinner.font", getControlTextFont()); + table.put("Spinner.background", getButtonBackgroundColor()); + table.put("Spinner.foreground", getButtonForegroundColor()); + table.put("Spinner.border", getBorderFactory().getSpinnerBorder()); + table.put("Spinner.arrowButtonInsets", null); + table.put("Spinner.arrowButtonBorder", BorderFactory.createEmptyBorder()); + table.put("Spinner.editorBorderPainted", Boolean.FALSE); + } + if (getTheme().isMacStyleScrollBarOn()) { + if (getTheme().isSmallFontSize()) { + table.put("ScrollBar.width", 8); + table.put("SplitPane.dividerSize", 7); + } else if (getTheme().isMediumFontSize()) { + table.put("ScrollBar.width", 10); + table.put("SplitPane.dividerSize", 9); + } else { + table.put("ScrollBar.width", 12); + table.put("SplitPane.dividerSize", 11); + } + } else { + if (getTheme().isSmallFontSize()) { + table.put("ScrollBar.width", 17); + table.put("SplitPane.dividerSize", 7); + } else if (getTheme().isMediumFontSize()) { + table.put("ScrollBar.width", 19); + table.put("SplitPane.dividerSize", 9); + } else { + table.put("ScrollBar.width", 21); + table.put("SplitPane.dividerSize", 11); + } + } + } + + public static void setTheme(AbstractTheme theme) { + if (theme == null) { + return; + } + + MetalLookAndFeel.setCurrentTheme(theme); + myTheme = theme; + if (isWindowDecorationOn()) { + DecorationHelper.decorateWindows(Boolean.TRUE); + } else { + DecorationHelper.decorateWindows(Boolean.FALSE); + } + } + + /** + * Set a theme by name. Allowed themes may come from the list returned by getThemes + * + * @param name the name of the theme + */ + public static void setTheme(String name) { + // Overwrite this in derived classes + } + + public static AbstractTheme getTheme() { + return myTheme; + } + + public static MetalTheme getCurrentTheme() { + return myTheme; + } + + public static java.util.List getThemes() { + ArrayList themes = new ArrayList(); + themes.add(getTheme().getName()); + return themes; + } + + public static boolean isWindowDecorationOn() { + return getTheme().isWindowDecorationOn(); + } + + public static ColorUIResource getForegroundColor() { + return getTheme().getForegroundColor(); + } + + public static ColorUIResource getDisabledForegroundColor() { + return getTheme().getDisabledForegroundColor(); + } + + public static ColorUIResource getBackgroundColor() { + return getTheme().getBackgroundColor(); + } + + public static ColorUIResource getAlterBackgroundColor() { + return getTheme().getAlterBackgroundColor(); + } + + public static ColorUIResource getDisabledBackgroundColor() { + return getTheme().getDisabledBackgroundColor(); + } + + public static ColorUIResource getInputForegroundColor() { + return getTheme().getInputForegroundColor(); + } + + public static ColorUIResource getInputBackgroundColor() { + return getTheme().getInputBackgroundColor(); + } + + public static ColorUIResource getFocusColor() { + return getTheme().getFocusColor(); + } + + public static ColorUIResource getFocusCellColor() { + return getTheme().getFocusCellColor(); + } + + public static ColorUIResource getFrameColor() { + return getTheme().getFrameColor(); + } + + public static ColorUIResource getGridColor() { + return getTheme().getGridColor(); + } + + public static ColorUIResource getSelectionForegroundColor() { + return getTheme().getSelectionForegroundColor(); + } + + public static ColorUIResource getSelectionBackgroundColor() { + return getTheme().getSelectionBackgroundColor(); + } + + public static ColorUIResource getButtonForegroundColor() { + return getTheme().getButtonForegroundColor(); + } + + public static ColorUIResource getButtonBackgroundColor() { + return getTheme().getButtonBackgroundColor(); + } + + public static ColorUIResource getButtonColorLight() { + return getTheme().getButtonColorLight(); + } + + public static ColorUIResource getButtonColorDark() { + return getTheme().getButtonColorDark(); + } + + public static ColorUIResource getControlForegroundColor() { + return getTheme().getControlForegroundColor(); + } + + public static ColorUIResource getControlBackgroundColor() { + return getTheme().getControlBackgroundColor(); + } + + public ColorUIResource getControlHighlightColor() { + return getTheme().getControlHighlightColor(); + } + + public ColorUIResource getControlShadowColor() { + return getTheme().getControlShadowColor(); + } + + public ColorUIResource getControlDarkShadowColor() { + return getTheme().getControlDarkShadowColor(); + } + + public static ColorUIResource getControlColorLight() { + return getTheme().getControlColorLight(); + } + + public static ColorUIResource getControlColorDark() { + return getTheme().getControlColorDark(); + } + + public static ColorUIResource getWindowTitleForegroundColor() { + return getTheme().getWindowTitleForegroundColor(); + } + + public static ColorUIResource getWindowTitleBackgroundColor() { + return getTheme().getWindowTitleBackgroundColor(); + } + + public static ColorUIResource getWindowTitleColorLight() { + return getTheme().getWindowTitleColorLight(); + } + + public static ColorUIResource getWindowTitleColorDark() { + return getTheme().getWindowTitleColorDark(); + } + + public static ColorUIResource getWindowBorderColor() { + return getTheme().getWindowBorderColor(); + } + + public static ColorUIResource getWindowInactiveTitleForegroundColor() { + return getTheme().getWindowInactiveTitleForegroundColor(); + } + + public static ColorUIResource getWindowInactiveTitleBackgroundColor() { + return getTheme().getWindowInactiveTitleBackgroundColor(); + } + + public static ColorUIResource getWindowInactiveTitleColorLight() { + return getTheme().getWindowInactiveTitleColorLight(); + } + + public static ColorUIResource getWindowInactiveTitleColorDark() { + return getTheme().getWindowInactiveTitleColorDark(); + } + + public static ColorUIResource getWindowInactiveBorderColor() { + return getTheme().getWindowInactiveBorderColor(); + } + + public static ColorUIResource getMenuForegroundColor() { + return getTheme().getMenuForegroundColor(); + } + + public static ColorUIResource getMenuBackgroundColor() { + return getTheme().getMenuBackgroundColor(); + } + + public static ColorUIResource getMenuSelectionForegroundColor() { + return getTheme().getMenuSelectionForegroundColor(); + } + + public static ColorUIResource getMenuSelectionBackgroundColor() { + return getTheme().getMenuSelectionBackgroundColor(); + } + + public static ColorUIResource getMenuColorLight() { + return getTheme().getMenuColorLight(); + } + + public static ColorUIResource getMenuColorDark() { + return getTheme().getMenuColorDark(); + } + + public static ColorUIResource getToolbarForegroundColor() { + return getTheme().getToolbarForegroundColor(); + } + + public static ColorUIResource getToolbarBackgroundColor() { + return getTheme().getToolbarBackgroundColor(); + } + + public static ColorUIResource getToolbarColorLight() { + return getTheme().getToolbarColorLight(); + } + + public static ColorUIResource getToolbarColorDark() { + return getTheme().getToolbarColorDark(); + } + + public static ColorUIResource getToolbarDockingColor() { + return getTheme().getFocusColor(); + } + + public static ColorUIResource getTabAreaBackgroundColor() { + return getTheme().getTabAreaBackgroundColor(); + } + + public static ColorUIResource getTabSelectionForegroundColor() { + return getTheme().getTabSelectionForegroundColor(); + } + + public static ColorUIResource getDesktopColor() { + return getTheme().getDesktopColor(); + } + + public static ColorUIResource getTooltipForegroundColor() { + return getTheme().getTooltipForegroundColor(); + } + + public static ColorUIResource getTooltipBackgroundColor() { + return getTheme().getTooltipBackgroundColor(); + } + +} diff --git a/src/com/jtattoo/plaf/AbstractTheme.java b/src/com/jtattoo/plaf/AbstractTheme.java new file mode 100644 index 0000000..f743f40 --- /dev/null +++ b/src/com/jtattoo/plaf/AbstractTheme.java @@ -0,0 +1,1448 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.Color; +import java.awt.Font; +import java.awt.RenderingHints; +import java.io.FileInputStream; +import java.util.Properties; +import javax.swing.Icon; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.FontUIResource; +import javax.swing.plaf.metal.MetalTheme; + +public abstract class AbstractTheme extends MetalTheme { + + public static final int TEXT_ANTIALIAS_DEFAULT = 0; + public static final int TEXT_ANTIALIAS_GRAY = 1; + public static final int TEXT_ANTIALIAS_HRGB = 2; + public static final int TEXT_ANTIALIAS_HBGR = 3; + public static final int TEXT_ANTIALIAS_VRGB = 4; + public static final int TEXT_ANTIALIAS_VBGR = 5; + public static final String DIALOG = "Dialog"; + + public static final ColorUIResource red = new ColorUIResource(255, 0, 0); + public static final ColorUIResource green = new ColorUIResource(0, 255, 255); + public static final ColorUIResource cyan = new ColorUIResource(0, 255, 255); + public static final ColorUIResource white = new ColorUIResource(255, 255, 255); + public static final ColorUIResource superLightGray = new ColorUIResource(248, 248, 248); + public static final ColorUIResource extraLightGray = new ColorUIResource(232, 232, 232); + public static final ColorUIResource lightGray = new ColorUIResource(196, 196, 196); + public static final ColorUIResource gray = new ColorUIResource(164, 164, 164); + public static final ColorUIResource darkGray = new ColorUIResource(148, 148, 148); + public static final ColorUIResource extraDarkGray = new ColorUIResource(96, 96, 96); + public static final ColorUIResource black = new ColorUIResource(0, 0, 0); + public static final ColorUIResource orange = new ColorUIResource(255, 200, 0); + public static final ColorUIResource lightOrange = new ColorUIResource(255, 220, 96); + public static final ColorUIResource yellow = new ColorUIResource(255, 255, 196); + public static final ColorUIResource blue = new ColorUIResource(0, 128, 255); + public static final ColorUIResource darkBlue = new ColorUIResource(0, 64, 128); + + protected static String internalName = "Default"; + protected static boolean windowDecoration = false; + protected static boolean macStyleWindowDecoration = false; + protected static boolean centerWindowTitle = false; + protected static boolean linuxStyleScrollBar = false; + protected static boolean macStyleScrollBar = false; + protected static boolean dynamicLayout = false; + protected static boolean textShadow = false; + protected static boolean textAntiAliasing = false; + protected static int textAntiAliasingMode = TEXT_ANTIALIAS_HRGB; + protected static boolean backgroundPattern = true; + protected static boolean brightMode = false; + protected static boolean showFocusFrame = false; + protected static boolean drawSquareButtons = false; + protected static boolean toolbarDecorated = true; + + protected static boolean menuOpaque = true; + protected static float menuAlpha = 0.9f; + protected static String logoString = "JTattoo"; + protected static FontUIResource controlFont = null; + protected static FontUIResource systemFont = null; + protected static FontUIResource userFont = null; + protected static FontUIResource smallFont = null; + protected static FontUIResource menuFont = null; + protected static FontUIResource windowTitleFont = null; + protected static ColorUIResource foregroundColor = null; + protected static ColorUIResource backgroundColor = null; + protected static ColorUIResource backgroundColorLight = null; + protected static ColorUIResource backgroundColorDark = null; + protected static ColorUIResource alterBackgroundColor = null; + protected static ColorUIResource disabledForegroundColor = null; + protected static ColorUIResource disabledBackgroundColor = null; + protected static ColorUIResource inputBackgroundColor = null; + protected static ColorUIResource inputForegroundColor = null; + protected static ColorUIResource selectionForegroundColor = null; + protected static ColorUIResource selectionBackgroundColorLight = null; + protected static ColorUIResource selectionBackgroundColorDark = null; + protected static ColorUIResource selectionBackgroundColor = null; + protected static ColorUIResource rolloverForegroundColor = null; + protected static ColorUIResource rolloverColor = null; + protected static ColorUIResource rolloverColorLight = null; + protected static ColorUIResource rolloverColorDark = null; + protected static ColorUIResource pressedForegroundColor = null; + protected static ColorUIResource focusColor = null; + protected static ColorUIResource focusCellColor = null; + protected static ColorUIResource focusFrameColor = null; + protected static ColorUIResource focusBackgroundColor = null; + protected static ColorUIResource focusForegroundColor = null; + protected static ColorUIResource frameColor = null; + protected static ColorUIResource gridColor = null; + protected static ColorUIResource shadowColor = null; + protected static ColorUIResource buttonForegroundColor = null; + protected static ColorUIResource buttonBackgroundColor = null; + protected static ColorUIResource buttonColorLight = null; + protected static ColorUIResource buttonColorDark = null; + protected static ColorUIResource controlForegroundColor = null; + protected static ColorUIResource controlBackgroundColor = null; + protected static ColorUIResource controlHighlightColor = null; + protected static ColorUIResource controlShadowColor = null; + protected static ColorUIResource controlDarkShadowColor = null; + protected static ColorUIResource controlColorLight = null; + protected static ColorUIResource controlColorDark = null; + protected static ColorUIResource windowTitleForegroundColor = null; + protected static ColorUIResource windowTitleBackgroundColor = null; + protected static ColorUIResource windowTitleColorLight = null; + protected static ColorUIResource windowTitleColorDark = null; + protected static ColorUIResource windowBorderColor = null; + protected static ColorUIResource windowIconColor = null; + protected static ColorUIResource windowIconShadowColor = null; + protected static ColorUIResource windowIconRolloverColor = null; + + protected static ColorUIResource windowInactiveTitleForegroundColor = null; + protected static ColorUIResource windowInactiveTitleBackgroundColor = null; + protected static ColorUIResource windowInactiveTitleColorLight = null; + protected static ColorUIResource windowInactiveTitleColorDark = null; + protected static ColorUIResource windowInactiveBorderColor = null; + protected static ColorUIResource menuForegroundColor = null; + protected static ColorUIResource menuBackgroundColor = null; + protected static ColorUIResource menuSelectionForegroundColor = null; + protected static ColorUIResource menuSelectionBackgroundColor = null; + protected static ColorUIResource menuSelectionBackgroundColorLight = null; + protected static ColorUIResource menuSelectionBackgroundColorDark = null; + protected static ColorUIResource menuColorLight = null; + protected static ColorUIResource menuColorDark = null; + protected static ColorUIResource toolbarForegroundColor = null; + protected static ColorUIResource toolbarBackgroundColor = null; + protected static ColorUIResource toolbarColorLight = null; + protected static ColorUIResource toolbarColorDark = null; + protected static ColorUIResource tabAreaBackgroundColor = null; + protected static ColorUIResource tabSelectionForegroundColor = null; + protected static ColorUIResource desktopColor = null; + protected static ColorUIResource tooltipForegroundColor = null; + protected static ColorUIResource tooltipBackgroundColor = null; + protected static int tooltipBorderSize = 6; + protected static int tooltipShadowSize = 6; + protected static boolean tooltipCastShadow = false; + + protected static Color DEFAULT_COLORS[] = null; + protected static Color HIDEFAULT_COLORS[] = null; + protected static Color ACTIVE_COLORS[] = null; + protected static Color INACTIVE_COLORS[] = null; + protected static Color ROLLOVER_COLORS[] = null; + protected static Color SELECTED_COLORS[] = null; + protected static Color SELECTION_COLORS[] = null; + protected static Color FOCUS_COLORS[] = null; + protected static Color MENU_SELECTION_COLORS[] = null; + protected static Color PRESSED_COLORS[] = null; + protected static Color DISABLED_COLORS[] = null; + protected static Color WINDOW_TITLE_COLORS[] = null; + protected static Color WINDOW_INACTIVE_TITLE_COLORS[] = null; + protected static Color TOOLBAR_COLORS[] = null; + protected static Color MENUBAR_COLORS[] = null; + protected static Color BUTTON_COLORS[] = null; + protected static Color CHECKBOX_COLORS[] = null; + protected static Color TAB_COLORS[] = null; + protected static Color COL_HEADER_COLORS[] = null; + protected static Color TRACK_COLORS[] = null; + protected static Color THUMB_COLORS[] = null; + protected static Color SLIDER_COLORS[] = null; + protected static Color PROGRESSBAR_COLORS[] = null; + + protected static String textureSet = "Default"; + protected static boolean darkTexture = true; + protected static Icon windowTexture = null; + protected static Icon backgroundTexture = null; + protected static Icon alterBackgroundTexture = null; + protected static Icon selectedTexture = null; + protected static Icon rolloverTexture = null; + protected static Icon pressedTexture = null; + protected static Icon disabledTexture = null; + protected static Icon menubarTexture = null; + + public AbstractTheme() { + super(); + } + + public String getName() { + return getInternalName(); + } + + public static String getInternalName() { + return internalName; + } + + public static void setInternalName(String name) { + internalName = name; + } + + public String getPropertyFileName() { + return "JTattooTheme.properties"; + } + + public void setUpColor() { + windowDecoration = true; + macStyleWindowDecoration = JTattooUtilities.isMac(); + centerWindowTitle = JTattooUtilities.isWindows() && JTattooUtilities.getOSVersion() >= 6.2; + linuxStyleScrollBar = !JTattooUtilities.isWindows(); + macStyleScrollBar = JTattooUtilities.isMac(); + dynamicLayout = true; + textShadow = false; + textAntiAliasing = false; + textAntiAliasingMode = TEXT_ANTIALIAS_HRGB; + backgroundPattern = true; + brightMode = false; + showFocusFrame = false; + drawSquareButtons = false; + toolbarDecorated = true; + menuOpaque = true; + menuAlpha = 0.9f; + logoString = "JTattoo"; + + controlFont = null; + systemFont = null; + userFont = null; + smallFont = null; + menuFont = null; + windowTitleFont = null; + + foregroundColor = black; + backgroundColor = extraLightGray; + backgroundColorLight = white; + backgroundColorDark = extraLightGray; + alterBackgroundColor = lightGray; + disabledForegroundColor = gray; + disabledBackgroundColor = superLightGray; + inputBackgroundColor = white; + inputForegroundColor = black; + selectionForegroundColor = black; + selectionBackgroundColor = lightGray; + selectionBackgroundColorLight = extraLightGray; + selectionBackgroundColorDark = lightGray; + focusColor = orange; + focusCellColor = orange; + focusFrameColor = new ColorUIResource(230, 191, 116); + focusBackgroundColor = new ColorUIResource(255, 250, 212); + focusForegroundColor = black; + frameColor = darkGray; + gridColor = gray; + shadowColor = new ColorUIResource(0, 24, 0); + + rolloverForegroundColor = black; + rolloverColor = extraLightGray; + rolloverColorLight = white; + rolloverColorDark = extraLightGray; + + pressedForegroundColor = black; + + buttonForegroundColor = black; + buttonBackgroundColor = lightGray; + buttonColorLight = white; + buttonColorDark = lightGray; + + controlForegroundColor = black; + controlBackgroundColor = lightGray; + controlHighlightColor = white; + controlShadowColor = lightGray; + controlDarkShadowColor = darkGray; + controlColorLight = white; + controlColorDark = lightGray; + + windowTitleForegroundColor = black; + windowTitleBackgroundColor = blue; + windowTitleColorLight = extraLightGray; + windowTitleColorDark = lightGray; + windowBorderColor = lightGray; + windowIconColor = black; + windowIconShadowColor = white; + windowIconRolloverColor = red; + + windowInactiveTitleForegroundColor = black; + windowInactiveTitleBackgroundColor = extraLightGray; + windowInactiveTitleColorLight = white; + windowInactiveTitleColorDark = extraLightGray; + windowInactiveBorderColor = extraLightGray; + + menuForegroundColor = black; + menuBackgroundColor = extraLightGray; + menuSelectionForegroundColor = black; + menuSelectionBackgroundColor = lightGray; + menuSelectionBackgroundColorLight = extraLightGray; + menuSelectionBackgroundColorDark = lightGray; + menuColorLight = extraLightGray; + menuColorDark = lightGray; + + toolbarForegroundColor = black; + toolbarBackgroundColor = lightGray; + toolbarColorLight = white; + toolbarColorDark = lightGray; + + tabAreaBackgroundColor = backgroundColor; + tabSelectionForegroundColor = selectionForegroundColor; + desktopColor = darkBlue; + tooltipForegroundColor = black; + tooltipBackgroundColor = yellow; + tooltipBorderSize = 6; + tooltipShadowSize = 6; + tooltipCastShadow = false; + + textureSet = "Default"; + darkTexture = true; + } + + public void setUpColorArrs() { + DEFAULT_COLORS = ColorHelper.createColorArr(controlColorLight, controlColorDark, 20); + HIDEFAULT_COLORS = ColorHelper.createColorArr(ColorHelper.brighter(controlColorLight, 40), ColorHelper.brighter(controlColorDark, 40), 20); + ACTIVE_COLORS = DEFAULT_COLORS; + INACTIVE_COLORS = HIDEFAULT_COLORS; + ROLLOVER_COLORS = ColorHelper.createColorArr(rolloverColorLight, rolloverColorDark, 20); + SELECTED_COLORS = DEFAULT_COLORS; + SELECTION_COLORS = ColorHelper.createColorArr(selectionBackgroundColorLight, selectionBackgroundColorDark, 20); + FOCUS_COLORS = ColorHelper.createColorArr(ColorHelper.brighter(focusBackgroundColor, 20), ColorHelper.darker(focusBackgroundColor, 10), 20); + MENU_SELECTION_COLORS = ColorHelper.createColorArr(menuSelectionBackgroundColorLight, menuSelectionBackgroundColorDark, 20); + PRESSED_COLORS = DEFAULT_COLORS; + DISABLED_COLORS = HIDEFAULT_COLORS; + WINDOW_TITLE_COLORS = ColorHelper.createColorArr(windowTitleColorLight, windowTitleColorDark, 20); + WINDOW_INACTIVE_TITLE_COLORS = ColorHelper.createColorArr(windowInactiveTitleColorLight, windowInactiveTitleColorDark, 20); + TOOLBAR_COLORS = ColorHelper.createColorArr(toolbarColorLight, toolbarColorDark, 20); + MENUBAR_COLORS = ColorHelper.createColorArr(menuColorLight, menuColorDark, 20); + BUTTON_COLORS = ColorHelper.createColorArr(buttonColorLight, buttonColorDark, 20); + CHECKBOX_COLORS = DEFAULT_COLORS; + TAB_COLORS = DEFAULT_COLORS; + COL_HEADER_COLORS = DEFAULT_COLORS; + TRACK_COLORS = ColorHelper.createColorArr(new Color(220, 220, 220), Color.white, 20); + THUMB_COLORS = DEFAULT_COLORS; + SLIDER_COLORS = DEFAULT_COLORS; + PROGRESSBAR_COLORS = DEFAULT_COLORS; + } + + public void setProperties(Properties props) { + if (props != null) { + if (props.getProperty("windowDecoration") != null) { + windowDecoration = props.getProperty("windowDecoration").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("macStyleWindowDecoration") != null) { + macStyleWindowDecoration = props.getProperty("macStyleWindowDecoration").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("centerWindowTitle") != null) { + centerWindowTitle = props.getProperty("centerWindowTitle").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("linuxStyleScrollBar") != null) { + linuxStyleScrollBar = props.getProperty("linuxStyleScrollBar").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("macStyleScrollBar") != null) { + macStyleScrollBar = props.getProperty("macStyleScrollBar").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("dynamicLayout") != null) { + dynamicLayout = props.getProperty("dynamicLayout").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("textShadow") != null) { + textShadow = props.getProperty("textShadow").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("textAntiAliasing") != null) { + textAntiAliasing = props.getProperty("textAntiAliasing").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("textAntiAliasingMode") != null) { + String mode = props.getProperty("textAntiAliasingMode"); + if (mode.equalsIgnoreCase("default")) { + textAntiAliasingMode = TEXT_ANTIALIAS_DEFAULT; + } + if (mode.equalsIgnoreCase("gray")) { + textAntiAliasingMode = TEXT_ANTIALIAS_GRAY; + } + if (mode.equalsIgnoreCase("hrgb")) { + textAntiAliasingMode = TEXT_ANTIALIAS_HRGB; + } + if (mode.equalsIgnoreCase("hbgr")) { + textAntiAliasingMode = TEXT_ANTIALIAS_HBGR; + } + if (mode.equalsIgnoreCase("vrgb")) { + textAntiAliasingMode = TEXT_ANTIALIAS_VRGB; + } + if (mode.equalsIgnoreCase("vbgr")) { + textAntiAliasingMode = TEXT_ANTIALIAS_VBGR; + } + } + if (props.getProperty("backgroundPattern") != null) { + backgroundPattern = props.getProperty("backgroundPattern").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("brightMode") != null) { + brightMode = props.getProperty("brightMode").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("showFocusFrame") != null) { + showFocusFrame = props.getProperty("showFocusFrame").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("drawSquareButtons") != null) { + drawSquareButtons = props.getProperty("drawSquareButtons").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("toolbarDecorated") != null) { + toolbarDecorated = props.getProperty("toolbarDecorated").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("menuOpaque") != null) { + menuOpaque = props.getProperty("menuOpaque").trim().equalsIgnoreCase("on"); + } + if (props.getProperty("logoString") != null) { + logoString = props.getProperty("logoString").trim(); + } + if (props.getProperty("controlTextFont") != null) { + controlFont = createFont(props.getProperty("controlTextFont")); + } + if (props.getProperty("systemTextFont") != null) { + systemFont = createFont(props.getProperty("systemTextFont")); + } + if (props.getProperty("userTextFont") != null) { + userFont = createFont(props.getProperty("userTextFont")); + } + if (props.getProperty("menuTextFont") != null) { + menuFont = createFont(props.getProperty("menuTextFont")); + } + if (props.getProperty("windowTitleFont") != null) { + windowTitleFont = createFont(props.getProperty("windowTitleFont")); + } + if (props.getProperty("subTextFont") != null) { + smallFont = createFont(props.getProperty("subTextFont")); + } + + if (props.getProperty("foregroundColor") != null) { + foregroundColor = createColor(props.getProperty("foregroundColor"), foregroundColor); + } + if (props.getProperty("backgroundColor") != null) { + backgroundColor = createColor(props.getProperty("backgroundColor"), backgroundColor); + } + if (props.getProperty("backgroundColorLight") != null) { + backgroundColorLight = createColor(props.getProperty("backgroundColorLight"), backgroundColorLight); + } + if (props.getProperty("backgroundColorDark") != null) { + backgroundColorDark = createColor(props.getProperty("backgroundColorDark"), backgroundColorDark); + } + if (props.getProperty("alterBackgroundColor") != null) { + alterBackgroundColor = createColor(props.getProperty("alterBackgroundColor"), alterBackgroundColor); + } + if (props.getProperty("disabledForegroundColor") != null) { + disabledForegroundColor = createColor(props.getProperty("disabledForegroundColor"), disabledForegroundColor); + } + if (props.getProperty("disabledBackgroundColor") != null) { + disabledBackgroundColor = createColor(props.getProperty("disabledBackgroundColor"), disabledBackgroundColor); + } + if (props.getProperty("inputForegroundColor") != null) { + inputForegroundColor = createColor(props.getProperty("inputForegroundColor"), inputForegroundColor); + } + if (props.getProperty("inputBackgroundColor") != null) { + inputBackgroundColor = createColor(props.getProperty("inputBackgroundColor"), inputBackgroundColor); + } + if (props.getProperty("selectionForegroundColor") != null) { + selectionForegroundColor = createColor(props.getProperty("selectionForegroundColor"), selectionForegroundColor); + } + if (props.getProperty("selectionBackgroundColor") != null) { + selectionBackgroundColor = createColor(props.getProperty("selectionBackgroundColor"), selectionBackgroundColor); + } + if (props.getProperty("selectionBackgroundColorLight") != null) { + selectionBackgroundColorLight = createColor(props.getProperty("selectionBackgroundColorLight"), selectionBackgroundColorLight); + } + if (props.getProperty("selectionBackgroundColorDark") != null) { + selectionBackgroundColorDark = createColor(props.getProperty("selectionBackgroundColorDark"), selectionBackgroundColorDark); + } + if (props.getProperty("frameColor") != null) { + frameColor = createColor(props.getProperty("frameColor"), frameColor); + } + if (props.getProperty("gridColor") != null) { + gridColor = createColor(props.getProperty("gridColor"), gridColor); + } + if (props.getProperty("shadowColor") != null) { + shadowColor = createColor(props.getProperty("shadowColor"), shadowColor); + } + if (props.getProperty("focusColor") != null) { + focusColor = createColor(props.getProperty("focusColor"), focusColor); + } + if (props.getProperty("focusCellColor") != null) { + focusCellColor = createColor(props.getProperty("focusCellColor"), focusCellColor); + } + if (props.getProperty("focusFrameColor") != null) { + focusFrameColor = createColor(props.getProperty("focusFrameColor"), focusFrameColor); + } + if (props.getProperty("focusBackgroundColor") != null) { + focusBackgroundColor = createColor(props.getProperty("focusBackgroundColor"), focusBackgroundColor); + } + if (props.getProperty("focusForegroundColor") != null) { + focusForegroundColor = createColor(props.getProperty("focusForegroundColor"), focusForegroundColor); + } + + if (props.getProperty("rolloverForegroundColor") != null) { + rolloverForegroundColor = createColor(props.getProperty("rolloverForegroundColor"), rolloverForegroundColor); + } + if (props.getProperty("rolloverColor") != null) { + rolloverColor = createColor(props.getProperty("rolloverColor"), rolloverColor); + } + if (props.getProperty("rolloverColorLight") != null) { + rolloverColorLight = createColor(props.getProperty("rolloverColorLight"), rolloverColorLight); + } + if (props.getProperty("rolloverColorDark") != null) { + rolloverColorDark = createColor(props.getProperty("rolloverColorDark"), rolloverColorDark); + } + if (props.getProperty("pressedForegroundColor") != null) { + pressedForegroundColor = createColor(props.getProperty("pressedForegroundColor"), pressedForegroundColor); + } + + if (props.getProperty("buttonForegroundColor") != null) { + buttonForegroundColor = createColor(props.getProperty("buttonForegroundColor"), buttonForegroundColor); + } + if (props.getProperty("buttonBackgroundColor") != null) { + buttonBackgroundColor = createColor(props.getProperty("buttonBackgroundColor"), buttonBackgroundColor); + } + if (props.getProperty("buttonColorLight") != null) { + buttonColorLight = createColor(props.getProperty("buttonColorLight"), buttonColorLight); + } + if (props.getProperty("buttonColorDark") != null) { + buttonColorDark = createColor(props.getProperty("buttonColorDark"), buttonColorDark); + } + + if (props.getProperty("controlForegroundColor") != null) { + controlForegroundColor = createColor(props.getProperty("controlForegroundColor"), controlForegroundColor); + } + if (props.getProperty("controlBackgroundColor") != null) { + controlBackgroundColor = createColor(props.getProperty("controlBackgroundColor"), controlBackgroundColor); + } + if (props.getProperty("controlColorLight") != null) { + controlColorLight = createColor(props.getProperty("controlColorLight"), controlColorLight); + } + if (props.getProperty("controlColorDark") != null) { + controlColorDark = createColor(props.getProperty("controlColorDark"), controlColorDark); + } + if (props.getProperty("controlHighlightColor") != null) { + controlHighlightColor = createColor(props.getProperty("controlHighlightColor"), controlHighlightColor); + } + if (props.getProperty("controlShadowColor") != null) { + controlShadowColor = createColor(props.getProperty("controlShadowColor"), controlShadowColor); + } + if (props.getProperty("controlDarkShadowColor") != null) { + controlDarkShadowColor = createColor(props.getProperty("controlDarkShadowColor"), controlDarkShadowColor); + } + + if (props.getProperty("windowTitleForegroundColor") != null) { + windowTitleForegroundColor = createColor(props.getProperty("windowTitleForegroundColor"), windowTitleForegroundColor); + } + if (props.getProperty("windowTitleBackgroundColor") != null) { + windowTitleBackgroundColor = createColor(props.getProperty("windowTitleBackgroundColor"), windowTitleBackgroundColor); + } + if (props.getProperty("windowTitleColorLight") != null) { + windowTitleColorLight = createColor(props.getProperty("windowTitleColorLight"), windowTitleColorLight); + } + if (props.getProperty("windowTitleColorDark") != null) { + windowTitleColorDark = createColor(props.getProperty("windowTitleColorDark"), windowTitleColorDark); + } + if (props.getProperty("windowBorderColor") != null) { + windowBorderColor = createColor(props.getProperty("windowBorderColor"), windowBorderColor); + } + if (props.getProperty("windowIconColor") != null) { + windowIconColor = createColor(props.getProperty("windowIconColor"), windowIconColor); + } + if (props.getProperty("windowIconShadowColor") != null) { + windowIconShadowColor = createColor(props.getProperty("windowIconShadowColor"), windowIconShadowColor); + } + if (props.getProperty("windowIconRolloverColor") != null) { + windowIconRolloverColor = createColor(props.getProperty("windowIconRolloverColor"), windowIconRolloverColor); + } + + if (props.getProperty("windowInactiveTitleForegroundColor") != null) { + windowInactiveTitleForegroundColor = createColor(props.getProperty("windowInactiveTitleForegroundColor"), windowInactiveTitleForegroundColor); + } + if (props.getProperty("windowTitleBackgroundColor") != null) { + windowInactiveTitleBackgroundColor = createColor(props.getProperty("windowInactiveTitleBackgroundColor"), windowInactiveTitleBackgroundColor); + } + if (props.getProperty("windowInactiveTitleColorLight") != null) { + windowInactiveTitleColorLight = createColor(props.getProperty("windowInactiveTitleColorLight"), windowInactiveTitleColorLight); + } + if (props.getProperty("windowInactiveTitleColorDark") != null) { + windowInactiveTitleColorDark = createColor(props.getProperty("windowInactiveTitleColorDark"), windowInactiveTitleColorDark); + } + if (props.getProperty("windowInactiveBorderColor") != null) { + windowInactiveBorderColor = createColor(props.getProperty("windowInactiveBorderColor"), windowInactiveBorderColor); + } + + if (props.getProperty("menuForegroundColor") != null) { + menuForegroundColor = createColor(props.getProperty("menuForegroundColor"), menuForegroundColor); + } + if (props.getProperty("menuBackgroundColor") != null) { + menuBackgroundColor = createColor(props.getProperty("menuBackgroundColor"), menuBackgroundColor); + } + if (props.getProperty("menuSelectionForegroundColor") != null) { + menuSelectionForegroundColor = createColor(props.getProperty("menuSelectionForegroundColor"), menuSelectionForegroundColor); + } + if (props.getProperty("menuSelectionBackgroundColor") != null) { + menuSelectionBackgroundColor = createColor(props.getProperty("menuSelectionBackgroundColor"), menuSelectionBackgroundColor); + } + if (props.getProperty("menuSelectionBackgroundColorLight") != null) { + menuSelectionBackgroundColorLight = createColor(props.getProperty("menuSelectionBackgroundColorLight"), menuSelectionBackgroundColorLight); + } + if (props.getProperty("menuSelectionBackgroundColorDark") != null) { + menuSelectionBackgroundColorDark = createColor(props.getProperty("menuSelectionBackgroundColorDark"), menuSelectionBackgroundColorDark); + } + if (props.getProperty("menuColorLight") != null) { + menuColorLight = createColor(props.getProperty("menuColorLight"), menuColorLight); + } + if (props.getProperty("menuColorDark") != null) { + menuColorDark = createColor(props.getProperty("menuColorDark"), menuColorDark); + } + + if (props.getProperty("toolbarForegroundColor") != null) { + toolbarForegroundColor = createColor(props.getProperty("toolbarForegroundColor"), toolbarForegroundColor); + } + if (props.getProperty("toolbarBackgroundColor") != null) { + toolbarBackgroundColor = createColor(props.getProperty("toolbarBackgroundColor"), toolbarBackgroundColor); + } + if (props.getProperty("toolbarColorLight") != null) { + toolbarColorLight = createColor(props.getProperty("toolbarColorLight"), toolbarColorLight); + } + if (props.getProperty("toolbarColorDark") != null) { + toolbarColorDark = createColor(props.getProperty("toolbarColorDark"), toolbarColorDark); + } + + if (props.getProperty("tabAreaBackgroundColor") != null) { + tabAreaBackgroundColor = createColor(props.getProperty("tabAreaBackgroundColor"), tabAreaBackgroundColor); + } else { + tabAreaBackgroundColor = backgroundColor; + } + if (props.getProperty("tabSelectionForegroundColor") != null) { + tabSelectionForegroundColor = createColor(props.getProperty("tabSelectionForegroundColor"), tabSelectionForegroundColor); + } + + if (props.getProperty("desktopColor") != null) { + desktopColor = createColor(props.getProperty("desktopColor"), desktopColor); + } + if (props.getProperty("tooltipForegroundColor") != null) { + tooltipForegroundColor = createColor(props.getProperty("tooltipForegroundColor"), tooltipForegroundColor); + } + if (props.getProperty("tooltipBackgroundColor") != null) { + tooltipBackgroundColor = createColor(props.getProperty("tooltipBackgroundColor"), tooltipBackgroundColor); + } + if (props.getProperty("tooltipBorderSize") != null) { + tooltipBorderSize = createInt(props.getProperty("tooltipBorderSize"), tooltipBorderSize); + } + if (props.getProperty("tooltipShadowSize") != null) { + tooltipShadowSize = createInt(props.getProperty("tooltipShadowSize"), tooltipShadowSize); + } + if (props.getProperty("tooltipCastShadow") != null) { + tooltipCastShadow = props.getProperty("tooltipCastShadow").trim().equalsIgnoreCase("on"); + } + + if (props.getProperty("textureSet") != null) { + textureSet = props.getProperty("textureSet"); + } + if (props.getProperty("darkTexture") != null) { + darkTexture = props.getProperty("darkTexture").trim().equalsIgnoreCase("on"); + } + if (props.get("windowTexture") != null) { + Object texture = props.get("windowTexture"); + if (texture instanceof Icon) { + windowTexture = (Icon)texture; + } + } + if (props.get("backgroundTexture") != null) { + Object texture = props.get("backgroundTexture"); + if (texture instanceof Icon) { + backgroundTexture = (Icon)texture; + } + } + if (props.get("alterBackgroundTexture") != null) { + Object texture = props.get("alterBackgroundTexture"); + if (texture instanceof Icon) { + alterBackgroundTexture = (Icon)texture; + } + } + if (props.get("selectedTexture") != null) { + Object texture = props.get("selectedTexture"); + if (texture instanceof Icon) { + selectedTexture = (Icon)texture; + } + } + if (props.get("rolloverTexture") != null) { + Object texture = props.get("rolloverTexture"); + if (texture instanceof Icon) { + rolloverTexture = (Icon)texture; + } + } + if (props.get("pressedTexture") != null) { + Object texture = props.get("pressedTexture"); + if (texture instanceof Icon) { + pressedTexture = (Icon)texture; + } + } + if (props.get("disabledTexture") != null) { + Object texture = props.get("disabledTexture"); + if (texture instanceof Icon) { + disabledTexture = (Icon)texture; + } + } + if (props.get("menubarTexture") != null) { + Object texture = props.get("menubarTexture"); + if (texture instanceof Icon) { + menubarTexture = (Icon)texture; + } + } + } + } + + public void loadProperties() { + FileInputStream in = null; + try { + String fileName = System.getProperty("user.home") + "/.jtattoo/" + getPropertyFileName(); + Properties props = new Properties(); + in = new FileInputStream(fileName); + props.load(in); + setProperties(props); + } catch (Exception ex) { + } finally { + try { + if (in != null) { + in.close(); + } + } catch (Exception ex) { + } + } + } + + protected static FontUIResource createFont(String fontProp) { + if ((fontProp != null) && (fontProp.trim().length() > 5)) { + return new FontUIResource(Font.decode(fontProp)); + } + return null; + } + + protected static ColorUIResource createColor(String colorProp, ColorUIResource color) { + if ((colorProp != null) && (colorProp.trim().length() >= 5)) { + colorProp = colorProp.trim(); + int r = color.getRed(); + int g = color.getGreen(); + int b = color.getBlue(); + try { + int p1 = 0; + int p2 = colorProp.indexOf(' '); + if (p2 > 0) { + r = Integer.parseInt(colorProp.substring(p1, p2)); + } + p1 = p2 + 1; + p2 = colorProp.indexOf(' ', p1); + if (p2 > 0) { + g = Integer.parseInt(colorProp.substring(p1, p2)); + } + b = Integer.parseInt(colorProp.substring(p2 + 1)); + return new ColorUIResource(r, g, b); + } catch (Exception ex) { + System.out.println("Exception while parsing color: " + colorProp); + } + } + return color; + } + + protected static int createInt(String intProp, int defaultValue) { + int val = defaultValue; + try { + val = Integer.parseInt(intProp); + } catch (Exception ex) { + System.out.println("Exception while parsing color: " + intProp); + } + return val; + } + + public boolean isTinyFontSize() { + return userFont.getSize() < 12; + } + + public boolean isSmallFontSize() { + return userFont.getSize() < 14; + } + + public boolean isMediumFontSize() { + return userFont.getSize() >= 14 && userFont.getSize() < 16; + } + + public boolean isLargeFontSize() { + return userFont.getSize() >= 16; + } + + public FontUIResource getControlTextFont() { + if (controlFont == null) { + if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) { + controlFont = new FontUIResource(DIALOG, Font.BOLD, 14); + } else { + controlFont = new FontUIResource(DIALOG, Font.PLAIN, 12); + } + } + return controlFont; + } + + public FontUIResource getSystemTextFont() { + if (systemFont == null) { + if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) { + systemFont = new FontUIResource(DIALOG, Font.BOLD, 14); + } else { + systemFont = new FontUIResource(DIALOG, Font.PLAIN, 12); + } + } + return systemFont; + } + + public FontUIResource getUserTextFont() { + if (userFont == null) { + if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) { + userFont = new FontUIResource(DIALOG, Font.BOLD, 14); + } else { + userFont = new FontUIResource(DIALOG, Font.PLAIN, 12); + } + } + return userFont; + } + + public FontUIResource getMenuTextFont() { + if (menuFont == null) { + if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) { + menuFont = new FontUIResource(DIALOG, Font.BOLD, 14); + } else { + menuFont = new FontUIResource(DIALOG, Font.PLAIN, 12); + } + } + return menuFont; + } + + public FontUIResource getWindowTitleFont() { + if (windowTitleFont == null) { + if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) { + windowTitleFont = new FontUIResource(DIALOG, Font.BOLD, 14); + } else { + windowTitleFont = new FontUIResource(DIALOG, Font.BOLD, 12); + } + } + return windowTitleFont; + } + + public FontUIResource getSubTextFont() { + if (smallFont == null) { + if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) { + smallFont = new FontUIResource(DIALOG, Font.BOLD, 12); + } else { + smallFont = new FontUIResource(DIALOG, Font.PLAIN, 10); + } + } + return smallFont; + } + + //----------------------------------------------------------------------------------- + protected ColorUIResource getPrimary1() { + return foregroundColor; + } + + protected ColorUIResource getPrimary2() { + return desktopColor; + } + + protected ColorUIResource getPrimary3() { + return selectionBackgroundColor; + } + + protected ColorUIResource getSecondary1() { + return frameColor; + } + + protected ColorUIResource getSecondary2() { + return controlBackgroundColor; + } + + protected ColorUIResource getSecondary3() { + return backgroundColor; + } + + public ColorUIResource getControl() { + return controlBackgroundColor; + } + + public ColorUIResource getControlShadow() { + return controlShadowColor; + } + + public ColorUIResource getControlDarkShadow() { + return controlDarkShadowColor; + } + + public ColorUIResource getControlInfo() { + return controlForegroundColor; + } + + public ColorUIResource getControlHighlight() { + return controlHighlightColor; + } + + public ColorUIResource getControlDisabled() { + return controlShadowColor; + } + + public ColorUIResource getPrimaryControl() { + return extraLightGray; + } + + public ColorUIResource getPrimaryControlShadow() { + return lightGray; + } + + public ColorUIResource getPrimaryControlDarkShadow() { + return gray; + } + + public ColorUIResource getPrimaryControlInfo() { + return darkGray; + } + + public ColorUIResource getPrimaryControlHighlight() { + return white; + } + + public ColorUIResource getControlTextColor() { + return controlForegroundColor; + } + + public ColorUIResource getSystemTextColor() { + return foregroundColor; + } + + public String getLogoString() { + if (logoString != null) { + if (logoString.trim().length() == 0) { + return null; + } + } + return logoString; + } + + public boolean isWindowDecorationOn() { + return windowDecoration; + } + + public boolean isCenterWindowTitleOn() { + return centerWindowTitle; + } + + public boolean isMacStyleWindowDecorationOn() { + return macStyleWindowDecoration; + } + + public boolean isLinuxStyleScrollBarOn() { + return linuxStyleScrollBar; + } + + public boolean isMacStyleScrollBarOn() { + return macStyleScrollBar; + } + + public boolean isDynamicLayout() { + return dynamicLayout; + } + + public boolean isTextShadowOn() { + return textShadow; + } + + public boolean isTextAntiAliasingOn() { + if (JTattooUtilities.getJavaVersion() < 1.4) { + return false; + } + return textAntiAliasing; + } + + public int getTextAntiAliasingMode() { + return textAntiAliasingMode; + } + + public Object getTextAntiAliasingHint() { + if (isTextAntiAliasingOn()) { + if (JTattooUtilities.getJavaVersion() >= 1.6) { + switch (textAntiAliasingMode) { + case TEXT_ANTIALIAS_DEFAULT: + return RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT; + case TEXT_ANTIALIAS_HRGB: + return RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB; + case TEXT_ANTIALIAS_HBGR: + return RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR; + case TEXT_ANTIALIAS_VRGB: + return RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB; + case TEXT_ANTIALIAS_VBGR: + return RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR; + default: + return RenderingHints.VALUE_TEXT_ANTIALIAS_ON; + } + } + return RenderingHints.VALUE_TEXT_ANTIALIAS_ON; + } + return RenderingHints.VALUE_TEXT_ANTIALIAS_OFF; + } + + public boolean isBackgroundPatternOn() { + return backgroundPattern; + } + + public boolean isBrightMode() { + return brightMode; + } + + public boolean doShowFocusFrame() { + return showFocusFrame; + } + + public boolean doDrawSquareButtons() { + return drawSquareButtons; + } + + public boolean isToolbarDecorated() { + return toolbarDecorated; + } + + public boolean isMenuOpaque() { + return menuOpaque; + } + + public float getMenuAlpha() { + return menuAlpha; + } + + public ColorUIResource getForegroundColor() { + return foregroundColor; + } + + public ColorUIResource getDisabledForegroundColor() { + return disabledForegroundColor; + } + + public ColorUIResource getBackgroundColor() { + return backgroundColor; + } + + public ColorUIResource getDisabledBackgroundColor() { + return disabledBackgroundColor; + } + + public ColorUIResource getBackgroundColorLight() { + return backgroundColorLight; + } + + public ColorUIResource getBackgroundColorDark() { + return backgroundColorDark; + } + + public ColorUIResource getAlterBackgroundColor() { + return alterBackgroundColor; + } + + public ColorUIResource getInputForegroundColor() { + return inputForegroundColor; + } + + public ColorUIResource getInputBackgroundColor() { + return inputBackgroundColor; + } + + public ColorUIResource getSelectionForegroundColor() { + return selectionForegroundColor; + } + + public ColorUIResource getSelectionBackgroundColorLight() { + return selectionBackgroundColorLight; + } + + public ColorUIResource getSelectionBackgroundColorDark() { + return selectionBackgroundColorDark; + } + + public ColorUIResource getSelectionBackgroundColor() { + return selectionBackgroundColor; + } + + public ColorUIResource getFrameColor() { + return frameColor; + } + + public ColorUIResource getGridColor() { + return gridColor; + } + + public ColorUIResource getShadowColor() { + return shadowColor; + } + + public ColorUIResource getFocusColor() { + return focusColor; + } + + public ColorUIResource getFocusCellColor() { + return focusCellColor; + } + + public ColorUIResource getFocusFrameColor() { + return focusFrameColor; + } + + public ColorUIResource getFocusBackgroundColor() { + return focusBackgroundColor; + } + + public ColorUIResource getFocusForegroundColor() { + return focusForegroundColor; + } + + public ColorUIResource getRolloverForegroundColor() { + return rolloverForegroundColor; + } + + public ColorUIResource getRolloverColor() { + return rolloverColor; + } + + public ColorUIResource getRolloverColorLight() { + return rolloverColorLight; + } + + public ColorUIResource getRolloverColorDark() { + return rolloverColorDark; + } + + public ColorUIResource getPressedForegroundColor() { + return pressedForegroundColor; + } + + public ColorUIResource getButtonForegroundColor() { + return buttonForegroundColor; + } + + public ColorUIResource getButtonBackgroundColor() { + return buttonBackgroundColor; + } + + public ColorUIResource getButtonColorLight() { + return buttonColorLight; + } + + public ColorUIResource getButtonColorDark() { + return buttonColorDark; + } + + public ColorUIResource getControlForegroundColor() { + return controlForegroundColor; + } + + public ColorUIResource getControlBackgroundColor() { + return controlBackgroundColor; + } + + public ColorUIResource getControlHighlightColor() { + return controlHighlightColor; + } + + public ColorUIResource getControlShadowColor() { + return controlShadowColor; + } + + public ColorUIResource getControlDarkShadowColor() { + return controlDarkShadowColor; + } + + public ColorUIResource getControlColorLight() { + return controlColorLight; + } + + public ColorUIResource getControlColorDark() { + return controlColorDark; + } + + public ColorUIResource getWindowTitleForegroundColor() { + return windowTitleForegroundColor; + } + + public ColorUIResource getWindowTitleBackgroundColor() { + return windowTitleBackgroundColor; + } + + public ColorUIResource getWindowTitleColorLight() { + return windowTitleColorLight; + } + + public ColorUIResource getWindowTitleColorDark() { + return windowTitleColorDark; + } + + public ColorUIResource getWindowBorderColor() { + return windowBorderColor; + } + + public ColorUIResource getWindowIconColor() { + return windowIconColor; + } + + public ColorUIResource getWindowIconShadowColor() { + return windowIconShadowColor; + } + + public ColorUIResource getWindowIconRolloverColor() { + return windowIconRolloverColor; + } + + public ColorUIResource getWindowInactiveTitleForegroundColor() { + return windowInactiveTitleForegroundColor; + } + + public ColorUIResource getWindowInactiveTitleBackgroundColor() { + return windowInactiveTitleBackgroundColor; + } + + public ColorUIResource getWindowInactiveTitleColorLight() { + return windowInactiveTitleColorLight; + } + + public ColorUIResource getWindowInactiveTitleColorDark() { + return windowInactiveTitleColorDark; + } + + public ColorUIResource getWindowInactiveBorderColor() { + return windowInactiveBorderColor; + } + + public ColorUIResource getMenuForegroundColor() { + return menuForegroundColor; + } + + public ColorUIResource getMenuBackgroundColor() { + return menuBackgroundColor; + } + + public ColorUIResource getMenuSelectionForegroundColor() { + return menuSelectionForegroundColor; + } + + public ColorUIResource getMenuSelectionBackgroundColor() { + return menuSelectionBackgroundColor; + } + + public ColorUIResource getMenuSelectionBackgroundColorLight() { + return menuSelectionBackgroundColorLight; + } + + public ColorUIResource getMenuSelectionBackgroundColorDark() { + return menuSelectionBackgroundColorDark; + } + + public ColorUIResource getMenuColorLight() { + return menuColorLight; + } + + public ColorUIResource getMenuColorDark() { + return menuColorDark; + } + + public ColorUIResource getToolbarForegroundColor() { + return toolbarForegroundColor; + } + + public ColorUIResource getToolbarBackgroundColor() { + return toolbarBackgroundColor; + } + + public ColorUIResource getToolbarColorLight() { + return toolbarColorLight; + } + + public ColorUIResource getToolbarColorDark() { + return toolbarColorDark; + } + + public ColorUIResource getTabAreaBackgroundColor() { + return tabAreaBackgroundColor; + } + + public ColorUIResource getTabSelectionForegroundColor() { + return tabSelectionForegroundColor; + } + + public ColorUIResource getDesktopColor() { + return desktopColor; + } + + public ColorUIResource getTooltipForegroundColor() { + return tooltipForegroundColor; + } + + public ColorUIResource getTooltipBackgroundColor() { + return tooltipBackgroundColor; + } + + public int getTooltipBorderSize() { + return Math.max(0, Math.min(8, tooltipBorderSize)); + } + + public int getTooltipShadowSize() { + return Math.max(0, Math.min(8, tooltipShadowSize)); + } + + public boolean isTooltipCastShadow() { + return tooltipCastShadow; + } + + public Color[] getDefaultColors() { + return DEFAULT_COLORS; + } + + public Color[] getHiDefaultColors() { + return HIDEFAULT_COLORS; + } + + public Color[] getActiveColors() { + return ACTIVE_COLORS; + } + + public Color[] getInActiveColors() { + return INACTIVE_COLORS; + } + + public Color[] getRolloverColors() { + return ROLLOVER_COLORS; + } + + public Color[] getSelectedColors() { + return SELECTED_COLORS; + } + + public Color[] getSelectionColors() { + return SELECTION_COLORS; + } + + public Color[] getFocusColors() { + return FOCUS_COLORS; + } + + public Color[] getMenuSelectionColors() { + return MENU_SELECTION_COLORS; + } + + public Color[] getPressedColors() { + return PRESSED_COLORS; + } + + public Color[] getDisabledColors() { + return DISABLED_COLORS; + } + + public Color[] getWindowTitleColors() { + return WINDOW_TITLE_COLORS; + } + + public Color[] getWindowInactiveTitleColors() { + return WINDOW_INACTIVE_TITLE_COLORS; + } + + public Color[] getToolBarColors() { + return TOOLBAR_COLORS; + } + + public Color[] getMenuBarColors() { + return MENUBAR_COLORS; + } + + public Color[] getButtonColors() { + return BUTTON_COLORS; + } + + public Color[] getCheckBoxColors() { + return CHECKBOX_COLORS; + } + + public Color[] getTabColors() { + return TAB_COLORS; + } + + public Color[] getColHeaderColors() { + return COL_HEADER_COLORS; + } + + public Color[] getTrackColors() { + return TRACK_COLORS; + } + + public Color[] getThumbColors() { + return THUMB_COLORS; + } + + public Color[] getSliderColors() { + return SLIDER_COLORS; + } + + public Color[] getProgressBarColors() { + return PROGRESSBAR_COLORS; + } + + public String getTextureSet() { + return textureSet; + } + + public boolean isDarkTexture() { + return darkTexture; + } + + public Icon getWindowTexture() { + return windowTexture; + } + + public Icon getBackgroundTexture() { + return backgroundTexture; + } + + public Icon getAlterBackgroundTexture() { + return alterBackgroundTexture; + } + + public Icon getSelectedTexture() { + return selectedTexture; + } + + public Icon getRolloverTexture() { + return rolloverTexture; + } + + public Icon getPressedTexture() { + return pressedTexture; + } + + public Icon getDisabledTexture() { + return disabledTexture; + } + + public Icon getMenubarTexture() { + return menubarTexture; + } +} diff --git a/src/com/jtattoo/plaf/AbstractToolBarUI.java b/src/com/jtattoo/plaf/AbstractToolBarUI.java new file mode 100644 index 0000000..7dc8f07 --- /dev/null +++ b/src/com/jtattoo/plaf/AbstractToolBarUI.java @@ -0,0 +1,258 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.ContainerEvent; +import java.awt.event.ContainerListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Hashtable; +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicToolBarUI; + +public abstract class AbstractToolBarUI extends BasicToolBarUI { + + private final static String IS_ROLLOVER = "JToolBar.isRollover"; + private final static Insets BUTTON_MARGIN = new Insets(1, 1, 1, 1); + private final static Border INNER_BORDER = BorderFactory.createEmptyBorder(2, 2, 2, 2); + private boolean rolloverEnabled = true; + private MyPropertyChangeListener propertyChangeListener = null; + private MyContainerListener containerListener = null; + private final Hashtable orgBorders = new Hashtable(); + private final Hashtable orgMargins = new Hashtable(); + + public abstract Border getRolloverBorder(); + + public abstract Border getNonRolloverBorder(); + + public abstract boolean isButtonOpaque(); + + public void installUI(JComponent c) { + super.installUI(c); + Boolean isRollover = (Boolean) UIManager.get(IS_ROLLOVER); + if (isRollover != null) { + rolloverEnabled = isRollover.booleanValue(); + } + SwingUtilities.invokeLater(new Runnable() { + public void run() { + changeBorders(); + } + }); + } + + public void uninstallUI(JComponent c) { + restoreBorders(); + super.uninstallUI(c); + } + + protected void installListeners() { + super.installListeners(); + propertyChangeListener = new MyPropertyChangeListener(); + if (propertyChangeListener != null) { + toolBar.addPropertyChangeListener(propertyChangeListener); + } + containerListener = new MyContainerListener(); + if (containerListener != null) { + toolBar.addContainerListener(containerListener); + } + } + + protected void uninstallListeners() { + if (propertyChangeListener != null) { + toolBar.removePropertyChangeListener(propertyChangeListener); + } + propertyChangeListener = null; + if (containerListener != null) { + toolBar.removeContainerListener(containerListener); + } + containerListener = null; + super.uninstallListeners(); + } + + protected boolean isRolloverEnabled() { + return rolloverEnabled; + } + + protected void setBorderToNormal(Component c) { + } + + protected void setBorderToRollover(Component c) { + } + + protected void setBorderToNonRollover(Component c) { + } + + protected void changeBorders() { + Component[] components = toolBar.getComponents(); + for (int i = 0; i < components.length; ++i) { + Component comp = components[i]; + if (comp instanceof AbstractButton) { + changeButtonBorder((AbstractButton) comp); + } + } + } + + protected void restoreBorders() { + Component[] components = toolBar.getComponents(); + for (int i = 0; i < components.length; ++i) { + Component comp = components[i]; + if (comp instanceof AbstractButton) { + restoreButtonBorder((AbstractButton) comp); + } + } + } + + protected void changeButtonBorder(AbstractButton b) { + Object cp = b.getClientProperty("paintToolBarBorder"); + if ((cp != null) && (cp instanceof Boolean)) { + Boolean changeBorder = (Boolean)cp; + if (!changeBorder.booleanValue()) { + return; + } + } + if (!orgBorders.contains(b)) { + if (b.getBorder() != null) { + orgBorders.put(b, b.getBorder()); + } else { + orgBorders.put(b, new NullBorder()); + } + } + + if (!orgMargins.contains(b)) { + orgMargins.put(b, b.getMargin()); + } + + if (b.getBorder() != null) { + if (isRolloverEnabled()) { + b.setBorderPainted(true); + b.setBorder(BorderFactory.createCompoundBorder(getRolloverBorder(), INNER_BORDER)); + b.setMargin(BUTTON_MARGIN); + b.setRolloverEnabled(true); + b.setOpaque(isButtonOpaque()); + b.setContentAreaFilled(isButtonOpaque()); + } else { + b.setBorder(BorderFactory.createCompoundBorder(getNonRolloverBorder(), INNER_BORDER)); + b.setMargin(BUTTON_MARGIN); + b.setRolloverEnabled(false); + b.setOpaque(isButtonOpaque()); + b.setContentAreaFilled(isButtonOpaque()); + } + } + } + + protected void restoreButtonBorder(AbstractButton b) { + Object cp = b.getClientProperty("paintToolBarBorder"); + if ((cp != null) && (cp instanceof Boolean)) { + Boolean changeBorder = (Boolean)cp; + if (!changeBorder.booleanValue()) { + return; + } + } + Border border = (Border) orgBorders.get(b); + if (border != null) { + if (border instanceof NullBorder) { + b.setBorder(null); + } else { + b.setBorder(border); + } + } + b.setMargin((Insets) orgMargins.get(b)); + } + + protected void updateToolbarBorder() { + toolBar.revalidate(); + toolBar.repaint(); + } + + protected boolean isToolBarUnderMenubar() { + if (toolBar != null && toolBar.getOrientation() == JToolBar.HORIZONTAL) { + JRootPane rp = SwingUtilities.getRootPane(toolBar); + JMenuBar mb = rp.getJMenuBar(); + if (mb != null) { + Point mbPoint = new Point(0, 0); + mbPoint = SwingUtilities.convertPoint(mb, mbPoint, rp); + Point tbPoint = new Point(0, 0); + tbPoint = SwingUtilities.convertPoint(toolBar, tbPoint, rp); + tbPoint.y -= mb.getHeight() - 1; + Rectangle rect = new Rectangle(mbPoint, mb.getSize()); + return rect.contains(tbPoint); + } + } + return false; + } + + protected boolean isToolbarDecorated() { + return AbstractLookAndFeel.getTheme().isToolbarDecorated(); + } + + protected class MyPropertyChangeListener implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent e) { + if (e.getPropertyName().equals(IS_ROLLOVER)) { + if (e.getNewValue() != null) { + rolloverEnabled = ((Boolean) e.getNewValue()).booleanValue(); + changeBorders(); + } + } else if ("componentOrientation".equals(e.getPropertyName())) { + updateToolbarBorder(); + } + } + } + + protected class MyContainerListener implements ContainerListener { + + public void componentAdded(ContainerEvent e) { + Component c = e.getChild(); + if (c instanceof AbstractButton) { + changeButtonBorder((AbstractButton) c); + } + } + + public void componentRemoved(ContainerEvent e) { + Component c = e.getChild(); + if (c instanceof AbstractButton) { + restoreButtonBorder((AbstractButton) c); + } + } + } + + private static class NullBorder implements Border, UIResource { + + private static final Insets insets = new Insets(0, 0, 0, 0); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + } + + public Insets getBorderInsets(Component c) { + return insets; + } + + public boolean isBorderOpaque() { + return true; + } + } // class NullBorder +} diff --git a/src/com/jtattoo/plaf/BaseBorders.java b/src/com/jtattoo/plaf/BaseBorders.java new file mode 100644 index 0000000..31b9287 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseBorders.java @@ -0,0 +1,896 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.geom.AffineTransform; +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.plaf.BorderUIResource; +import javax.swing.plaf.UIResource; + +/** + * @author Michael Hagen + */ +public class BaseBorders { + + protected static Border buttonBorder = null; + protected static Border focusFrameBorder = null; + protected static Border textFieldBorder = null; + protected static Border spinnerBorder = null; + protected static Border comboBoxBorder = null; + protected static Border progressBarBorder = null; + protected static Border tableHeaderBorder = null; + protected static Border popupMenuBorder = null; + protected static Border menuItemBorder = null; + protected static Border toolBarBorder = null; + protected static Border toolButtonBorder = null; + protected static Border rolloverToolButtonBorder = null; + protected static Border internalFrameBorder = null; + protected static Border paletteBorder = null; + protected static Border scrollPaneBorder = null; + protected static Border tableScrollPaneBorder = null; + protected static Border tabbedPaneBorder = null; + protected static Border desktopIconBorder = null; + + public static void initDefaults() { + buttonBorder = null; + textFieldBorder = null; + spinnerBorder = null; + comboBoxBorder = null; + progressBarBorder = null; + tableHeaderBorder = null; + popupMenuBorder = null; + menuItemBorder = null; + toolBarBorder = null; + toolButtonBorder = null; + rolloverToolButtonBorder = null; + paletteBorder = null; + internalFrameBorder = null; + scrollPaneBorder = null; + tableScrollPaneBorder = null; + tabbedPaneBorder = null; + desktopIconBorder = null; + } + + //------------------------------------------------------------------------------------ + // Lazy access methods + //------------------------------------------------------------------------------------ + public static Border getFocusFrameBorder() { + if (focusFrameBorder == null) { + focusFrameBorder = new FocusFrameBorder(); + } + return focusFrameBorder; + } + + //------------------------------------------------------------------------------------ + // Lazy access methods + //------------------------------------------------------------------------------------ + public static Border getTextBorder() { + if (textFieldBorder == null) { + textFieldBorder = new TextFieldBorder(); + } + return textFieldBorder; + } + + public static Border getSpinnerBorder() { + if (spinnerBorder == null) { + spinnerBorder = new SpinnerBorder(); + } + return spinnerBorder; + } + + public static Border getTextFieldBorder() { + return getTextBorder(); + } + + public static Border getComboBoxBorder() { + if (comboBoxBorder == null) { + comboBoxBorder = new ComboBoxBorder(); + } + return comboBoxBorder; + } + + public static Border getProgressBarBorder() { + if (progressBarBorder == null) { + progressBarBorder = BorderFactory.createLineBorder(ColorHelper.darker(AbstractLookAndFeel.getBackgroundColor(), 30)); + } + return progressBarBorder; + } + + public static Border getTableHeaderBorder() { + if (tableHeaderBorder == null) { + tableHeaderBorder = new TableHeaderBorder(); + } + return tableHeaderBorder; + } + + public static Border getPopupMenuBorder() { + if (popupMenuBorder == null) { + if (AbstractLookAndFeel.getTheme().isMenuOpaque()) { + popupMenuBorder = new BasePopupMenuBorder(); + } else { + popupMenuBorder = new BasePopupMenuShadowBorder(); + } + } + return popupMenuBorder; + } + + public static Border getMenuItemBorder() { + if (menuItemBorder == null) { + menuItemBorder = new MenuItemBorder(); + } + return menuItemBorder; + } + + public static Border getToolBarBorder() { + if (toolBarBorder == null) { + toolBarBorder = new ToolBarBorder(); + } + return toolBarBorder; + } + + public static Border getToolButtonBorder() { + if (toolButtonBorder == null) { + toolButtonBorder = new ToolButtonBorder(); + } + return toolButtonBorder; + } + + public static Border getMenuBarBorder() { + return BorderFactory.createEmptyBorder(1, 1, 1, 1); + } + + public static Border getPaletteBorder() { + if (paletteBorder == null) { + paletteBorder = new PaletteBorder(); + } + return paletteBorder; + } + + public static Border getScrollPaneBorder() { + if (scrollPaneBorder == null) { + scrollPaneBorder = new ScrollPaneBorder(false); + } + return scrollPaneBorder; + } + + public static Border getTableScrollPaneBorder() { + if (tableScrollPaneBorder == null) { + tableScrollPaneBorder = new ScrollPaneBorder(true); + } + return tableScrollPaneBorder; + } + + public static Border getTabbedPaneBorder() { + if (tabbedPaneBorder == null) { + tabbedPaneBorder = BorderFactory.createEmptyBorder(1, 1, 1, 1); + } + return tabbedPaneBorder; + } + + public static Border getDesktopIconBorder() { + if (desktopIconBorder == null) { + desktopIconBorder = new BorderUIResource.CompoundBorderUIResource( + new LineBorder(AbstractLookAndFeel.getWindowBorderColor(), 1), + new MatteBorder(2, 2, 1, 2, AbstractLookAndFeel.getWindowBorderColor())); + } + return desktopIconBorder; + } + + //------------------------------------------------------------------------------------ + // Implementation of border classes + //------------------------------------------------------------------------------------ + public static class FocusFrameBorder extends AbstractBorder implements UIResource { + + private static final Insets insets = new Insets(2, 2, 2, 2); + + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + Color hiColor = ColorHelper.brighter(AbstractLookAndFeel.getTheme().getFocusFrameColor(), 60); + Color loColor = AbstractLookAndFeel.getTheme().getFocusFrameColor(); + g.setColor(loColor); + g.drawRect(x, y, width - 1, height - 1); + g.setColor(hiColor); + g.drawRect(x + 1, y + 1, width - 3, height - 3); + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + } // class FocusFrameBorder + + public static class TextFieldBorder extends AbstractBorder implements UIResource { + + private static final Insets insets = new Insets(2, 2, 2, 2); + + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + g.setColor(AbstractLookAndFeel.getTheme().getFrameColor()); + g.drawRect(x, y, width - 1, height - 1); + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + } // class TextFieldBorder + + public static class SpinnerBorder extends AbstractBorder implements UIResource { + + private static final Insets insets = new Insets(1, 1, 1, 1); + + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + g.setColor(AbstractLookAndFeel.getTheme().getFrameColor()); + g.drawRect(x, y, width - 1, height - 1); + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + } // class SpinnerBorder + + public static class ComboBoxBorder extends AbstractBorder implements UIResource { + + private static final Insets insets = new Insets(1, 1, 1, 1); + + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + g.setColor(AbstractLookAndFeel.getTheme().getFrameColor()); + g.drawRect(x, y, width - 1, height - 1); + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + } // class ComboBoxBorder + + public static class TableHeaderBorder extends AbstractBorder implements UIResource { + + private static final Insets insets = new Insets(2, 2, 2, 0); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + Graphics2D g2D = (Graphics2D)g; + Composite savedComposite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f); + g2D.setComposite(alpha); + Color cHi = AbstractLookAndFeel.getTheme().getControlHighlightColor(); + Color cLo = AbstractLookAndFeel.getTheme().getControlShadowColor(); + JTattooUtilities.draw3DBorder(g, cHi, cLo, x, y, w, h); + g2D.setComposite(savedComposite); + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + } // class TableHeaderBorder + + public static class ScrollPaneBorder extends AbstractBorder implements UIResource { + + private static final Insets insets = new Insets(2, 2, 2, 2); + private static final Insets tableInsets = new Insets(1, 1, 1, 1); + + private boolean tableBorder = false; + + public ScrollPaneBorder(boolean tableBorder) { + this.tableBorder = tableBorder; + } + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + g.setColor(AbstractLookAndFeel.getTheme().getFrameColor()); + g.drawRect(x, y, w - 1, h - 1); + g.setColor(ColorHelper.brighter(AbstractLookAndFeel.getTheme().getBackgroundColor(), 50)); + g.drawRect(x + 1, y + 1, w - 3, h - 3); + } + + public Insets getBorderInsets(Component c) { + if (tableBorder) { + return new Insets(tableInsets.top, tableInsets.left, tableInsets.bottom, tableInsets.right); + } else { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + Insets ins = getBorderInsets(c); + borderInsets.left = ins.left; + borderInsets.top = ins.top; + borderInsets.right = ins.right; + borderInsets.bottom = ins.bottom; + return borderInsets; + } + + } // class ScrollPaneBorder + + public static class BasePopupMenuBorder extends AbstractBorder implements UIResource { + + protected static Font logoFont; + protected static Insets leftLogoInsets; + protected static Insets rightLogoInsets; + protected static Insets insets; + protected static int shadowSize; + + public BasePopupMenuBorder() { + logoFont = new Font("Dialog", Font.BOLD, 12); + leftLogoInsets = new Insets(2, 18, 1, 1); + rightLogoInsets = new Insets(2, 2, 1, 18); + insets = new Insets(2, 1, 1, 1); + shadowSize = 0; + } + + public boolean isMenuBarPopup(Component c) { + boolean menuBarPopup = false; + if (c instanceof JPopupMenu) { + JPopupMenu pm = (JPopupMenu) c; + if (pm.getInvoker() != null) { + menuBarPopup = (pm.getInvoker().getParent() instanceof JMenuBar); + } + } + return menuBarPopup; + } + + public boolean hasLogo(Component c) { + return ((AbstractLookAndFeel.getTheme().getLogoString() != null) && (AbstractLookAndFeel.getTheme().getLogoString().length() > 0)); + } + + public Color getLogoColorHi() { + return Color.white; + } + + public Color getLogoColorLo() { + return ColorHelper.darker(AbstractLookAndFeel.getTheme().getMenuSelectionBackgroundColor(), 20); + } + + public void paintLogo(Component c, Graphics g, int x, int y, int w, int h) { + if (hasLogo(c)) { + Graphics2D g2D = (Graphics2D)g; + + Font savedFont = g2D.getFont(); + g.setFont(logoFont); + FontMetrics fm = JTattooUtilities.getFontMetrics((JComponent)c, g, c.getFont()); + String logo = JTattooUtilities.getClippedText(AbstractLookAndFeel.getTheme().getLogoString(), fm, h - 16); + + AffineTransform savedTransform = g2D.getTransform(); + + Color fc = getLogoColorHi(); + Color bc = getLogoColorLo(); + + if (JTattooUtilities.isLeftToRight(c)) { + g2D.translate(fm.getAscent() + 1, h - shadowSize - 4); + g2D.rotate(Math.toRadians(-90)); + g2D.setColor(bc); + JTattooUtilities.drawString((JComponent)c, g, logo, 0, 1); + g2D.setColor(fc); + JTattooUtilities.drawString((JComponent)c, g, logo, 1, 0); + } else { + g2D.translate(w - shadowSize - 4, h - shadowSize - 4); + g2D.rotate(Math.toRadians(-90)); + g2D.setColor(bc); + JTattooUtilities.drawString((JComponent)c, g, logo, 0, 1); + g2D.setColor(fc); + JTattooUtilities.drawString((JComponent)c, g, logo, 1, 0); + } + + g2D.setTransform(savedTransform); + g2D.setFont(savedFont); + } + } + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + Color logoColor = AbstractLookAndFeel.getMenuSelectionBackgroundColor(); + Color borderColorLo = AbstractLookAndFeel.getFrameColor(); + Color borderColorHi = ColorHelper.brighter(AbstractLookAndFeel.getMenuSelectionBackgroundColor(), 40); + g.setColor(logoColor); + if (JTattooUtilities.isLeftToRight(c)) { + int dx = getBorderInsets(c).left; + g.fillRect(x, y, dx - 1, h - 1); + paintLogo(c, g, x, y, w, h); + // - highlight + g.setColor(ColorHelper.brighter(AbstractLookAndFeel.getMenuBackgroundColor(), 40)); + g.drawLine(x + dx, y + 1, x + w - 2, y + 1); + g.setColor(borderColorHi); + g.drawLine(x + 1, y, x + 1, y + h - 2); + // - outer frame + g.setColor(borderColorLo); + if (isMenuBarPopup(c)) { + // top + g.drawLine(x + dx - 1, y, x + w, y); + // left + g.drawLine(x, y, x, y + h - 1); + // bottom + g.drawLine(x, y + h - 1, x + w, y + h - 1); + // right + g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1); + } else { + g.drawRect(x, y, w - 1, h - 1); + } + // - logo separator + g.drawLine(x + dx - 1, y + 1, x + dx - 1, y + h - 1); + } else { + int dx = getBorderInsets(c).right; + g.fillRect(x + w - dx, y, dx, h - 1); + paintLogo(c, g, x, y, w, h); + // - highlight + g.setColor(ColorHelper.brighter(AbstractLookAndFeel.getMenuBackgroundColor(), 40)); + g.drawLine(x + 1, y + 1, x + w - dx - 1, y + 1); + g.drawLine(x + 1, y + 1, x + 1, y + h - 2); + // - outer frame + g.setColor(borderColorLo); + if (isMenuBarPopup(c)) { + // top + g.drawLine(x, y, x + w - dx, y); + // left + g.drawLine(x, y, x, y + h - 1); + // bottom + g.drawLine(x, y + h - 1, x + w, y + h - 1); + // right + g.drawLine(x + w - 1, y, x + w - 1, y + h - 1); + } else { + g.drawRect(x, y, w - 1, h - 1); + } + // - logo separator + g.drawLine(x + w - dx, y + 1, x + w - dx, y + h - 1); + } + } + + public Insets getBorderInsets(Component c) { + if (hasLogo(c)) { + if (JTattooUtilities.isLeftToRight(c)) { + return new Insets(leftLogoInsets.top, leftLogoInsets.left, leftLogoInsets.bottom + shadowSize, leftLogoInsets.right + shadowSize); + } else { + return new Insets(rightLogoInsets.top, rightLogoInsets.left, rightLogoInsets.bottom + shadowSize, rightLogoInsets.right + shadowSize); + } + } else { + return new Insets(insets.top, insets.left, insets.bottom + shadowSize, insets.right + shadowSize); + } + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + Insets ins = getBorderInsets(c); + borderInsets.left = ins.left; + borderInsets.top = ins.top; + borderInsets.right = ins.right; + borderInsets.bottom = ins.bottom; + return borderInsets; + } + + } // class PopupMenuBorder + + public static class BasePopupMenuShadowBorder extends BasePopupMenuBorder { + + public BasePopupMenuShadowBorder() { + shadowSize = 4; + } + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, AbstractLookAndFeel.getTheme().getMenuAlpha()); + g2D.setComposite(alpha); + Color logoColor = AbstractLookAndFeel.getTheme().getMenuSelectionBackgroundColor(); + Color borderColorLo = AbstractLookAndFeel.getFrameColor(); + Color borderColorHi = ColorHelper.brighter(AbstractLookAndFeel.getMenuSelectionBackgroundColor(), 40); + g.setColor(logoColor); + if (JTattooUtilities.isLeftToRight(c)) { + int dx = getBorderInsets(c).left; + g.fillRect(x, y, dx - 1, h - 1 - shadowSize); + paintLogo(c, g, x, y, w, h); + // - highlight + g.setColor(ColorHelper.brighter(AbstractLookAndFeel.getMenuBackgroundColor(), 40)); + g.drawLine(x + dx, y + 1, x + w - shadowSize - 2, y + 1); + g.setColor(borderColorHi); + g.drawLine(x + 1, y, x + 1, y + h - shadowSize - 2); + // - outer frame + g.setColor(borderColorLo); + if (isMenuBarPopup(c)) { + // top + g.drawLine(x + dx - 1, y, x + w - shadowSize - 1, y); + // left + g.drawLine(x, y, x, y + h - shadowSize - 1); + // bottom + g.drawLine(x, y + h - shadowSize - 1, x + w - shadowSize - 1, y + h - shadowSize - 1); + // right + g.drawLine(x + w - shadowSize - 1, y + 1, x + w - shadowSize - 1, y + h - shadowSize - 1); + } else { + g.drawRect(x, y, w - shadowSize - 1, h - shadowSize - 1); + } + // - logo separator + g.drawLine(x + dx - 1, y + 1, x + dx - 1, y + h - shadowSize - 1); + } else { + int dx = getBorderInsets(c).right - shadowSize; + g.fillRect(x + w - dx - shadowSize, y, dx - 1, h - 1 - shadowSize); + paintLogo(c, g, x, y, w, h); + // - highlight + g.setColor(ColorHelper.brighter(AbstractLookAndFeel.getMenuBackgroundColor(), 40)); + g.drawLine(x + 1, y + 1, x + w - dx - shadowSize - 1, y + 1); + g.drawLine(x + 1, y + 1, x + 1, y + h - shadowSize - 2); + // - outer frame + g.setColor(borderColorLo); + if (isMenuBarPopup(c)) { + // top + g.drawLine(x, y, x + w - dx - shadowSize, y); + // left + g.drawLine(x, y, x, y + h - shadowSize - 1); + // bottom + g.drawLine(x, y + h - shadowSize - 1, x + w - shadowSize - 1, y + h - shadowSize - 1); + // right + g.drawLine(x + w - shadowSize - 1, y, x + w - shadowSize - 1, y + h - shadowSize - 1); + } else { + g.drawRect(x, y, w - shadowSize - 1, h - shadowSize - 1); + } + // - logo separator + g.drawLine(x + w - dx - shadowSize, y + 1, x + w - dx - shadowSize, y + h - shadowSize - 1); + } + + // paint the shadow + g2D.setColor(AbstractLookAndFeel.getTheme().getShadowColor()); + float alphaValue = 0.4f; + for (int i = 0; i < shadowSize; i++) { + alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alphaValue); + g2D.setComposite(alpha); + g.drawLine(x + w - shadowSize + i, y + shadowSize, x + w - shadowSize + i, y + h - shadowSize - 1 + i); + g.drawLine(x + shadowSize, y + h - shadowSize + i, x + w - shadowSize + i, y + h - shadowSize + i); + alphaValue -= (alphaValue / 2); + } + + g2D.setComposite(savedComposite); + } + + } // class PopupMenuShadowBorder + + public static class MenuItemBorder extends AbstractBorder implements UIResource { + + private static final Insets insets = new Insets(2, 2, 2, 2); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + JMenuItem b = (JMenuItem) c; + ButtonModel model = b.getModel(); + Color borderColorLo = AbstractLookAndFeel.getFrameColor(); + Color borderColorHi = ColorHelper.brighter(AbstractLookAndFeel.getMenuSelectionBackgroundColor(), 40); + if (c.getParent() instanceof JMenuBar) { + if (model.isArmed() || model.isSelected()) { + g.setColor(borderColorLo); + g.drawLine(x, y, x + w - 1, y); + g.drawLine(x, y, x, y + h - 1); + g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1); + g.setColor(borderColorHi); + g.drawLine(x + 1, y + 1, x + w - 2, y + 1); + g.drawLine(x + 1, y + 1, x + 1, y + h - 1); + } + } else { + if (model.isArmed() || (c instanceof JMenu && model.isSelected())) { + g.setColor(borderColorLo); + g.drawLine(x, y, x + w - 1, y); + g.drawLine(x, y + h - 1, x + w - 1, y + h - 1); + g.setColor(borderColorHi); + g.drawLine(x, y + 1, x + w - 2, y + 1); + } + } + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + } // class MenuItemBorder + + public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants { + + private static final Color shadow = new Color(160, 160, 160); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + if (((JToolBar) c).isFloatable()) { + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); + g2D.setComposite(alpha); + if (((JToolBar) c).getOrientation() == HORIZONTAL) { + if (!JTattooUtilities.isLeftToRight(c)) { + x += w - 15; + } + g.setColor(Color.white); + g.drawLine(x + 3, y + 4, x + 3, h - 5); + g.drawLine(x + 6, y + 3, x + 6, h - 4); + g.drawLine(x + 9, y + 4, x + 9, h - 5); + g.setColor(shadow); + g.drawLine(x + 4, y + 4, x + 4, h - 5); + g.drawLine(x + 7, y + 3, x + 7, h - 4); + g.drawLine(x + 10, y + 4, x + 10, h - 5); + } else { + // vertical + g.setColor(Color.white); + g.drawLine(x + 3, y + 3, w - 4, y + 3); + g.drawLine(x + 3, y + 6, w - 4, y + 6); + g.drawLine(x + 3, y + 9, w - 4, y + 9); + g.setColor(shadow); + g.drawLine(x + 3, y + 4, w - 4, y + 4); + g.drawLine(x + 3, y + 7, w - 4, y + 7); + g.drawLine(x + 3, y + 10, w - 4, y + 10); + } + g2D.setComposite(savedComposite); + } + } + + public Insets getBorderInsets(Component c) { + Insets insets = new Insets(2, 2, 2, 2); + if (((JToolBar) c).isFloatable()) { + if (((JToolBar) c).getOrientation() == HORIZONTAL) { + if (JTattooUtilities.isLeftToRight(c)) { + insets.left = 15; + } else { + insets.right = 15; + } + } else { + insets.top = 15; + } + } + Insets margin = ((JToolBar) c).getMargin(); + if (margin != null) { + insets.left += margin.left; + insets.top += margin.top; + insets.right += margin.right; + insets.bottom += margin.bottom; + } + return insets; + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + Insets insets = getBorderInsets(c); + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + } // class ToolBarBorder + + public static class ToolButtonBorder implements Border, UIResource { + + private static final Insets insets = new Insets(2, 2, 2, 2); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + AbstractButton button = (AbstractButton) c; + ButtonModel model = button.getModel(); + Color frameColor = AbstractLookAndFeel.getToolbarBackgroundColor(); + Color frameHiColor = ColorHelper.brighter(frameColor, 10); + Color frameLoColor = ColorHelper.darker(frameColor, 30); + JTattooUtilities.draw3DBorder(g, frameHiColor, frameLoColor, x, y, w, h); + if ((model.isPressed() && model.isArmed()) || model.isSelected()) { + JTattooUtilities.draw3DBorder(g, frameLoColor, frameHiColor, x, y, w, h); + } else { + JTattooUtilities.draw3DBorder(g, frameLoColor, frameHiColor, x, y, w, h); + JTattooUtilities.draw3DBorder(g, frameHiColor, frameLoColor, x + 1, y + 1, w - 2, h - 2); + } + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + public boolean isBorderOpaque() { + return true; + } + } // class ToolButtonBorder + + public static class PaletteBorder extends AbstractBorder implements UIResource { + + private static final Insets insets = new Insets(1, 1, 1, 1); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + if (JTattooUtilities.isFrameActive((JComponent) c)) { + g.setColor(AbstractLookAndFeel.getWindowBorderColor()); + } else { + g.setColor(AbstractLookAndFeel.getWindowInactiveBorderColor()); + } + g.drawRect(x, y, w - 1, h - 1); + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + } // class PaletteBorder + + public static class BaseInternalFrameBorder extends AbstractBorder implements UIResource { + + protected final int dw = 5; + protected final int trackWidth = 22; + protected final Insets insets = new Insets(dw, dw, dw, dw); + protected final Insets paletteInsets = new Insets(3, 3, 3, 3); + + public BaseInternalFrameBorder() { + } + + public boolean isResizable(Component c) { + boolean resizable = true; + if (c instanceof JDialog) { + JDialog dialog = (JDialog) c; + resizable = dialog.isResizable(); + } else if (c instanceof JInternalFrame) { + JInternalFrame frame = (JInternalFrame) c; + resizable = frame.isResizable(); + } else if (c instanceof JRootPane) { + JRootPane jp = (JRootPane) c; + if (jp.getParent() instanceof JFrame) { + JFrame frame = (JFrame) c.getParent(); + resizable = frame.isResizable(); + } else if (jp.getParent() instanceof JDialog) { + JDialog dialog = (JDialog) c.getParent(); + resizable = dialog.isResizable(); + } + } + return resizable; + } + + public boolean isActive(Component c) { + if (c instanceof JComponent) { + return JTattooUtilities.isActive((JComponent)c); + } else { + return true; + } + } + + public int getTitleHeight(Component c) { + int th = 21; + int fh = getBorderInsets(c).top + getBorderInsets(c).bottom; + if (c instanceof JDialog) { + JDialog dialog = (JDialog) c; + th = dialog.getSize().height - dialog.getContentPane().getSize().height - fh - 1; + if (dialog.getJMenuBar() != null) { + th -= dialog.getJMenuBar().getSize().height; + } + } else if (c instanceof JInternalFrame) { + JInternalFrame frame = (JInternalFrame) c; + th = frame.getSize().height - frame.getRootPane().getSize().height - fh - 1; + if (frame.getJMenuBar() != null) { + th -= frame.getJMenuBar().getSize().height; + } + } else if (c instanceof JRootPane) { + JRootPane jp = (JRootPane) c; + if (jp.getParent() instanceof JFrame) { + JFrame frame = (JFrame) c.getParent(); + th = frame.getSize().height - frame.getContentPane().getSize().height - fh - 1; + if (frame.getJMenuBar() != null) { + th -= frame.getJMenuBar().getSize().height; + } + } else if (jp.getParent() instanceof JDialog) { + JDialog dialog = (JDialog) c.getParent(); + th = dialog.getSize().height - dialog.getContentPane().getSize().height - fh - 1; + if (dialog.getJMenuBar() != null) { + th -= dialog.getJMenuBar().getSize().height; + } + } + } + return th; + } + + public Insets getBorderInsets(Component c) { + if (isResizable(c)) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } else { + return new Insets(paletteInsets.top, paletteInsets.left, paletteInsets.bottom, paletteInsets.right); + } + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + Insets ins = getBorderInsets(c); + borderInsets.left = ins.left; + borderInsets.top = ins.top; + borderInsets.right = ins.right; + borderInsets.bottom = ins.bottom; + return borderInsets; + } + + } // class BaseInternalFrameBorder + + public static class Down3DBorder extends AbstractBorder implements UIResource { + + private static final Insets insets = new Insets(1, 1, 1, 1); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + Color frameColor = AbstractLookAndFeel.getTheme().getBackgroundColor(); + JTattooUtilities.draw3DBorder(g, ColorHelper.darker(frameColor, 20), ColorHelper.brighter(frameColor, 80), x, y, w, h); + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + } // class Down3DBorder + +} // class BaseBorders diff --git a/src/com/jtattoo/plaf/BaseButtonListener.java b/src/com/jtattoo/plaf/BaseButtonListener.java new file mode 100644 index 0000000..ea4c720 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseButtonListener.java @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.event.FocusEvent; +import java.awt.event.MouseEvent; +import javax.swing.AbstractButton; +import javax.swing.plaf.basic.BasicButtonListener; + +public class BaseButtonListener extends BasicButtonListener { + + public BaseButtonListener(AbstractButton b) { + super(b); + } + + public void focusGained(FocusEvent e) { + AbstractButton b = (AbstractButton) e.getSource(); + b.repaint(); + } + + public void focusLost(FocusEvent e) { + AbstractButton b = (AbstractButton) e.getSource(); + b.repaint(); + } + + public void mouseEntered(MouseEvent e) { + super.mouseEntered(e); + AbstractButton button = (AbstractButton) e.getSource(); + button.getModel().setRollover(true); + } + + public void mouseExited(MouseEvent e) { + super.mouseExited(e); + AbstractButton button = (AbstractButton) e.getSource(); + button.getModel().setRollover(false); + } + + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + } +} diff --git a/src/com/jtattoo/plaf/BaseButtonUI.java b/src/com/jtattoo/plaf/BaseButtonUI.java new file mode 100644 index 0000000..af200be --- /dev/null +++ b/src/com/jtattoo/plaf/BaseButtonUI.java @@ -0,0 +1,241 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is dual licensed. You can use it under the terms and conditions of the +* GNU General Public License version 2.0 or later as published by the Free Software +* Foundation. +* +* see: gpl-2.0.txt +* +* Registered users (this who payed for a license) could use the software under the +* terms and conditions of the GNU Lesser General Public License version 2.0 or later +* with classpath exception as published by the Free Software Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.KeyEvent; +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.*; +import javax.swing.text.View; + +/** + * @author Michael Hagen + */ +public class BaseButtonUI extends BasicButtonUI { + + protected static Rectangle viewRect = new Rectangle(); + protected static Rectangle textRect = new Rectangle(); + protected static Rectangle iconRect = new Rectangle(); + protected static Color[] defaultColors = null; + + public static ComponentUI createUI(JComponent c) { + return new BaseButtonUI(); + } + + protected void installKeyboardActions(AbstractButton b) { + super.installKeyboardActions(b); + InputMap im = (InputMap) UIManager.get("Button.focusInputMap"); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "pressed"); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), "released"); + Color cArr[] = AbstractLookAndFeel.getTheme().getButtonColors(); + defaultColors = new Color[cArr.length]; + for (int i = 0; i < cArr.length; i++) { + defaultColors[i] = ColorHelper.brighter(cArr[i], 20); + } + } + + public void installDefaults(AbstractButton b) { + super.installDefaults(b); + b.setOpaque(false); + b.setRolloverEnabled(true); + } + + protected void uninstallDefaults(AbstractButton b) { + super.uninstallDefaults(b); + b.setOpaque(true); + b.setRolloverEnabled(false); + } + + + protected BasicButtonListener createButtonListener(AbstractButton b) { + return new BaseButtonListener(b); + } + + protected void paintBackground(Graphics g, AbstractButton b) { + if (!b.isContentAreaFilled() || (b.getParent() instanceof JMenuBar)) { + return; + } + + int width = b.getWidth(); + int height = b.getHeight(); + + ButtonModel model = b.getModel(); + Color colors[] = AbstractLookAndFeel.getTheme().getButtonColors(); + if (b.isEnabled()) { + Color background = b.getBackground(); + if (background instanceof ColorUIResource) { + if (model.isPressed() && model.isArmed()) { + colors = AbstractLookAndFeel.getTheme().getPressedColors(); + } else if (b.isRolloverEnabled() && model.isRollover()) { + colors = AbstractLookAndFeel.getTheme().getRolloverColors(); + } else if (AbstractLookAndFeel.getTheme().doShowFocusFrame() && b.hasFocus()) { + colors = AbstractLookAndFeel.getTheme().getFocusColors(); + } else if (JTattooUtilities.isFrameActive(b) + && (b.getRootPane() != null) + && (b.equals(b.getRootPane().getDefaultButton()))) { + colors = defaultColors; + } + } else { + if (model.isPressed() && model.isArmed()) { + colors = ColorHelper.createColorArr(ColorHelper.darker(background, 30), ColorHelper.darker(background, 10), 20); + } else { + if (b.isRolloverEnabled() && model.isRollover()) { + colors = ColorHelper.createColorArr(ColorHelper.brighter(background, 50), ColorHelper.brighter(background, 10), 20); + } else { + colors = ColorHelper.createColorArr(ColorHelper.brighter(background, 30), ColorHelper.darker(background, 10), 20); + } + } + } + } else { // disabled + colors = AbstractLookAndFeel.getTheme().getDisabledColors(); + } + + if (b.isBorderPainted() && (b.getBorder() != null) && !(b.getBorder() instanceof EmptyBorder)) { + Insets insets = b.getBorder().getBorderInsets(b); + int x = insets.left > 0 ? 1 : 0; + int y = insets.top > 0 ? 1 : 0; + int w = insets.right > 0 ? width - 1 : width; + int h = insets.bottom > 0 ? height - 1 : height; + JTattooUtilities.fillHorGradient(g, colors, x, y, w - x, h - y); + } else { + JTattooUtilities.fillHorGradient(g, colors, 0, 0, width, height); + } + } + + protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) { + ButtonModel model = b.getModel(); + FontMetrics fm = JTattooUtilities.getFontMetrics(b, g, b.getFont()); + int mnemIndex; + if (JTattooUtilities.getJavaVersion() >= 1.4) { + mnemIndex = b.getDisplayedMnemonicIndex(); + } else { + mnemIndex = JTattooUtilities.findDisplayedMnemonicIndex(b.getText(), model.getMnemonic()); + } + + if (model.isEnabled()) { + Color foreground = b.getForeground(); + Color background = b.getBackground(); + int offs = 0; + if (model.isArmed() && model.isPressed()) { + offs = 1; + } + if (!(model.isPressed() && model.isArmed())) { + Object sc = b.getClientProperty("shadowColor"); + if (sc instanceof Color) { + g.setColor((Color)sc); + JTattooUtilities.drawStringUnderlineCharAt(b, g, text, mnemIndex, textRect.x + 1, textRect.y + 1 + fm.getAscent()); + } + } + if (background instanceof ColorUIResource) { + if (model.isPressed() && model.isArmed()) { + g.setColor(AbstractLookAndFeel.getTheme().getPressedForegroundColor()); + } else if (model.isRollover()) { + g.setColor(AbstractLookAndFeel.getTheme().getRolloverForegroundColor()); + } else { + g.setColor(foreground); + } + } else { + g.setColor(foreground); + } + JTattooUtilities.drawStringUnderlineCharAt(b, g, text, mnemIndex, textRect.x + offs, textRect.y + offs + fm.getAscent()); + } else { + if (ColorHelper.getGrayValue(b.getForeground()) < 128) { + g.setColor(Color.white); + JTattooUtilities.drawStringUnderlineCharAt(b, g, text, mnemIndex, textRect.x + 1, textRect.y + 1 + fm.getAscent()); + } + g.setColor(AbstractLookAndFeel.getDisabledForegroundColor()); + JTattooUtilities.drawStringUnderlineCharAt(b, g, text, mnemIndex, textRect.x, textRect.y + fm.getAscent()); + } + } + + protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect) { + g.setColor(AbstractLookAndFeel.getFocusColor()); + BasicGraphicsUtils.drawDashedRect(g, 4, 3, b.getWidth() - 8, b.getHeight() - 6); + } + + public void paint(Graphics g, JComponent c) { + Graphics2D g2D = (Graphics2D) g; + + AbstractButton b = (AbstractButton) c; + Font f = c.getFont(); + g.setFont(f); + FontMetrics fm = JTattooUtilities.getFontMetrics(b, g, b.getFont()); + Insets insets = c.getInsets(); + + viewRect.x = insets.left; + viewRect.y = insets.top; + viewRect.width = b.getWidth() - (insets.right + viewRect.x); + viewRect.height = b.getHeight() - (insets.bottom + viewRect.y); + + textRect.x = textRect.y = textRect.width = textRect.height = 0; + iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0; + + int iconTextGap = defaultTextIconGap; + if (JTattooUtilities.getJavaVersion() >= 1.4) { + iconTextGap = b.getIconTextGap(); + } + String text = SwingUtilities.layoutCompoundLabel( + c, fm, b.getText(), b.getIcon(), + b.getVerticalAlignment(), b.getHorizontalAlignment(), + b.getVerticalTextPosition(), b.getHorizontalTextPosition(), + viewRect, iconRect, textRect, + b.getText() == null ? 0 : iconTextGap); + + paintBackground(g, b); + + if (b.getIcon() != null) { + if (!b.isEnabled()) { + Composite savedComposite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); + g2D.setComposite(alpha); + paintIcon(g, c, iconRect); + g2D.setComposite(savedComposite); + } else { + if (b.getModel().isPressed() && b.getModel().isRollover()) { + iconRect.x++; + iconRect.y++; + } + paintIcon(g, c, iconRect); + } + } + + if (text != null && !text.equals("")) { + View v = (View) c.getClientProperty(BasicHTML.propertyKey); + if (v != null) { + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + } + v.paint(g, textRect); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } else { + paintText(g, b, textRect, text); + } + } + + if (b.isFocusPainted() && b.hasFocus()) { + paintFocus(g, b, viewRect, textRect, iconRect); + } + } +} \ No newline at end of file diff --git a/src/com/jtattoo/plaf/BaseCheckBoxMenuItemUI.java b/src/com/jtattoo/plaf/BaseCheckBoxMenuItemUI.java new file mode 100644 index 0000000..3b643da --- /dev/null +++ b/src/com/jtattoo/plaf/BaseCheckBoxMenuItemUI.java @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import javax.swing.JComponent; +import javax.swing.UIManager; +import javax.swing.plaf.ComponentUI; + +/** + * @author Michael Hagen + */ +public class BaseCheckBoxMenuItemUI extends BaseMenuItemUI { + + public static ComponentUI createUI(JComponent c) { + return new BaseCheckBoxMenuItemUI(); + } + + protected void installDefaults() { + super.installDefaults(); + checkIcon = UIManager.getIcon("CheckBoxMenuItem.checkIcon"); + } + +} diff --git a/src/com/jtattoo/plaf/BaseCheckBoxUI.java b/src/com/jtattoo/plaf/BaseCheckBoxUI.java new file mode 100644 index 0000000..b218291 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseCheckBoxUI.java @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import javax.swing.*; +import javax.swing.plaf.ComponentUI; + +/** + * @author Michael Hagen + */ +public class BaseCheckBoxUI extends BaseRadioButtonUI { + + private static BaseCheckBoxUI checkBoxUI = null; + + public static ComponentUI createUI(JComponent b) { + if (checkBoxUI == null) { + checkBoxUI = new BaseCheckBoxUI(); + } + return checkBoxUI; + } + + public void installDefaults(AbstractButton b) { + super.installDefaults(b); + icon = UIManager.getIcon("CheckBox.icon"); + } +} diff --git a/src/com/jtattoo/plaf/BaseComboBoxUI.java b/src/com/jtattoo/plaf/BaseComboBoxUI.java new file mode 100644 index 0000000..49f9a25 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseComboBoxUI.java @@ -0,0 +1,186 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicComboBoxUI; + +public class BaseComboBoxUI extends BasicComboBoxUI { + + private PropertyChangeListener propertyChangeListener = null; + private FocusListener focusListener = null; + private Border orgBorder = null; + private Color orgBackgroundColor = null; + + public static ComponentUI createUI(JComponent c) { + return new BaseComboBoxUI(); + } + + public void installUI(JComponent c) { + super.installUI(c); + comboBox.setRequestFocusEnabled(true); + if (comboBox.getEditor() != null) { + if (comboBox.getEditor().getEditorComponent() instanceof JTextField) { + ((JTextField) (comboBox.getEditor().getEditorComponent())).setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); + } + } + } + + protected void installListeners() { + super.installListeners(); + propertyChangeListener = new PropertyChangeHandler(); + comboBox.addPropertyChangeListener(propertyChangeListener); + + if (AbstractLookAndFeel.getTheme().doShowFocusFrame()) { + focusListener = new FocusListener() { + + public void focusGained(FocusEvent e) { + if (comboBox != null) { + orgBorder = comboBox.getBorder(); + orgBackgroundColor = comboBox.getBackground(); + LookAndFeel laf = UIManager.getLookAndFeel(); + if (laf instanceof AbstractLookAndFeel) { + if (orgBorder instanceof UIResource) { + Border focusBorder = ((AbstractLookAndFeel)laf).getBorderFactory().getFocusFrameBorder(); + comboBox.setBorder(focusBorder); + } + Color backgroundColor = AbstractLookAndFeel.getTheme().getFocusBackgroundColor(); + comboBox.setBackground(backgroundColor); + } + } + } + + public void focusLost(FocusEvent e) { + if (comboBox != null) { + if (orgBorder instanceof UIResource) { + comboBox.setBorder(orgBorder); + } + comboBox.setBackground(orgBackgroundColor); + } + } + }; + comboBox.addFocusListener(focusListener); + } + } + + protected void uninstallListeners() { + comboBox.removePropertyChangeListener(propertyChangeListener); + comboBox.removeFocusListener(focusListener); + propertyChangeListener = null; + focusListener = null; + super.uninstallListeners(); + } + + public Dimension getPreferredSize(JComponent c) { + Dimension size = super.getPreferredSize(c); + if (comboBox.getGraphics() != null) { + FontMetrics fm = JTattooUtilities.getFontMetrics(comboBox, comboBox.getGraphics(), comboBox.getFont()); + size.height = fm.getHeight() + 2; + if (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel) { + AbstractLookAndFeel laf = (AbstractLookAndFeel)UIManager.getLookAndFeel(); + size.height = Math.max(size.height, laf.getIconFactory().getDownArrowIcon().getIconHeight() + 2); + } + } + return new Dimension(size.width + 2, size.height + 2); + } + + public JButton createArrowButton() { + JButton button = new ArrowButton(); + if (JTattooUtilities.isLeftToRight(comboBox)) { + Border border = BorderFactory.createMatteBorder(0, 1, 0, 0, AbstractLookAndFeel.getFrameColor()); + button.setBorder(border); + } else { + Border border = BorderFactory.createMatteBorder(0, 0, 0, 1, AbstractLookAndFeel.getFrameColor()); + button.setBorder(border); + } + return button; + } + + protected void setButtonBorder() { + if (JTattooUtilities.isLeftToRight(comboBox)) { + Border border = BorderFactory.createMatteBorder(0, 1, 0, 0, AbstractLookAndFeel.getFrameColor()); + arrowButton.setBorder(border); + } else { + Border border = BorderFactory.createMatteBorder(0, 0, 0, 1, AbstractLookAndFeel.getFrameColor()); + arrowButton.setBorder(border); + } + } + + public class PropertyChangeHandler implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent e) { + String name = e.getPropertyName(); + if (name.equals("componentOrientation")) { + setButtonBorder(); + } + } + } +//----------------------------------------------------------------------------- + + public static class ArrowButton extends NoFocusButton { + + public void paint(Graphics g) { + Dimension size = getSize(); + Color colors[]; + if (isEnabled()) { + if (getModel().isArmed() && getModel().isPressed()) { + colors = AbstractLookAndFeel.getTheme().getPressedColors(); + } else if (getModel().isRollover()) { + colors = AbstractLookAndFeel.getTheme().getRolloverColors(); + } else { + colors = AbstractLookAndFeel.getTheme().getButtonColors(); + } + } else { + colors = AbstractLookAndFeel.getTheme().getDisabledColors(); + } + JTattooUtilities.fillHorGradient(g, colors, 0, 0, size.width, size.height); + + boolean inverse = ColorHelper.getGrayValue(colors) < 128; + + Icon icon = inverse ? BaseIcons.getComboBoxInverseIcon() : BaseIcons.getComboBoxIcon(); + int x = (size.width - icon.getIconWidth()) / 2; + int y = (size.height - icon.getIconHeight()) / 2; + + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f)); + if (getModel().isPressed() && getModel().isArmed()) { + icon.paintIcon(this, g, x + 2, y + 1); + } else { + icon.paintIcon(this, g, x + 1, y); + } + g2D.setComposite(savedComposite); + paintBorder(g2D); + + } + } +} diff --git a/src/com/jtattoo/plaf/BaseDesktopPaneUI.java b/src/com/jtattoo/plaf/BaseDesktopPaneUI.java new file mode 100644 index 0000000..21a3255 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseDesktopPaneUI.java @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.Graphics; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicDesktopPaneUI; + +/** + * @author Michael Hagen + */ +public class BaseDesktopPaneUI extends BasicDesktopPaneUI { + + public static ComponentUI createUI(JComponent c) { + return new BaseDesktopPaneUI(); + } + + public void update(Graphics g, JComponent c) { + if (c.isOpaque()) { + Object backgroundTexture = c.getClientProperty("backgroundTexture"); + if (backgroundTexture instanceof Icon) { + JTattooUtilities.fillComponent(g, c, (Icon)backgroundTexture); + } else { + g.setColor(c.getBackground()); + g.fillRect(0, 0, c.getWidth(), c.getHeight()); + } + } + paint(g, c); + } +} diff --git a/src/com/jtattoo/plaf/BaseEditorPaneUI.java b/src/com/jtattoo/plaf/BaseEditorPaneUI.java new file mode 100644 index 0000000..fbb9094 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseEditorPaneUI.java @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.Graphics; +import java.awt.Toolkit; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicEditorPaneUI; +import javax.swing.text.DefaultEditorKit; +import javax.swing.text.JTextComponent; + +/** + * @author Michael Hagen + */ +public class BaseEditorPaneUI extends BasicEditorPaneUI { + + private Border orgBorder = null; + private FocusListener focusListener = null; + + public static ComponentUI createUI(JComponent c) { + return new BaseEditorPaneUI(); + } + + public void installDefaults() { + super.installDefaults(); + updateBackground(); + } + + @SuppressWarnings("deprecation") + protected void installKeyboardActions() { + super.installKeyboardActions(); + if (JTattooUtilities.isMac()) { + InputMap im = (InputMap) UIManager.get("TextField.focusInputMap"); + int commandKey = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, commandKey), DefaultEditorKit.copyAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, commandKey), DefaultEditorKit.pasteAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, commandKey), DefaultEditorKit.cutAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.ALT_DOWN_MASK), DefaultEditorKit.nextWordAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, KeyEvent.ALT_DOWN_MASK), DefaultEditorKit.previousWordAction); + } + } + + protected void installListeners() { + super.installListeners(); + + if (AbstractLookAndFeel.getTheme().doShowFocusFrame()) { + focusListener = new FocusListener() { + + public void focusGained(FocusEvent e) { + if (getComponent() != null) { + orgBorder = getComponent().getBorder(); + LookAndFeel laf = UIManager.getLookAndFeel(); + if (laf instanceof AbstractLookAndFeel && orgBorder instanceof UIResource) { + Border focusBorder = ((AbstractLookAndFeel)laf).getBorderFactory().getFocusFrameBorder(); + getComponent().setBorder(focusBorder); + } + getComponent().invalidate(); + getComponent().repaint(); + } + } + + public void focusLost(FocusEvent e) { + if (getComponent() != null) { + if (orgBorder instanceof UIResource) { + getComponent().setBorder(orgBorder); + } + getComponent().invalidate(); + getComponent().repaint(); + } + } + }; + getComponent().addFocusListener(focusListener); + } + } + + protected void uninstallListeners() { + getComponent().removeFocusListener(focusListener); + focusListener = null; + super.uninstallListeners(); + } + + protected void paintBackground(Graphics g) { + g.setColor(getComponent().getBackground()); + if (AbstractLookAndFeel.getTheme().doShowFocusFrame()) { + if (getComponent().hasFocus() && getComponent().isEditable()) { + g.setColor(AbstractLookAndFeel.getTheme().getFocusBackgroundColor()); + } + } + g.fillRect(0, 0, getComponent().getWidth(), getComponent().getHeight()); + } + + private void updateBackground() { + JTextComponent c = getComponent(); + if (c.getBackground() instanceof UIResource) { + if (!c.isEnabled() || !c.isEditable()) { + c.setBackground(AbstractLookAndFeel.getDisabledBackgroundColor()); + } else { + c.setBackground(AbstractLookAndFeel.getInputBackgroundColor()); + } + } + } +} diff --git a/src/com/jtattoo/plaf/BaseFileChooserUI.java b/src/com/jtattoo/plaf/BaseFileChooserUI.java new file mode 100644 index 0000000..0d9945b --- /dev/null +++ b/src/com/jtattoo/plaf/BaseFileChooserUI.java @@ -0,0 +1,134 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.Dimension; +import java.awt.Window; +import java.io.File; +import javax.swing.*; +import javax.swing.event.AncestorEvent; +import javax.swing.event.AncestorListener; +import javax.swing.filechooser.FileView; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.metal.MetalFileChooserUI; + +/** + * @author Michael Hagen + */ +public class BaseFileChooserUI extends MetalFileChooserUI { + + private FileView fileView = null; + + // Preferred and Minimum sizes for the dialog box + private static final int PREF_WIDTH = 580; + private static final int PREF_HEIGHT = 340; + private static final Dimension PREF_SIZE = new Dimension(PREF_WIDTH, PREF_HEIGHT); + + private AncestorListener ancestorListener = null; + + public BaseFileChooserUI(JFileChooser fileChooser) { + super(fileChooser); + fileView = new BaseFileView(); + } + + public static ComponentUI createUI(JComponent c) { + return new BaseFileChooserUI((JFileChooser) c); + } + + protected void installListeners(JFileChooser fc) { + super.installListeners(fc); + ancestorListener = new AncestorListener() { + + public void ancestorAdded(AncestorEvent event) { + Window w = SwingUtilities.getWindowAncestor(getFileChooser()); + if (w != null) { + w.setMinimumSize(getPreferredSize(getFileChooser())); + } + } + + public void ancestorRemoved(AncestorEvent event) { + } + + public void ancestorMoved(AncestorEvent event) { + } + }; + + fc.addAncestorListener(ancestorListener); + } + + protected void uninstallListeners(JFileChooser fc) { + super.uninstallListeners(fc); + fc.removeAncestorListener(ancestorListener); + } + + /** + * Returns the preferred size of the specified + * JFileChooser. + * The preferred size is at least as large, + * in both height and width, + * as the preferred size recommended + * by the file chooser's layout manager. + * + * @param c a JFileChooser + * @return a Dimension specifying the preferred + * width and height of the file chooser + */ + public Dimension getPreferredSize(JComponent c) { + int prefWidth = PREF_SIZE.width; + Dimension d = c.getLayout().preferredLayoutSize(c); + if (d != null) { + return new Dimension(d.width < prefWidth ? prefWidth : d.width, + d.height < PREF_SIZE.height ? PREF_SIZE.height : d.height); + } else { + return new Dimension(prefWidth, PREF_SIZE.height); + } + } + + public FileView getFileView(JFileChooser fc) { + if (JTattooUtilities.getJavaVersion() < 1.4) { + return super.getFileView(fc); + } else { + return fileView; + } + } + +//------------------------------------------------------------------------------ + protected class BaseFileView extends BasicFileView { + + public Icon getIcon(File f) { + Icon icon = getCachedIcon(f); + if (icon != null) { + return icon; + } + if (f != null) { + icon = getFileChooser().getFileSystemView().getSystemIcon(f); + } + if (icon == null) { + icon = super.getIcon(f); + } + cacheIcon(f, icon); + return icon; + } + } +} diff --git a/src/com/jtattoo/plaf/BaseFormattedTextFieldUI.java b/src/com/jtattoo/plaf/BaseFormattedTextFieldUI.java new file mode 100644 index 0000000..2548535 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseFormattedTextFieldUI.java @@ -0,0 +1,108 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicFormattedTextFieldUI; + +/** + * @author Michael Hagen + */ +public class BaseFormattedTextFieldUI extends BasicFormattedTextFieldUI { + + private Border orgBorder = null; + private FocusListener focusListener = null; + + public static ComponentUI createUI(JComponent c) { + return new BaseFormattedTextFieldUI(); + } + + protected void installListeners() { + super.installListeners(); + + if (AbstractLookAndFeel.getTheme().doShowFocusFrame()) { + focusListener = new FocusListener() { + + public void focusGained(FocusEvent e) { + if (getComponent() != null) { + orgBorder = getComponent().getBorder(); + LookAndFeel laf = UIManager.getLookAndFeel(); + if (laf instanceof AbstractLookAndFeel && orgBorder instanceof UIResource) { + Border focusBorder = ((AbstractLookAndFeel)laf).getBorderFactory().getFocusFrameBorder(); + getComponent().setBorder(focusBorder); + } + getComponent().invalidate(); + getComponent().repaint(); + } + } + + public void focusLost(FocusEvent e) { + if (getComponent() != null) { + if (orgBorder instanceof UIResource) { + getComponent().setBorder(orgBorder); + getComponent().invalidate(); + getComponent().repaint(); + } + } + } + }; + getComponent().addFocusListener(focusListener); + } + } + + protected void uninstallListeners() { + getComponent().removeFocusListener(focusListener); + focusListener = null; + super.uninstallListeners(); + } + + protected void paintBackground(Graphics g) { + g.setColor(getComponent().getBackground()); + if (AbstractLookAndFeel.getTheme().doShowFocusFrame()) { + if (getComponent().hasFocus() && getComponent().isEditable()) { + g.setColor(AbstractLookAndFeel.getTheme().getFocusBackgroundColor()); + } + } + g.fillRect(0, 0, getComponent().getWidth(), getComponent().getHeight()); + } + + protected void paintSafely(Graphics g) { + Graphics2D g2D = (Graphics2D) g; + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + super.paintSafely(g); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } +} diff --git a/src/com/jtattoo/plaf/BaseIcons.java b/src/com/jtattoo/plaf/BaseIcons.java new file mode 100644 index 0000000..ed3e5c5 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseIcons.java @@ -0,0 +1,1514 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.geom.*; +import javax.swing.*; +import javax.swing.plaf.UIResource; + +/** + * @author Michael Hagen + */ +public class BaseIcons { + + public static final LazyImageIcon PEARL_RED_SMALL = new LazyImageIcon("icons/small/pearl_red_24x24.png"); + public static final LazyImageIcon PEARL_YELLOW_SMALL = new LazyImageIcon("icons/small/pearl_yellow_24x24.png"); + public static final LazyImageIcon PEARL_GREEN_SMALL = new LazyImageIcon("icons/small/pearl_green_24x24.png"); + public static final LazyImageIcon PEARL_GREY_SMALL = new LazyImageIcon("icons/small/pearl_grey_24x24.png"); + public static final LazyImageIcon PEARL_RED_MEDIUM = new LazyImageIcon("icons/medium/pearl_red_28x28.png"); + public static final LazyImageIcon PEARL_YELLOW_MEDIUM = new LazyImageIcon("icons/medium/pearl_yellow_28x28.png"); + public static final LazyImageIcon PEARL_GREEN_MEDIUM = new LazyImageIcon("icons/medium/pearl_green_28x28.png"); + public static final LazyImageIcon PEARL_GREY_MEDIUM = new LazyImageIcon("icons/medium/pearl_grey_28x28.png"); + public static final LazyImageIcon PEARL_RED_LARGE = new LazyImageIcon("icons/large/pearl_red_32x32.png"); + public static final LazyImageIcon PEARL_YELLOW_LARGE = new LazyImageIcon("icons/large/pearl_yellow_32x32.png"); + public static final LazyImageIcon PEARL_GREEN_LARGE = new LazyImageIcon("icons/large/pearl_green_32x32.png"); + public static final LazyImageIcon PEARL_GREY_LARGE = new LazyImageIcon("icons/large/pearl_grey_32x32.png"); + + public static final LazyImageIcon ICONIZER_SMALL = new LazyImageIcon("icons/small/iconizer_10x10.png"); + public static final LazyImageIcon MINIMIZER_SMALL = new LazyImageIcon("icons/small/minimizer_10x10.png"); + public static final LazyImageIcon MAXIMIZER_SMALL = new LazyImageIcon("icons/small/maximizer_10x10.png"); + public static final LazyImageIcon CLOSER_SMALL = new LazyImageIcon("icons/small/closer_10x10.png"); + public static final LazyImageIcon ICONIZER_MEDIUM = new LazyImageIcon("icons/medium/iconizer_12x12.png"); + public static final LazyImageIcon MINIMIZER_MEDIUM = new LazyImageIcon("icons/medium/minimizer_12x12.png"); + public static final LazyImageIcon MAXIMIZER_MEDIUM = new LazyImageIcon("icons/medium/maximizer_12x12.png"); + public static final LazyImageIcon CLOSER_MEDIUM = new LazyImageIcon("icons/medium/closer_12x12.png"); + public static final LazyImageIcon ICONIZER_LARGE = new LazyImageIcon("icons/large/iconizer_12x12.png"); + public static final LazyImageIcon MINIMIZER_LARGE = new LazyImageIcon("icons/large/minimizer_12x12.png"); + public static final LazyImageIcon MAXIMIZER_LARGE = new LazyImageIcon("icons/large/maximizer_12x12.png"); + public static final LazyImageIcon CLOSER_LARGE = new LazyImageIcon("icons/large/closer_12x12.png"); + + public static final LazyImageIcon EMPTY_8x8 = new LazyImageIcon("icons/empty_8x8.png"); + + protected static Icon checkBoxIcon = null; + protected static Icon menuCheckBoxIcon = null; + protected static Icon radioButtonIcon = null; + protected static Icon menuRadioButtonIcon = null; + protected static Icon optionPaneErrorIcon = null; + protected static Icon optionPaneWarningIcon = null; + protected static Icon optionPaneInformationIcon = null; + protected static Icon optionPaneQuestionIcon = null; + + protected static Icon fileChooserUpFolderIcon = null; + protected static Icon fileChooserHomeFolderIcon = null; + protected static Icon fileChooserNewFolderIcon = null; + protected static Icon fileChooserListViewIcon = null; + protected static Icon fileChooserDetailViewIcon = null; + protected static Icon fileViewComputerIcon = null; + protected static Icon fileViewFloppyDriveIcon = null; + protected static Icon fileViewHardDriveIcon = null; + + protected static Icon treeOpenedIcon = null; + protected static Icon treeClosedIcon = null; + protected static Icon treeLeafIcon = null; + protected static Icon treeExpandedIcon = null; + protected static Icon treeCollapsedIcon = null; + + protected static Icon paletteCloseIcon = null; + protected static Icon menuIcon = null; + + protected static Icon iconIcon = null; + protected static Icon maxIcon = null; + protected static Icon minIcon = null; + protected static Icon closeIcon = null; + + protected static Icon upArrowIcon = null; + protected static Icon upArrowInverseIcon = null; + protected static Icon downArrowIcon = null; + protected static Icon downArrowInverseIcon = null; + protected static Icon leftArrowIcon = null; + protected static Icon leftArrowInverseIcon = null; + protected static Icon rightArrowIcon = null; + protected static Icon rightArrowInverseIcon = null; + protected static Icon menuArrowIcon = null; + protected static Icon splitterUpArrowIcon = null; + protected static Icon splitterDownArrowIcon = null; + protected static Icon splitterLeftArrowIcon = null; + protected static Icon splitterRightArrowIcon = null; + protected static Icon splitterHorBumpIcon = null; + protected static Icon splitterVerBumpIcon = null; + protected static Icon thumbHorIcon = null; + protected static Icon thumbVerIcon = null; + protected static Icon thumbHorIconRollover = null; + protected static Icon thumbVerIconRollover = null; + + public static void initDefaults() { + checkBoxIcon = null; + menuCheckBoxIcon = null; + radioButtonIcon = null; + menuRadioButtonIcon = null; + optionPaneErrorIcon = null; + optionPaneWarningIcon = null; + optionPaneInformationIcon = null; + optionPaneQuestionIcon = null; + fileChooserUpFolderIcon = null; + fileChooserHomeFolderIcon = null; + fileChooserNewFolderIcon = null; + fileChooserListViewIcon = null; + fileChooserDetailViewIcon = null; + fileViewComputerIcon = null; + fileViewFloppyDriveIcon = null; + fileViewHardDriveIcon = null; + treeOpenedIcon = null; + treeClosedIcon = null; + treeLeafIcon = null; + treeExpandedIcon = null; + treeCollapsedIcon = null; + paletteCloseIcon = null; + menuIcon = null; + iconIcon = null; + maxIcon = null; + minIcon = null; + closeIcon = null; + upArrowIcon = null; + upArrowInverseIcon = null; + downArrowIcon = null; + downArrowInverseIcon = null; + leftArrowIcon = null; + leftArrowInverseIcon = null; + rightArrowIcon = null; + rightArrowInverseIcon = null; + menuArrowIcon = null; + splitterUpArrowIcon = null; + splitterDownArrowIcon = null; + splitterLeftArrowIcon = null; + splitterRightArrowIcon = null; + splitterHorBumpIcon = null; + splitterVerBumpIcon = null; + thumbHorIcon = null; + thumbVerIcon = null; + thumbHorIconRollover = null; + thumbVerIconRollover = null; + } + + public static Icon getRadioButtonIcon() { + if (radioButtonIcon == null) { + radioButtonIcon = new RadioButtonIcon(); + } + return radioButtonIcon; + } + + public static Icon getCheckBoxIcon() { + if (checkBoxIcon == null) { + checkBoxIcon = new CheckBoxIcon(); + } + return checkBoxIcon; + } + + // ComboBox + public static Icon getComboBoxIcon() { + return getDownArrowIcon(); + } + + public static Icon getComboBoxInverseIcon() { + return getDownArrowInverseIcon(); + } + + // OptionPane + public static Icon getOptionPaneErrorIcon() { + if (optionPaneErrorIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + optionPaneErrorIcon = new LazyImageIcon("icons/medium/error_32x32.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + optionPaneErrorIcon = new LazyImageIcon("icons/medium/error_32x32.png"); + } else { + optionPaneErrorIcon = new LazyImageIcon("icons/large/error_48x48.png"); + } + } + return optionPaneErrorIcon; + } + + public static Icon getOptionPaneWarningIcon() { + if (optionPaneWarningIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + optionPaneWarningIcon = new LazyImageIcon("icons/medium/warning_32x32.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + optionPaneWarningIcon = new LazyImageIcon("icons/medium/warning_32x32.png"); + } else { + optionPaneWarningIcon = new LazyImageIcon("icons/large/warning_48x48.png"); + } + } + return optionPaneWarningIcon; + } + + public static Icon getOptionPaneInformationIcon() { + if (optionPaneInformationIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + optionPaneInformationIcon = new LazyImageIcon("icons/medium/information_32x32.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + optionPaneInformationIcon = new LazyImageIcon("icons/medium/information_32x32.png"); + } else { + optionPaneInformationIcon = new LazyImageIcon("icons/large/information_48x48.png"); + } + } + return optionPaneInformationIcon; + } + + public static Icon getOptionPaneQuestionIcon() { + if (optionPaneQuestionIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + optionPaneQuestionIcon = new LazyImageIcon("icons/medium/question_32x32.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + optionPaneQuestionIcon = new LazyImageIcon("icons/medium/question_32x32.png"); + } else { + optionPaneQuestionIcon = new LazyImageIcon("icons/large/question_48x48.png"); + } + } + return optionPaneQuestionIcon; + } + + // FileChooser + public static Icon getFileChooserUpFolderIcon() { + if (fileChooserUpFolderIcon == null) { + fileChooserUpFolderIcon = new LazyImageIcon("icons/folder_up_22x22.png"); + } + return fileChooserUpFolderIcon; + } + + public static Icon getFileChooserHomeFolderIcon() { + if (fileChooserHomeFolderIcon == null) { + fileChooserHomeFolderIcon = new LazyImageIcon("icons/home_22x22.png"); + } + return fileChooserHomeFolderIcon; + } + + public static Icon getFileChooserNewFolderIcon() { + if (fileChooserNewFolderIcon == null) { + fileChooserNewFolderIcon = new LazyImageIcon("icons/folder_new_22x22.png"); + } + return fileChooserNewFolderIcon; + } + + public static Icon getFileChooserListViewIcon() { + if (fileChooserListViewIcon == null) { + fileChooserListViewIcon = new LazyImageIcon("icons/view_list_22x22.png"); + } + return fileChooserListViewIcon; + } + + public static Icon getFileChooserDetailViewIcon() { + if (fileChooserDetailViewIcon == null) { + fileChooserDetailViewIcon = new LazyImageIcon("icons/view_detail_22x22.png"); + } + return fileChooserDetailViewIcon; + } + + public static Icon getFileViewComputerIcon() { + if (fileViewComputerIcon == null) { + fileViewComputerIcon = new LazyImageIcon("icons/computer_16x16.png"); + } + return fileViewComputerIcon; + } + + public static Icon getFileViewFloppyDriveIcon() { + if (fileViewFloppyDriveIcon == null) { + fileViewFloppyDriveIcon = new LazyImageIcon("icons/floppy_drive_16x16.png"); + } + return fileViewFloppyDriveIcon; + } + + public static Icon getFileViewHardDriveIcon() { + if (fileViewHardDriveIcon == null) { + fileViewHardDriveIcon = new LazyImageIcon("icons/hard_drive_16x16.png"); + } + return fileViewHardDriveIcon; + } + + // Tree + public static Icon getTreeOpenedIcon() { + if (treeOpenedIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + treeOpenedIcon = new LazyImageIcon("icons/small/folder_opened_16x16.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + treeOpenedIcon = new LazyImageIcon("icons/medium/folder_opened_20x20.png"); + } else { + treeOpenedIcon = new LazyImageIcon("icons/large/folder_opened_24x24.png"); + } + } + return treeOpenedIcon; + } + + public static Icon getTreeClosedIcon() { + if (treeClosedIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + treeClosedIcon = new LazyImageIcon("icons/small/folder_closed_16x16.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + treeClosedIcon = new LazyImageIcon("icons/medium/folder_closed_20x20.png"); + } else { + treeClosedIcon = new LazyImageIcon("icons/large/folder_closed_24x24.png"); + } + } + return treeClosedIcon; + } + + public static Icon getTreeLeafIcon() { + if (treeLeafIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + treeLeafIcon = new LazyImageIcon("icons/small/document_16x16.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + treeLeafIcon = new LazyImageIcon("icons/medium/document_20x20.png"); + } else { + treeLeafIcon = new LazyImageIcon("icons/large/document_24x24.png"); + } + } + return treeLeafIcon; + } + + public static Icon getTreeCollapsedIcon() { + if (treeCollapsedIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + treeCollapsedIcon = new LazyImageIcon("icons/small/tree_collapsed_9x9.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + treeCollapsedIcon = new LazyImageIcon("icons/medium/tree_collapsed_11x11.png"); + } else { + treeCollapsedIcon = new LazyImageIcon("icons/large/tree_collapsed_14x14.png"); + } + } + return treeCollapsedIcon; + } + + public static Icon getTreeExpandedIcon() { + if (treeExpandedIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + treeExpandedIcon = new LazyImageIcon("icons/small/tree_expanded_9x9.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + treeExpandedIcon = new LazyImageIcon("icons/medium/tree_expanded_11x11.png"); + } else { + treeExpandedIcon = new LazyImageIcon("icons/large/tree_expanded_14x14.png"); + } + } + return treeExpandedIcon; + } + + // TitlePane icons + public static Icon getMenuIcon() { + if (menuIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + menuIcon = new LazyImageIcon("icons/small/cup_16x16.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + menuIcon = new LazyImageIcon("icons/medium/cup_20x20.png"); + } else { + menuIcon = new LazyImageIcon("icons/large/cup_24x24.png"); + } + } + return menuIcon; + } + + public static Icon getIconIcon() { + if (iconIcon == null) { + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + iconIcon = new MacIconIcon(); + } else { + Color iconColor = AbstractLookAndFeel.getTheme().getWindowIconColor(); + Color iconRolloverColor = AbstractLookAndFeel.getTheme().getWindowIconRolloverColor(); + iconIcon = new IconSymbol(iconColor, null, iconRolloverColor); + } + } + return iconIcon; + } + + public static Icon getMaxIcon() { + if (maxIcon == null) { + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + maxIcon = new MacMaxIcon(); + } else { + Color iconColor = AbstractLookAndFeel.getTheme().getWindowIconColor(); + Color iconRolloverColor = AbstractLookAndFeel.getTheme().getWindowIconRolloverColor(); + maxIcon = new MaxSymbol(iconColor, null, iconRolloverColor); + } + } + return maxIcon; + } + + public static Icon getMinIcon() { + if (minIcon == null) { + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + minIcon = new MacMinIcon(); + } else { + Color iconColor = AbstractLookAndFeel.getTheme().getWindowIconColor(); + Color iconRolloverColor = AbstractLookAndFeel.getTheme().getWindowIconRolloverColor(); + minIcon = new MinSymbol(iconColor, null, iconRolloverColor); + } + } + return minIcon; + } + + public static Icon getCloseIcon() { + if (closeIcon == null) { + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + closeIcon = new MacCloseIcon(); + } else { + Color iconColor = AbstractLookAndFeel.getTheme().getWindowIconColor(); + Color iconRolloverColor = AbstractLookAndFeel.getTheme().getWindowIconRolloverColor(); + closeIcon = new CloseSymbol(iconColor, null, iconRolloverColor); + } + } + return closeIcon; + } + + public static Icon getPaletteCloseIcon() { + if (paletteCloseIcon == null) { + paletteCloseIcon = new CloseSymbol(Color.black, null, Color.red); + } + return paletteCloseIcon; + } + + // MenuIcons + public static Icon getMenuArrowIcon() { + if (menuArrowIcon == null) { + menuArrowIcon = new LazyMenuArrowImageIcon("icons/MenuRightArrow.gif", "icons/MenuLeftArrow.gif"); + } + return menuArrowIcon; + } + + public static Icon getMenuCheckBoxIcon() { + if (menuCheckBoxIcon == null) { + menuCheckBoxIcon = new CheckBoxIcon(); + } + return menuCheckBoxIcon; + } + + public static Icon getMenuRadioButtonIcon() { + if (menuRadioButtonIcon == null) { + menuRadioButtonIcon = new RadioButtonIcon(); + } + return menuRadioButtonIcon; + } + + // ArrowIcons + public static Icon getUpArrowIcon() { + if (upArrowIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + upArrowIcon = new LazyImageIcon("icons/small/arrow_up_7x4.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + upArrowIcon = new LazyImageIcon("icons/medium/arrow_up_9x6.png"); + } else { + upArrowIcon = new LazyImageIcon("icons/large/arrow_up_11x8.png"); + } + } + return upArrowIcon; + } + + public static Icon getUpArrowInverseIcon() { + if (upArrowInverseIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + upArrowInverseIcon = new LazyImageIcon("icons/small/arrow_up_inverse_7x4.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + upArrowInverseIcon = new LazyImageIcon("icons/medium/arrow_up_inverse_9x6.png"); + } else { + upArrowInverseIcon = new LazyImageIcon("icons/large/arrow_up_inverse_11x8.png"); + } + } + return upArrowInverseIcon; + } + + public static Icon getDownArrowIcon() { + if (downArrowIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + downArrowIcon = new LazyImageIcon("icons/small/arrow_down_7x4.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + downArrowIcon = new LazyImageIcon("icons/medium/arrow_down_9x6.png"); + } else { + downArrowIcon = new LazyImageIcon("icons/large/arrow_down_11x8.png"); + } + } + return downArrowIcon; + } + + public static Icon getDownArrowInverseIcon() { + if (downArrowInverseIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + downArrowInverseIcon = new LazyImageIcon("icons/small/arrow_down_inverse_7x4.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + downArrowInverseIcon = new LazyImageIcon("icons/medium/arrow_down_inverse_9x6.png"); + } else { + downArrowInverseIcon = new LazyImageIcon("icons/large/arrow_down_inverse_11x8.png"); + } + } + return downArrowInverseIcon; + } + + public static Icon getLeftArrowIcon() { + if (leftArrowIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + leftArrowIcon = new LazyImageIcon("icons/small/arrow_left_4x7.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + leftArrowIcon = new LazyImageIcon("icons/medium/arrow_left_6x9.png"); + } else { + leftArrowIcon = new LazyImageIcon("icons/large/arrow_left_8x11.png"); + } + } + return leftArrowIcon; + } + + public static Icon getLeftArrowInverseIcon() { + if (leftArrowInverseIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + leftArrowInverseIcon = new LazyImageIcon("icons/small/arrow_left_inverse_4x7.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + leftArrowInverseIcon = new LazyImageIcon("icons/medium/arrow_left_inverse_6x9.png"); + } else { + leftArrowInverseIcon = new LazyImageIcon("icons/large/arrow_left_inverse_8x11.png"); + } + } + return leftArrowInverseIcon; + } + + public static Icon getRightArrowIcon() { + if (rightArrowIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + rightArrowIcon = new LazyImageIcon("icons/small/arrow_right_4x7.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + rightArrowIcon = new LazyImageIcon("icons/medium/arrow_right_6x9.png"); + } else { + rightArrowIcon = new LazyImageIcon("icons/large/arrow_right_8x11.png"); + } + } + return rightArrowIcon; + } + + public static Icon getRightArrowInverseIcon() { + if (rightArrowInverseIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + rightArrowInverseIcon = new LazyImageIcon("icons/small/arrow_right_inverse_4x7.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + rightArrowInverseIcon = new LazyImageIcon("icons/medium/arrow_right_inverse_6x9.png"); + } else { + rightArrowInverseIcon = new LazyImageIcon("icons/large/arrow_right_inverse_8x11.png"); + } + } + return rightArrowInverseIcon; + } + + // Splitter + public static Icon getSplitterUpArrowIcon() { + if (splitterUpArrowIcon == null) { + splitterUpArrowIcon = new LazyImageIcon("icons/SplitterUpArrow.gif"); + } + return splitterUpArrowIcon; + } + + public static Icon getSplitterDownArrowIcon() { + if (splitterDownArrowIcon == null) { + splitterDownArrowIcon = new LazyImageIcon("icons/SplitterDownArrow.gif"); + } + return splitterDownArrowIcon; + } + + public static Icon getSplitterLeftArrowIcon() { + if (splitterLeftArrowIcon == null) { + splitterLeftArrowIcon = new LazyImageIcon("icons/SplitterLeftArrow.gif"); + } + return splitterLeftArrowIcon; + } + + public static Icon getSplitterRightArrowIcon() { + if (splitterRightArrowIcon == null) { + splitterRightArrowIcon = new LazyImageIcon("icons/SplitterRightArrow.gif"); + } + return splitterRightArrowIcon; + } + + public static Icon getSplitterHorBumpIcon() { + if (splitterHorBumpIcon == null) { + splitterHorBumpIcon = new LazyImageIcon("icons/SplitterHorBumps.gif"); + } + return splitterHorBumpIcon; + } + + public static Icon getSplitterVerBumpIcon() { + if (splitterVerBumpIcon == null) { + splitterVerBumpIcon = new LazyImageIcon("icons/SplitterVerBumps.gif"); + } + return splitterVerBumpIcon; + } + + // Slider + public static Icon getThumbHorIcon() { + if (thumbHorIcon == null) { + thumbHorIcon = new LazyImageIcon("icons/thumb_hor.gif"); + } + return thumbHorIcon; + } + + public static Icon getThumbVerIcon() { + if (thumbVerIcon == null) { + thumbVerIcon = new LazyImageIcon("icons/thumb_ver.gif"); + } + return thumbVerIcon; + } + + public static Icon getThumbHorIconRollover() { + if (thumbHorIconRollover == null) { + thumbHorIconRollover = new LazyImageIcon("icons/thumb_hor_rollover.gif"); + } + return thumbHorIconRollover; + } + + public static Icon getThumbVerIconRollover() { + if (thumbVerIconRollover == null) { + thumbVerIconRollover = new LazyImageIcon("icons/thumb_ver_rollover.gif"); + } + return thumbVerIconRollover; + } + +//----------------------------------------------------------------------------------------------------------- + private static class CheckBoxIcon implements Icon { + + private static int GAP = 2; + private static final Icon SMALL_CHECK_ICON = new LazyImageIcon("icons/small/check_symbol_10x10.png"); + private static final Icon SMALL_CHECK_DISABLED_ICON = new LazyImageIcon("icons/small/check_symbol_disabled_10x10.png"); + private static final Icon MEDIUM_CHECK_ICON = new LazyImageIcon("icons/medium/check_symbol_12x12.png"); + private static final Icon MEDIUM_CHECK_DISABLED_ICON = new LazyImageIcon("icons/medium/check_symbol_disabled_12x12.png"); + private static final Icon LARGE_CHECK_ICON = new LazyImageIcon("icons/large/check_symbol_14x14.png"); + private static final Icon LARGE_CHECK_DISABLED_ICON = new LazyImageIcon("icons/large/check_symbol_disabled_14x14.png"); + + public void paintIcon(Component c, Graphics g, int x, int y) { + if (!JTattooUtilities.isLeftToRight(c)) { + x += GAP; + } + int w = getIconWidth() - GAP; + int h = getIconHeight(); + AbstractButton button = (AbstractButton) c; + ButtonModel model = button.getModel(); + if (c instanceof JCheckBoxMenuItem) { + g.setColor(Color.white); + g.fillRect(x, y, w, h); + if (button.isEnabled()) { + g.setColor(AbstractLookAndFeel.getFrameColor()); + } else { + g.setColor(ColorHelper.brighter(AbstractLookAndFeel.getFrameColor(), 40)); + } + g.drawRect(x, y, w, h); + } else { + if (button.isEnabled()) { + if ((button.isRolloverEnabled() && model.isRollover())) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getRolloverColors(), x, y, w, h); + } else { + if (AbstractLookAndFeel.getTheme().doShowFocusFrame() && button.hasFocus()) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getFocusColors(), x, y, w, h); + } else { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getCheckBoxColors(), x, y, w, h); + } + if (!model.isPressed()) { + g.setColor(Color.white); + g.drawLine(x + 1, y + 1, x + 1, y + h - 2); + g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 2); + } + } + if (AbstractLookAndFeel.getTheme().doShowFocusFrame() && button.hasFocus()) { + Color hiColor = ColorHelper.brighter(AbstractLookAndFeel.getTheme().getFocusFrameColor(), 30); + Color loColor = ColorHelper.darker(AbstractLookAndFeel.getTheme().getFocusFrameColor(), 20); + g.setColor(hiColor); + g.drawRect(x - 1, y - 1, w + 2, h + 2); + g.setColor(loColor); + g.drawRect(x, y, w, h); + } else { + g.setColor(AbstractLookAndFeel.getFrameColor()); + g.drawRect(x, y, w, h); + } + } else { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getDisabledColors(), x, y, w, h); + g.setColor(ColorHelper.brighter(AbstractLookAndFeel.getFrameColor(), 40)); + g.drawRect(x, y, w, h); + } + } + + Icon checkIcon; + Icon checkDisabledIcon; + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + checkIcon = SMALL_CHECK_ICON; + checkDisabledIcon = SMALL_CHECK_DISABLED_ICON; + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + checkIcon = MEDIUM_CHECK_ICON; + checkDisabledIcon = MEDIUM_CHECK_DISABLED_ICON; + } else { + checkIcon = LARGE_CHECK_ICON; + checkDisabledIcon = LARGE_CHECK_DISABLED_ICON; + } + int xi = x + ((w - checkIcon.getIconWidth()) / 2) + 1; + int yi = y + ((h - checkIcon.getIconHeight()) / 2) + 1; + if (model.isPressed() && model.isArmed()) { + Color bc = AbstractLookAndFeel.getTheme().getSelectionBackgroundColor(); + Color fc = ColorHelper.darker(bc, 40); + g.setColor(fc); + g.drawRect(x + 3, y + 3, w - 6, h - 6); + g.setColor(bc); + g.fillRect(x + 4, y + 4, w - 7, h - 7); + } else if (model.isSelected()) { + if (button.isEnabled()) { + checkIcon.paintIcon(c, g, xi, yi); + } else { + checkDisabledIcon.paintIcon(c, g, xi, yi); + } + } + } + + public int getIconWidth() { + int w; + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + w = 15; + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + w = 17; + } else { + w = 19; + } + return w + GAP; + } + + public int getIconHeight() { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + return 15; + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + return 17; + } else { + return 19; + } + } + } + +//----------------------------------------------------------------------------------------------------------- + private static class RadioButtonIcon implements Icon { + + private static int GAP = 2; + + public void paintIcon(Component c, Graphics g, int x, int y) { + if (!JTattooUtilities.isLeftToRight(c)) { + x += GAP; + } + int w = getIconWidth() - GAP; + int h = getIconHeight(); + Graphics2D g2D = (Graphics2D) g; + AbstractButton button = (AbstractButton) c; + ButtonModel model = button.getModel(); + Color cHi = Color.white; + Color cLo = Color.white; + if (!(c instanceof JRadioButtonMenuItem)) { + Color colors[]; + if (button.isEnabled()) { + if ((button.isRolloverEnabled() && model.isRollover()) || (model.isPressed() && model.isArmed())) { + colors = AbstractLookAndFeel.getTheme().getRolloverColors(); + } else { + if (AbstractLookAndFeel.getTheme().doShowFocusFrame() && button.hasFocus()) { + colors = AbstractLookAndFeel.getTheme().getFocusColors(); + } else { + colors = AbstractLookAndFeel.getTheme().getCheckBoxColors(); + } + } + } else { + colors = AbstractLookAndFeel.getTheme().getDisabledColors(); + } + cHi = colors[0]; + cLo = colors[colors.length - 1]; + } + Paint savedPaint = g2D.getPaint(); + g2D.setPaint(new GradientPaint(0, 0, cHi, 0, h, cLo)); + g2D.fillOval(x, y, w, h); + g2D.setPaint(savedPaint); + + Shape savedClip = g.getClip(); + //Area clipArea = new Area(new Ellipse2D.Double(x + 1, y + 1, w - 1, h - 1)); + Area clipArea = new Area(new Ellipse2D.Double(x, y, w + 1, h + 1)); + if (savedClip != null) { + clipArea.intersect(new Area(savedClip)); + } + g2D.setClip(clipArea); + if (c instanceof JRadioButtonMenuItem) { + g.setColor(Color.white); + g.fillRect(x, y, w, h); + } else { + if (button.isEnabled()) { + if ((button.isRolloverEnabled() && model.isRollover()) || (model.isPressed() && model.isArmed())) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getRolloverColors(), x, y, w, h); + } else { + if (AbstractLookAndFeel.getTheme().doShowFocusFrame() && button.hasFocus()) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getFocusColors(), x, y, w, h); + } else { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getCheckBoxColors(), x, y, w, h); + } + } + } else { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getDisabledColors(), x, y, w, h); + } + } + g2D.setClip(savedClip); + + Object savedRederingHint = g2D.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + if (!model.isRollover()) { + Composite savedComposite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f); + g2D.setComposite(alpha); + g2D.setColor(Color.white); + g2D.drawOval(x + 1, y + 1, w - 2, h - 2); + g2D.setComposite(savedComposite); + } + if (button.isEnabled()) { + if (AbstractLookAndFeel.getTheme().doShowFocusFrame() && button.hasFocus()) { + Color hiColor = ColorHelper.brighter(AbstractLookAndFeel.getTheme().getFocusFrameColor(), 30); + Color loColor = ColorHelper.darker(AbstractLookAndFeel.getTheme().getFocusFrameColor(), 20); + g.setColor(hiColor); + g.drawOval(x - 1, y - 1, w + 2, h + 2); + g.setColor(loColor); + g2D.drawOval(x, y, w, h); + } else { + g.setColor(AbstractLookAndFeel.getFrameColor()); + g2D.drawOval(x, y, w, h); + } + } else { + g.setColor(ColorHelper.brighter(AbstractLookAndFeel.getFrameColor(), 40)); + g2D.drawOval(x, y, w, h); + } + + if (model.isSelected()) { + if (button.isEnabled()) { + Color fc = AbstractLookAndFeel.getForegroundColor(); + if (ColorHelper.getGrayValue(cLo) < 128) { + if (ColorHelper.getGrayValue(fc) < 128) { + g2D.setColor(Color.white); + } else { + g2D.setColor(fc); + } + } else { + if (ColorHelper.getGrayValue(fc) > 128) { + g2D.setColor(Color.black); + } else { + g2D.setColor(fc); + } + } + } else { + g.setColor(AbstractLookAndFeel.getDisabledForegroundColor()); + } + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + g2D.fillOval(x + 4, y + 4, w - 7, h - 7); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + g2D.fillOval(x + 4, y + 4, w - 7, h - 7); + } else { + g2D.fillOval(x + 5, y + 5, w - 9, h - 9); + } + } + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, savedRederingHint); + } + + public int getIconWidth() { + int w; + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + w = 14; + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + w = 16; + } else { + w = 18; + } + return w + GAP; + } + + public int getIconHeight() { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + return 14; + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + return 16; + } else { + return 18; + } + } + } + +//----------------------------------------------------------------------------------------------------------- + public static class MacCloseIcon implements Icon, UIResource { + + public void paintIcon(Component c, Graphics g, int x, int y) { + AbstractButton btn = (AbstractButton) c; + ButtonModel model = btn.getModel(); + int w = c.getWidth(); + int h = c.getHeight(); + Icon closerIcon; + Icon pearlIcon; + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + closerIcon = CLOSER_SMALL; + pearlIcon = PEARL_RED_SMALL; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_SMALL; + } + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + closerIcon = CLOSER_MEDIUM; + pearlIcon = PEARL_RED_MEDIUM; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_MEDIUM; + } + } else { + closerIcon = CLOSER_LARGE; + pearlIcon = PEARL_RED_LARGE; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_LARGE; + } + } + x = (w - pearlIcon.getIconWidth()) / 2; + y = (h - pearlIcon.getIconHeight()) / 2; + pearlIcon.paintIcon(c, g, x, y); + if (model.isRollover()) { + x += (pearlIcon.getIconWidth() - closerIcon.getIconWidth()) / 2; + y += (pearlIcon.getIconHeight() - closerIcon.getIconHeight()) / 2; + closerIcon.paintIcon(c, g, x, y); + } + } + + public int getIconHeight() { + return 24; + } + + public int getIconWidth() { + return 24; + } + } + + public static class MacIconIcon implements Icon, UIResource { + + public void paintIcon(Component c, Graphics g, int x, int y) { + AbstractButton btn = (AbstractButton) c; + ButtonModel model = btn.getModel(); + int w = c.getWidth(); + int h = c.getHeight(); + Icon iconizerIcon; + Icon pearlIcon; + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + iconizerIcon = ICONIZER_SMALL; + pearlIcon = PEARL_YELLOW_SMALL; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_SMALL; + } + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + iconizerIcon = ICONIZER_MEDIUM; + pearlIcon = PEARL_YELLOW_MEDIUM; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_MEDIUM; + } + } else { + iconizerIcon = ICONIZER_LARGE; + pearlIcon = PEARL_YELLOW_LARGE; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_LARGE; + } + } + + } else { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + iconizerIcon = ICONIZER_SMALL; + pearlIcon = PEARL_GREEN_SMALL; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_SMALL; + } + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + iconizerIcon = ICONIZER_MEDIUM; + pearlIcon = PEARL_GREEN_MEDIUM; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_MEDIUM; + } + } else { + iconizerIcon = ICONIZER_LARGE; + pearlIcon = PEARL_GREEN_LARGE; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_LARGE; + } + } + } + x = (w - pearlIcon.getIconWidth()) / 2; + y = (h - pearlIcon.getIconHeight()) / 2; + pearlIcon.paintIcon(c, g, x, y); + if (model.isRollover()) { + x += (pearlIcon.getIconWidth() - iconizerIcon.getIconWidth()) / 2; + y += (pearlIcon.getIconHeight() - iconizerIcon.getIconHeight()) / 2; + iconizerIcon.paintIcon(c, g, x, y); + } + } + + public int getIconHeight() { + return 24; + } + + public int getIconWidth() { + return 24; + } + } + + public static class MacMaxIcon implements Icon, UIResource { + + public void paintIcon(Component c, Graphics g, int x, int y) { + AbstractButton btn = (AbstractButton) c; + ButtonModel model = btn.getModel(); + int w = c.getWidth(); + int h = c.getHeight(); + Icon maximizerIcon; + Icon pearlIcon; + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + maximizerIcon = MAXIMIZER_SMALL; + pearlIcon = PEARL_GREEN_SMALL; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_SMALL; + } + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + maximizerIcon = MAXIMIZER_MEDIUM; + pearlIcon = PEARL_GREEN_MEDIUM; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_MEDIUM; + } + } else { + maximizerIcon = MAXIMIZER_LARGE; + pearlIcon = PEARL_GREEN_LARGE; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_LARGE; + } + } + } else { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + maximizerIcon = MAXIMIZER_SMALL; + pearlIcon = PEARL_YELLOW_SMALL; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_SMALL; + } + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + maximizerIcon = MAXIMIZER_MEDIUM; + pearlIcon = PEARL_YELLOW_MEDIUM; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_MEDIUM; + } + } else { + maximizerIcon = MAXIMIZER_LARGE; + pearlIcon = PEARL_YELLOW_LARGE; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_LARGE; + } + } + } + x = (w - pearlIcon.getIconWidth()) / 2; + y = (h - pearlIcon.getIconHeight()) / 2; + pearlIcon.paintIcon(c, g, x, y); + if (model.isRollover()) { + x += (pearlIcon.getIconWidth() - maximizerIcon.getIconWidth()) / 2; + y += (pearlIcon.getIconHeight() - maximizerIcon.getIconHeight()) / 2; + maximizerIcon.paintIcon(c, g, x, y); + } + } + + public int getIconHeight() { + return 24; + } + + public int getIconWidth() { + return 24; + } + } + + public static class MacMinIcon implements Icon, UIResource { + + public void paintIcon(Component c, Graphics g, int x, int y) { + AbstractButton btn = (AbstractButton) c; + ButtonModel model = btn.getModel(); + int w = c.getWidth(); + int h = c.getHeight(); + Icon minimizerIcon; + Icon pearlIcon; + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + minimizerIcon = MINIMIZER_SMALL; + pearlIcon = PEARL_GREEN_SMALL; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_SMALL; + } + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + minimizerIcon = MINIMIZER_MEDIUM; + pearlIcon = PEARL_GREEN_MEDIUM; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_MEDIUM; + } + } else { + minimizerIcon = MINIMIZER_LARGE; + pearlIcon = PEARL_GREEN_LARGE; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_LARGE; + } + } + } else { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + minimizerIcon = MINIMIZER_SMALL; + pearlIcon = PEARL_YELLOW_SMALL; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_SMALL; + } + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + minimizerIcon = MINIMIZER_MEDIUM; + pearlIcon = PEARL_YELLOW_MEDIUM; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_MEDIUM; + } + } else { + minimizerIcon = MINIMIZER_LARGE; + pearlIcon = PEARL_YELLOW_LARGE; + if (!JTattooUtilities.isActive(btn)) { + pearlIcon = PEARL_GREY_LARGE; + } + } + } + x = (w - pearlIcon.getIconWidth()) / 2; + y = (h - pearlIcon.getIconHeight()) / 2; + pearlIcon.paintIcon(c, g, x, y); + if (model.isRollover()) { + x += (pearlIcon.getIconWidth() - minimizerIcon.getIconWidth()) / 2; + y += (pearlIcon.getIconHeight() - minimizerIcon.getIconHeight()) / 2; + minimizerIcon.paintIcon(c, g, x, y); + } + } + + public int getIconHeight() { + return 24; + } + + public int getIconWidth() { + return 24; + } + } + +//----------------------------------------------------------------------------------------------------------- + public static class IconSymbol implements Icon { + + private Color foregroundColor = null; + private Color shadowColor = null; + private Color inactiveForegroundColor = null; + private Color inactiveShadowColor = null; + private Color rolloverColor = null; + private Insets insets = new Insets(0, 0, 0, 0); + + public IconSymbol(Color foregroundColor, Color shadowColor, Color rolloverColor) { + this.foregroundColor = foregroundColor; + this.shadowColor = shadowColor; + this.rolloverColor = rolloverColor; + this.inactiveForegroundColor = foregroundColor; + this.inactiveShadowColor = shadowColor; + } + + public IconSymbol(Color foregroundColor, Color shadowColor, Color rolloverColor, Insets insets) { + this.foregroundColor = foregroundColor; + this.shadowColor = shadowColor; + this.rolloverColor = rolloverColor; + this.inactiveForegroundColor = foregroundColor; + this.inactiveShadowColor = shadowColor; + this.insets = insets; + } + + public IconSymbol(Color foregroundColor, Color shadowColor, Color rolloverColor, Color inactiveForegroundColor, Color inactiveShadowColor, Insets insets) { + this.foregroundColor = foregroundColor; + this.shadowColor = shadowColor; + this.rolloverColor = rolloverColor; + this.inactiveForegroundColor = inactiveForegroundColor; + this.inactiveShadowColor = inactiveShadowColor; + this.insets = insets; + } + + public int getIconHeight() { + return 16; + } + + public int getIconWidth() { + return 16; + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + Graphics2D g2D = (Graphics2D) g; + g2D.translate(insets.left, insets.top); + int w = c.getWidth() - insets.left - insets.right; + int h = c.getHeight() - insets.top - insets.bottom; + boolean active = JTattooUtilities.isActive((JComponent) c); + Color color = foregroundColor; + if (!active) { + color = inactiveForegroundColor; + } + if (c instanceof AbstractButton) { + if (((AbstractButton) c).getModel().isRollover() && (rolloverColor != null)) { + color = rolloverColor; + } + } + //int lw = (w / 12) + 1; + int lw = (h > 22) ? 3 : 2; + + int dx = (w / 5) + 2; + int dy = dx; + + Stroke savedStroke = g2D.getStroke(); + g2D.setStroke(new BasicStroke(lw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)); + if (shadowColor != null) { + if (!active) { + g2D.setColor(inactiveShadowColor); + } else { + g2D.setColor(shadowColor); + } + g2D.drawLine(dx + 1, h - dy, w - dx + 1, h - dy); + } + g2D.setColor(color); + g2D.drawLine(dx, h - dy - 1, w - dx, h - dy - 1); + g2D.setStroke(savedStroke); + g2D.translate(-insets.left, -insets.top); + } + } + +//----------------------------------------------------------------------------------------------------------- + public static class MaxSymbol implements Icon { + + private Color foregroundColor = null; + private Color shadowColor = null; + private Color rolloverColor = null; + private Color inactiveForegroundColor = null; + private Color inactiveShadowColor = null; + private Insets insets = new Insets(0, 0, 0, 0); + + public MaxSymbol(Color foregroundColor, Color shadowColor, Color rolloverColor) { + this.foregroundColor = foregroundColor; + this.shadowColor = shadowColor; + this.rolloverColor = rolloverColor; + this.inactiveForegroundColor = foregroundColor; + this.inactiveShadowColor = shadowColor; + } + + public MaxSymbol(Color foregroundColor, Color shadowColor, Color rolloverColor, Insets insets) { + this.foregroundColor = foregroundColor; + this.shadowColor = shadowColor; + this.rolloverColor = rolloverColor; + this.inactiveForegroundColor = foregroundColor; + this.inactiveShadowColor = shadowColor; + this.insets = insets; + } + + public MaxSymbol(Color foregroundColor, Color shadowColor, Color rolloverColor, Color inactiveForegroundColor, Color inactiveShadowColor, Insets insets) { + this.foregroundColor = foregroundColor; + this.shadowColor = shadowColor; + this.rolloverColor = rolloverColor; + this.inactiveForegroundColor = inactiveForegroundColor; + this.inactiveShadowColor = inactiveShadowColor; + this.insets = insets; + } + + public int getIconHeight() { + return 16; + } + + public int getIconWidth() { + return 16; + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + Graphics2D g2D = (Graphics2D) g; + g2D.translate(insets.left, insets.top); + int w = c.getWidth() - insets.left - insets.right; + int h = c.getHeight() - insets.top - insets.bottom; + boolean active = JTattooUtilities.isActive((JComponent) c); + Color color = foregroundColor; + if (!active) { + color = inactiveForegroundColor; + } + if (c instanceof AbstractButton) { + if (((AbstractButton) c).getModel().isRollover() && (rolloverColor != null)) { + color = rolloverColor; + } + } + int lw = (h > 22) ? 2 : 1; + + int dx = (w / 5) + 1; + int dy = (h / 5) + 2; + + Stroke savedStroke = g2D.getStroke(); + g2D.setStroke(new BasicStroke(lw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)); + if (shadowColor != null) { + if (!active) { + g2D.setColor(inactiveShadowColor); + } else { + g2D.setColor(shadowColor); + } + g2D.drawRect(dx + 1, dy + 1, w - (2 * dx), h - (2 * dy)); + g2D.drawLine(dx + 1, dy + lw + 1, w - dx, dy + lw + 1); + } + g2D.setColor(color); + g2D.drawRect(dx, dy, w - (2 * dx), h - (2 * dy)); + g2D.drawLine(dx + 1, dy + lw, w - dx, dy + lw); + + g2D.setStroke(savedStroke); + g2D.translate(-insets.left, -insets.top); + } + } + +//----------------------------------------------------------------------------------------------------------- + public static class MinSymbol implements Icon { + + private Color foregroundColor = null; + private Color shadowColor = null; + private Color rolloverColor = null; + private Color inactiveForegroundColor = null; + private Color inactiveShadowColor = null; + private Insets insets = new Insets(0, 0, 0, 0); + + public MinSymbol(Color foregroundColor, Color shadowColor, Color rolloverColor) { + this.foregroundColor = foregroundColor; + this.shadowColor = shadowColor; + this.rolloverColor = rolloverColor; + this.inactiveForegroundColor = foregroundColor; + this.inactiveShadowColor = shadowColor; + } + + public MinSymbol(Color foregroundColor, Color shadowColor, Color rolloverColor, Insets insets) { + this.foregroundColor = foregroundColor; + this.shadowColor = shadowColor; + this.rolloverColor = rolloverColor; + this.inactiveForegroundColor = foregroundColor; + this.inactiveShadowColor = shadowColor; + this.insets = insets; + } + + public MinSymbol(Color foregroundColor, Color shadowColor, Color rolloverColor, Color inactiveForegroundColor, Color inactiveShadowColor, Insets insets) { + this.foregroundColor = foregroundColor; + this.shadowColor = shadowColor; + this.rolloverColor = rolloverColor; + this.inactiveForegroundColor = inactiveForegroundColor; + this.inactiveShadowColor = inactiveShadowColor; + this.insets = insets; + } + + public int getIconHeight() { + return 16; + } + + public int getIconWidth() { + return 16; + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + Graphics2D g2D = (Graphics2D) g; + g2D.translate(insets.left, insets.top); + int w = c.getWidth() - insets.left - insets.right; + int h = c.getHeight() - insets.top - insets.bottom; + + int lw = (h > 22) ? 2 : 1; + int delta = w / 4; + + w = Math.min(w, h) - 6; + h = w; + + int x1 = 3; + int y1 = 3; + int w1 = w - delta; + int h1 = h - delta; + + int x2 = delta + 2; + int y2 = Math.max(delta + 2, y1 + (2 * lw) + 1); + int w2 = w - delta; + int h2 = h - delta; + + boolean active = JTattooUtilities.isActive((JComponent) c); + Color ic = foregroundColor; + Color sc = shadowColor; + if (!active) { + ic = inactiveForegroundColor; + if (sc != null) { + sc = inactiveShadowColor; + } + } + if (c instanceof AbstractButton) { + if (((AbstractButton) c).getModel().isRollover() && (rolloverColor != null)) { + ic = rolloverColor; + } + } + + Shape savedClip = g2D.getClip(); + Stroke savedStroke = g2D.getStroke(); + g2D.setStroke(new BasicStroke(lw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)); + Area clipArea = new Area(savedClip); + clipArea.subtract(new Area(new Rectangle2D.Double(x2, y2, w2, h2))); + g2D.setClip(clipArea); + paintRect(g2D, x1, y1, w1, h1, lw, ic, sc); + g2D.setClip(savedClip); + paintRect(g2D, x2, y2, w2, h2, lw, ic, sc); + + g2D.setStroke(savedStroke); + g2D.translate(-insets.left, -insets.top); + } + + private void paintRect(Graphics2D g2D, int x, int y, int w, int h, int lw, Color iconColor, Color shadowColor) { + if (shadowColor != null) { + g2D.setColor(shadowColor); + g2D.drawRect(x + 1, y + 1, w, h); + g2D.drawLine(x + 1, y + lw + 1, x + w + 1, y + lw + 1); + } + g2D.setColor(iconColor); + g2D.drawRect(x, y, w, h); + g2D.drawLine(x, y + lw, x + w, y + lw); + + } + } + +//----------------------------------------------------------------------------------------------------------- + public static class CloseSymbol implements Icon { + + private Color foregroundColor = null; + private Color shadowColor = null; + private Color rolloverColor = null; + private Color inactiveForegroundColor = null; + private Color inactiveShadowColor = null; + private Insets insets = new Insets(0, 0, 0, 0); + + public CloseSymbol(Color foregroundColor, Color shadowColor, Color rolloverColor) { + this.foregroundColor = foregroundColor; + this.shadowColor = shadowColor; + this.rolloverColor = rolloverColor; + this.inactiveForegroundColor = foregroundColor; + this.inactiveShadowColor = shadowColor; + } + + public CloseSymbol(Color foregroundColor, Color shadowColor, Color rolloverColor, Insets insets) { + this.foregroundColor = foregroundColor; + this.shadowColor = shadowColor; + this.rolloverColor = rolloverColor; + this.insets = insets; + this.inactiveForegroundColor = foregroundColor; + this.inactiveShadowColor = shadowColor; + } + + public CloseSymbol(Color foregroundColor, Color shadowColor, Color rolloverColor, Color inactiveForegroundColor, Color inactiveShadowColor, Insets insets) { + this.foregroundColor = foregroundColor; + this.shadowColor = shadowColor; + this.rolloverColor = rolloverColor; + this.inactiveForegroundColor = inactiveForegroundColor; + this.inactiveShadowColor = inactiveShadowColor; + this.insets = insets; + } + + public int getIconHeight() { + return 16; + } + + public int getIconWidth() { + return 16; + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + Graphics2D g2D = (Graphics2D) g; + g2D.translate(insets.left, insets.top); + int w = c.getWidth() - insets.left - insets.right; + int h = c.getHeight() - insets.top - insets.bottom; + boolean active = JTattooUtilities.isActive((JComponent) c); + Color color = foregroundColor; + if (!active) { + color = inactiveForegroundColor; + } + if (c instanceof AbstractButton) { + if (((AbstractButton) c).getModel().isRollover() && (rolloverColor != null)) { + color = rolloverColor; + } + } + //int lw = (w / 12) + 1; + int lw = (h > 22) ? 3 : 2; + int dx = (w / 5) + 2; + int dy = dx; + + Stroke savedStroke = g2D.getStroke(); + Object savedRederingHint = g2D.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g2D.setStroke(new BasicStroke(lw, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL)); + if (shadowColor != null) { + if (!active) { + g2D.setColor(inactiveShadowColor); + } else { + g2D.setColor(shadowColor); + } + g2D.drawLine(dx + 1, dy + 1, w - dx + 1, h - dy + 1); + g2D.drawLine(w - dx + 1, dy + 1, dx + 1, h - dy + 1); + } + g2D.setColor(color); + g2D.drawLine(dx, dy, w - dx, h - dy); + g2D.drawLine(w - dx, dy, dx, h - dy); + + g2D.setStroke(savedStroke); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, savedRederingHint); + g2D.translate(-insets.left, -insets.top); + } + } +} diff --git a/src/com/jtattoo/plaf/BaseInternalFrameTitlePane.java b/src/com/jtattoo/plaf/BaseInternalFrameTitlePane.java new file mode 100644 index 0000000..28a1cc9 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseInternalFrameTitlePane.java @@ -0,0 +1,516 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.*; +import javax.swing.plaf.basic.BasicInternalFrameTitlePane; + +/** + * This class is a modified copy of the javax.swing.plaf.metal.MetalInternalFrameTitlePane + * + * Class that manages a JLF title bar

+ * + * @author Steve Wilson + * @author Brian Beck + * @author Michael Hagen + */ +public class BaseInternalFrameTitlePane extends BasicInternalFrameTitlePane implements ActionListener { + + public static final String PAINT_ACTIVE = "paintActive"; + public static final String ICONIFY = "Iconify"; + public static final String MAXIMIZE = "Maximize"; + public static final String CLOSE = "Close"; + protected boolean isPalette = false; + protected Icon paletteCloseIcon; + protected int paletteTitleHeight; + protected int buttonsWidth = 0; + protected JPanel customTitlePanel; + + public BaseInternalFrameTitlePane(JInternalFrame f) { + super(f); + } + + protected void installDefaults() { + super.installDefaults(); + setFont(UIManager.getFont("InternalFrame.font")); + paletteTitleHeight = UIManager.getInt("InternalFrame.paletteTitleHeight"); + paletteCloseIcon = UIManager.getIcon("InternalFrame.paletteCloseIcon"); + iconIcon = UIManager.getIcon("InternalFrame.iconifyIcon"); + minIcon = UIManager.getIcon("InternalFrame.minimizeIcon"); + maxIcon = UIManager.getIcon("InternalFrame.maximizeIcon"); + closeIcon = UIManager.getIcon("InternalFrame.closeIcon"); + if (frame.getClientProperty("customTitlePanel") instanceof JPanel) { + setCustomizedTitlePanel((JPanel)frame.getClientProperty("customTitlePanel")); + } + } + + public void setCustomizedTitlePanel(JPanel panel) { + if (customTitlePanel != null) { + remove(customTitlePanel); + customTitlePanel = null; + } + if (panel != null) { + customTitlePanel = panel; + add(customTitlePanel); + } + frame.putClientProperty("customTitlePanel", customTitlePanel); + revalidate(); + repaint(); + } + + protected void createButtons() { + iconButton = new BaseTitleButton(iconifyAction, ICONIFY, iconIcon, 1.0f); + maxButton = new BaseTitleButton(maximizeAction, MAXIMIZE, maxIcon, 1.0f); + closeButton = new BaseTitleButton(closeAction, CLOSE, closeIcon, 1.0f); + setButtonIcons(); + } + + protected void setButtonIcons() { + super.setButtonIcons(); + iconButton.setToolTipText(null); + maxButton.setToolTipText(null); + closeButton.setToolTipText(null); + } + + protected void enableActions() { + super.enableActions(); + maximizeAction.setEnabled(frame.isMaximizable()); + } + + protected void assembleSystemMenu() { + } + + protected void addSystemMenuItems(JMenu systemMenu) { + } + + protected void addSubComponents() { + add(iconButton); + add(maxButton); + add(closeButton); + } + + protected PropertyChangeListener createPropertyChangeListener() { + return new BasePropertyChangeHandler(); + } + + protected LayoutManager createLayout() { + return new BaseTitlePaneLayout(); + } + + protected int getHorSpacing() { + return 3; + } + + protected int getVerSpacing() { + return 3; + } + + protected boolean centerButtons() { + return true; + } + + public void activateFrame() { + } + + public void deactivateFrame() { + } + + protected boolean isMacStyleWindowDecoration() { + return AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn(); + } + + public boolean isActive() { + return JTattooUtilities.isActive(this); + } + + public boolean isPalette() { + return isPalette; + } + + public void setPalette(boolean b) { + isPalette = b; + if (isPalette) { + closeButton.setIcon(paletteCloseIcon); + if (frame.isMaximizable()) { + remove(maxButton); + } + if (frame.isIconifiable()) { + remove(iconButton); + } + } else { + closeButton.setIcon(closeIcon); + if (frame.isMaximizable()) { + add(maxButton); + } + if (frame.isIconifiable()) { + add(iconButton); + } + } + revalidate(); + repaint(); + } + + public void actionPerformed(ActionEvent e) { + AbstractButton button = (AbstractButton) e.getSource(); + button.getModel().setRollover(false); + } + + public void paintPalette(Graphics g) { + int width = getWidth(); + int height = getHeight(); + if (JTattooUtilities.isFrameActive(this)) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getWindowTitleColors(), 0, 0, width, height); + } else { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getWindowInactiveTitleColors(), 0, 0, width, height); + } + } + + public void paintBackground(Graphics g) { + if (isActive()) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getWindowTitleColors(), 0, 0, getWidth(), getHeight()); + } else { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getWindowInactiveTitleColors(), 0, 0, getWidth(), getHeight()); + } + } + + private Image iconToImage(Icon icon) { + if (icon instanceof ImageIcon) { + return ((ImageIcon) icon).getImage(); + } else if (icon != null) { + int w = icon.getIconWidth(); + int h = icon.getIconHeight(); + BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = image.createGraphics(); + icon.paintIcon(null, g, 0, 0); + g.dispose(); + return image; + } + return null; + } + + protected int getIconWidth() { + Image image = iconToImage(frame.getFrameIcon()); + if (image != null) { + int h = getHeight(); + int ih = image.getHeight(null); + int iw = image.getWidth(null); + if (ih > h) { + double fac = (double) iw / (double) ih; + ih = h - 1; + iw = (int) (fac * (double) ih); + } + return iw; + } + return 0; + } + + protected int paintIcon(Graphics g, int x) { + Image image = iconToImage(frame.getFrameIcon()); + if (image != null) { + Graphics2D g2D = (Graphics2D)g; + Object savedHint = g2D.getRenderingHint(RenderingHints.KEY_INTERPOLATION); + if (JTattooUtilities.getJavaVersion() >= 1.6) { + g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + } + int h = getHeight(); + int ih = image.getHeight(null); + int iw = image.getWidth(null); + if (ih <= h) { + g2D.drawImage(image, x, (h - ih) / 2, iw, ih, null); + } else { + double fac = (double) iw / (double) ih; + ih = h; + iw = (int) (fac * (double) ih); + g2D.drawImage(image, x, 0, iw, ih, null); + } + if (savedHint != null) { + g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, savedHint); + } + return iw; + } + return 0; + } + + public void paintText(Graphics g, int x, int y, String title) { + if (isActive()) { + g.setColor(AbstractLookAndFeel.getWindowTitleForegroundColor()); + } else { + g.setColor(AbstractLookAndFeel.getWindowInactiveTitleForegroundColor()); + } + JTattooUtilities.drawString(frame, g, title, x, y); + } + + public void paintBorder(Graphics g) { + Color borderColor = AbstractLookAndFeel.getWindowInactiveBorderColor(); + if (isActive() || isPalette) { + borderColor = AbstractLookAndFeel.getWindowBorderColor(); + } + JTattooUtilities.draw3DBorder(g, ColorHelper.brighter(borderColor, 20), ColorHelper.darker(borderColor, 10), 0, 0, getWidth(), getHeight()); + } + + public void paintComponent(Graphics g) { + if (isPalette) { + paintPalette(g); + return; + } + + paintBackground(g); + + g.setFont(getFont()); + FontMetrics fm = JTattooUtilities.getFontMetrics(this, g, getFont()); + int width = getWidth(); + int height = getHeight(); + int x = 0; + int y = ((height - fm.getHeight()) / 2) + fm.getAscent(); + int titleWidth = width - buttonsWidth - 4; + String frameTitle = frame.getTitle(); + if (JTattooUtilities.isLeftToRight(frame)) { + if (isMacStyleWindowDecoration()) { + int iconWidth = getIconWidth(); + titleWidth -= iconWidth + 4; + frameTitle = JTattooUtilities.getClippedText(frameTitle, fm, titleWidth); + int titleLength = fm.stringWidth(frameTitle); + x += buttonsWidth + ((titleWidth - titleLength) / 2); + paintIcon(g, x); + x += iconWidth + 4; + } else { + int iconWidth = paintIcon(g, x); + titleWidth -= iconWidth + 4; + frameTitle = JTattooUtilities.getClippedText(frameTitle, fm, titleWidth); + if (AbstractLookAndFeel.getTheme().isCenterWindowTitleOn()) { + int titleLength = fm.stringWidth(frameTitle); + x += iconWidth + 4; + x += (titleWidth - titleLength) / 2; + } else { + x += iconWidth + 4; + } + } + } else { + int iconWidth = getIconWidth(); + if (isMacStyleWindowDecoration()) { + titleWidth -= iconWidth + 4; + frameTitle = JTattooUtilities.getClippedText(frameTitle, fm, titleWidth); + int titleLength = fm.stringWidth(frameTitle); + x = buttonsWidth + 4 + ((titleWidth - titleLength) / 2); + paintIcon(g, x + titleLength + 4); + } else { + x = width - iconWidth; + paintIcon(g, x); + titleWidth -= iconWidth + 4; + frameTitle = JTattooUtilities.getClippedText(frameTitle, fm, titleWidth); + int titleLength = fm.stringWidth(frameTitle); + if (AbstractLookAndFeel.getTheme().isCenterWindowTitleOn()) { + x = buttonsWidth + 4 + ((titleWidth - titleLength) / 2); + } else { + x = width - iconWidth - 4 - titleLength; + } + } + } + paintText(g, x, y, frameTitle); + + paintBorder(g); + } + + class BasePropertyChangeHandler extends BasicInternalFrameTitlePane.PropertyChangeHandler { + + public void propertyChange(PropertyChangeEvent evt) { + String prop = (String) evt.getPropertyName(); + if (prop.equals(JInternalFrame.IS_SELECTED_PROPERTY)) { + Boolean b = (Boolean) evt.getNewValue(); + iconButton.putClientProperty(PAINT_ACTIVE, b); + closeButton.putClientProperty(PAINT_ACTIVE, b); + maxButton.putClientProperty(PAINT_ACTIVE, b); + if (b.booleanValue()) { + activateFrame(); + } else { + deactivateFrame(); + } + repaint(); + } + super.propertyChange(evt); + } + } + +//------------------------------------------------------------------------------ +// inner classes +//------------------------------------------------------------------------------ + class BaseTitlePaneLayout extends TitlePaneLayout { + + public void addLayoutComponent(String name, Component c) { + } + + public void removeLayoutComponent(Component c) { + } + + public Dimension preferredLayoutSize(Container c) { + return minimumLayoutSize(c); + } + + public Dimension minimumLayoutSize(Container c) { + int width = 30; + if (frame.isClosable()) { + width += 21; + } + if (frame.isMaximizable()) { + width += 16 + (frame.isClosable() ? 10 : 4); + } + if (frame.isIconifiable()) { + width += 16 + (frame.isMaximizable() ? 2 : (frame.isClosable() ? 10 : 4)); + } + FontMetrics fm = JTattooUtilities.getFontMetrics(BaseInternalFrameTitlePane.this, null, getFont()); + String frameTitle = frame.getTitle(); + int title_w = frameTitle != null ? fm.stringWidth(frameTitle) : 0; + int title_length = frameTitle != null ? frameTitle.length() : 0; + + if (title_length > 2) { + int subtitle_w = fm.stringWidth(frame.getTitle().substring(0, 2) + "..."); + width += (title_w < subtitle_w) ? title_w : subtitle_w; + } else { + width += title_w; + } + + int height = paletteTitleHeight; + if (!isPalette) { + Icon icon = isMacStyleWindowDecoration() ? null : frame.getFrameIcon(); + if (icon == null) { + height = Math.max(fm.getHeight() + 6, 16); + } else { + height = Math.max(fm.getHeight() + 6, Math.min(icon.getIconHeight(), 24)); + } + } + return new Dimension(width, height); + } + + public void layoutContainer(Container c) { + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + layoutMacStyle(c); + } else { + layoutDefault(c); + } + } + + public void layoutDefault(Container c) { + boolean leftToRight = JTattooUtilities.isLeftToRight(frame); + + int spacing = getHorSpacing(); + int w = getWidth(); + int h = getHeight(); + + // assumes all buttons have the same dimensions these dimensions include the borders + int btnHeight = h - getVerSpacing(); + int btnWidth = btnHeight; + + int x = leftToRight ? w - spacing : 0; + int y = Math.max(0, ((h - btnHeight) / 2) - 1); + + if (frame.isClosable()) { + x += leftToRight ? -btnWidth : spacing; + closeButton.setBounds(x, y, btnWidth, btnHeight); + if (!leftToRight) { + x += btnWidth; + } + } + + if (frame.isMaximizable() && !isPalette) { + x += leftToRight ? -spacing - btnWidth : spacing; + maxButton.setBounds(x, y, btnWidth, btnHeight); + if (!leftToRight) { + x += btnWidth; + } + } + + if (frame.isIconifiable() && !isPalette) { + x += leftToRight ? -spacing - btnWidth : spacing; + iconButton.setBounds(x, y, btnWidth, btnHeight); + if (!leftToRight) { + x += btnWidth; + } + } + + buttonsWidth = leftToRight ? w - x : x; + + if (customTitlePanel != null) { + int maxWidth = w - buttonsWidth - spacing - 20; + Icon icon = frame.getFrameIcon(); + if (icon != null) { + maxWidth -= icon.getIconWidth(); + maxWidth -= spacing; + } + int cpw = Math.min(maxWidth, customTitlePanel.getPreferredSize().width); + int cph = h; + int cpx = leftToRight ? w - buttonsWidth - cpw : buttonsWidth; + int cpy = 0; + customTitlePanel.setBounds(cpx, cpy, cpw, cph); + buttonsWidth += customTitlePanel.getPreferredSize().width; + } + } + + private void layoutMacStyle(Container c) { + int spacing = getHorSpacing(); + int h = getHeight(); + + // assumes all buttons have the same dimensions these dimensions include the borders + int btnHeight = h - getVerSpacing() - 1; + int btnWidth = btnHeight; + + int x = 2; + int y = centerButtons() ? Math.max(0, ((h - btnHeight) / 2)) : 0; + + if (frame.isClosable()) { + closeButton.setBounds(x, y, btnWidth, btnHeight); + x += spacing + btnWidth; + } + if (frame.isIconifiable() && !isPalette) { + iconButton.setBounds(x, y, btnWidth, btnHeight); + x += spacing + btnWidth; + } + if (frame.isMaximizable() && !isPalette) { + maxButton.setBounds(x, y, btnWidth, btnHeight); + x += spacing + btnWidth; + } + + buttonsWidth = x; + + if (customTitlePanel != null) { + int cpx = buttonsWidth + 5; + int cpy = 0; + int cpw = customTitlePanel.getPreferredSize().width; + int cph = h; + customTitlePanel.setBounds(cpx, cpy, cpw, cph); + buttonsWidth += cpw + 5; + } + } + } // end class BaseTitlePaneLayout +} \ No newline at end of file diff --git a/src/com/jtattoo/plaf/BaseInternalFrameUI.java b/src/com/jtattoo/plaf/BaseInternalFrameUI.java new file mode 100644 index 0000000..cda0500 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseInternalFrameUI.java @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. + * + * JTattoo is multiple licensed. If your are an open source developer you can use + * it under the terms and conditions of the GNU General Public License version 2.0 + * or later as published by the Free Software Foundation. + * + * see: gpl-2.0.txt + * + * If you pay for a license you will become a registered user who could use the + * software under the terms and conditions of the GNU Lesser General Public License + * version 2.0 or later with classpath exception as published by the Free Software + * Foundation. + * + * see: lgpl-2.0.txt + * see: classpath-exception.txt + * + * Registered users could also use JTattoo under the terms and conditions of the + * Apache License, Version 2.0 as published by the Apache Software Foundation. + * + * see: APACHE-LICENSE-2.0.txt + */ +package com.jtattoo.plaf; + +import java.awt.Container; +import java.awt.Window; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicInternalFrameUI; + +public class BaseInternalFrameUI extends BasicInternalFrameUI { + + private static final PropertyChangeListener MY_PROPERTY_CHANGE_HANDLER = new MyPropertyChangeHandler(); + private static final WindowAdapter MY_WINDOW_HANDLER = new MyWindowHandler(); + + private static final Border HANDY_EMPTY_BORDER = new EmptyBorder(0, 0, 0, 0); + + private static final String IS_PALETTE = "JInternalFrame.isPalette"; + private static final String FRAME_TYPE = "JInternalFrame.frameType"; + private static final String FRAME_BORDER = "InternalFrame.border"; + private static final String FRAME_PALETTE_BORDER = "InternalFrame.paletteBorder"; + private static final String PALETTE_FRAME = "palette"; + + public BaseInternalFrameUI(JInternalFrame b) { + super(b); + } + + public static ComponentUI createUI(JComponent c) { + return new BaseInternalFrameUI((JInternalFrame) c); + } + + public void installUI(JComponent c) { + super.installUI(c); + Object paletteProp = c.getClientProperty(IS_PALETTE); + if (paletteProp != null) { + setPalette(((Boolean) paletteProp).booleanValue()); + } + stripContentBorder(); + } + + public void uninstallUI(JComponent c) { + Container cp = frame.getContentPane(); + if (cp instanceof JComponent) { + JComponent contentPane = (JComponent) cp; + if (contentPane.getBorder() == HANDY_EMPTY_BORDER) { + contentPane.setBorder(null); + } + } + super.uninstallUI(c); + } + + protected void installDefaults() { + super.installDefaults(); + Icon frameIcon = frame.getFrameIcon(); + if (frameIcon == null || frameIcon instanceof LazyImageIcon) { + frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon")); + } + } + + protected void installListeners() { + super.installListeners(); + frame.addPropertyChangeListener(MY_PROPERTY_CHANGE_HANDLER); + } + + protected void uninstallListeners() { + frame.removePropertyChangeListener(MY_PROPERTY_CHANGE_HANDLER); + super.uninstallListeners(); + } + + protected void uninstallComponents() { + titlePane = null; + super.uninstallComponents(); + } + + public void stripContentBorder() { + Container cp = frame.getContentPane(); + if (cp instanceof JComponent) { + JComponent contentPane = (JComponent) cp; + Border contentBorder = contentPane.getBorder(); + if (contentBorder == null || contentBorder instanceof UIResource) { + contentPane.setBorder(HANDY_EMPTY_BORDER); + } + } + } + + protected JComponent createNorthPane(JInternalFrame w) { + return new BaseInternalFrameTitlePane(w); + } + + public BaseInternalFrameTitlePane getTitlePane() { + return (BaseInternalFrameTitlePane) titlePane; + } + + public void setPalette(boolean isPalette) { + if (isPalette) { + frame.setBorder(UIManager.getBorder(FRAME_PALETTE_BORDER)); + } else { + frame.setBorder(UIManager.getBorder(FRAME_BORDER)); + } + getTitlePane().setPalette(isPalette); + } + +//----------------------------------------------------------------------------- +// inner classes +//----------------------------------------------------------------------------- + private static class MyPropertyChangeHandler implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent e) { + JInternalFrame jif = (JInternalFrame) e.getSource(); + if (!(jif.getUI() instanceof BaseInternalFrameUI)) { + return; + } + + BaseInternalFrameUI ui = (BaseInternalFrameUI) jif.getUI(); + String name = e.getPropertyName(); + if (name.equals(FRAME_TYPE)) { + if (e.getNewValue() instanceof String) { + if (PALETTE_FRAME.equals(e.getNewValue())) { + LookAndFeel.installBorder(ui.frame, FRAME_PALETTE_BORDER); + ui.setPalette(true); + } else { + LookAndFeel.installBorder(ui.frame, FRAME_BORDER); + ui.setPalette(false); + } + } + } else if (name.equals(IS_PALETTE)) { + if (e.getNewValue() != null) { + ui.setPalette(((Boolean) e.getNewValue()).booleanValue()); + } else { + ui.setPalette(false); + } + } else if (name.equals(JInternalFrame.CONTENT_PANE_PROPERTY)) { + ui.stripContentBorder(); + } else if (name.equals("ancestor") && !AbstractLookAndFeel.isWindowDecorationOn()) { + if (e.getNewValue() instanceof JDesktopPane) { + JDesktopPane jp = (JDesktopPane)e.getNewValue(); + Window window = SwingUtilities.getWindowAncestor(jp); + if (window != null) { + WindowListener wl[] = window.getWindowListeners(); + boolean doAdd = true; + for (int i = 0; i < wl.length; i++) { + if (wl[i].equals(MY_WINDOW_HANDLER)) { + doAdd = false; + break; + } + } + if (doAdd) { + window.addWindowListener(MY_WINDOW_HANDLER); + } + } + } else if (e.getOldValue() instanceof JDesktopPane) { + JDesktopPane jp = (JDesktopPane)e.getOldValue(); + Window window = SwingUtilities.getWindowAncestor(jp); + if (window != null) { + window.removeWindowListener(MY_WINDOW_HANDLER); + } + } + } + } + } // end class MyPropertyChangeHandler + +//----------------------------------------------------------------------------- + private static class MyWindowHandler extends WindowAdapter { + + public void windowActivated(WindowEvent e) { + e.getWindow().invalidate(); + e.getWindow().repaint(); + } + + public void windowDeactivated(WindowEvent e) { + e.getWindow().invalidate(); + e.getWindow().repaint(); + } + } // end class MyWindowHandler +} diff --git a/src/com/jtattoo/plaf/BaseLabelUI.java b/src/com/jtattoo/plaf/BaseLabelUI.java new file mode 100644 index 0000000..7db65b2 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseLabelUI.java @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.Color; +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicLabelUI; + +/** + * @author Michael Hagen + */ +public class BaseLabelUI extends BasicLabelUI { + + private static BaseLabelUI baseLabelUI = null; + + public static ComponentUI createUI(JComponent c) { + if (baseLabelUI == null) { + baseLabelUI = new BaseLabelUI(); + } + return baseLabelUI; + } + + protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) { + int mnemIndex; + if (JTattooUtilities.getJavaVersion() >= 1.4) { + mnemIndex = l.getDisplayedMnemonicIndex(); + } else { + mnemIndex = JTattooUtilities.findDisplayedMnemonicIndex(l.getText(), l.getDisplayedMnemonic()); + } + Object sc = l.getClientProperty("shadowColor"); + if (sc instanceof Color) { + g.setColor((Color)sc); + JTattooUtilities.drawStringUnderlineCharAt(l, g, s, mnemIndex, textX, textY + 1); + } + g.setColor(l.getForeground()); + JTattooUtilities.drawStringUnderlineCharAt(l, g, s, mnemIndex, textX, textY); + } + + protected void paintDisabledText(JLabel l, Graphics g, String s, int textX, int textY) { + int mnemIndex; + if (JTattooUtilities.getJavaVersion() >= 1.4) { + mnemIndex = l.getDisplayedMnemonicIndex(); + } else { + mnemIndex = JTattooUtilities.findDisplayedMnemonicIndex(l.getText(), l.getDisplayedMnemonic()); + } + g.setColor(Color.white); + JTattooUtilities.drawStringUnderlineCharAt(l, g, s, mnemIndex, textX + 1, textY + 1); + g.setColor(AbstractLookAndFeel.getDisabledForegroundColor()); + JTattooUtilities.drawStringUnderlineCharAt(l, g, s, mnemIndex, textX, textY); + } +} + diff --git a/src/com/jtattoo/plaf/BaseMenuBarUI.java b/src/com/jtattoo/plaf/BaseMenuBarUI.java new file mode 100644 index 0000000..cde711d --- /dev/null +++ b/src/com/jtattoo/plaf/BaseMenuBarUI.java @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicMenuBarUI; + +/** + * @author Michael Hagen + */ +public class BaseMenuBarUI extends BasicMenuBarUI { + + public static ComponentUI createUI(JComponent c) { + return new BaseMenuBarUI(); + } + + public void paint(Graphics g, JComponent c) { + int w = c.getWidth(); + int h = c.getHeight(); + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getMenuBarColors(), 0, 0, w, h); + } +} \ No newline at end of file diff --git a/src/com/jtattoo/plaf/BaseMenuItemUI.java b/src/com/jtattoo/plaf/BaseMenuItemUI.java new file mode 100644 index 0000000..c1b6112 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseMenuItemUI.java @@ -0,0 +1,112 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicMenuItemUI; + +/** + * @author Michael Hagen + */ +public class BaseMenuItemUI extends BasicMenuItemUI { + + public static ComponentUI createUI(JComponent c) { + return new BaseMenuItemUI(); + } + + public void installUI(JComponent c) { + super.installUI(c); + c.setOpaque(false); + } + + public void uninstallUI(JComponent c) { + c.setOpaque(true); + super.uninstallUI(c); + } + + public void update(Graphics g, JComponent c) { + paintBackground(g, c, 0, 0, c.getWidth(), c.getHeight()); + paint(g, c); + } + + protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { + if (menuItem.isOpaque()) { + int w = menuItem.getWidth(); + int h = menuItem.getHeight(); + paintBackground(g, menuItem, 0, 0, w, h); + } + } + + protected void paintBackground(Graphics g, JComponent c, int x, int y, int w, int h) { + JMenuItem mi = (JMenuItem) c; + Color backColor = mi.getBackground(); + if (backColor == null || backColor instanceof UIResource) { + backColor = AbstractLookAndFeel.getMenuBackgroundColor(); + } + + ButtonModel model = mi.getModel(); + if (model.isArmed() || model.isRollover() || (c instanceof JMenu && model.isSelected())) { + g.setColor(AbstractLookAndFeel.getMenuSelectionBackgroundColor()); + g.fillRect(x, y, w, h); + g.setColor(AbstractLookAndFeel.getMenuSelectionForegroundColor()); + } else if (!AbstractLookAndFeel.getTheme().isMenuOpaque()) { + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, AbstractLookAndFeel.getTheme().getMenuAlpha()); + g2D.setComposite(alpha); + g2D.setColor(backColor); + g2D.fillRect(x, y, w, h); + g2D.setComposite(savedComposite); + g.setColor(AbstractLookAndFeel.getMenuForegroundColor()); + } else { + g.setColor(backColor); + g.fillRect(x, y, w, h); + g.setColor(AbstractLookAndFeel.getMenuForegroundColor()); + } + } + + protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { + ButtonModel model = menuItem.getModel(); + Color foreColor = menuItem.getForeground(); + if (model.isArmed() || model.isRollover()) { + foreColor = AbstractLookAndFeel.getMenuSelectionForegroundColor(); + } else if (foreColor == null || foreColor instanceof UIResource) { + foreColor = AbstractLookAndFeel.getMenuForegroundColor(); + } + Graphics2D g2D = (Graphics2D) g; + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + g2D.setColor(foreColor); + super.paintText(g, menuItem, textRect, text); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } +} diff --git a/src/com/jtattoo/plaf/BaseMenuUI.java b/src/com/jtattoo/plaf/BaseMenuUI.java new file mode 100644 index 0000000..ecd4a5a --- /dev/null +++ b/src/com/jtattoo/plaf/BaseMenuUI.java @@ -0,0 +1,182 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.MouseEvent; +import javax.swing.*; +import javax.swing.event.MouseInputListener; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicMenuUI; + +/** + * @author Michael Hagen + */ +public class BaseMenuUI extends BasicMenuUI { + + protected boolean paintRolloverBorder = true; + + public static ComponentUI createUI(JComponent c) { + return new BaseMenuUI(); + } + + public void installUI(JComponent c) { + super.installUI(c); + c.setOpaque(false); + } + + public void uninstallUI(JComponent c) { + c.setOpaque(true); + super.uninstallUI(c); + } + + public void update(Graphics g, JComponent c) { + paintBackground(g, c, 0, 0, c.getWidth(), c.getHeight()); + paint(g, c); + } + + protected void installDefaults() { + super.installDefaults(); + Boolean isRolloverEnabled = (Boolean)UIManager.get("MenuBar.rolloverEnabled"); + if (isRolloverEnabled.booleanValue()) { + menuItem.setRolloverEnabled(true); + } + } + + protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { + if (menuItem.isOpaque()) { + int w = menuItem.getWidth(); + int h = menuItem.getHeight(); + paintBackground(g, menuItem, 0, 0, w, h); + } + } + + protected void paintBackground(Graphics g, JComponent c, int x, int y, int w, int h) { + JMenuItem mi = (JMenuItem) c; + Color backColor = mi.getBackground(); + if (backColor == null || backColor instanceof UIResource) { + backColor = AbstractLookAndFeel.getMenuBackgroundColor(); + } + ButtonModel model = mi.getModel(); + if (c.getParent() instanceof JMenuBar) { + if (model.isRollover() || model.isArmed() || (c instanceof JMenu && model.isSelected())) { + backColor = AbstractLookAndFeel.getMenuSelectionBackgroundColor(); + if (model.isRollover()) { + backColor = ColorHelper.brighter(backColor, 10); + } + g.setColor(backColor); + g.fillRect(x, y, w, h); + if (paintRolloverBorder && model.isRollover() && !model.isSelected()) { + backColor = ColorHelper.darker(backColor, 20); + g.setColor(backColor); + g.drawRect(x, y, w - 1, h - 1); + } + g.setColor(AbstractLookAndFeel.getMenuSelectionForegroundColor()); + } + } else { + if (model.isArmed() || model.isRollover() || (c instanceof JMenu && model.isSelected())) { + g.setColor(AbstractLookAndFeel.getMenuSelectionBackgroundColor()); + g.fillRect(x, y, w, h); + g.setColor(AbstractLookAndFeel.getMenuSelectionForegroundColor()); + } else if (!AbstractLookAndFeel.getTheme().isMenuOpaque()) { + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, AbstractLookAndFeel.getTheme().getMenuAlpha()); + g2D.setComposite(alpha); + g2D.setColor(backColor); + g2D.fillRect(x, y, w, h); + g2D.setComposite(savedComposite); + g2D.setColor(AbstractLookAndFeel.getMenuForegroundColor()); + } else { + g.setColor(backColor); + g.fillRect(x, y, w, h); + g.setColor(AbstractLookAndFeel.getMenuForegroundColor()); + } + } + } + + protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { + ButtonModel model = menuItem.getModel(); + Graphics2D g2D = (Graphics2D) g; + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + if (menuItem.getParent() instanceof JMenuBar) { + if (model.isRollover() || model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) { + g.setColor(AbstractLookAndFeel.getMenuSelectionForegroundColor()); + } + } else if (model.isArmed() || model.isRollover()) { + g.setColor(AbstractLookAndFeel.getMenuSelectionForegroundColor()); + } else { + Color foreColor = menuItem.getForeground(); + if (foreColor instanceof UIResource) { + foreColor = AbstractLookAndFeel.getMenuForegroundColor(); + } + g.setColor(foreColor); + } + super.paintText(g, menuItem, textRect, text); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } + + protected MouseInputListener createMouseInputListener(JComponent c) { + if (JTattooUtilities.getJavaVersion() >= 1.5) { + return new MyMouseInputHandler(); + } else { + return super.createMouseInputListener(c); + } + } + +//------------------------------------------------------------------------------ +// inner classes +//------------------------------------------------------------------------------ + + protected class MyMouseInputHandler extends BasicMenuUI.MouseInputHandler { + + public void mouseEntered(MouseEvent evt) { + super.mouseEntered(evt); + + JMenu menu = (JMenu) evt.getSource(); + if (menu.isTopLevelMenu() && menu.isRolloverEnabled()) { + menu.getModel().setRollover(true); + menuItem.repaint(); + } + } + + public void mouseExited(MouseEvent evt) { + super.mouseExited(evt); + + JMenu menu = (JMenu) evt.getSource(); + ButtonModel model = menu.getModel(); + if (menu.isRolloverEnabled()) { + model.setRollover(false); + menuItem.repaint(); + } + } + } +} diff --git a/src/com/jtattoo/plaf/BasePanelUI.java b/src/com/jtattoo/plaf/BasePanelUI.java new file mode 100644 index 0000000..f5a9cb2 --- /dev/null +++ b/src/com/jtattoo/plaf/BasePanelUI.java @@ -0,0 +1,92 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.lang.reflect.Field; +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicPanelUI; + +/** + * @author Michael Hagen + */ +public class BasePanelUI extends BasicPanelUI { + + private static BasePanelUI panelUI = null; + + public static ComponentUI createUI(JComponent c) { + if (panelUI == null) { + panelUI = new BasePanelUI(); + } + return panelUI; + } + + protected void installDefaults(JPanel p) { + super.installDefaults(p); + p.setFont(AbstractLookAndFeel.getTheme().getControlTextFont()); + + // We don't want medium weight popups for tool tips, so we try to force heavy weight popups. + try { + Field field; + if (JTattooUtilities.getJavaVersion() < 1.7) { + Class clazz = Class.forName("javax.swing.PopupFactory"); + field = clazz.getDeclaredField("forceHeavyWeightPopupKey"); + field.setAccessible(true); + p.putClientProperty(field.get(null), Boolean.TRUE); + } else if (JTattooUtilities.getJavaVersion() < 1.10) { // 1.7, 1.8 and 1.9 + Class clazz = Class.forName("javax.swing.ClientPropertyKey"); + field = clazz.getDeclaredField("PopupFactory_FORCE_HEAVYWEIGHT_POPUP"); + field.setAccessible(true); + p.putClientProperty(field.get(null), Boolean.TRUE); + } + } catch(Exception ex) { + } + } + + public void update(Graphics g, JComponent c) { + if (c.isOpaque()) { + Object backgroundTexture = c.getClientProperty("backgroundTexture"); + if (backgroundTexture instanceof Icon) { + JTattooUtilities.fillComponent(g, c, (Icon)backgroundTexture); + } else { + g.setColor(c.getBackground()); + g.fillRect(0, 0, c.getWidth(), c.getHeight()); + } + } + } + + public void paint(Graphics g, JComponent c) { + Graphics2D g2D = (Graphics2D) g; + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + super.paint(g, c); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } +} diff --git a/src/com/jtattoo/plaf/BasePasswordFieldUI.java b/src/com/jtattoo/plaf/BasePasswordFieldUI.java new file mode 100644 index 0000000..9c722e8 --- /dev/null +++ b/src/com/jtattoo/plaf/BasePasswordFieldUI.java @@ -0,0 +1,124 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicPasswordFieldUI; +import javax.swing.text.DefaultEditorKit; + +/** + * @author Michael Hagen + */ +public class BasePasswordFieldUI extends BasicPasswordFieldUI { + + private Border orgBorder = null; + private FocusListener focusListener = null; + + public static ComponentUI createUI(JComponent c) { + return new BasePasswordFieldUI(); + } + + @SuppressWarnings("deprecation") + protected void installKeyboardActions() { + super.installKeyboardActions(); + if (JTattooUtilities.isMac()) { + InputMap im = (InputMap) UIManager.get("TextField.focusInputMap"); + int commandKey = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, commandKey), DefaultEditorKit.copyAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, commandKey), DefaultEditorKit.pasteAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, commandKey), DefaultEditorKit.cutAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.ALT_DOWN_MASK), DefaultEditorKit.nextWordAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, KeyEvent.ALT_DOWN_MASK), DefaultEditorKit.previousWordAction); + } + } + + protected void installListeners() { + super.installListeners(); + + if (AbstractLookAndFeel.getTheme().doShowFocusFrame()) { + focusListener = new FocusListener() { + + public void focusGained(FocusEvent e) { + if (getComponent() != null) { + orgBorder = getComponent().getBorder(); + LookAndFeel laf = UIManager.getLookAndFeel(); + if (laf instanceof AbstractLookAndFeel && orgBorder instanceof UIResource) { + Border focusBorder = ((AbstractLookAndFeel)laf).getBorderFactory().getFocusFrameBorder(); + getComponent().setBorder(focusBorder); + } + getComponent().invalidate(); + getComponent().repaint(); + } + } + + public void focusLost(FocusEvent e) { + if (getComponent() != null) { + if (orgBorder instanceof UIResource) { + getComponent().setBorder(orgBorder); + } + getComponent().invalidate(); + getComponent().repaint(); + } + } + }; + getComponent().addFocusListener(focusListener); + } + } + + protected void uninstallListeners() { + getComponent().removeFocusListener(focusListener); + focusListener = null; + super.uninstallListeners(); + } + + protected void paintBackground(Graphics g) { + g.setColor(getComponent().getBackground()); + if (AbstractLookAndFeel.getTheme().doShowFocusFrame()) { + if (getComponent().hasFocus() && getComponent().isEditable()) { + g.setColor(AbstractLookAndFeel.getTheme().getFocusBackgroundColor()); + } + } + g.fillRect(0, 0, getComponent().getWidth(), getComponent().getHeight()); + } + + protected void paintSafely(Graphics g) { + Graphics2D g2D = (Graphics2D) g; + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + super.paintSafely(g); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } +} diff --git a/src/com/jtattoo/plaf/BasePopupMenuUI.java b/src/com/jtattoo/plaf/BasePopupMenuUI.java new file mode 100644 index 0000000..b7e9ef5 --- /dev/null +++ b/src/com/jtattoo/plaf/BasePopupMenuUI.java @@ -0,0 +1,153 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.image.BufferedImage; +import javax.swing.*; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicPopupMenuUI; + +/** + * @author Michael Hagen + */ +public class BasePopupMenuUI extends BasicPopupMenuUI { + + protected static Robot robot = null; + protected BufferedImage screenImage = null; + protected MyPopupMenuListener myPopupListener = null; + + public static ComponentUI createUI(JComponent c) { + return new BasePopupMenuUI(); + } + + public void installUI(JComponent c) { + super.installUI(c); + c.setOpaque(false); + } + + public void uninstallUI(JComponent c) { + super.uninstallUI(c); + c.setOpaque(true); + } + + public void installListeners() { + super.installListeners(); + if (!isMenuOpaque()) { + myPopupListener = new MyPopupMenuListener(this); + popupMenu.addPopupMenuListener(myPopupListener); + } + } + + public void uninstallListeners() { + if (!isMenuOpaque()) { + popupMenu.removePopupMenuListener(myPopupListener); + } + super.uninstallListeners(); + } + + private boolean isMenuOpaque() { + return (AbstractLookAndFeel.getTheme().isMenuOpaque() || (getRobot() == null)); + } + + private Robot getRobot() { + if (robot == null) { + try { + robot = new Robot(); + } catch (Exception ex) { + } + } + return robot; + } + + public Popup getPopup(JPopupMenu popupMenu, int x, int y) { + Popup popup = super.getPopup(popupMenu, x, y); + if (!isMenuOpaque()) { + try { + Dimension size = popupMenu.getPreferredSize(); + if (size.width > 0 && size.height > 0) { + Rectangle screenRect = new Rectangle(x, y, size.width, size.height); + screenImage = getRobot().createScreenCapture(screenRect); + } + for (int i = 0; i < popupMenu.getComponentCount(); i++) { + if (popupMenu.getComponent(i) instanceof JPanel) { + JPanel panel = (JPanel)popupMenu.getComponent(i); + panel.setOpaque(true); + } + } + } catch (Exception ex) { + screenImage = null; + } + } + return popup; + } + + private void resetScreenImage() { + screenImage = null; + } + + public void update(Graphics g, JComponent c) { + if (screenImage != null) { + g.drawImage(screenImage, 0, 0, null); + } else { + g.setColor(AbstractLookAndFeel.getMenuBackgroundColor()); + g.fillRect(0, 0, c.getWidth(), c.getHeight()); + } + } + +//---------------------------------------------------------------------------------------- +// inner classes +//---------------------------------------------------------------------------------------- + public static class MyPopupMenuListener implements PopupMenuListener { + + private BasePopupMenuUI popupMenuUI = null; + + public MyPopupMenuListener(BasePopupMenuUI aPopupMenuUI) { + popupMenuUI = aPopupMenuUI; + } + + public void popupMenuCanceled(PopupMenuEvent e) { + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + if (popupMenuUI.screenImage != null) { + JPopupMenu popup = (JPopupMenu) e.getSource(); + JRootPane root = popup.getRootPane(); + if (popup.isShowing() && root.isShowing()) { + Point ptPopup = popup.getLocationOnScreen(); + Point ptRoot = root.getLocationOnScreen(); + Graphics g = popup.getRootPane().getGraphics(); + g.drawImage(popupMenuUI.screenImage, ptPopup.x - ptRoot.x, ptPopup.y - ptRoot.y, null); + popupMenuUI.resetScreenImage(); + } + } + } + + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + } + } +} + diff --git a/src/com/jtattoo/plaf/BaseProgressBarUI.java b/src/com/jtattoo/plaf/BaseProgressBarUI.java new file mode 100644 index 0000000..2c5a228 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseProgressBarUI.java @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. + * + * JTattoo is multiple licensed. If your are an open source developer you can use + * it under the terms and conditions of the GNU General Public License version 2.0 + * or later as published by the Free Software Foundation. + * + * see: gpl-2.0.txt + * + * If you pay for a license you will become a registered user who could use the + * software under the terms and conditions of the GNU Lesser General Public License + * version 2.0 or later with classpath exception as published by the Free Software + * Foundation. + * + * see: lgpl-2.0.txt + * see: classpath-exception.txt + * + * Registered users could also use JTattoo under the terms and conditions of the + * Apache License, Version 2.0 as published by the Apache Software Foundation. + * + * see: APACHE-LICENSE-2.0.txt + */ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicProgressBarUI; + +/** + * @author Michael Hagen + */ +public class BaseProgressBarUI extends BasicProgressBarUI { + + protected PropertyChangeListener propertyChangeListener; + + public static ComponentUI createUI(JComponent c) { + return new BaseProgressBarUI(); + } + + public void installUI(JComponent c) { + super.installUI(c); + c.setBorder(UIManager.getBorder("ProgressBar.border")); + propertyChangeListener = new PropertyChangeHandler(); + c.addPropertyChangeListener(propertyChangeListener); + } + + public void uninstallUI(JComponent c) { + c.removePropertyChangeListener(propertyChangeListener); + super.uninstallUI(c); + } + + /* + * The "selectionForeground" is the color of the text when it is painted over a filled area of the progress bar. + */ + protected Color getSelectionForeground() { + Object selectionForeground = progressBar.getClientProperty("selectionForeground"); + if (selectionForeground instanceof Color) { + return (Color) selectionForeground; + } + return super.getSelectionForeground(); + } + + /* + * The "selectionBackground" is the color of the text when it is painted over an unfilled area of the progress bar. + */ + protected Color getSelectionBackground() { + Object selectionBackground = progressBar.getClientProperty("selectionBackground"); + if (selectionBackground instanceof Color) { + return (Color) selectionBackground; + } + return super.getSelectionBackground(); + } + + private void paintString(Graphics g, int x, int y, int width, int height, int fillStart, int amountFull, Insets b) { + if (!(g instanceof Graphics2D)) { + return; + } + + Graphics2D g2D = (Graphics2D) g; + String progressString = progressBar.getString(); + g2D.setFont(progressBar.getFont()); + Point renderLocation = getStringPlacement(g2D, progressString, x, y, width, height); + Rectangle savedClip = g2D.getClipBounds(); + + if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { + g2D.setColor(getSelectionBackground()); + JTattooUtilities.drawString(progressBar, g2D, progressString, renderLocation.x, renderLocation.y); + g2D.setColor(getSelectionForeground()); + g2D.clipRect(fillStart, y, amountFull, height); + JTattooUtilities.drawString(progressBar, g2D, progressString, renderLocation.x, renderLocation.y); + } else { // VERTICAL + g2D.setColor(getSelectionBackground()); + AffineTransform rotate = AffineTransform.getRotateInstance(Math.PI / 2); + g2D.setFont(progressBar.getFont().deriveFont(rotate)); + renderLocation = getStringPlacement(g2D, progressString, x, y, width, height); + JTattooUtilities.drawString(progressBar, g2D, progressString, renderLocation.x, renderLocation.y); + g2D.setColor(getSelectionForeground()); + g2D.clipRect(x, fillStart, width, amountFull); + JTattooUtilities.drawString(progressBar, g2D, progressString, renderLocation.x, renderLocation.y); + } + g2D.setClip(savedClip); + } + + protected void paintString(Graphics g, int x, int y, int width, int height, int amountFull, Insets b) { + boolean indeterminate = false; + if (JTattooUtilities.getJavaVersion() >= 1.6) { + indeterminate = progressBar.isIndeterminate(); + } + if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { + if (JTattooUtilities.isLeftToRight(progressBar)) { + if (indeterminate) { + boxRect = getBox(boxRect); + paintString(g, x, y, width, height, boxRect.x, boxRect.width, b); + } else { + paintString(g, x, y, width, height, x, amountFull, b); + } + } else { + paintString(g, x, y, width, height, x + width - amountFull, amountFull, b); + } + } else { + if (indeterminate) { + boxRect = getBox(boxRect); + paintString(g, x, y, width, height, boxRect.y, boxRect.height, b); + } else { + paintString(g, x, y, width, height, y + height - amountFull, amountFull, b); + } + } + } + + protected void paintIndeterminate(Graphics g, JComponent c) { + if (!(g instanceof Graphics2D)) { + return; + } + Graphics2D g2D = (Graphics2D) g; + + Insets b = progressBar.getInsets(); // area for border + int barRectWidth = progressBar.getWidth() - (b.right + b.left); + int barRectHeight = progressBar.getHeight() - (b.top + b.bottom); + + Color colors[]; + if (progressBar.getForeground() instanceof UIResource) { + if (!JTattooUtilities.isActive(c)) { + colors = AbstractLookAndFeel.getTheme().getInActiveColors(); + } else if (c.isEnabled()) { + colors = AbstractLookAndFeel.getTheme().getProgressBarColors(); + } else { + colors = AbstractLookAndFeel.getTheme().getDisabledColors(); + } + } else { + Color hiColor = ColorHelper.brighter(progressBar.getForeground(), 40); + Color loColor = ColorHelper.darker(progressBar.getForeground(), 20); + colors = ColorHelper.createColorArr(hiColor, loColor, 20); + } + + Color cHi = ColorHelper.darker(colors[colors.length - 1], 5); + Color cLo = ColorHelper.darker(colors[colors.length - 1], 10); + + // Paint the bouncing box. + Rectangle box = getBox(null); + if (box != null) { + g2D.setColor(progressBar.getForeground()); + JTattooUtilities.draw3DBorder(g, cHi, cLo, box.x + 1, box.y + 1, box.width - 2, box.height - 2); + if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { + JTattooUtilities.fillHorGradient(g, colors, box.x + 2, box.y + 2, box.width - 4, box.height - 4); + } else { + JTattooUtilities.fillVerGradient(g, colors, box.x + 2, box.y + 2, box.width - 4, box.height - 4); + } + + // Deal with possible text painting + if (progressBar.isStringPainted()) { + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { + paintString(g2D, b.left, b.top, barRectWidth, barRectHeight, box.width, b); + } else { + paintString(g2D, b.left, b.top, barRectWidth, barRectHeight, box.height, b); + } + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } + } + } + + protected void paintDeterminate(Graphics g, JComponent c) { + if (!(g instanceof Graphics2D)) { + return; + } + + Graphics2D g2D = (Graphics2D) g; + Insets b = progressBar.getInsets(); // area for border + int w = progressBar.getWidth() - (b.right + b.left); + int h = progressBar.getHeight() - (b.top + b.bottom); + + // amount of progress to draw + int amountFull = getAmountFull(b, w, h); + Color colors[]; + if (progressBar.getForeground() instanceof UIResource) { + if (!JTattooUtilities.isActive(c)) { + colors = AbstractLookAndFeel.getTheme().getInActiveColors(); + } else if (c.isEnabled()) { + colors = AbstractLookAndFeel.getTheme().getProgressBarColors(); + } else { + colors = AbstractLookAndFeel.getTheme().getDisabledColors(); + } + } else { + Color hiColor = ColorHelper.brighter(progressBar.getForeground(), 40); + Color loColor = ColorHelper.darker(progressBar.getForeground(), 20); + colors = ColorHelper.createColorArr(hiColor, loColor, 20); + } + Color cHi = ColorHelper.darker(colors[colors.length - 1], 5); + Color cLo = ColorHelper.darker(colors[colors.length - 1], 10); + if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { + if (JTattooUtilities.isLeftToRight(progressBar)) { + JTattooUtilities.draw3DBorder(g, cHi, cLo, 1 + b.left, 2, amountFull - 2, h - 2); + JTattooUtilities.fillHorGradient(g, colors, 2 + b.left, 3, amountFull - 4, h - 4); + } else { + JTattooUtilities.draw3DBorder(g, cHi, cLo, progressBar.getWidth() - amountFull - b.right + 2, 2, amountFull - 2, h - 2); + JTattooUtilities.fillHorGradient(g, colors, progressBar.getWidth() - amountFull - b.right + 3, 3, amountFull - 4, h - 4); + } + } else { // VERTICAL + JTattooUtilities.draw3DBorder(g, cHi, cLo, 2, h - amountFull + 2, w - 2, amountFull - 2); + JTattooUtilities.fillVerGradient(g, colors, 3, h - amountFull + 3, w - 4, amountFull - 4); + } + + // Deal with possible text painting + if (progressBar.isStringPainted()) { + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + paintString(g, b.left, b.top, w, h, amountFull, b); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } + } + + public void paint(Graphics g, JComponent c) { + if (JTattooUtilities.getJavaVersion() >= 1.4) { + if (progressBar.isIndeterminate()) { + paintIndeterminate(g, c); + } else { + paintDeterminate(g, c); + } + } else { + paintDeterminate(g, c); + } + } + +//----------------------------------------------------------------------------------------------- + protected class PropertyChangeHandler implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent e) { + if ("selectionForeground".equals(e.getPropertyName()) && (e.getNewValue() instanceof Color)) { + progressBar.invalidate(); + progressBar.repaint(); + } else if ("selectionBackground".equals(e.getPropertyName()) && (e.getNewValue() instanceof Color)) { + progressBar.invalidate(); + progressBar.repaint(); + } + } + } +} diff --git a/src/com/jtattoo/plaf/BaseRadioButtonMenuItemUI.java b/src/com/jtattoo/plaf/BaseRadioButtonMenuItemUI.java new file mode 100644 index 0000000..40f901d --- /dev/null +++ b/src/com/jtattoo/plaf/BaseRadioButtonMenuItemUI.java @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import javax.swing.JComponent; +import javax.swing.UIManager; +import javax.swing.plaf.ComponentUI; + +/** + * @author Michael Hagen + */ +public class BaseRadioButtonMenuItemUI extends BaseMenuItemUI { + + public static ComponentUI createUI(JComponent b) { + return new BaseRadioButtonMenuItemUI(); + } + + protected void installDefaults() { + super.installDefaults(); + checkIcon = UIManager.getIcon("RadioButtonMenuItem.checkIcon"); + } + +} diff --git a/src/com/jtattoo/plaf/BaseRadioButtonUI.java b/src/com/jtattoo/plaf/BaseRadioButtonUI.java new file mode 100644 index 0000000..74dd2af --- /dev/null +++ b/src/com/jtattoo/plaf/BaseRadioButtonUI.java @@ -0,0 +1,196 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.*; +import javax.swing.text.View; + +/** + * @author Michael Hagen + */ +public class BaseRadioButtonUI extends BasicRadioButtonUI { + + private static BaseRadioButtonUI radioButtonUI = null; + /* These Dimensions/Rectangles are allocated once for all + * RadioButtonUI.paint() calls. Re-using rectangles + * rather than allocating them in each paint call substantially + * reduced the time it took paint to run. Obviously, this + * method can't be re-entered. + */ + protected static Dimension size = new Dimension(); + protected static Rectangle viewRect = new Rectangle(); + protected static Rectangle iconRect = new Rectangle(); + protected static Rectangle textRect = new Rectangle(); + + public static ComponentUI createUI(JComponent c) { + if (radioButtonUI == null) { + radioButtonUI = new BaseRadioButtonUI(); + } + return radioButtonUI; + } + + public void installDefaults(AbstractButton b) { + super.installDefaults(b); + b.setRolloverEnabled(true); + icon = UIManager.getIcon("RadioButton.icon"); + } + + public void paint(Graphics g, JComponent c) { + AbstractButton b = (AbstractButton) c; + g.setFont(c.getFont()); + FontMetrics fm = JTattooUtilities.getFontMetrics(c, g, c.getFont()); + + Insets i = c.getInsets(); + size = b.getSize(size); + viewRect.x = i.left; + viewRect.y = i.top; + viewRect.width = size.width - (i.right + viewRect.x); + viewRect.height = size.height - (i.bottom + viewRect.y); + iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0; + textRect.x = textRect.y = textRect.width = textRect.height = 0; + Icon altIcon = b.getIcon(); + int iconTextGap = getDefaultTextIconGap(b); + if (JTattooUtilities.getJavaVersion() >= 1.4) { + iconTextGap = b.getIconTextGap(); + } + String text = SwingUtilities.layoutCompoundLabel( + c, + fm, + b.getText(), + altIcon != null ? altIcon : getDefaultIcon(), + b.getVerticalAlignment(), + b.getHorizontalAlignment(), + b.getVerticalTextPosition(), + b.getHorizontalTextPosition(), + viewRect, + iconRect, + textRect, + iconTextGap); + + // fill background + if (c.isOpaque()) { + paintBackground(g, c); + } + + paintIcon(g, c, iconRect); + + if (text != null) { + paintText(g, c, text, textRect); + } + + if (b.hasFocus() && b.isFocusPainted() && (textRect.width > 0) && (textRect.height > 0)) { + paintFocus(g, textRect, size); + } + } + + protected void paintBackground(Graphics g, JComponent c) { + g.setColor(c.getBackground()); + g.fillRect(0, 0, c.getWidth(), c.getHeight()); + } + + protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect) { + AbstractButton b = (AbstractButton) c; + ButtonModel model = b.getModel(); + Icon ico; + if (!model.isEnabled()) { + if (b.isSelected()) { + ico = b.getDisabledSelectedIcon(); + } else { + ico = b.getDisabledIcon(); + } + } else { + if (model.isPressed()) { + ico = b.getPressedIcon(); + } else { + if (model.isRollover()) { + if (b.isSelected()) { + ico = b.getRolloverSelectedIcon(); + } else { + ico = b.getRolloverIcon(); + } + } else { + if (b.isSelected()) { + ico = b.getSelectedIcon(); + } else { + ico = b.getIcon(); + } + } + } + } + + if (ico != null) { + ico.paintIcon(c, g, iconRect.x, iconRect.y - 1); + } else { + if (b.getIcon() != null) { + b.getIcon().paintIcon(c, g, iconRect.x, iconRect.y - 1); + } else { + getDefaultIcon().paintIcon(c, g, iconRect.x, iconRect.y - 1); + } + } + } + + protected void paintText(Graphics g, JComponent c, String text, Rectangle textRect) { + View v = (View) c.getClientProperty(BasicHTML.propertyKey); + if (v != null) { + Graphics2D g2D = (Graphics2D) g; + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + v.paint(g, textRect); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } else { + AbstractButton b = (AbstractButton) c; + ButtonModel model = b.getModel(); + g.setFont(b.getFont()); + FontMetrics fm = JTattooUtilities.getFontMetrics(b, g, b.getFont()); + int mnemIndex; + if (JTattooUtilities.getJavaVersion() >= 1.4) { + mnemIndex = b.getDisplayedMnemonicIndex(); + } else { + mnemIndex = JTattooUtilities.findDisplayedMnemonicIndex(b.getText(), model.getMnemonic()); + } + if (model.isEnabled()) { + g.setColor(b.getForeground()); + JTattooUtilities.drawStringUnderlineCharAt(c, g, text, mnemIndex, textRect.x, textRect.y + fm.getAscent()); + } else { + g.setColor(Color.white); + JTattooUtilities.drawStringUnderlineCharAt(c, g, text, mnemIndex, textRect.x + 1, textRect.y + 1 + fm.getAscent()); + g.setColor(AbstractLookAndFeel.getDisabledForegroundColor()); + JTattooUtilities.drawStringUnderlineCharAt(c, g, text, mnemIndex, textRect.x, textRect.y + fm.getAscent()); + } + } + } + + protected void paintFocus(Graphics g, Rectangle t, Dimension d) { + g.setColor(AbstractLookAndFeel.getFocusColor()); + BasicGraphicsUtils.drawDashedRect(g, t.x, t.y - 1, t.width + 1, t.height + 1); + } +} diff --git a/src/com/jtattoo/plaf/BaseRootPaneUI.java b/src/com/jtattoo/plaf/BaseRootPaneUI.java new file mode 100644 index 0000000..6108f8b --- /dev/null +++ b/src/com/jtattoo/plaf/BaseRootPaneUI.java @@ -0,0 +1,997 @@ +/* + * Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. + * + * JTattoo is multiple licensed. If your are an open source developer you can use + * it under the terms and conditions of the GNU General Public License version 2.0 + * or later as published by the Free Software Foundation. + * + * see: gpl-2.0.txt + * + * If you pay for a license you will become a registered user who could use the + * software under the terms and conditions of the GNU Lesser General Public License + * version 2.0 or later with classpath exception as published by the Free Software + * Foundation. + * + * see: lgpl-2.0.txt + * see: classpath-exception.txt + * + * Registered users could also use JTattoo under the terms and conditions of the + * Apache License, Version 2.0 as published by the Apache Software Foundation. + * + * see: APACHE-LICENSE-2.0.txt + */ +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.awt.image.BufferedImage; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.*; +import javax.swing.event.MouseInputListener; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicRootPaneUI; + +/** + * This source is a modified copy of javax.swing.plaf.metal.MetalRootPaneUI Provides the base look and feel + * implementation of RootPaneUI. + *

+ * BaseRootPaneUI provides support for the windowDecorationStyle property of + * JRootPane. BaseRootPaneUI does this by way of installing a custom + * LayoutManager, a private Component to render the appropriate widgets, and a private + * Border. The LayoutManager is always installed, regardless of the value of the + * windowDecorationStyle property, but the Border and Component are only + * installed/added if the windowDecorationStyle is other than JRootPane.NONE. + *

+ * Warning: + * Serialized objects of this class will not be compatible with future Swing releases. The current serialization support + * is appropriate for short term storage or RMI between applications running the same version of Swing. As of 1.4, + * support for long term storage of all JavaBeansTM + * has been added to the java.beans package. Please see {@link java.beans.XMLEncoder}. + * + * @version 1.20 04/27/04 + * @author Terry Kellerman + * @author Michael Hagen + * @since 1.4 + */ +public class BaseRootPaneUI extends BasicRootPaneUI { + + // Konstanten aus javax.swing.JRootPane damit Attribute aus Java 1.4 sich mit Java 1.3 uebersetzen lassen + + public static final int NONE = 0; + public static final int FRAME = 1; + public static final int PLAIN_DIALOG = 2; + public static final int INFORMATION_DIALOG = 3; + public static final int ERROR_DIALOG = 4; + public static final int COLOR_CHOOSER_DIALOG = 5; + public static final int FILE_CHOOSER_DIALOG = 6; + public static final int QUESTION_DIALOG = 7; + public static final int WARNING_DIALOG = 8; + // Konstanten aus java.awt.Frame damit Attribute aus Java 1.4 sich mit Java 1.3 uebersetzen lassen + public static final int MAXIMIZED_HORIZ = 2; + public static final int MAXIMIZED_VERT = 4; + public static final int MAXIMIZED_BOTH = MAXIMIZED_VERT | MAXIMIZED_HORIZ; + private static final String[] borderKeys = new String[]{ + null, + "RootPane.frameBorder", + "RootPane.plainDialogBorder", + "RootPane.informationDialogBorder", + "RootPane.errorDialogBorder", + "RootPane.colorChooserDialogBorder", + "RootPane.fileChooserDialogBorder", + "RootPane.questionDialogBorder", + "RootPane.warningDialogBorder" + }; + /** + * The minimum/maximum size of a Window + */ + private static final Dimension MINIMUM_SIZE = new Dimension(120, 80); + private static final Dimension MAXIMUM_SIZE = Toolkit.getDefaultToolkit().getScreenSize(); + /** + * The amount of space (in pixels) that the cursor is changed on. + */ + private static final int CORNER_DRAG_WIDTH = 16; + /** + * Region from edges that dragging is active from. + */ + private static final int BORDER_DRAG_THICKNESS = 5; + /** + * Window the JRootPane is in. + */ + private Window window; + /** + * JComponent providing window decorations. This will be null if not providing window decorations. + */ + private JComponent titlePane; + /** + * MouseInputListener that is added to the parent Window the JRootPane is + * contained in. + */ + private MouseInputListener mouseInputListener; + /** + * WindowListener that is added to the parent Window the JRootPane is + * contained in. + */ + private WindowListener windowListener; + /** + * WindowListener that is added to the parent Window the JRootPane is + * contained in. + */ + private PropertyChangeListener propertyChangeListener; + /** + * The LayoutManager that is set on the JRootPane. + */ + private LayoutManager layoutManager; + /** + * LayoutManager of the JRootPane before we replaced it. + */ + private LayoutManager savedOldLayout; + /** + * JRootPane providing the look and feel for. + */ + private JRootPane root; + + private Cursor savedCursor = null; + + /** + * Cursor used to track the cursor set by the user. This is initially + * Cursor.DEFAULT_CURSOR. + */ + /** + * Creates a UI for a JRootPane. + * + * @param c the JRootPane the RootPaneUI will be created for + * @return the RootPaneUI implementation for the passed in JRootPane + */ + public static ComponentUI createUI(JComponent c) { + return new BaseRootPaneUI(); + } + + public void installUI(JComponent c) { + super.installUI(c); + root = (JRootPane) c; + if (DecorationHelper.getWindowDecorationStyle(root) != NONE) { + installClientDecorations(root); + } + } + + public void uninstallUI(JComponent c) { + super.uninstallUI(c); + uninstallClientDecorations(root); + layoutManager = null; + mouseInputListener = null; + root = null; + } + + protected void installListeners(JRootPane root) { + super.installListeners(root); + + if (DecorationHelper.getWindowDecorationStyle(root) == NONE) { + propertyChangeListener = new PropertyChangeListener() { + + public void propertyChange(PropertyChangeEvent evt) { + if ("ancestor".equals(evt.getPropertyName())) { + if (getRootPane() != null && getRootPane().getParent() instanceof Window) { + window = (Window) getRootPane().getParent(); + windowListener = new WindowAdapter() { + + public void windowActivated(WindowEvent e) { + if (getRootPane() != null) { + getRootPane().repaint(); + } + } + + public void windowDeactivated(WindowEvent e) { + if (getRootPane() != null) { + getRootPane().repaint(); + } + } + }; + window.addWindowListener(windowListener); + } + } + } + }; + root.addPropertyChangeListener(propertyChangeListener); + } + } + + protected void uninstallListeners(JRootPane root) { + super.uninstallListeners(root); + if (DecorationHelper.getWindowDecorationStyle(root) == NONE) { + if (root.getParent() instanceof Window && windowListener != null) { + window = (Window) root.getParent(); + window.removeWindowListener(windowListener); + } + root.removePropertyChangeListener(propertyChangeListener); + } + } + + public void installBorder(JRootPane root) { + int style = DecorationHelper.getWindowDecorationStyle(root); + if (style == NONE) { + LookAndFeel.uninstallBorder(root); + } else { + LookAndFeel.installBorder(root, borderKeys[style]); + } + } + + /** + * Removes any border that may have been installed. + * + * @param root + */ + public void uninstallBorder(JRootPane root) { + LookAndFeel.uninstallBorder(root); + } + + /** + * Installs the necessary Listeners on the parent Window, if there is one. + *

+ * This takes the parent so that cleanup can be done from removeNotify, at which point the parent + * hasn't been reset yet. + * + * @param root + * @param parent The parent of the JRootPane + */ + public void installWindowListeners(JRootPane root, Component parent) { + if (parent instanceof Window) { + window = (Window) parent; + } else { + window = SwingUtilities.getWindowAncestor(parent); + } + if (window != null) { + if (mouseInputListener == null) { + mouseInputListener = createWindowMouseInputListener(root); + } + window.addMouseListener(mouseInputListener); + window.addMouseMotionListener(mouseInputListener); + // fixes a problem with netbeans, decorated windows and java 1.5 + // the MetalLookAndFeel seems to have the same problem + if ((JTattooUtilities.getJavaVersion() >= 1.5) && (JTattooUtilities.getJavaVersion() <= 1.6)) { + SwingUtilities.invokeLater(new Runnable() { + + public void run() { + if (window != null) { + if (window instanceof JFrame) { + JFrame frame = (JFrame) window; + frame.update(frame.getGraphics()); + } + } + } + }); + } + } + } + + /** + * Uninstalls the necessary Listeners on the Window the Listeners were last installed on. + * + * @param root + */ + public void uninstallWindowListeners(JRootPane root) { + if (window != null) { + window.removeMouseListener(mouseInputListener); + window.removeMouseMotionListener(mouseInputListener); + } + } + + /** + * Installs the appropriate LayoutManager on the JRootPane to render the window decorations. + * + * @param root + */ + public void installLayout(JRootPane root) { + if (layoutManager == null) { + layoutManager = createLayoutManager(); + } + savedOldLayout = root.getLayout(); + root.setLayout(layoutManager); + } + + public void uninstallLayout(JRootPane root) { + if (savedOldLayout != null) { + root.setLayout(savedOldLayout); + savedOldLayout = null; + } + } + + public void installClientDecorations(JRootPane root) { + installBorder(root); + if (titlePane == null) { + setTitlePane(root, createTitlePane(root)); + } + installWindowListeners(root, root.getParent()); + installLayout(root); + if (window != null) { + savedCursor = window.getCursor(); + root.revalidate(); + root.repaint(); + } + } + + public void uninstallClientDecorations(JRootPane root) { + uninstallBorder(root); + uninstallWindowListeners(root); + setTitlePane(root, null); + uninstallLayout(root); + int style = DecorationHelper.getWindowDecorationStyle(root); + if (style == NONE) { + root.repaint(); + root.revalidate(); + } + // Reset the cursor, as we may have changed it to a resize cursor + if (window != null) { + window.setCursor(savedCursor); + } + window = null; + } + + /** + * Returns the JComponent to render the window decoration style. + * + * @param root + * @return + */ + public JComponent createTitlePane(JRootPane root) { + return new BaseTitlePane(root, this); + } + + /** + * Returns a MouseListener that will be added to the Window containing the + * JRootPane. + * + * @param root + * @return + */ + public MouseInputListener createWindowMouseInputListener(JRootPane root) { + return new MouseInputHandler(); + } + + /** + * Returns a LayoutManager that will be set on the JRootPane. + * + * @return + */ + public LayoutManager createLayoutManager() { + return new BaseRootLayout(); + } + + /** + * Sets the window title pane -- the JComponent used to provide a plaf a way to override the native operating + * system's window title pane with one whose look and feel are controlled by the plaf. The plaf creates and sets + * this value; the default is null, implying a native operating system window title pane. + * + * @param root the JRootPane where to set the title pane + * @param titlePane the JComponent to use for the window title pane. + */ + public void setTitlePane(JRootPane root, JComponent titlePane) { + JComponent oldTitlePane = internalGetTitlePane(); + if ((oldTitlePane == null && titlePane == null) || (oldTitlePane != null && oldTitlePane.equals(titlePane))) { + return; + } + JLayeredPane layeredPane = root.getLayeredPane(); + if (oldTitlePane != null) { + oldTitlePane.setVisible(false); + layeredPane.remove(oldTitlePane); + } + if (titlePane != null) { + layeredPane.add(titlePane, JLayeredPane.FRAME_CONTENT_LAYER); + titlePane.setVisible(true); + } + this.titlePane = titlePane; + } + + /** + * Returns the BaseTitlePane rendering the title pane. If this returns null, it implies there is no need + * to render window decorations. + * + * @return the current window title pane, or null + * @see #setTitlePane + */ + public BaseTitlePane getTitlePane() { + if (titlePane instanceof BaseTitlePane) { + return (BaseTitlePane)titlePane; + } + return null; + } + + private JComponent internalGetTitlePane() { + return titlePane; + } + + public JRootPane getRootPane() { + return root; + } + + public void propertyChange(PropertyChangeEvent e) { + super.propertyChange(e); + + String propertyName = e.getPropertyName(); + JRootPane root = (JRootPane) e.getSource(); + if ("windowDecorationStyle".equals(propertyName)) { + int style = DecorationHelper.getWindowDecorationStyle(root); + + // This is potentially more than needs to be done, + // but it rarely happens and makes the install/uninstall process + // simpler. BaseTitlePane also assumes it will be recreated if + // the decoration style changes. + uninstallClientDecorations(root); + if (style != NONE) { + installClientDecorations(root); + } +// if (!JTattooUtilities.isMac() && (window instanceof Frame)) { +// Frame frame = (Frame) window; +// if (frame != null) { +// GraphicsConfiguration gc = frame.getGraphicsConfiguration(); +// Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc); +// Rectangle screenBounds = gc.getBounds(); +// int x = Math.max(0, screenInsets.left); +// int y = Math.max(0, screenInsets.top); +// int w = screenBounds.width - (screenInsets.left + screenInsets.right); +// int h = screenBounds.height - (screenInsets.top + screenInsets.bottom); +// // Keep taskbar visible +// frame.setMaximizedBounds(new Rectangle(x, y, w, h)); +// } +// } + } else if ("ancestor".equals(propertyName)) { + uninstallWindowListeners(root); + if (DecorationHelper.getWindowDecorationStyle(root) != NONE) { + installWindowListeners(root, root.getParent()); + } + } + } + + private boolean isDynamicLayout() { + return AbstractLookAndFeel.getTheme().isDynamicLayout(); + } + +//------------------------------------------------------------------------------ + private static class BaseRootLayout implements LayoutManager2 { + + /** + * Returns the amount of space the layout would like to have. + * + * @param the Container for which this layout manager is being used + * @return a Dimension object containing the layout's preferred size + */ + public Dimension preferredLayoutSize(Container parent) { + Dimension cpd, mbd, tpd; + int cpWidth = 0; + int cpHeight = 0; + int mbWidth = 0; + int mbHeight = 0; + int tpWidth = 0; + Insets i = parent.getInsets(); + JRootPane root = (JRootPane) parent; + + if (root.getContentPane() != null) { + cpd = root.getContentPane().getPreferredSize(); + } else { + cpd = root.getSize(); + } + if (cpd != null) { + cpWidth = cpd.width; + cpHeight = cpd.height; + } + + if (root.getJMenuBar() != null) { + mbd = root.getJMenuBar().getPreferredSize(); + if (mbd != null) { + mbWidth = mbd.width; + mbHeight = mbd.height; + } + } + + if (DecorationHelper.getWindowDecorationStyle(root) != NONE && (root.getUI() instanceof BaseRootPaneUI)) { + JComponent titlePane = ((BaseRootPaneUI) root.getUI()).internalGetTitlePane(); + if (titlePane != null) { + tpd = titlePane.getPreferredSize(); + if (tpd != null) { + tpWidth = tpd.width; + } + } + } + + return new Dimension(Math.max(Math.max(cpWidth, mbWidth), tpWidth) + i.left + i.right, cpHeight + mbHeight + tpWidth + i.top + i.bottom); + } + + /** + * Returns the minimum amount of space the layout needs. + * + * @param the Container for which this layout manager is being used + * @return a Dimension object containing the layout's minimum size + */ + public Dimension minimumLayoutSize(Container parent) { + return MINIMUM_SIZE; + } + + /** + * Returns the maximum amount of space the layout can use. + * + * @param the Container for which this layout manager is being used + * @return a Dimension object containing the layout's maximum size + */ + public Dimension maximumLayoutSize(Container target) { + return MAXIMUM_SIZE; + } + + /** + * Instructs the layout manager to perform the layout for the specified container. + * + * @param the Container for which this layout manager is being used + */ + public void layoutContainer(Container parent) { + JRootPane root = (JRootPane) parent; + Rectangle b = root.getBounds(); + Insets i = root.getInsets(); + int nextY = 0; + int w = b.width - i.right - i.left; + int h = b.height - i.top - i.bottom; + + if (root.getLayeredPane() != null) { + root.getLayeredPane().setBounds(i.left, i.top, w, h); + } + if (root.getGlassPane() != null) { + if (DecorationHelper.getWindowDecorationStyle(root) != NONE && (root.getUI() instanceof BaseRootPaneUI)) { + JComponent titlePane = ((BaseRootPaneUI) root.getUI()).internalGetTitlePane(); + int titleHeight = 0; + if (titlePane != null) { + titleHeight = titlePane.getSize().height; + } + root.getGlassPane().setBounds(i.left, i.top + titleHeight, w, h - titleHeight); + } else { + root.getGlassPane().setBounds(i.left, i.top, w, h); + } + } + // Note: This is laying out the children in the layeredPane, + // technically, these are not our children. + if (DecorationHelper.getWindowDecorationStyle(root) != NONE && (root.getUI() instanceof BaseRootPaneUI)) { + JComponent titlePane = ((BaseRootPaneUI) root.getUI()).internalGetTitlePane(); + if (titlePane != null) { + Dimension tpd = titlePane.getPreferredSize(); + if (tpd != null) { + int tpHeight = tpd.height; + titlePane.setBounds(0, 0, w, tpHeight); + nextY += tpHeight; + } + } + } + if (root.getJMenuBar() != null) { + Dimension mbd = root.getJMenuBar().getPreferredSize(); + root.getJMenuBar().setBounds(0, nextY, w, mbd.height); + nextY += mbd.height; + } + if (root.getContentPane() != null) { + root.getContentPane().setBounds(0, nextY, w, h < nextY ? 0 : h - nextY); + } + } + + public void addLayoutComponent(String name, Component comp) { + } + + public void removeLayoutComponent(Component comp) { + } + + public void addLayoutComponent(Component comp, Object constraints) { + } + + public float getLayoutAlignmentX(Container target) { + return 0.0f; + } + + public float getLayoutAlignmentY(Container target) { + return 0.0f; + } + + public void invalidateLayout(Container target) { + } + } + /** + * Maps from positions to cursor type. Refer to calculateCorner and calculatePosition for details of this. + */ + private static final int[] cursorMapping = new int[]{ + Cursor.NW_RESIZE_CURSOR, Cursor.NW_RESIZE_CURSOR, Cursor.N_RESIZE_CURSOR, + Cursor.NE_RESIZE_CURSOR, Cursor.NE_RESIZE_CURSOR, + Cursor.NW_RESIZE_CURSOR, 0, 0, 0, Cursor.NE_RESIZE_CURSOR, + Cursor.W_RESIZE_CURSOR, 0, 0, 0, Cursor.E_RESIZE_CURSOR, + Cursor.SW_RESIZE_CURSOR, 0, 0, 0, Cursor.SE_RESIZE_CURSOR, + Cursor.SW_RESIZE_CURSOR, Cursor.SW_RESIZE_CURSOR, Cursor.S_RESIZE_CURSOR, + Cursor.SE_RESIZE_CURSOR, Cursor.SE_RESIZE_CURSOR + }; + +//------------------------------------------------------------------------------ + /** + * MouseInputHandler is responsible for handling resize/moving of the Window. It sets the cursor directly on the + * Window when then mouse moves over a hot spot. + */ + private class MouseInputHandler implements MouseInputListener { + + /** + * Set to true if the drag operation is moving the window. + */ + private boolean isMovingWindow; + /** + * Set to true if the drag operation is resizing the window. + */ + private boolean isResizingWindow; + /** + * Used to determine the corner the resize is occuring from. + */ + private int dragCursor; + /** + * X location the mouse went down on for a drag operation. + */ + private int dragOffsetX; + /** + * Y location the mouse went down on for a drag operation. + */ + private int dragOffsetY; + /** + * Width of the window when the drag started. + */ + private int dragWidth; + /** + * Height of the window when the drag started. + */ + private int dragHeight; + private Container savedContentPane = null; + private ResizingPanel resizingPanel = null; + + public void mousePressed(MouseEvent ev) { + Window w = (Window) ev.getSource(); + if (w instanceof Window) { + JRootPane root = getRootPane(); + if (DecorationHelper.getWindowDecorationStyle(root) == NONE) { + return; + } + w.toFront(); + + Point dragWindowOffset = ev.getPoint(); + Point convertedDragWindowOffset = SwingUtilities.convertPoint(w, dragWindowOffset, internalGetTitlePane()); + + Frame f = null; + Dialog d = null; + + if (w instanceof Frame) { + f = (Frame) w; + } else if (w instanceof Dialog) { + d = (Dialog) w; + } + + int frameState = (f != null) ? DecorationHelper.getExtendedState(f) : 0; + + if (internalGetTitlePane() != null && internalGetTitlePane().contains(convertedDragWindowOffset)) { + if ((f != null && ((frameState & BaseRootPaneUI.MAXIMIZED_BOTH) == 0) || (d != null)) + && dragWindowOffset.y >= BORDER_DRAG_THICKNESS + && dragWindowOffset.x >= BORDER_DRAG_THICKNESS + && dragWindowOffset.x < w.getWidth() - BORDER_DRAG_THICKNESS) { + isMovingWindow = true; + dragOffsetX = dragWindowOffset.x; + dragOffsetY = dragWindowOffset.y; + if (window instanceof JFrame) { + JFrame frame = (JFrame) window; + PropertyChangeListener[] pcl = frame.getPropertyChangeListeners(); + for (int i = 0; i < pcl.length; i++) { + pcl[i].propertyChange(new PropertyChangeEvent(window, "windowMoving", Boolean.FALSE, Boolean.FALSE)); + } + } + if (window instanceof JDialog) { + JDialog dialog = (JDialog) window; + PropertyChangeListener[] pcl = dialog.getPropertyChangeListeners(); + for (int i = 0; i < pcl.length; i++) { + pcl[i].propertyChange(new PropertyChangeEvent(window, "windowMoving", Boolean.FALSE, Boolean.FALSE)); + } + } + } + } else if (f != null + && f.isResizable() + && ((frameState & BaseRootPaneUI.MAXIMIZED_BOTH) == 0) + || (d != null && d.isResizable())) { + isResizingWindow = true; + if (!isDynamicLayout()) { + savedContentPane = getRootPane().getContentPane(); + GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); + BufferedImage bi = gc.createCompatibleImage(savedContentPane.getWidth(), savedContentPane.getHeight()); + savedContentPane.paint(bi.getGraphics()); + resizingPanel = new ResizingPanel(bi); + getRootPane().setContentPane(resizingPanel); + } + dragOffsetX = dragWindowOffset.x; + dragOffsetY = dragWindowOffset.y; + dragWidth = w.getWidth(); + dragHeight = w.getHeight(); + dragCursor = getCursor(calculateCorner(w, dragWindowOffset.x, dragWindowOffset.y)); + if (window instanceof JFrame) { + JFrame frame = (JFrame) window; + PropertyChangeListener[] pcl = frame.getPropertyChangeListeners(); + for (int i = 0; i < pcl.length; i++) { + pcl[i].propertyChange(new PropertyChangeEvent(window, "windowResizing", Boolean.FALSE, Boolean.FALSE)); + } + } + if (window instanceof JDialog) { + JDialog dialog = (JDialog) window; + PropertyChangeListener[] pcl = dialog.getPropertyChangeListeners(); + for (int i = 0; i < pcl.length; i++) { + pcl[i].propertyChange(new PropertyChangeEvent(window, "windowResizing", Boolean.FALSE, Boolean.FALSE)); + } + } + } + } + } + + public void mouseReleased(MouseEvent ev) { + if (ev.getSource() instanceof Window) { + Window w = (Window) ev.getSource(); + if (w != null) { + if (!isDynamicLayout() && isResizingWindow) { + getRootPane().setContentPane(savedContentPane); + getRootPane().updateUI(); + resizingPanel = null; + } else if (dragCursor != 0 && !window.isValid()) { + // Some Window systems validate as you resize, others won't, + // thus the check for validity before repainting. + w.validate(); + getRootPane().repaint(); + } + + if (window instanceof JFrame) { + JFrame frame = (JFrame) window; + PropertyChangeListener[] pcl = frame.getPropertyChangeListeners(); + for (int i = 0; i < pcl.length; i++) { + if (isMovingWindow) { + pcl[i].propertyChange(new PropertyChangeEvent(window, "windowMoved", Boolean.FALSE, Boolean.FALSE)); + } else { + pcl[i].propertyChange(new PropertyChangeEvent(window, "windowResized", Boolean.FALSE, Boolean.FALSE)); + } + } + } + if (window instanceof JDialog) { + JDialog dialog = (JDialog) window; + PropertyChangeListener[] pcl = dialog.getPropertyChangeListeners(); + for (int i = 0; i < pcl.length; i++) { + if (isMovingWindow) { + pcl[i].propertyChange(new PropertyChangeEvent(window, "windowMoved", Boolean.FALSE, Boolean.FALSE)); + } else { + pcl[i].propertyChange(new PropertyChangeEvent(window, "windowResized", Boolean.FALSE, Boolean.FALSE)); + } + } + } + } + isMovingWindow = false; + isResizingWindow = false; + dragCursor = 0; + } + } + + public void mouseMoved(MouseEvent ev) { + if (ev.getSource() instanceof Window) { + JRootPane root = getRootPane(); + if (DecorationHelper.getWindowDecorationStyle(root) == NONE) { + return; + } + + Window w = (Window) ev.getSource(); + Frame f = null; + Dialog d = null; + + if (w instanceof Frame) { + f = (Frame) w; + } else if (w instanceof Dialog) { + d = (Dialog) w; + } + + // Update the cursor + int cursor = getCursor(calculateCorner(w, ev.getX(), ev.getY())); + if (cursor != 0 && ((f != null && (f.isResizable() && (DecorationHelper.getExtendedState(f) & BaseRootPaneUI.MAXIMIZED_BOTH) == 0)) || (d != null && d.isResizable()))) { + w.setCursor(Cursor.getPredefinedCursor(cursor)); + } else { + w.setCursor(savedCursor); + } + } + } + + private void adjust(Rectangle bounds, Dimension min, int deltaX, int deltaY, int deltaWidth, int deltaHeight) { + bounds.x += deltaX; + bounds.y += deltaY; + bounds.width += deltaWidth; + bounds.height += deltaHeight; + if (min != null) { + if (bounds.width < min.width) { + int correction = min.width - bounds.width; + if (deltaX != 0) { + bounds.x -= correction; + } + bounds.width = min.width; + } + if (bounds.height < min.height) { + int correction = min.height - bounds.height; + if (deltaY != 0) { + bounds.y -= correction; + } + bounds.height = min.height; + } + } + } + + private int getMinScreenY() { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice devices[] = ge.getScreenDevices(); + GraphicsDevice gd = devices[0]; + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + int minScreenY = gc.getBounds().y + Toolkit.getDefaultToolkit().getScreenInsets(gc).top; + if (devices.length > 1) { + for (int i = 1; i < devices.length; i++) { + gd = devices[i]; + gc = gd.getDefaultConfiguration(); + minScreenY = Math.min(minScreenY, gc.getBounds().y + Toolkit.getDefaultToolkit().getScreenInsets(gc).top); + } + } + return minScreenY; + } + + public void mouseDragged(MouseEvent ev) { + if (ev.getSource() instanceof Window) { + Window w = (Window) ev.getSource(); + int minScreenY = getMinScreenY(); + if (isMovingWindow) { + if (JTattooUtilities.getJavaVersion() < 1.6) { + Point pt = ev.getPoint(); + Point location = w.getLocationOnScreen(); + location.x += pt.x - dragOffsetX; + location.y += pt.y - dragOffsetY; + location.y = Math.max(minScreenY, location.y); + w.setLocation(location); + } else { + Point location = ev.getLocationOnScreen(); + location.x -= dragOffsetX; + location.y = Math.max(minScreenY, location.y - dragOffsetY); + w.setLocation(location); + } + } else if (dragCursor != 0) { + Point pt = ev.getPoint(); + Rectangle bounds = w.getBounds(); + Rectangle startBounds = new Rectangle(bounds); + Dimension min = MINIMUM_SIZE; + switch (dragCursor) { + case Cursor.E_RESIZE_CURSOR: + adjust(bounds, min, 0, 0, pt.x + (dragWidth - dragOffsetX) - bounds.width, 0); + break; + case Cursor.S_RESIZE_CURSOR: + adjust(bounds, min, 0, 0, 0, pt.y + (dragHeight - dragOffsetY) - bounds.height); + break; + case Cursor.N_RESIZE_CURSOR: + adjust(bounds, min, 0, pt.y - dragOffsetY, 0, -(pt.y - dragOffsetY)); + break; + case Cursor.W_RESIZE_CURSOR: + adjust(bounds, min, pt.x - dragOffsetX, 0, -(pt.x - dragOffsetX), 0); + break; + case Cursor.NE_RESIZE_CURSOR: + adjust(bounds, min, 0, pt.y - dragOffsetY, pt.x + (dragWidth - dragOffsetX) - bounds.width, -(pt.y - dragOffsetY)); + break; + case Cursor.SE_RESIZE_CURSOR: + adjust(bounds, min, 0, 0, pt.x + (dragWidth - dragOffsetX) - bounds.width, pt.y + (dragHeight - dragOffsetY) - bounds.height); + break; + case Cursor.NW_RESIZE_CURSOR: + adjust(bounds, min, pt.x - dragOffsetX, pt.y - dragOffsetY, -(pt.x - dragOffsetX), -(pt.y - dragOffsetY)); + break; + case Cursor.SW_RESIZE_CURSOR: + adjust(bounds, min, pt.x - dragOffsetX, 0, -(pt.x - dragOffsetX), pt.y + (dragHeight - dragOffsetY) - bounds.height); + break; + default: + break; + } + if (!bounds.equals(startBounds)) { + if (bounds.y < minScreenY) { + int delta = minScreenY - bounds.y; + bounds.y = minScreenY; + bounds.height -= delta; + } + w.setBounds(bounds); + w.validate(); + } + } + } + } + + public void mouseEntered(MouseEvent ev) { + mouseMoved(ev); + } + + public void mouseExited(MouseEvent ev) { + if (ev.getSource() instanceof Window) { + Window w = (Window) ev.getSource(); + w.setCursor(savedCursor); + } + } + + @SuppressWarnings("deprecation") + public void mouseClicked(MouseEvent ev) { + if (ev.getSource() instanceof Window) { + Window window = (Window) ev.getSource(); + if (!(window instanceof Frame)) { + return; + } + Frame frame = (Frame) window; + Point convertedPoint = SwingUtilities.convertPoint(window, ev.getPoint(), internalGetTitlePane()); + int state = DecorationHelper.getExtendedState(frame); + if (titlePane != null && titlePane instanceof TitlePane && titlePane.contains(convertedPoint) && frame.isResizable()) { + if ((ev.getClickCount() % 2) == 0 && ((ev.getModifiers() & InputEvent.BUTTON1_MASK) != 0)) { + if ((state & BaseRootPaneUI.MAXIMIZED_BOTH) != 0) { + ((TitlePane) titlePane).restore(); + } else { + ((TitlePane) titlePane).maximize(); + } + } + } + } + } + + /** + * Returns the corner that contains the point x, y, or -1 if the position doesn't + * match a corner. + */ + private int calculateCorner(Component c, int x, int y) { + int xPosition = calculatePosition(x, c.getWidth()); + int yPosition = calculatePosition(y, c.getHeight()); + + if (xPosition == -1 || yPosition == -1) { + return -1; + } + return yPosition * 5 + xPosition; + } + + /** + * Returns the Cursor to render for the specified corner. This returns 0 if the corner doesn't map to a valid + * Cursor + */ + private int getCursor(int corner) { + if (corner == -1) { + return 0; + } + return cursorMapping[corner]; + } + + /** + * Returns an integer indicating the position of spot in width. The return value will + * be: 0 if < BORDER_DRAG_THICKNESS 1 if < CORNER_DRAG_WIDTH 2 if >= CORNER_DRAG_WIDTH && + * < width - BORDER_DRAG_THICKNESS 3 if >= width - CORNER_DRAG_WIDTH 4 if >= width - BORDER_DRAG_THICKNESS 5 + * otherwise + */ + private int calculatePosition(int spot, int width) { + if (spot < BORDER_DRAG_THICKNESS) { + return 0; + } + if (spot < CORNER_DRAG_WIDTH) { + return 1; + } + if (spot >= (width - BORDER_DRAG_THICKNESS)) { + return 4; + } + if (spot >= (width - CORNER_DRAG_WIDTH)) { + return 3; + } + return 2; + } + } + +//------------------------------------------------------------------------------ + private static class ResizingPanel extends JPanel { + + private BufferedImage bi = null; + + public ResizingPanel(BufferedImage bi) { + super(); + this.bi = bi; + } + + public void paint(Graphics g) { + super.paint(g); + g.drawImage(bi, 0, 0, null); + } + } +} diff --git a/src/com/jtattoo/plaf/BaseScrollBarUI.java b/src/com/jtattoo/plaf/BaseScrollBarUI.java new file mode 100644 index 0000000..7110d13 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseScrollBarUI.java @@ -0,0 +1,399 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.event.MouseEvent; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JScrollBar; +import javax.swing.UIManager; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicScrollBarUI; + +/** + * @author Michael Hagen + */ +public class BaseScrollBarUI extends BasicScrollBarUI { + + protected int scrollBarWidth = 17; + protected int incrGap = 0; + protected int decrGap = 0; + protected boolean isRollover = false; + + public static ComponentUI createUI(JComponent c) { + return new BaseScrollBarUI(); + } + + protected void installDefaults() { + super.installDefaults(); + + scrollBarWidth = UIManager.getInt("ScrollBar.width"); + incrGap = UIManager.getInt("ScrollBar.incrementButtonGap"); + decrGap = UIManager.getInt("ScrollBar.decrementButtonGap"); + + // TODO this can be removed when incrGap/decrGap become protected + // handle scaling for sizeVarients for special case components. The + // key "JComponent.sizeVariant" scales for large/small/mini + // components are based on Apples LAF + String scaleKey = (String)scrollbar.getClientProperty("JComponent.sizeVariant"); + if (scaleKey != null){ + if ("large".equals(scaleKey)){ + scrollBarWidth *= 1.15; + incrGap *= 1.15; + decrGap *= 1.15; + } else if ("small".equals(scaleKey)){ + scrollBarWidth *= 0.857; + incrGap *= 0.857; + decrGap *= 0.857; + } else if ("mini".equals(scaleKey)){ + scrollBarWidth *= 0.714; + incrGap *= 0.714; + decrGap *= 0.714; + } + } + } + + protected JButton createDecreaseButton(int orientation) { + if (AbstractLookAndFeel.getTheme().isMacStyleScrollBarOn()) { + return new InvisibleScrollButton(); + } else { + return new BaseScrollButton(orientation, scrollBarWidth); + } + } + + protected JButton createIncreaseButton(int orientation) { + if (AbstractLookAndFeel.getTheme().isMacStyleScrollBarOn()) { + return new InvisibleScrollButton(); + } else { + return new BaseScrollButton(orientation, scrollBarWidth); + } + } + + public TrackListener createTrackListener() { + return new MyTrackListener(); + } + + public Dimension getPreferredSize(JComponent c) { + if (AbstractLookAndFeel.getTheme().isMacStyleScrollBarOn()) { + if (scrollbar.getOrientation() == JScrollBar.VERTICAL) { + return new Dimension(scrollBarWidth + 1, scrollBarWidth * 3); + } else { + return new Dimension(scrollBarWidth * 3, scrollBarWidth); + } + } else { + if (scrollbar.getOrientation() == JScrollBar.VERTICAL) { + return new Dimension(scrollBarWidth, scrollBarWidth * 3 + 16); + } else { + return new Dimension(scrollBarWidth * 3 + 16, scrollBarWidth); + } + } + } + + protected Dimension getMinimumThumbSize() { + return new Dimension(scrollBarWidth, scrollBarWidth); + } + + protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds) { + int w = c.getWidth(); + int h = c.getHeight(); + if (AbstractLookAndFeel.getTheme().isMacStyleScrollBarOn()) { + Color bc = ColorHelper.darker(AbstractLookAndFeel.getTheme().getBackgroundColor(), 4); + g.setColor(bc); + g.fillRect(0, 0, w, h); + } else { + if (scrollbar.getOrientation() == JScrollBar.VERTICAL) { + JTattooUtilities.fillVerGradient(g, AbstractLookAndFeel.getTheme().getTrackColors(), 0, 0, w, h); + } else { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getTrackColors(), 0, 0, w, h); + } + } + } + + protected Color[] getThumbColors() { + if (isRollover || isDragging) { + return AbstractLookAndFeel.getTheme().getRolloverColors(); + } else if (!JTattooUtilities.isActive(scrollbar)) { + return AbstractLookAndFeel.getTheme().getInActiveColors(); + } else { + return AbstractLookAndFeel.getTheme().getThumbColors(); + } + } + + protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) { + if (!c.isEnabled()) { + return; + } + + g.translate(thumbBounds.x, thumbBounds.y); + + Color colors[] = getThumbColors(); + + Color frameColorHi = ColorHelper.brighter(colors[1], 20); + Color frameColorLo = ColorHelper.darker(colors[colors.length - 1], 10); + + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + if (scrollbar.getOrientation() == JScrollBar.VERTICAL) { + JTattooUtilities.fillVerGradient(g, colors, 1, 1, thumbBounds.width - 1, thumbBounds.height - 1); + JTattooUtilities.draw3DBorder(g, frameColorLo, ColorHelper.darker(frameColorLo, 15), 0, 0, thumbBounds.width, thumbBounds.height); + + g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f)); + g.setColor(frameColorHi); + g.drawLine(1, 1, thumbBounds.width - 2, 1); + g.drawLine(1, 1, 1, thumbBounds.height - 2); + + if (!AbstractLookAndFeel.getTheme().isMacStyleScrollBarOn()) { + int dx = 5; + int dy = thumbBounds.height / 2 - 3; + int dw = thumbBounds.width - 11; + + Color c1 = Color.white; + Color c2 = Color.darkGray; + + for (int i = 0; i < 4; i++) { + g.setColor(c1); + g.drawLine(dx, dy, dx + dw, dy); + dy++; + g.setColor(c2); + g.drawLine(dx, dy, dx + dw, dy); + dy++; + } + } + g2D.setComposite(savedComposite); + } else { // HORIZONTAL + JTattooUtilities.fillHorGradient(g, colors, 1, 1, thumbBounds.width - 1, thumbBounds.height - 1); + JTattooUtilities.draw3DBorder(g, frameColorLo, ColorHelper.darker(frameColorLo, 10), 0, 0, thumbBounds.width, thumbBounds.height); + + g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f)); + g.setColor(frameColorHi); + g.drawLine(1, 1, thumbBounds.width - 2, 1); + g.drawLine(1, 1, 1, thumbBounds.height - 2); + + if (!AbstractLookAndFeel.getTheme().isMacStyleScrollBarOn()) { + int dx = thumbBounds.width / 2 - 3; + int dy = 5; + int dh = thumbBounds.height - 11; + + Color c1 = Color.white; + Color c2 = Color.darkGray; + + for (int i = 0; i < 4; i++) { + g.setColor(c1); + g.drawLine(dx, dy, dx, dy + dh); + dx++; + g.setColor(c2); + g.drawLine(dx, dy, dx, dy + dh); + dx++; + } + } + } + g2D.setComposite(savedComposite); + + g.translate(-thumbBounds.x, -thumbBounds.y); + } + + protected void layoutVScrollbar(JScrollBar sb) { + if (AbstractLookAndFeel.getTheme().isLinuxStyleScrollBarOn() && incrButton.isVisible() && decrButton.isVisible()) { + Dimension sbSize = sb.getSize(); + Insets sbInsets = sb.getInsets(); + int sizeH = sbSize.height - sbInsets.top - sbInsets.bottom; + + /* + * Width and left edge of the buttons and thumb. + */ + int itemX = sbInsets.left; + int itemW = sbSize.width - (sbInsets.left + sbInsets.right); + int itemH = Math.min(itemW, sizeH / 2); + + /* Nominal locations of the buttons, assuming their preferred + * size will fit. + */ + int decrButtonY = sbSize.height - sbInsets.bottom - itemH - itemH + 1; + int incrButtonY = sbSize.height - sbInsets.bottom - itemH; + + /* Compute the height and origin of the thumb. The case + * where the thumb is at the bottom edge is handled specially + * to avoid numerical problems in computing thumbY. Enforce + * the thumbs min/max dimensions. If the thumb doesn't + * fit in the track (trackH) we'll hide it later. + */ + float trackH = sbSize.height - sbInsets.top - sbInsets.bottom - itemW - itemW + 1; + float min = sb.getMinimum(); + float max = sb.getMaximum(); + float extent = sb.getVisibleAmount(); + float range = max - min; + float value = sb.getValue(); + + int maxThumbH = getMaximumThumbSize().height; + int minThumbH = getMinimumThumbSize().height; + int thumbH = (range <= 0) ? maxThumbH : (int) (trackH * (extent / range)); + thumbH = Math.max(thumbH, minThumbH); + thumbH = Math.min(thumbH, maxThumbH); + + int thumbY = decrButtonY - thumbH; + if (value < (max - extent)) { + float thumbRange = trackH - thumbH; + thumbY = (int) (0.5f + (thumbRange * ((value - min) / (range - extent)))); + } + + /* If the thumb isn't going to fit, zero it's bounds. Otherwise + * make sure it fits between the buttons. Note that setting the + * thumbs bounds will cause a repaint. + */ + if (thumbH > trackH) { + setThumbBounds(0, 0, 0, 0); + } else { + setThumbBounds(itemX, thumbY, itemW, thumbH); + } + decrButton.setBounds(itemX, decrButtonY, itemW, itemH); + incrButton.setBounds(itemX, incrButtonY, itemW, itemH); + + /* Update the trackRect field. + */ + trackRect.setBounds(itemX, 0, itemW, (int)trackH); + + } else { + super.layoutVScrollbar(sb); + } + } + + protected void layoutHScrollbar(JScrollBar sb) { + if (AbstractLookAndFeel.getTheme().isLinuxStyleScrollBarOn() && incrButton.isVisible() && decrButton.isVisible()) { + Dimension sbSize = sb.getSize(); + Insets sbInsets = sb.getInsets(); + int sizeW = sbSize.width - sbInsets.left - sbInsets.right; + + /* + * Height and top edge of the buttons and thumb. + */ + int itemY = sbInsets.top; + int itemH = sbSize.height - (sbInsets.top + sbInsets.bottom);//Math.min(itemW, sizeH / 2); + int itemW = Math.min(itemH, sizeW / 2);//sbSize.width - (sbInsets.left + sbInsets.right); + + /* Nominal locations of the buttons, assuming their preferred + * size will fit. + */ + int decrButtonX = sbSize.width - sbInsets.right - itemW - itemW + 1; + int incrButtonX = sbSize.width - sbInsets.right - itemW; + + /* Compute the width and origin of the thumb. The case + * where the thumb is at the right edge is handled specially + * to avoid numerical problems in computing thumbX. Enforce + * the thumbs min/max dimensions. If the thumb doesn't + * fit in the track (trackW) we'll hide it later. + */ + float trackW = sbSize.width - sbInsets.left - sbInsets.right - itemH - itemH + 1; + float min = sb.getMinimum(); + float max = sb.getMaximum(); + float extent = sb.getVisibleAmount(); + float range = max - min; + float value = sb.getValue(); + + int maxThumbW = getMaximumThumbSize().width; + int minThumbW = getMinimumThumbSize().width; + int thumbW = (range <= 0) ? maxThumbW : (int) (trackW * (extent / range)); + thumbW = Math.max(thumbW, minThumbW); + thumbW = Math.min(thumbW, maxThumbW); + + int thumbX = decrButtonX - thumbW; + if (value < (max - extent)) { + float thumbRange = trackW - thumbW; + thumbX = (int) (0.5f + (thumbRange * ((value - min) / (range - extent)))); + } + + /* If the thumb isn't going to fit, zero it's bounds. Otherwise + * make sure it fits between the buttons. Note that setting the + * thumbs bounds will cause a repaint. + */ + if (thumbW > trackW) { + setThumbBounds(0, 0, 0, 0); + } else { + setThumbBounds(thumbX, itemY, thumbW, itemH); + } + decrButton.setBounds(decrButtonX, itemY, itemW, itemH); + incrButton.setBounds(incrButtonX, itemY, itemW, itemH); + + /* Update the trackRect field. + */ + trackRect.setBounds(0, itemY, (int)trackW, itemH); + + } else { + super.layoutHScrollbar(sb); + } + } + +//----------------------------------------------------------------------------- +// inner classes +//----------------------------------------------------------------------------- + protected class MyTrackListener extends TrackListener { + + public void mouseEntered(MouseEvent e) { + super.mouseEntered(e); + isRollover = true; + Rectangle r = getTrackBounds(); + scrollbar.repaint(r.x, r.y, r.width, r.height); + } + + public void mouseExited(MouseEvent e) { + super.mouseExited(e); + isRollover = false; + Rectangle r = getTrackBounds(); + scrollbar.repaint(r.x, r.y, r.width, r.height); + } + + public void mousePressed(MouseEvent e) { + super.mousePressed(e); + Rectangle r = getTrackBounds(); + scrollbar.repaint(r.x, r.y, r.width, r.height); + } + + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + Rectangle r = getTrackBounds(); + scrollbar.repaint(r.x, r.y, r.width, r.height); + } + } + +//----------------------------------------------------------------------------- + private static class InvisibleScrollButton extends JButton { + + public InvisibleScrollButton() { + super(); + setVisible(false); + } + + public Dimension getPreferredSize() { + return new Dimension(0, 0); + } + + } +} diff --git a/src/com/jtattoo/plaf/BaseScrollButton.java b/src/com/jtattoo/plaf/BaseScrollButton.java new file mode 100644 index 0000000..57d8300 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseScrollButton.java @@ -0,0 +1,127 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import javax.swing.Icon; +import javax.swing.plaf.basic.BasicArrowButton; + +/** + * @author Michael Hagen + */ +public class BaseScrollButton extends BasicArrowButton { + + protected int buttonWidth = 24; + + public BaseScrollButton(int direction, int width) { + super(direction); + buttonWidth = width; + } + + public void paint(Graphics g) { + boolean isPressed = getModel().isPressed(); + boolean isRollover = getModel().isRollover(); + + int width = getWidth(); + int height = getHeight(); + + Color colors[]; + if (isPressed) { + colors = AbstractLookAndFeel.getTheme().getPressedColors(); + } else if (isRollover) { + colors = AbstractLookAndFeel.getTheme().getRolloverColors(); + } else { + colors = AbstractLookAndFeel.getTheme().getButtonColors(); + } + + boolean inverse = ColorHelper.getGrayValue(colors) < 128; + + Color frameColorHi = ColorHelper.brighter(colors[0], 20); + Color frameColorLo = ColorHelper.darker(colors[colors.length - 1], 20); + + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + if ((getDirection() == NORTH) || (getDirection() == SOUTH)) { + JTattooUtilities.fillVerGradient(g2D, colors, 0, 0, width, height); + } else { + JTattooUtilities.fillHorGradient(g2D, colors, 0, 0, width, height); + } + g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f)); + if (getDirection() == NORTH) { + Icon upArrow = inverse ? BaseIcons.getUpArrowInverseIcon() : BaseIcons.getUpArrowIcon(); + int x = (width / 2) - (upArrow.getIconWidth() / 2); + int y = (height / 2) - (upArrow.getIconHeight() / 2) - 1; + upArrow.paintIcon(this, g2D, x, y); + } else if (getDirection() == SOUTH) { + Icon downArrow = inverse ? BaseIcons.getDownArrowInverseIcon() : BaseIcons.getDownArrowIcon(); + int x = (width / 2) - (downArrow.getIconWidth() / 2); + int y = (height / 2) - (downArrow.getIconHeight() / 2); + downArrow.paintIcon(this, g2D, x, y); + } else if (getDirection() == WEST) { + Icon leftArrow = inverse ? BaseIcons.getLeftArrowInverseIcon() : BaseIcons.getLeftArrowIcon(); + int x = (width / 2) - (leftArrow.getIconWidth() / 2) - 1; + int y = (height / 2) - (leftArrow.getIconHeight() / 2); + leftArrow.paintIcon(this, g2D, x, y); + } else { + Icon rightArrow = inverse ? BaseIcons.getRightArrowInverseIcon() : BaseIcons.getRightArrowIcon(); + int x = (width / 2) - (rightArrow.getIconWidth() / 2); + int y = (height / 2) - (rightArrow.getIconHeight() / 2); + rightArrow.paintIcon(this, g2D, x, y); + } + JTattooUtilities.draw3DBorder(g2D, frameColorLo, ColorHelper.darker(frameColorLo, 10), 0, 0, width, height); + g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f)); + g2D.setColor(frameColorHi); + g2D.drawLine(1, 1, width - 2, 1); + g2D.drawLine(1, 1, 1, height - 2); + + g2D.setComposite(savedComposite); + } + + public Dimension getPreferredSize() { + if (getDirection() == NORTH) { + return new Dimension(buttonWidth, buttonWidth + 1); + } else if (getDirection() == SOUTH) { + return new Dimension(buttonWidth, buttonWidth + 1); + } else if (getDirection() == EAST) { + return new Dimension(buttonWidth + 1, buttonWidth); + } else if (getDirection() == WEST) { + return new Dimension(buttonWidth + 1, buttonWidth); + } else { + return new Dimension(0, 0); + } + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + public Dimension getMaximumSize() { + return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + } + + public int getButtonWidth() { + return buttonWidth; + } +} + diff --git a/src/com/jtattoo/plaf/BaseScrollPaneUI.java b/src/com/jtattoo/plaf/BaseScrollPaneUI.java new file mode 100644 index 0000000..b925d30 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseScrollPaneUI.java @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicScrollPaneUI; + +/** + * @author Michael Hagen + */ +public class BaseScrollPaneUI extends BasicScrollPaneUI { + + public static ComponentUI createUI(JComponent c) { + return new BaseScrollPaneUI(); + } + +} diff --git a/src/com/jtattoo/plaf/BaseSeparatorUI.java b/src/com/jtattoo/plaf/BaseSeparatorUI.java new file mode 100644 index 0000000..bd73a93 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseSeparatorUI.java @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.JPopupMenu; +import javax.swing.JSeparator; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicSeparatorUI; + +/** + * @author Michael Hagen + */ +public class BaseSeparatorUI extends BasicSeparatorUI { + + private static final Dimension size = new Dimension(2, 3); + + public static ComponentUI createUI(JComponent c) { + return new BaseSeparatorUI(); + } + + public void paint(Graphics g, JComponent c) { + boolean horizontal = true; + if (c instanceof JSeparator) { + horizontal = (((JSeparator) c).getOrientation() == JSeparator.HORIZONTAL); + } + Color background = (c instanceof JPopupMenu.Separator) ? AbstractLookAndFeel.getMenuBackgroundColor() : AbstractLookAndFeel.getBackgroundColor(); + if (horizontal) { + int w = c.getWidth(); + g.setColor(background); + g.drawLine(0, 0, w, 0); + g.setColor(ColorHelper.darker(background, 30)); + g.drawLine(0, 1, w, 1); + g.setColor(ColorHelper.brighter(background, 50)); + g.drawLine(0, 2, w, 2); + } else { + int h = c.getHeight(); + g.setColor(ColorHelper.darker(background, 30)); + g.drawLine(0, 0, 0, h); + g.setColor(ColorHelper.brighter(background, 50)); + g.drawLine(1, 0, 1, h); + } + } + + public Dimension getPreferredSize(JComponent c) { + return size; + } +} + + + + diff --git a/src/com/jtattoo/plaf/BaseSliderUI.java b/src/com/jtattoo/plaf/BaseSliderUI.java new file mode 100644 index 0000000..8cde2e1 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseSliderUI.java @@ -0,0 +1,377 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.event.MouseEvent; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JSlider; +import javax.swing.UIManager; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicSliderUI; + +/** + * @author Michael Hagen + */ +public class BaseSliderUI extends BasicSliderUI { + + protected boolean isRollover = false; + + public BaseSliderUI(JSlider slider) { + super(slider); + } + + public static ComponentUI createUI(JComponent c) { + return new BaseSliderUI((JSlider) c); + } + + public TrackListener createTrackListener(JSlider slider) { + return new MyTrackListener(); + } + + public Icon getThumbHorIcon() { + if (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel) { + return ((AbstractLookAndFeel) UIManager.getLookAndFeel()).getIconFactory().getThumbHorIcon(); + } + return null; + } + + public Icon getThumbHorIconRollover() { + if (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel) { + return ((AbstractLookAndFeel) UIManager.getLookAndFeel()).getIconFactory().getThumbHorIconRollover(); + } + return null; + } + + public Icon getThumbVerIcon() { + if (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel) { + return ((AbstractLookAndFeel) UIManager.getLookAndFeel()).getIconFactory().getThumbVerIcon(); + } + return null; + } + + public Icon getThumbVerIconRollover() { + if (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel) { + return ((AbstractLookAndFeel) UIManager.getLookAndFeel()).getIconFactory().getThumbVerIconRollover(); + } + return null; + } + + protected int getTrackWidth() { + if (slider.getOrientation() == JSlider.HORIZONTAL) { + return (thumbRect.height - 9); + } else { + return (thumbRect.width - 9); + } + } + + protected Dimension getThumbSize() { + Dimension size = super.getThumbSize(); + if ((getThumbHorIcon() != null) && (getThumbVerIcon() != null)) { + if (slider.getOrientation() == JSlider.HORIZONTAL) { + size.width = getThumbHorIcon().getIconWidth(); + size.height = getThumbHorIcon().getIconHeight(); + } else { + size.width = getThumbVerIcon().getIconWidth(); + size.height = getThumbVerIcon().getIconHeight(); + } + } + return size; + } + + public void paint(Graphics g, JComponent c) { + paintBackground(g, c); + recalculateIfInsetsChanged(); + recalculateIfOrientationChanged(); + Rectangle clip = g.getClipBounds(); + + if ( !clip.intersects(trackRect) && slider.getPaintTrack()) { + calculateGeometry(); + } + + if (slider.getPaintTrack() && clip.intersects(trackRect)) { + paintTrack(g); + } + if (slider.getPaintTicks() && clip.intersects(tickRect)) { + paintTicks(g); + } + if (slider.getPaintLabels() && clip.intersects(labelRect)) { + paintLabels(g); + } + if (slider.hasFocus() && clip.intersects(focusRect)) { + paintFocus(g); + } + if (clip.intersects(thumbRect)) { + paintThumb(g); + } + } + + public void paintBackground(Graphics g, JComponent c) { + if (c.isOpaque()) { + if (c.getBackground() instanceof ColorUIResource) { + g.setColor(AbstractLookAndFeel.getBackgroundColor()); + } else { + g.setColor(c.getBackground()); + } + g.fillRect(0, 0, c.getWidth(), c.getHeight()); + } + } + + public void paintTrack(Graphics g) { + boolean leftToRight = JTattooUtilities.isLeftToRight(slider); + + g.translate(trackRect.x, trackRect.y); + int overhang = 4; + int trackLeft = 0; + int trackTop = 0; + int trackRight; + int trackBottom; + + if (slider.getOrientation() == JSlider.HORIZONTAL) { + trackBottom = (trackRect.height - 1) - overhang; + trackTop = trackBottom - (getTrackWidth() - 1); + trackRight = trackRect.width - 1; + } else { + if (leftToRight) { + trackLeft = (trackRect.width - overhang) - getTrackWidth(); + trackRight = (trackRect.width - overhang) - 1; + } else { + trackLeft = overhang; + trackRight = overhang + getTrackWidth() - 1; + } + trackBottom = trackRect.height - 1; + } + + g.setColor(AbstractLookAndFeel.getFrameColor()); + g.drawRect(trackLeft, trackTop, (trackRight - trackLeft) - 1, (trackBottom - trackTop) - 1); + + int middleOfThumb; + int fillTop; + int fillLeft; + int fillBottom; + int fillRight; + + if (slider.getOrientation() == JSlider.HORIZONTAL) { + middleOfThumb = thumbRect.x + (thumbRect.width / 2); + middleOfThumb -= trackRect.x; + fillTop = trackTop + 1; + fillBottom = trackBottom - 2; + + if (!drawInverted()) { + fillLeft = trackLeft + 1; + fillRight = middleOfThumb; + } else { + fillLeft = middleOfThumb; + fillRight = trackRight - 2; + } + Color colors[]; + if (!JTattooUtilities.isActive(slider)) { + colors = AbstractLookAndFeel.getTheme().getInActiveColors(); + } else { + if (slider.isEnabled()) { + colors = AbstractLookAndFeel.getTheme().getSliderColors(); + } else { + colors = AbstractLookAndFeel.getTheme().getDisabledColors(); + } + } + JTattooUtilities.fillHorGradient(g, colors, fillLeft + 2, fillTop + 2, fillRight - fillLeft - 2, fillBottom - fillTop - 2); + Color cHi = ColorHelper.darker(colors[colors.length - 1], 5); + Color cLo = ColorHelper.darker(colors[colors.length - 1], 10); + JTattooUtilities.draw3DBorder(g, cHi, cLo, fillLeft + 1, fillTop + 1, fillRight - fillLeft - 1, fillBottom - fillTop - 1); + } else { + middleOfThumb = thumbRect.y + (thumbRect.height / 2); + middleOfThumb -= trackRect.y; + fillLeft = trackLeft + 1; + fillRight = trackRight - 2; + + if (!drawInverted()) { + fillTop = middleOfThumb; + fillBottom = trackBottom - 2; + } else { + fillTop = trackTop + 1; + fillBottom = middleOfThumb; + } + Color colors[]; + if (!JTattooUtilities.isActive(slider)) { + colors = AbstractLookAndFeel.getTheme().getInActiveColors(); + } else { + if (slider.isEnabled()) { + colors = AbstractLookAndFeel.getTheme().getSliderColors(); + } else { + colors = AbstractLookAndFeel.getTheme().getDisabledColors(); + } + } + JTattooUtilities.fillVerGradient(g, colors, fillLeft + 2, fillTop + 2, fillRight - fillLeft - 2, fillBottom - fillTop - 2); + Color cHi = ColorHelper.darker(colors[colors.length - 1], 5); + Color cLo = ColorHelper.darker(colors[colors.length - 1], 10); + JTattooUtilities.draw3DBorder(g, cHi, cLo, fillLeft + 1, fillTop + 1, fillRight - fillLeft - 1, fillBottom - fillTop - 1); + } + g.translate(-trackRect.x, -trackRect.y); + } + + public void paintTicks(Graphics g) { + boolean leftToRight = JTattooUtilities.isLeftToRight(slider); + Rectangle tickBounds = tickRect; + g.setColor(slider.getForeground()); + if (slider.getOrientation() == JSlider.HORIZONTAL) { + g.translate(0, tickBounds.y); + + int value = slider.getMinimum(); + int xPos; + + if (slider.getMinorTickSpacing() > 0) { + while (value <= slider.getMaximum()) { + xPos = xPositionForValue(value); + paintMinorTickForHorizSlider(g, tickBounds, xPos); + value += slider.getMinorTickSpacing(); + } + } + + if (slider.getMajorTickSpacing() > 0) { + value = slider.getMinimum(); + while (value <= slider.getMaximum()) { + xPos = xPositionForValue(value); + paintMajorTickForHorizSlider(g, tickBounds, xPos); + value += slider.getMajorTickSpacing(); + } + } + + g.translate(0, -tickBounds.y); + } else { + g.translate(tickBounds.x, 0); + + int value = slider.getMinimum(); + int yPos; + + if (slider.getMinorTickSpacing() > 0) { + int offset = 0; + if (!leftToRight) { + offset = tickBounds.width - tickBounds.width / 2; + g.translate(offset, 0); + } + + while (value <= slider.getMaximum()) { + yPos = yPositionForValue(value); + paintMinorTickForVertSlider(g, tickBounds, yPos); + value += slider.getMinorTickSpacing(); + } + if (!leftToRight) { + g.translate(-offset, 0); + } + } + + if (slider.getMajorTickSpacing() > 0) { + value = slider.getMinimum(); + if (!leftToRight) { + g.translate(2, 0); + } + + while (value <= slider.getMaximum()) { + yPos = yPositionForValue(value); + paintMajorTickForVertSlider(g, tickBounds, yPos); + value += slider.getMajorTickSpacing(); + } + + if (!leftToRight) { + g.translate(-2, 0); + } + } + g.translate(-tickBounds.x, 0); + } + } + + protected boolean isDragging() { + if (JTattooUtilities.getJavaVersion() >= 1.5) { + return super.isDragging(); + } else { + return false; + } + } + + public void paintThumb(Graphics g) { + Icon icon; + if (slider.getOrientation() == JSlider.HORIZONTAL) { + if ((isRollover || isDragging()) && slider.isEnabled()) { + icon = getThumbHorIconRollover(); + } else { + icon = getThumbHorIcon(); + } + } else { + if ((isRollover || isDragging()) && slider.isEnabled()) { + icon = getThumbVerIconRollover(); + } else { + icon = getThumbVerIcon(); + } + } + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + if (!slider.isEnabled()) { + g.setColor(AbstractLookAndFeel.getBackgroundColor()); + g.fillRect(thumbRect.x + 1, thumbRect.y + 1, thumbRect.width - 2, thumbRect.height - 2); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f); + g2D.setComposite(alpha); + } + icon.paintIcon(null, g, thumbRect.x, thumbRect.y); + g2D.setComposite(savedComposite); + } + + protected class MyTrackListener extends TrackListener { + + public void mouseEntered(MouseEvent e) { + super.mouseEntered(e); + if (slider.isEnabled()) { + isRollover = thumbRect.contains(e.getPoint()); + slider.repaint(); + } + } + + public void mouseMoved(MouseEvent e) { + super.mouseMoved(e); + if (slider.isEnabled()) { + boolean rollover = thumbRect.contains(e.getPoint()); + if (rollover != isRollover) { + isRollover = rollover; + slider.repaint(); + } + } + } + + public void mouseExited(MouseEvent e) { + super.mouseExited(e); + if (slider.isEnabled()) { + isRollover = false; + slider.repaint(); + } + } + + } +} diff --git a/src/com/jtattoo/plaf/BaseSpinnerUI.java b/src/com/jtattoo/plaf/BaseSpinnerUI.java new file mode 100644 index 0000000..2d6dfa2 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseSpinnerUI.java @@ -0,0 +1,265 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicSpinnerUI; + +/** + * + * @author Michael Hagen + */ +public class BaseSpinnerUI extends BasicSpinnerUI { + /** + * Used by the default LayoutManager class - SpinnerLayout for + * missing (null) editor/nextButton/previousButton children. + */ + private static final Dimension zeroSize = new Dimension(0, 0); + + private MyLayoutManager myLayoutManager = null; + + /** + * Returns a new instance of BaseSpinnerUI. SpinnerListUI + * delegates are allocated one per JSpinner. + * + * @param c the JSpinner (not used) + * @see ComponentUI#createUI + * @return a new BasicSpinnerUI object + */ + public static ComponentUI createUI(JComponent c) { + return new BaseSpinnerUI(); + } + + /** + * Create a LayoutManager that manages the editor, + * nextButton, and previousButton + * children of the JSpinner. These three children must be + * added with a constraint that identifies their role: + * "Editor", "Next", and "Previous". The default layout manager + * can handle the absence of any of these children. + * + * @return a LayoutManager for the editor, next button, and previous button. + * @see #createNextButton + * @see #createPreviousButton + * @see #createEditor + */ + protected LayoutManager createLayout() { + if (myLayoutManager == null) { + myLayoutManager = new MyLayoutManager(); + } + return myLayoutManager; + } + + protected Component createNextButton() { + JButton button = new SpinButton(SwingConstants.NORTH); + if (JTattooUtilities.isLeftToRight(spinner)) { + Border border = BorderFactory.createMatteBorder(0, 1, 1, 0, AbstractLookAndFeel.getFrameColor()); + button.setBorder(border); + } else { + Border border = BorderFactory.createMatteBorder(0, 0, 1, 1, AbstractLookAndFeel.getFrameColor()); + button.setBorder(border); + } + installNextButtonListeners(button); + return button; + } + + protected Component createPreviousButton() { + JButton button = new SpinButton(SwingConstants.SOUTH); + if (JTattooUtilities.isLeftToRight(spinner)) { + Border border = BorderFactory.createMatteBorder(0, 1, 0, 0, AbstractLookAndFeel.getFrameColor()); + button.setBorder(border); + } else { + Border border = BorderFactory.createMatteBorder(0, 0, 0, 1, AbstractLookAndFeel.getFrameColor()); + button.setBorder(border); + } + installPreviousButtonListeners(button); + return button; + } + + +//----------------------------------------------------------------------------------------- +// inner classes +//----------------------------------------------------------------------------------------- + public static class SpinButton extends NoFocusButton { + + private static final Dimension minSize = new Dimension(14, 12); + private int direction = SwingConstants.NORTH; + + public SpinButton(int aDirection) { + super(); + setInheritsPopupMenu(true); + direction = aDirection; + } + + public Dimension getPreferredSize() { + Dimension size = super.getPreferredSize(); + size.width = Math.max(size.width, minSize.width); + size.height = Math.max(size.height, minSize.height); + return size; + } + + public void paint(Graphics g) { + Color colors[]; + if (isEnabled()) { + ButtonModel model = getModel(); + if (model.isPressed() && model.isArmed()) { + colors = AbstractLookAndFeel.getTheme().getPressedColors(); + } else { + if (model.isRollover()) + colors = AbstractLookAndFeel.getTheme().getRolloverColors(); + else if (JTattooUtilities.isFrameActive(this)) + colors = AbstractLookAndFeel.getTheme().getButtonColors(); + else + colors = AbstractLookAndFeel.getTheme().getInActiveColors(); + } + } else { + colors = AbstractLookAndFeel.getTheme().getDisabledColors(); + } + JTattooUtilities.fillHorGradient(g, colors, 0, 0, getWidth(), getHeight()); + paintBorder(g); + g.setColor(getForeground()); + int w = 4; + int h = 3; + int x = (getWidth() - w) / 2; + int y = (getHeight() - h) / 2; + if (direction == SwingConstants.NORTH) { + for (int i = 0; i < h; i++) { + g.drawLine(x + (h - i) - 1, y + i, x + w - (h - i) + 1, y + i); + } + } else { + for (int i = 0; i < h; i++) { + g.drawLine(x + i, y + i, x + w - i, y + i); + } + } + } + + } + +//---------------------------------------------------------------------------------------------- +// inner classes +//---------------------------------------------------------------------------------------------- + private static class MyLayoutManager implements LayoutManager { + + private Component nextButton = null; + private Component previousButton = null; + private Component editor = null; + + public void addLayoutComponent(String name, Component c) { + if ("Next".equals(name)) { + nextButton = c; + } else if ("Previous".equals(name)) { + previousButton = c; + } else if ("Editor".equals(name)) { + editor = c; + } + } + + public void removeLayoutComponent(Component c) { + if (c == nextButton) { + nextButton = null; + } else if (c == previousButton) { + previousButton = null; + } else if (c == editor) { + editor = null; + } + } + + private Dimension preferredSize(Component c) { + return (c == null) ? zeroSize : c.getPreferredSize(); + } + + public Dimension preferredLayoutSize(Container parent) { + Dimension nextD = preferredSize(nextButton); + Dimension previousD = preferredSize(previousButton); + Dimension editorD = preferredSize(editor); + + // Force the editors height to be a multiple of 2 + editorD.height = ((editorD.height + 1) / 2) * 2; + + Dimension size = new Dimension(editorD.width, editorD.height); + size.width += Math.max(nextD.width, previousD.width); + Insets insets = parent.getInsets(); + size.width += insets.left + insets.right; + size.height += insets.top + insets.bottom + 4; + return size; + } + + public Dimension minimumLayoutSize(Container parent) { + return preferredLayoutSize(parent); + } + + private void setBounds(Component c, int x, int y, int width, int height) { + if (c != null) { + c.setBounds(x, y, width, height); + } + } + + public void layoutContainer(Container parent) { + int width = parent.getWidth(); + int height = parent.getHeight(); + + Insets insets = parent.getInsets(); + Dimension nextD = preferredSize(nextButton); + Dimension previousD = preferredSize(previousButton); + int buttonsWidth = Math.max(nextD.width, previousD.width); + int editorHeight = height - (insets.top + insets.bottom); + + // The arrowButtonInsets value is used instead of the JSpinner's + // insets if not null. Defining this to be (0, 0, 0, 0) causes the + // buttons to be aligned with the outer edge of the spinner's + // border, and leaving it as "null" places the buttons completely + // inside the spinner's border. + Insets buttonInsets = UIManager.getInsets("Spinner.arrowButtonInsets"); + if (buttonInsets == null) { + buttonInsets = insets; + } + + // Deal with the spinner's componentOrientation property. + int editorX, editorWidth, buttonsX; + if (parent.getComponentOrientation().isLeftToRight()) { + editorX = insets.left; + editorWidth = width - insets.left - buttonsWidth - buttonInsets.right; + buttonsX = width - buttonsWidth - buttonInsets.right; + } else { + buttonsX = buttonInsets.left; + editorX = buttonsX + buttonsWidth; + editorWidth = width - buttonInsets.left - buttonsWidth - insets.right; + } + + int nextY = buttonInsets.top; + int nextHeight = (height / 2) + (height % 2) - nextY; + int previousY = buttonInsets.top + nextHeight; + int previousHeight = height - previousY - buttonInsets.bottom; + + setBounds(editor, editorX, insets.top, editorWidth, editorHeight); + setBounds(nextButton, buttonsX, nextY, buttonsWidth, nextHeight); + setBounds(previousButton, buttonsX, previousY, buttonsWidth, previousHeight); + } + + } + +} diff --git a/src/com/jtattoo/plaf/BaseSplitPaneDivider.java b/src/com/jtattoo/plaf/BaseSplitPaneDivider.java new file mode 100644 index 0000000..2d8d798 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseSplitPaneDivider.java @@ -0,0 +1,330 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.plaf.basic.BasicSplitPaneDivider; +import javax.swing.plaf.basic.BasicSplitPaneUI; + +/** + * @author Michael Hagen + */ +public class BaseSplitPaneDivider extends BasicSplitPaneDivider { + + protected boolean centerOneTouchButtons = true; + protected boolean flatMode = false; + + public BaseSplitPaneDivider(BasicSplitPaneUI ui) { + super(ui); + if (JTattooUtilities.getJavaVersion() >= 1.4) { + if (UIManager.get("SplitPane.centerOneTouchButtons") != null) { + centerOneTouchButtons = UIManager.getBoolean("SplitPane.centerOneTouchButtons"); + } + } + setLayout(new MyDividerLayout()); + Object flatModeProperty = ui.getSplitPane().getClientProperty("flatMode"); + if (flatModeProperty instanceof Boolean) { + flatMode = ((Boolean)flatModeProperty).booleanValue(); + } + } + + public boolean isFlatMode() { + return flatMode; + } + + public void setFlatMode(boolean flatMode) { + this.flatMode = flatMode; + } + + public Border getBorder() { + return null; + } + + public Color getRolloverColor() { + return ColorHelper.darker(AbstractLookAndFeel.getTheme().getRolloverColor(), 16); + } + + public void paint(Graphics g) { + if (!isFlatMode()) { + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + int width = getSize().width; + int height = getSize().height; + int dx = 0; + int dy = 0; + if ((width % 2) == 1) { + dx = 1; + } + if ((height % 2) == 1) { + dy = 1; + } + Color color = AbstractLookAndFeel.getBackgroundColor(); + Color cHi = ColorHelper.brighter(color, 25); + Color cLo = ColorHelper.darker(color, 5); + Color colors[] = ColorHelper.createColorArr(cHi, cLo, 10); + + if (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel) { + AbstractLookAndFeel laf = (AbstractLookAndFeel) UIManager.getLookAndFeel(); + if (orientation == JSplitPane.HORIZONTAL_SPLIT) { + JTattooUtilities.fillVerGradient(g, colors, 0, 0, width, height); + Icon horBumps = laf.getIconFactory().getSplitterHorBumpIcon(); + if ((horBumps != null) && (width > horBumps.getIconWidth())) { + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f); + g2D.setComposite(alpha); + + if (splitPane.isOneTouchExpandable() && centerOneTouchButtons) { + int centerY = height / 2; + int x = (width - horBumps.getIconWidth()) / 2 + dx; + int y = centerY - horBumps.getIconHeight() - 40; + horBumps.paintIcon(this, g, x, y); + y = centerY + 40; + horBumps.paintIcon(this, g, x, y); + } else { + int x = (width - horBumps.getIconWidth()) / 2 + dx; + int y = (height - horBumps.getIconHeight()) / 2; + horBumps.paintIcon(this, g, x, y); + } + } + } else { + JTattooUtilities.fillHorGradient(g, colors, 0, 0, width, height); + Icon verBumps = laf.getIconFactory().getSplitterVerBumpIcon(); + if ((verBumps != null) && (height > verBumps.getIconHeight())) { + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f); + g2D.setComposite(alpha); + if (splitPane.isOneTouchExpandable() && centerOneTouchButtons) { + int centerX = width / 2; + int x = centerX - verBumps.getIconWidth() - 40; + int y = (height - verBumps.getIconHeight()) / 2 + dy; + verBumps.paintIcon(this, g, x, y); + x = centerX + 40; + verBumps.paintIcon(this, g, x, y); + } else { + int x = (width - verBumps.getIconWidth()) / 2; + int y = (height - verBumps.getIconHeight()) / 2 + dy; + verBumps.paintIcon(this, g, x, y); + } + } + } + } + g2D.setComposite(savedComposite); + } + paintComponents(g); + } + + protected JButton createLeftOneTouchButton() { + JButton b = new JButton() { + + public void paint(Graphics g) { + Color color = getBackground(); + int w = getSize().width; + int h = getSize().height; + if (getModel().isPressed() && getModel().isArmed()) { + g.setColor(ColorHelper.darker(color, 40)); + g.fillRect(0, 0, w, h); + } else if (getModel().isRollover()) { + g.setColor(getRolloverColor()); + g.fillRect(0, 0, w, h); + } + Icon icon; + if (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel) { + AbstractLookAndFeel lf = (AbstractLookAndFeel) UIManager.getLookAndFeel(); + if (orientation == JSplitPane.HORIZONTAL_SPLIT) { + icon = lf.getIconFactory().getSplitterLeftArrowIcon(); + } else { + icon = lf.getIconFactory().getSplitterUpArrowIcon(); + } + int x = (w - icon.getIconWidth()) / 2; + int y = (h - icon.getIconHeight()) / 2; + icon.paintIcon(this, g, x, y); + } + if (getModel().isArmed()) { + if (getModel().isPressed()) { + JTattooUtilities.draw3DBorder(g, ColorHelper.darker(color, 30), ColorHelper.brighter(color, 80), 0, 0, w, h); + } else { + JTattooUtilities.draw3DBorder(g, ColorHelper.brighter(color, 80), ColorHelper.darker(color, 30), 0, 0, w, h); + } + } + } + + @SuppressWarnings("deprecation") + public boolean isFocusTraversable() { + return false; + } + }; + b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + b.setFocusPainted(false); + b.setBorderPainted(false); + b.setContentAreaFilled(false); + b.setRolloverEnabled(true); + return b; + } + + protected JButton createRightOneTouchButton() { + JButton b = new JButton() { + + public void paint(Graphics g) { + Color color = getBackground(); + int w = getSize().width; + int h = getSize().height; + if (getModel().isPressed() && getModel().isArmed()) { + g.setColor(ColorHelper.darker(color, 40)); + g.fillRect(0, 0, w, h); + } else if (getModel().isRollover()) { + g.setColor(getRolloverColor()); + g.fillRect(0, 0, w, h); + } + Icon icon; + if (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel) { + AbstractLookAndFeel laf = (AbstractLookAndFeel) UIManager.getLookAndFeel(); + if (orientation == JSplitPane.HORIZONTAL_SPLIT) { + icon = laf.getIconFactory().getSplitterRightArrowIcon(); + } else { + icon = laf.getIconFactory().getSplitterDownArrowIcon(); + } + int x = (w - icon.getIconWidth()) / 2; + int y = (h - icon.getIconHeight()) / 2; + icon.paintIcon(this, g, x, y); + } + if (getModel().isArmed()) { + if (getModel().isPressed()) { + JTattooUtilities.draw3DBorder(g, ColorHelper.darker(color, 30), ColorHelper.brighter(color, 80), 0, 0, w, h); + } else { + JTattooUtilities.draw3DBorder(g, ColorHelper.brighter(color, 80), ColorHelper.darker(color, 30), 0, 0, w, h); + } + } + } + + @SuppressWarnings("deprecation") + public boolean isFocusTraversable() { + return false; + } + }; + b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + b.setFocusPainted(false); + b.setBorderPainted(false); + b.setContentAreaFilled(false); + b.setRolloverEnabled(true); + return b; + } + + /** + * Used to layout a BasicSplitPaneDivider. + * Layout for the divider + * involves appropriately moving the left/right buttons around. + *

+ */ + protected class MyDividerLayout implements LayoutManager { + + public void layoutContainer(Container c) { + if (leftButton != null && rightButton != null && c == BaseSplitPaneDivider.this) { + if (splitPane.isOneTouchExpandable()) { + Insets insets = getInsets(); + int blockSize = 11; + int xOffs = 0; + int yOffs = 0; + if (centerOneTouchButtons) { + blockSize = 13; + xOffs = ((getWidth() - (2 * blockSize)) / 2) - blockSize; + yOffs = ((getHeight() - (2 * blockSize)) / 2) - blockSize; + } + + if (orientation == JSplitPane.VERTICAL_SPLIT) { + int extraX = (insets != null) ? insets.left : 0; + if (insets != null) { + blockSize -= (insets.top + insets.bottom); + blockSize = Math.max(blockSize, 0); + } + int y = (c.getSize().height - blockSize) / 2; + leftButton.setBounds(xOffs + extraX, y, blockSize * 2, blockSize); + rightButton.setBounds(xOffs + extraX + blockSize * 2 + 1, y, blockSize * 2, blockSize); + } else { + int extraY = (insets != null) ? insets.top : 0; + if (insets != null) { + blockSize -= (insets.left + insets.right); + blockSize = Math.max(blockSize, 0); + } + int x = (c.getSize().width - blockSize) / 2; + leftButton.setBounds(x, yOffs + extraY, blockSize, blockSize * 2); + rightButton.setBounds(x, yOffs + extraY + blockSize * 2 + 1, blockSize, blockSize * 2); + } + } else { + leftButton.setBounds(-5, -5, 1, 1); + rightButton.setBounds(-5, -5, 1, 1); + } + } + } + + public Dimension minimumLayoutSize(Container c) { + // NOTE: This isn't really used, refer to + // BasicSplitPaneDivider.getPreferredSize for the reason. + // I leave it in hopes of having this used at some point. + if (c != BaseSplitPaneDivider.this || splitPane == null) { + return new Dimension(0, 0); + } + Dimension buttonMinSize = null; + + if (splitPane.isOneTouchExpandable() && leftButton != null) { + buttonMinSize = leftButton.getMinimumSize(); + } + + Insets insets = getInsets(); + int width = getDividerSize(); + int height = width; + + if (orientation == JSplitPane.VERTICAL_SPLIT) { + if (buttonMinSize != null) { + int size = buttonMinSize.height; + if (insets != null) { + size += insets.top + insets.bottom; + } + height = Math.max(height, size); + } + width = 1; + } else { + if (buttonMinSize != null) { + int size = buttonMinSize.width; + if (insets != null) { + size += insets.left + insets.right; + } + width = Math.max(width, size); + } + height = 1; + } + return new Dimension(width, height); + } + + public Dimension preferredLayoutSize(Container c) { + return minimumLayoutSize(c); + } + + public void removeLayoutComponent(Component c) { + } + + public void addLayoutComponent(String string, Component c) { + } + + } // end class MyDividerLayout +} diff --git a/src/com/jtattoo/plaf/BaseSplitPaneUI.java b/src/com/jtattoo/plaf/BaseSplitPaneUI.java new file mode 100644 index 0000000..0dd9316 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseSplitPaneUI.java @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicSplitPaneDivider; +import javax.swing.plaf.basic.BasicSplitPaneUI; + +/** + * @author Michael Hagen + */ +public class BaseSplitPaneUI extends BasicSplitPaneUI { + + protected PropertyChangeListener myPropertyChangeListener = null; + + public static ComponentUI createUI(JComponent c) { + return new BaseSplitPaneUI(); + } + + protected void installListeners() { + super.installListeners(); + myPropertyChangeListener = new PropertyChangeListener() { + + public void propertyChange(PropertyChangeEvent evt) { + if ("flatMode".equals(evt.getPropertyName()) && evt.getNewValue() instanceof Boolean) { + ((BaseSplitPaneDivider)getDivider()).setFlatMode(((Boolean)evt.getNewValue()).booleanValue()); + } + } + }; + getSplitPane().addPropertyChangeListener(myPropertyChangeListener); + } + + protected void uninstallListeners() { + super.uninstallListeners(); + getSplitPane().removePropertyChangeListener(myPropertyChangeListener); + } + + + public BasicSplitPaneDivider createDefaultDivider() { + return new BaseSplitPaneDivider(this); + } +} diff --git a/src/com/jtattoo/plaf/BaseTabbedPaneUI.java b/src/com/jtattoo/plaf/BaseTabbedPaneUI.java new file mode 100644 index 0000000..47a5fa6 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseTabbedPaneUI.java @@ -0,0 +1,3994 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.*; +import java.awt.geom.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.HashMap; +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.*; +import javax.swing.plaf.basic.BasicGraphicsUtils; +import javax.swing.plaf.basic.BasicHTML; +import javax.swing.text.View; + +/** + * This class is a modified copy of the javax.swing.plaf.basic.BasicTabbedPaneUI + * + * A Basic L&F implementation of TabbedPaneUI. + * + * @version 1.87 06/08/99 + * @author Amy Fowler + * @author Philip Milne + * @author Steve Wilson + * @author Tom Santos + * @author Dave Moore + * @author Michael Hagen + */ +public class BaseTabbedPaneUI extends TabbedPaneUI implements SwingConstants { + + protected static final Insets NULL_BORDER_INSETS = new Insets(0, 0, 0, 0); + protected static final int GAP = 5; + + // Instance variables initialized at installation + protected JTabbedPane tabPane; + protected Color tabAreaBackground; + protected Color selectedColor; + protected int textIconGap; + protected int tabRunOverlay; + protected Insets tabInsets; + protected Insets selectedTabPadInsets; + protected Insets tabAreaInsets; + protected Insets contentBorderInsets; +// Transient variables (recalculated each time TabbedPane is layed out) + protected int tabRuns[] = new int[10]; + protected int runCount = 0; + protected int selectedRun = -1; + protected Rectangle rects[] = new Rectangle[0]; + protected int maxTabHeight; + protected int maxTabWidth; +// Listeners + protected ChangeListener tabChangeListener; + protected ComponentListener tabComponentListener; + protected PropertyChangeListener propertyChangeListener; + protected MouseListener mouseListener; + protected MouseMotionListener mouseMotionListener; + protected FocusListener focusListener; + // PENDING(api): See comment for ContainerHandler + private ContainerListener containerListener; +// Private instance data + private Insets currentPadInsets = new Insets(0, 0, 0, 0); + private Insets currentTabAreaInsets = new Insets(0, 0, 0, 0); + private Component visibleComponent; + // PENDING(api): See comment for ContainerHandler + private ArrayList htmlViews; + private HashMap mnemonicToIndexMap; + /** + * InputMap used for mnemonics. Only non-null if the JTabbedPane has + * mnemonics associated with it. Lazily created in initMnemonics. + */ + private InputMap mnemonicInputMap; + // For use when tabLayoutPolicy = SCROLL_TAB_LAYOUT + private ScrollableTabSupport tabScroller; + private TabContainer tabContainer; + /** + * A rectangle used for general layout calculations in order + * to avoid constructing many new Rectangles on the fly. + */ + protected transient Rectangle calcRect = new Rectangle(0, 0, 0, 0); + /** + * Number of tabs. When the count differs, the mnemonics are updated. + */ + // PENDING: This wouldn't be necessary if JTabbedPane had a better + // way of notifying listeners when the count changed. + private int tabCount; + protected int oldRolloverIndex = -1; + protected int rolloverIndex = -1; + protected boolean roundedTabs = true; + protected boolean simpleButtonBorder = false; + + public static ComponentUI createUI(JComponent c) { + return new BaseTabbedPaneUI(); + } + + // UI Installation/De-installation + public void installUI(JComponent c) { + this.tabPane = (JTabbedPane) c; + c.setLayout(createLayoutManager()); + installComponents(); + installDefaults(); + installListeners(); + installKeyboardActions(); + } + + public void uninstallUI(JComponent c) { + uninstallKeyboardActions(); + uninstallListeners(); + uninstallDefaults(); + uninstallComponents(); + c.setLayout(null); + + this.tabPane = null; + } + + /** + * Invoked by installUI to create + * a layout manager object to manage + * the JTabbedPane. + * + * @return a layout manager object + * + * @see TabbedPaneLayout + * @see javax.swing.JTabbedPane#getTabLayoutPolicy + */ + protected LayoutManager createLayoutManager() { + if (JTattooUtilities.getJavaVersion() >= 1.4) { + if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT) { + return new TabbedPaneScrollLayout(); + } + } + /* WRAP_TAB_LAYOUT */ + return new TabbedPaneLayout(); + } + + /* In an attempt to preserve backward compatibility for programs + * which have extended BaseTabbedPaneUI to do their own layout, the + * UI uses the installed layoutManager (and not tabLayoutPolicy) to + * determine if scrollTabLayout is enabled. + */ + protected boolean scrollableTabLayoutEnabled() { + return (tabPane.getLayout() instanceof TabbedPaneScrollLayout); + } + + /** + * Creates and installs any required subcomponents for the JTabbedPane. + * Invoked by installUI. + * + * @since 1.4 + */ + protected void installComponents() { + if (scrollableTabLayoutEnabled()) { + if (tabScroller == null) { + tabScroller = new ScrollableTabSupport(tabPane.getTabPlacement()); + tabPane.add(tabScroller.viewport); + tabPane.add(tabScroller.scrollForwardButton); + tabPane.add(tabScroller.scrollBackwardButton); + tabPane.add(tabScroller.popupMenuButton); + tabScroller.tabPanel.setBackground(tabAreaBackground); + } + } + installTabContainer(); + } + + private Component getTabComponentAt(int index) { + if (JTattooUtilities.getJavaVersion() >= 1.6) { + return tabPane.getTabComponentAt(index); + } + return null; + } + + private void installTabContainer() { + if (JTattooUtilities.getJavaVersion() >= 1.6) { + for (int i = 0; i < tabPane.getTabCount(); i++) { + Component tabComponent = getTabComponentAt(i); + if (tabComponent != null) { + if (tabContainer == null) { + tabContainer = new TabContainer(); + } + tabContainer.add(tabComponent); + addMyPropertyChangeListeners(tabComponent); + } + } + if (tabContainer == null) { + return; + } + if (scrollableTabLayoutEnabled()) { + tabScroller.tabPanel.add(tabContainer); + } else { + tabPane.add(tabContainer); + } + } + } + + /** + * Removes any installed subcomponents from the JTabbedPane. + * Invoked by uninstallUI. + * + * @since 1.4 + */ + protected void uninstallComponents() { + uninstallTabContainer(); + if (scrollableTabLayoutEnabled()) { + tabPane.remove(tabScroller.viewport); + tabPane.remove(tabScroller.scrollForwardButton); + tabPane.remove(tabScroller.scrollBackwardButton); + tabPane.remove(tabScroller.popupMenuButton); + tabScroller = null; + } + } + + private void addMyPropertyChangeListeners(Component component) { + component.addPropertyChangeListener(new MyTabComponentListener()); + if (component instanceof Container) { + Container container = (Container) component; + for (int i = 0; i < container.getComponentCount(); i++) { + Component c = container.getComponent(i); + addMyPropertyChangeListeners(c); + } + } + } + + private void removeMyPropertyChangeListeners(Component component) { + PropertyChangeListener[] listeners = component.getPropertyChangeListeners(); + for (int i = 0; i < listeners.length; i++) { + if (listeners[i] instanceof MyTabComponentListener) { + component.removePropertyChangeListener(listeners[i]); + } + } + if (component instanceof Container) { + Container container = (Container) component; + for (int i = 0; i < container.getComponentCount(); i++) { + Component c = container.getComponent(i); + removeMyPropertyChangeListeners(c); + } + } + } + + private void uninstallTabContainer() { + if (JTattooUtilities.getJavaVersion() >= 1.6) { + if (tabContainer == null) { + return; + } + // Remove all the tabComponents, making sure not to notify the tabbedpane. + tabContainer.notifyTabbedPane = false; + for (int i = 0; i < tabContainer.getComponentCount(); i++) { + Component c = tabContainer.getComponent(i); + removeMyPropertyChangeListeners(c); + } + tabContainer.removeAll(); + if (scrollableTabLayoutEnabled()) { + tabScroller.tabPanel.remove(tabContainer); + } else { + tabPane.remove(tabContainer); + } + tabContainer = null; + } + } + + protected void installDefaults() { + LookAndFeel.installColorsAndFont(tabPane, "TabbedPane.background", "TabbedPane.foreground", "TabbedPane.font"); + tabAreaBackground = UIManager.getColor("TabbedPane.tabAreaBackground"); + selectedColor = UIManager.getColor("TabbedPane.selected"); + textIconGap = UIManager.getInt("TabbedPane.textIconGap"); + tabInsets = UIManager.getInsets("TabbedPane.tabInsets"); + selectedTabPadInsets = UIManager.getInsets("TabbedPane.selectedTabPadInsets"); + tabAreaInsets = UIManager.getInsets("TabbedPane.tabAreaInsets"); + contentBorderInsets = UIManager.getInsets("TabbedPane.contentBorderInsets"); + tabRunOverlay = UIManager.getInt("TabbedPane.tabRunOverlay"); + tabPane.setBorder(UIManager.getBorder("TabbedPane.boder")); + } + + protected void uninstallDefaults() { + tabInsets = null; + selectedTabPadInsets = null; + tabAreaInsets = null; + contentBorderInsets = null; + } + + protected void installListeners() { + if ((propertyChangeListener = createPropertyChangeListener()) != null) { + tabPane.addPropertyChangeListener(propertyChangeListener); + } + if ((tabChangeListener = createChangeListener()) != null) { + tabPane.addChangeListener(tabChangeListener); + } + if ((tabComponentListener = createComponentListener()) != null) { + tabPane.addComponentListener(tabComponentListener); + } + if ((mouseListener = createMouseListener()) != null) { + if (scrollableTabLayoutEnabled()) { + tabScroller.tabPanel.addMouseListener(mouseListener); + + } else { // WRAP_TAB_LAYOUT + tabPane.addMouseListener(mouseListener); + } + } + if ((mouseMotionListener = createMouseMotionListener()) != null) { + if (scrollableTabLayoutEnabled()) { + tabScroller.tabPanel.addMouseMotionListener(mouseMotionListener); + + } else { // WRAP_TAB_LAYOUT + tabPane.addMouseMotionListener(mouseMotionListener); + } + } + if ((focusListener = createFocusListener()) != null) { + tabPane.addFocusListener(focusListener); + } + // PENDING(api) : See comment for ContainerHandler + containerListener = new ContainerHandler(); + tabPane.addContainerListener(containerListener); + if (tabPane.getTabCount() > 0) { + htmlViews = createHTMLViewList(); + } + } + + protected void uninstallListeners() { + if (mouseListener != null) { + if (scrollableTabLayoutEnabled()) { + // SCROLL_TAB_LAYOUT + tabScroller.tabPanel.removeMouseListener(mouseListener); + } else { + // WRAP_TAB_LAYOUT + tabPane.removeMouseListener(mouseListener); + } + mouseListener = null; + } + if (mouseMotionListener != null) { + if (scrollableTabLayoutEnabled()) { + // SCROLL_TAB_LAYOUT + tabScroller.tabPanel.removeMouseMotionListener(mouseMotionListener); + } else { + // WRAP_TAB_LAYOUT + tabPane.removeMouseMotionListener(mouseMotionListener); + } + mouseMotionListener = null; + } + if (focusListener != null) { + tabPane.removeFocusListener(focusListener); + focusListener = null; + } + + // PENDING(api): See comment for ContainerHandler + if (containerListener != null) { + tabPane.removeContainerListener(containerListener); + containerListener = null; + if (htmlViews != null) { + htmlViews.clear(); + htmlViews = null; + } + } + if (tabChangeListener != null) { + tabPane.removeChangeListener(tabChangeListener); + tabChangeListener = null; + } + if (tabComponentListener != null) { + tabPane.removeComponentListener(tabComponentListener); + tabChangeListener = null; + } + if (propertyChangeListener != null) { + tabPane.removePropertyChangeListener(propertyChangeListener); + propertyChangeListener = null; + } + } + + protected MouseListener createMouseListener() { + return new MouseHandler(); + } + + protected MouseMotionListener createMouseMotionListener() { + return new MouseMotionHandler(); + } + + protected FocusListener createFocusListener() { + return new FocusHandler(); + } + + protected ChangeListener createChangeListener() { + return new TabSelectionHandler(); + } + + protected ComponentListener createComponentListener() { + return new TabComponentHandler(); + } + + protected PropertyChangeListener createPropertyChangeListener() { + return new PropertyChangeHandler(); + } + + protected void installKeyboardActions() { + InputMap km = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, km); + km = getInputMap(JComponent.WHEN_FOCUSED); + SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_FOCUSED, km); + ActionMap am = getActionMap(); + SwingUtilities.replaceUIActionMap(tabPane, am); + if (scrollableTabLayoutEnabled()) { + tabScroller.scrollForwardButton.setAction(am.get("scrollTabsForwardAction")); + tabScroller.scrollBackwardButton.setAction(am.get("scrollTabsBackwardAction")); + tabScroller.popupMenuButton.setAction(am.get("scrollTabsPopupMenuAction")); + } + } + + InputMap getInputMap(int condition) { + if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) { + return (InputMap) UIManager.get("TabbedPane.ancestorInputMap"); + } else if (condition == JComponent.WHEN_FOCUSED) { + return (InputMap) UIManager.get("TabbedPane.focusInputMap"); + } + return null; + } + + ActionMap getActionMap() { + ActionMap map = (ActionMap) UIManager.get("TabbedPane.actionMap"); + + if (map == null) { + map = createActionMap(); + if (map != null) { + UIManager.getLookAndFeelDefaults().put("TabbedPane.actionMap", map); + } + } + return map; + } + + ActionMap createActionMap() { + ActionMap map = new ActionMapUIResource(); + map.put("navigateNext", new NextAction()); + map.put("navigatePrevious", new PreviousAction()); + map.put("navigateRight", new RightAction()); + map.put("navigateLeft", new LeftAction()); + map.put("navigateUp", new UpAction()); + map.put("navigateDown", new DownAction()); + map.put("navigatePageUp", new PageUpAction()); + map.put("navigatePageDown", new PageDownAction()); + map.put("requestFocus", new RequestFocusAction()); + map.put("requestFocusForVisibleComponent", new RequestFocusForVisibleAction()); + map.put("setSelectedIndex", new SetSelectedIndexAction()); + map.put("scrollTabsForwardAction", new ScrollTabsForwardAction()); + map.put("scrollTabsBackwardAction", new ScrollTabsBackwardAction()); + map.put("scrollTabsPopupMenuAction", new ScrollTabsPopupMenuAction()); + return map; + } + + protected void uninstallKeyboardActions() { + SwingUtilities.replaceUIActionMap(tabPane, null); + SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null); + SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_FOCUSED, null); + SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_IN_FOCUSED_WINDOW, null); + } + + /** + * Reloads the mnemonics. This should be invoked when a memonic changes, + * when the title of a mnemonic changes, or when tabs are added/removed. + */ + private void updateMnemonics() { + if (JTattooUtilities.getJavaVersion() >= 1.4) { + resetMnemonics(); + for (int counter = tabPane.getTabCount() - 1; counter >= 0; counter--) { + int mnemonic = tabPane.getMnemonicAt(counter); + if (mnemonic > 0) { + addMnemonic(counter, mnemonic); + } + } + } + } + + /** + * Resets the mnemonics bindings to an empty state. + */ + private void resetMnemonics() { + if (mnemonicToIndexMap != null) { + mnemonicToIndexMap.clear(); + mnemonicInputMap.clear(); + } + } + + /** + * Adds the specified mnemonic at the specified index. + */ + @SuppressWarnings("deprecation") + private void addMnemonic(int index, int mnemonic) { + if (mnemonicToIndexMap == null) { + initMnemonics(); + } + mnemonicInputMap.put(KeyStroke.getKeyStroke(mnemonic, Event.ALT_MASK), "setSelectedIndex"); + mnemonicToIndexMap.put(mnemonic, index); + } + + /** + * Installs the state needed for mnemonics. + */ + private void initMnemonics() { + mnemonicToIndexMap = new HashMap(); +// mnemonicInputMap = new InputMapUIResource(); +// mnemonicInputMap.setParent(SwingUtilities.getUIInputMap(tabPane, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)); +// SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, mnemonicInputMap); + mnemonicInputMap = new ComponentInputMapUIResource(tabPane); + mnemonicInputMap.setParent(SwingUtilities.getUIInputMap(tabPane, JComponent.WHEN_IN_FOCUSED_WINDOW)); + SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_IN_FOCUSED_WINDOW, mnemonicInputMap); + } + + protected boolean isContentOpaque() { + if (!tabPane.isOpaque()) { + if (UIManager.get("TabbedPane.contentOpaque") != null) { + return UIManager.getBoolean("TabbedPane.contentOpaque"); + } + } + return true; + } + + protected boolean isTabOpaque() { + if (!tabPane.isOpaque()) { + if (UIManager.get("TabbedPane.tabsOpaque") != null) { + return UIManager.getBoolean("TabbedPane.tabsOpaque"); + } + } + return true; + } + + protected boolean hasInnerBorder() { + return false; + } + + // colors + protected Color[] getTabColors(int tabIndex, boolean isSelected, boolean isRollover) { + Color colorArr[] = AbstractLookAndFeel.getTheme().getTabColors(); + if ((tabIndex >= 0) && (tabIndex < tabPane.getTabCount())) { + boolean isEnabled = tabPane.isEnabledAt(tabIndex); + Color backColor = tabPane.getBackgroundAt(tabIndex); + if (backColor instanceof UIResource) { + if (isSelected) { + colorArr = AbstractLookAndFeel.getTheme().getSelectedColors(); + } else if (isRollover && isEnabled) { + colorArr = AbstractLookAndFeel.getTheme().getRolloverColors(); + } else { + if (JTattooUtilities.isFrameActive(tabPane)) { + colorArr = AbstractLookAndFeel.getTheme().getTabColors(); + } else { + colorArr = AbstractLookAndFeel.getTheme().getInActiveColors(); + } + } + } else if (backColor != null) { + if (isSelected) { + colorArr = ColorHelper.createColorArr(ColorHelper.brighter(backColor, 60), backColor, 20); + } else if (isRollover && isEnabled) { + colorArr = ColorHelper.createColorArr(ColorHelper.brighter(backColor, 80), ColorHelper.brighter(backColor, 20), 20); + } else { + colorArr = ColorHelper.createColorArr(ColorHelper.brighter(backColor, 40), ColorHelper.darker(backColor, 10), 20); + } + } + } + return colorArr; + } + + protected Color getLoBorderColor(int tabIndex) { + return AbstractLookAndFeel.getControlDarkShadow(); + } + + protected Color getHiBorderColor(int tabIndex) { + Color backColor = tabPane.getBackgroundAt(tabIndex); + if (tabIndex == tabPane.getSelectedIndex()) { + if (backColor instanceof UIResource) { + return AbstractLookAndFeel.getControlHighlight(); + } else { + return ColorHelper.brighter(backColor, 40); + } + } + if (tabIndex >= 0 && tabIndex <= tabCount) { + if (!isTabOpaque() || backColor instanceof UIResource) { + return AbstractLookAndFeel.getControlHighlight(); + } else { + return ColorHelper.brighter(backColor, 40); + } + } + return AbstractLookAndFeel.getControlHighlight(); + } + + protected Color[] getContentBorderColors(int tabPlacement) { + int sepHeight = tabAreaInsets.bottom; + Color selColors[] = AbstractLookAndFeel.getTheme().getSelectedColors(); + Color loColor = selColors[selColors.length - 1]; + Color darkLoColor = ColorHelper.darker(loColor, 20); + return ColorHelper.createColorArr(loColor, darkLoColor, sepHeight); + } + + protected Color getContentBorderColor() { + return AbstractLookAndFeel.getFrameColor(); + } + + protected Color getGapColor(int tabIndex) { + if (isTabOpaque() || tabIndex == tabPane.getSelectedIndex()) { + if ((tabIndex >= 0) && (tabIndex < tabCount)) { + Color tabColors[] = getTabColors(tabIndex, tabIndex == tabPane.getSelectedIndex(), false); + if (tabColors != null && tabColors.length > 0) { + return tabColors[tabColors.length - 1]; + } else { + return tabPane.getBackgroundAt(tabIndex); + } + } + } + if (!tabPane.isOpaque()) { + Container parent = tabPane.getParent(); + while (parent != null) { + if (parent.isOpaque()) { + return parent.getBackground(); + } + parent = parent.getParent(); + } + } + return tabAreaBackground; + } + + // Geometry + public Dimension getPreferredSize(JComponent c) { + // Default to LayoutManager's preferredLayoutSize + return null; + } + + public Dimension getMinimumSize(JComponent c) { + // Default to LayoutManager's minimumLayoutSize + return null; + } + + public Dimension getMaximumSize(JComponent c) { + // Default to LayoutManager's maximumLayoutSize + return null; + } + + // UI Rendering + public void paint(Graphics g, JComponent c) { + int tc = tabPane.getTabCount(); + if (tabCount != tc) { + tabCount = tc; + updateMnemonics(); + } + + int selectedIndex = tabPane.getSelectedIndex(); + int tabPlacement = tabPane.getTabPlacement(); + + ensureCurrentLayout(); + + // Paint content border + paintContentBorder(g, tabPlacement, selectedIndex, 0, 0, c.getWidth(), c.getHeight()); + + // Paint tab area + // If scrollable tabs are enabled, the tab area will be + // painted by the scrollable tab panel instead. + // + if (!scrollableTabLayoutEnabled()) { + // WRAP_TAB_LAYOUT + paintTabArea(g, tabPlacement, selectedIndex); + } + } + + /** + * Paints the tabs in the tab area. + * Invoked by paint(). + * The graphics parameter must be a valid Graphics + * object. Tab placement may be either: + * JTabbedPane.TOP, JTabbedPane.BOTTOM, + * JTabbedPane.LEFT, or JTabbedPane.RIGHT. + * The selected index must be a valid tabbed pane tab index (0 to + * tab count - 1, inclusive) or -1 if no tab is currently selected. + * The handling of invalid parameters is unspecified. + * + * @param g the graphics object to use for rendering + * @param tabPlacement the placement for the tabs within the JTabbedPane + * @param selectedIndex the tab index of the selected component + * + * @since 1.4 + */ + protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) { + int tc = tabPane.getTabCount(); + Rectangle iconRect = new Rectangle(), textRect = new Rectangle(); + Shape savedClip = g.getClip(); + Rectangle clipRect = g.getClipBounds(); + // Dirty trick to fix clipping problem + if (scrollableTabLayoutEnabled() && tabScroller.scrollBackwardButton.isVisible()) { + if ((tabPlacement == TOP) || (tabPlacement == BOTTOM)) { + g.setClip(clipRect.x, clipRect.y, clipRect.width + 1, clipRect.height); + } else { + g.setClip(clipRect.x, clipRect.y, clipRect.width, clipRect.height + 1); + } + } + // Paint tabRuns of tabs from back to front + for (int i = runCount - 1; i >= 0; i--) { + int start = tabRuns[i]; + int next = tabRuns[(i == runCount - 1) ? 0 : i + 1]; + int end = (next != 0 ? next - 1 : tc - 1); + for (int j = start; j <= end; j++) { + if (rects[j].intersects(clipRect)) { + paintTab(g, tabPlacement, rects, j, iconRect, textRect); + } + } + } + + // Paint selected tab if its in the front run + // since it may overlap other tabs + if ((selectedIndex >= 0) && (selectedIndex < rects.length) && getRunForTab(tc, selectedIndex) == 0) { + if (rects[selectedIndex].intersects(clipRect)) { + paintTab(g, tabPlacement, rects, selectedIndex, iconRect, textRect); + } + } + g.setClip(savedClip); + } + + protected Font getTabFont(boolean isSelected) { + return tabPane.getFont(); + } + + protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect) { + Rectangle tabRect = rects[tabIndex]; + int selectedIndex = tabPane.getSelectedIndex(); + boolean isSelected = selectedIndex == tabIndex; + Graphics2D g2D = null; + Polygon cropShape = null; + Shape savedClip = null; + int cropx = 0; + int cropy = 0; + + if (scrollableTabLayoutEnabled()) { + if (g instanceof Graphics2D) { + g2D = (Graphics2D) g; + + // Render visual for cropped tab edge... + Rectangle viewRect = tabScroller.viewport.getViewRect(); + int cropline; + switch (tabPlacement) { + case LEFT: + case RIGHT: + cropline = viewRect.y + viewRect.height; + if ((tabRect.y < cropline) && (tabRect.y + tabRect.height > cropline)) { + cropShape = createCroppedTabClip(tabPlacement, tabRect, cropline); + cropx = tabRect.x; + cropy = cropline - 1; + } + break; + case TOP: + case BOTTOM: + default: + cropline = viewRect.x + viewRect.width; + if ((tabRect.x < cropline) && (tabRect.x + tabRect.width > cropline)) { + cropShape = createCroppedTabClip(tabPlacement, tabRect, cropline); + cropx = cropline - 1; + cropy = tabRect.y; + } + } + if (cropShape != null) { + savedClip = g2D.getClip(); + g2D.clip(cropShape); + } + } + } + + paintTabBackground(g, tabPlacement, tabIndex, tabRect.x, tabRect.y, tabRect.width, tabRect.height, isSelected); + paintTabBorder(g, tabPlacement, tabIndex, tabRect.x, tabRect.y, tabRect.width, tabRect.height, isSelected); + + try { + boolean doPaintContent = getTabComponentAt(tabIndex) == null; + if (doPaintContent) { + String title = tabPane.getTitleAt(tabIndex); + Font font = getTabFont(isSelected); + FontMetrics fm = JTattooUtilities.getFontMetrics(tabPane, g, font); + Icon icon = getIconForTab(tabIndex); + + layoutLabel(tabPlacement, fm, tabIndex, title, icon, tabRect, iconRect, textRect, isSelected); + paintText(g, tabPlacement, font, fm, tabIndex, title, textRect, isSelected); + paintIcon(g, tabPlacement, tabIndex, icon, iconRect, isSelected); + } + paintFocusIndicator(g, tabPlacement, rects, tabIndex, iconRect, textRect, isSelected); + } catch (Exception ex) { + } + + if (cropShape != null) { + paintCroppedTabEdge(g, tabPlacement, tabIndex, cropx, cropy); + if (g2D != null && savedClip != null) { + g2D.setClip(savedClip); + } + } + } + /* This method will create and return a polygon shape for the given tab rectangle + * which has been cropped at the specified cropline with a torn edge visual. + * e.g. A "File" tab which has cropped been cropped just after the "i": + * ------------- + * | ..... | + * | . | + * | ... . | + * | . . | + * | . . | + * | . . | + * -------------- + * + * The x, y arrays below define the pattern used to create a "torn" edge + * segment which is repeated to fill the edge of the tab. + * For tabs placed on TOP and BOTTOM, this righthand torn edge is created by + * line segments which are defined by coordinates obtained by + * subtracting xCropLen[i] from (tab.x + tab.width) and adding yCroplen[i] + * to (tab.y). + * For tabs placed on LEFT or RIGHT, the bottom torn edge is created by + * subtracting xCropLen[i] from (tab.y + tab.height) and adding yCropLen[i] + * to (tab.x). + */ + private int xCropLen[] = {1, 1, 0, 0, 1, 1, 2, 2}; + private int yCropLen[] = {0, 3, 3, 6, 6, 9, 9, 12}; + private static final int CROP_SEGMENT = 12; + + private Polygon createCroppedTabClip(int tabPlacement, Rectangle tabRect, int cropline) { + int rlen; + int start; + int end; + int ostart; + + switch (tabPlacement) { + case LEFT: + case RIGHT: + rlen = tabRect.width; + start = tabRect.x; + end = tabRect.x + tabRect.width; + ostart = tabRect.y; + break; + case TOP: + case BOTTOM: + default: + rlen = tabRect.height; + start = tabRect.y; + end = tabRect.y + tabRect.height; + ostart = tabRect.x; + } + int rcnt = rlen / CROP_SEGMENT; + if (rlen % CROP_SEGMENT > 0) { + rcnt++; + } + int npts = 2 + (rcnt * 8); + int xp[] = new int[npts]; + int yp[] = new int[npts]; + int pcnt = 0; + + xp[pcnt] = ostart; + yp[pcnt++] = end; + xp[pcnt] = ostart; + yp[pcnt++] = start; + for (int i = 0; i < rcnt; i++) { + for (int j = 0; j < xCropLen.length; j++) { + xp[pcnt] = cropline - xCropLen[j]; + yp[pcnt] = start + (i * CROP_SEGMENT) + yCropLen[j]; + if (yp[pcnt] >= end) { + yp[pcnt] = end; + pcnt++; + break; + } + pcnt++; + } + } + if (tabPlacement == JTabbedPane.TOP || tabPlacement == JTabbedPane.BOTTOM) { + return new Polygon(xp, yp, pcnt); + } else { + // LEFT or RIGHT + return new Polygon(yp, xp, pcnt); + } + } + + /* If tabLayoutPolicy == SCROLL_TAB_LAYOUT, this method will paint an edge + * indicating the tab is cropped in the viewport display + */ + private void paintCroppedTabEdge(Graphics g, int tabPlacement, int tabIndex, int x, int y) { + g.setColor(Color.gray); + switch (tabPlacement) { + case LEFT: + case RIGHT: + int xx = x; + while (xx <= x + rects[tabIndex].width) { + for (int i = 0; i < xCropLen.length; i += 2) { + g.drawLine(xx + yCropLen[i], y - xCropLen[i], xx + yCropLen[i + 1] - 1, y - xCropLen[i + 1]); + } + xx += CROP_SEGMENT; + } + break; + case TOP: + case BOTTOM: + default: + int yy = y; + while (yy <= y + rects[tabIndex].height) { + for (int i = 0; i < xCropLen.length; i += 2) { + g.drawLine(x - xCropLen[i], yy + yCropLen[i], x - xCropLen[i + 1], yy + yCropLen[i + 1] - 1); + } + yy += CROP_SEGMENT; + } + } + } + + protected void layoutLabel(int tabPlacement, FontMetrics metrics, + int tabIndex, String title, Icon icon, Rectangle tabRect, + Rectangle iconRect, Rectangle textRect, boolean isSelected) { + textRect.x = textRect.y = iconRect.x = iconRect.y = 0; + View v = getTextViewForTab(tabIndex); + if (v != null) { + tabPane.putClientProperty("html", v); + } + + SwingUtilities.layoutCompoundLabel((JComponent) tabPane, + metrics, title, icon, + SwingUtilities.CENTER, + SwingUtilities.CENTER, + SwingUtilities.CENTER, + SwingUtilities.TRAILING, + tabRect, + iconRect, + textRect, + textIconGap); + + tabPane.putClientProperty("html", null); + + int xNudge = getTabLabelShiftX(tabPlacement, tabIndex, isSelected); + int yNudge = getTabLabelShiftY(tabPlacement, tabIndex, isSelected); + iconRect.x += xNudge; + iconRect.y += yNudge; + textRect.x += xNudge; + textRect.y += yNudge; + } + + protected int getTabLabelShiftX(int tabPlacement, int tabIndex, boolean isSelected) { + return 0; + } + + protected int getTabLabelShiftY(int tabPlacement, int tabIndex, boolean isSelected) { + if (!isSelected) { + if (tabPlacement == TOP) { + return 1; + } else if (tabPlacement == BOTTOM) { + return -1; + } + } + return 0; + } + + protected void paintIcon(Graphics g, int tabPlacement, int tabIndex, Icon icon, Rectangle iconRect, boolean isSelected) { + if (icon != null) { + icon.paintIcon(tabPane, g, iconRect.x, iconRect.y); + } + } + + protected void paintText(Graphics g, int tabPlacement, Font font, FontMetrics metrics, int tabIndex, String title, Rectangle textRect, boolean isSelected) { + g.setFont(font); + View v = getTextViewForTab(tabIndex); + if (v != null) { + // html + Graphics2D g2D = (Graphics2D) g; + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + v.paint(g, textRect); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } else { + // plain text + int mnemIndex = -1; + if (JTattooUtilities.getJavaVersion() >= 1.4) { + mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex); + } + + if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex)) { + if (isSelected) { + Color backColor = tabPane.getBackgroundAt(tabIndex); + if (backColor instanceof UIResource) { + g.setColor(AbstractLookAndFeel.getTabSelectionForegroundColor()); + } else { + g.setColor(tabPane.getForegroundAt(tabIndex)); + } + } else { + if (tabIndex == rolloverIndex) { + g.setColor(AbstractLookAndFeel.getTheme().getRolloverForegroundColor()); + } else { + g.setColor(tabPane.getForegroundAt(tabIndex)); + } + } + JTattooUtilities.drawStringUnderlineCharAt(tabPane, g, title, mnemIndex, textRect.x, textRect.y + metrics.getAscent()); + + } else { // tab disabled + g.setColor(tabPane.getBackgroundAt(tabIndex).brighter()); + JTattooUtilities.drawStringUnderlineCharAt(tabPane, g, title, mnemIndex, textRect.x, textRect.y + metrics.getAscent()); + g.setColor(tabPane.getBackgroundAt(tabIndex).darker()); + JTattooUtilities.drawStringUnderlineCharAt(tabPane, g, title, mnemIndex, textRect.x - 1, textRect.y + metrics.getAscent() - 1); + } + } + } + + protected void paintFocusIndicator(Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect, boolean isSelected) { + if (tabPane.isRequestFocusEnabled() && tabPane.hasFocus() && isSelected && tabIndex >= 0 && textRect.width > 8) { + g.setColor(AbstractLookAndFeel.getTheme().getFocusColor()); + BasicGraphicsUtils.drawDashedRect(g, textRect.x - 4, textRect.y + 1, textRect.width + 8, textRect.height); + } + } + + /** + * this function draws the border around each tab + * note that this function does now draw the background of the tab. + * that is done elsewhere + */ + protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) { + int x2 = x + (w); + int y2 = y + (h); + switch (tabPlacement) { + case LEFT: + paintLeftTabBorder(tabIndex, g, x, y, x2, y2, isSelected); + break; + case RIGHT: + paintRightTabBorder(tabIndex, g, x, y, x2, y2, isSelected); + break; + case BOTTOM: + if (roundedTabs) { + paintRoundedBottomTabBorder(tabIndex, g, x, y, x2, y2 - 1, isSelected); + } else { + paintBottomTabBorder(tabIndex, g, x, y, x2, y2 - 1, isSelected); + } + break; + case TOP: + default: + if (roundedTabs) { + paintRoundedTopTabBorder(tabIndex, g, x, y, x2, y2, isSelected); + } else { + paintTopTabBorder(tabIndex, g, x, y, x2, y2, isSelected); + } + } + } + + protected void paintRoundedTopTabBorder(int tabIndex, Graphics g, int x1, int y1, int x2, int y2, boolean isSelected) { + Graphics2D g2D = (Graphics2D) g; + Object savedRederingHint = g2D.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + Color borderColor = getLoBorderColor(tabIndex); + g.setColor(borderColor); + int d = 2 * GAP; + if (isSelected) { + g.drawLine(x1 + GAP, y1, x2 - GAP, y1); + g.drawArc(x1, y1, d, d, 90, 90); + g.drawArc(x2 - d, y1, d, d, 0, 90); + g.drawLine(x1, y1 + GAP + 1, x1, y2); + g.drawLine(x2, y1 + GAP + 1, x2, y2); + } else { + g.drawLine(x1 + GAP, y1, x2 - GAP, y1); + g.drawArc(x1, y1, d, d, 90, 90); + g.drawArc(x2 - d, y1, d, d, 0, 90); + g.drawLine(x1, y1 + GAP + 1, x1, y2 - 1); + g.drawLine(x2, y1 + GAP + 1, x2, y2 - 1); + } + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, savedRederingHint); + } + + protected void paintTopTabBorder(int tabIndex, Graphics g, int x1, int y1, int x2, int y2, boolean isSelected) { + int tc = tabPane.getTabCount(); + int currentRun = getRunForTab(tc, tabIndex); + int lastIndex = lastTabInRun(tc, currentRun); + int firstIndex = tabRuns[currentRun]; + boolean leftToRight = JTattooUtilities.isLeftToRight(tabPane); + + Color loColor = getLoBorderColor(tabIndex); + Color hiColor = getHiBorderColor(tabIndex); + + g.setColor(loColor); + g.drawLine(x1 + GAP, y1, x2, y1); + g.drawLine(x1 + GAP, y1, x1, y1 + GAP); + g.drawLine(x1, y1 + GAP + 1, x1, y2); + g.drawLine(x2, y1, x2, y2); + g.setColor(hiColor); + g.drawLine(x1 + GAP + 1, y1 + 1, x2 - 1, y1 + 1); + g.drawLine(x1 + GAP + 1, y1 + 1, x1 + 1, y1 + GAP + 1); + g.drawLine(x1 + 1, y1 + GAP + 1, x1 + 1, y2 - 1); + + // paint gap + int gapTabIndex = getTabAtLocation(x1 + 2, y1 - 2); + Color gapColor = getGapColor(gapTabIndex); + g.setColor(gapColor); + for (int i = 0; i < GAP; i++) { + g.drawLine(x1, y1 + i, x1 + GAP - i - 1, y1 + i); + } + + if (leftToRight) { + if ((tabIndex != firstIndex) || (currentRun != (runCount - 1))) { + g.setColor(loColor); + g.drawLine(x1, y1, x1, y1 + GAP); + } + if (!isSelected && (tabIndex == firstIndex) && (currentRun != (runCount - 1))) { + g.setColor(hiColor); + g.drawLine(x1 + 1, y1, x1 + 1, y1 + GAP - 2); + } + } else { + if ((tabIndex != lastIndex) || (currentRun != (runCount - 1))) { + g.setColor(loColor); + g.drawLine(x1, y1, x1, y1 + GAP); + } + } + } + + protected void paintLeftTabBorder(int tabIndex, Graphics g, int x1, int y1, int x2, int y2, boolean isSelected) { + Graphics2D g2D = (Graphics2D)g; + + int tc = tabPane.getTabCount(); + int currentRun = getRunForTab(tc, tabIndex); + int lastIndex = lastTabInRun(tc, currentRun); + int firstIndex = tabRuns[currentRun]; + + Color loColor = getLoBorderColor(tabIndex); + Color hiColor = getHiBorderColor(tabIndex); + + g.setColor(hiColor); + Composite savedComposite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f); + g2D.setComposite(alpha); + g.drawLine(x1 + GAP + 1, y1 + 1, x2 - 1, y1 + 1); + g.drawLine(x1 + GAP, y1 + 1, x1 + 1, y1 + GAP); + g.drawLine(x1 + 1, y1 + GAP + 1, x1 + 1, y2 - 1); + g2D.setComposite(savedComposite); + + g.setColor(loColor); + g.drawLine(x1 + GAP, y1, x2 - 1, y1); + g.drawLine(x1 + GAP, y1, x1, y1 + GAP); + g.drawLine(x1, y1 + GAP, x1, y2); + g.drawLine(x1 + GAP, y2, x2 - 1, y2); + if (tabIndex == lastIndex) { + g.drawLine(x1, y2, x1 + GAP, y2); + } + // paint gap + int gapTabIndex = getTabAtLocation(x1 + 2, y1 - 2); + Color gapColor = getGapColor(gapTabIndex); + g.setColor(gapColor); + for (int i = 0; i < GAP; i++) { + g.drawLine(x1, y1 + i, x1 + GAP - i - 1, y1 + i); + } + + if ((tabIndex != firstIndex) || (currentRun != (runCount - 1))) { + loColor = getLoBorderColor(gapTabIndex); + g.setColor(loColor); + g.drawLine(x1, y1, x1, y1 + GAP - 1); + if (tabIndex != firstIndex) { + g2D.setComposite(alpha); + hiColor = getHiBorderColor(gapTabIndex); + g.setColor(hiColor); + g.drawLine(x1 + 1, y1, x1 + 1, y1 + GAP - 2); + g2D.setComposite(savedComposite); + } + } + } + + protected void paintRoundedBottomTabBorder(int tabIndex, Graphics g, int x1, int y1, int x2, int y2, boolean isSelected) { + Graphics2D g2D = (Graphics2D) g; + Object savedRederingHint = g2D.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + Color loColor = getLoBorderColor(tabIndex); + int d = 2 * GAP; + g.setColor(loColor); + g.drawLine(x1 + GAP, y2, x2 - GAP, y2); + g.drawArc(x1, y2 - d, d, d, 180, 90); + g.drawArc(x2 - d, y2 - d, d, d, -90, 90); + g.drawLine(x1, y1, x1, y2 - GAP - 1); + g.drawLine(x2, y1, x2, y2 - GAP - 1); + + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, savedRederingHint); + } + + protected void paintBottomTabBorder(int tabIndex, Graphics g, int x1, int y1, int x2, int y2, boolean isSelected) { + int tc = tabPane.getTabCount(); + int currentRun = getRunForTab(tc, tabIndex); + int lastIndex = lastTabInRun(tc, currentRun); + int firstIndex = tabRuns[currentRun]; + boolean leftToRight = JTattooUtilities.isLeftToRight(tabPane); + + Color loColor = getLoBorderColor(tabIndex); + Color hiColor = getHiBorderColor(tabIndex); + + g.setColor(loColor); + g.drawLine(x1, y1, x1, y2 - GAP); + g.drawLine(x1, y2 - GAP, x1 + GAP, y2); + g.drawLine(x1 + GAP, y2, x2, y2); + g.drawLine(x2, y2, x2, y1); + g.setColor(hiColor); + g.drawLine(x1 + 1, y1, x1 + 1, y2 - GAP - 1); + g.drawLine(x1 + 1, y2 - GAP, x1 + GAP, y2 - 1); + + // paint gap + int gapTabIndex = getTabAtLocation(x1 + 2, y2 + 2); + Color gapColor = getGapColor(gapTabIndex); + + g.setColor(gapColor); + for (int i = 0; i < GAP; i++) { + g.drawLine(x1, y2 - i, x1 + GAP - i - 1, y2 - i); + } + if (leftToRight) { + if ((tabIndex != firstIndex) || (currentRun != (runCount - 1))) { + g.setColor(loColor); + g.drawLine(x1, y2 - GAP, x1, y2); + } + } else { + if ((tabIndex != lastIndex) || (currentRun != (runCount - 1))) { + g.setColor(loColor); + g.drawLine(x1, y2 - GAP, x1, y2); + } + } + } + + protected void paintRightTabBorder(int tabIndex, Graphics g, int x1, int y1, int x2, int y2, boolean isSelected) { + Graphics2D g2D = (Graphics2D)g; + + int tc = tabPane.getTabCount(); + int currentRun = getRunForTab(tc, tabIndex); + int lastIndex = lastTabInRun(tc, currentRun); + int firstIndex = tabRuns[currentRun]; + + Color loColor = getLoBorderColor(tabIndex); + Color hiColor = getHiBorderColor(tabIndex); + + Composite savedComposite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f); + g2D.setComposite(alpha); + g.setColor(hiColor); + g.drawLine(x1, y1 + 1, x2 - GAP - 1, y1 + 1); + g.drawLine(x2 - GAP, y1 + 1, x2 - 1, y1 + GAP); + g2D.setComposite(savedComposite); + + g.setColor(loColor); + g.drawLine(x1, y1, x2 - GAP, y1); + g.drawLine(x2 - GAP, y1, x2, y1 + GAP); + g.drawLine(x2, y1 + GAP, x2, y2); + if (tabIndex == lastIndex) { + g.drawLine(x2, y2, x1, y2); + } + + // paint gap + int gapTabIndex = getTabAtLocation(x1 + 2, y1 - 2); + Color gapColor = getGapColor(gapTabIndex); + g.setColor(gapColor); + for (int i = 0; i < GAP; i++) { + g.drawLine(x2 - GAP + i + 1, y1 + i, x2, y1 + i); + } + + if ((tabIndex != firstIndex) || (currentRun != (runCount - 1))) { + loColor = getLoBorderColor(gapTabIndex); + g.setColor(loColor); + g.drawLine(x2, y1, x2, y1 + GAP - 1); + } + } + + protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) { + if (isTabOpaque() || isSelected) { + Graphics2D g2D = (Graphics2D) g; + Shape savedClip = g.getClip(); + Area orgClipArea = new Area(new Rectangle2D.Double(x, y, w, h)); + if (savedClip != null) { + orgClipArea = new Area(savedClip); + } + Color colorArr[] = getTabColors(tabIndex, isSelected, tabIndex == rolloverIndex); + int d = 2 * GAP; + switch (tabPlacement) { + case TOP: + default: + if (isSelected) { + Area clipArea = new Area(new RoundRectangle2D.Double(x, y, w , h + 4, d, d)); + Area rectArea = new Area(new Rectangle2D.Double(x, y, w, h + 2)); + clipArea.intersect(rectArea); + clipArea.intersect(orgClipArea); + g2D.setClip(clipArea); + JTattooUtilities.fillHorGradient(g, colorArr, x, y, w, h + 4); + g2D.setClip(savedClip); + } else { + Area clipArea = new Area(new RoundRectangle2D.Double(x, y, w, h + 4, d, d)); + Area rectArea = new Area(new Rectangle2D.Double(x, y, w, h)); + clipArea.intersect(rectArea); + clipArea.intersect(orgClipArea); + g2D.setClip(clipArea); + JTattooUtilities.fillHorGradient(g, colorArr, x, y, w, h + 4); + g2D.setClip(savedClip); + } + break; + case LEFT: + if (isSelected) { + JTattooUtilities.fillHorGradient(g, colorArr, x + 1, y + 1, w + 1, h - 1); + } else { + JTattooUtilities.fillHorGradient(g, colorArr, x + 1, y + 1, w - 1, h - 1); + } + break; + case BOTTOM: + if (isSelected) { + Area clipArea = new Area(new RoundRectangle2D.Double(x, y - 4, w, h + 4, d, d)); + Area rectArea = new Area(new Rectangle2D.Double(x, y - 2, w, h + 1)); + clipArea.intersect(rectArea); + clipArea.intersect(orgClipArea); + g2D.setClip(clipArea); + JTattooUtilities.fillHorGradient(g, colorArr, x, y - 4, w, h + 4); + g2D.setClip(savedClip); + } else { + Area clipArea = new Area(new RoundRectangle2D.Double(x, y - 4, w, h + 4, d, d)); + Area rectArea = new Area(new Rectangle2D.Double(x, y, w, h)); + clipArea.intersect(rectArea); + clipArea.intersect(orgClipArea); + g2D.setClip(clipArea); + JTattooUtilities.fillHorGradient(g, colorArr, x, y - 4, w, h + 4); + g2D.setClip(savedClip); + } + break; + case RIGHT: + if (isSelected) { + JTattooUtilities.fillHorGradient(g, colorArr, x - 2, y + 1, w + 2, h - 1); + } else { + JTattooUtilities.fillHorGradient(g, colorArr, x, y + 1, w + 1, h - 1); + } + break; + } + } + } + + protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { + int tabAreaHeight = calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight); + int tabAreaWidth = calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth); + + // paint the background + if (tabPane.isOpaque()) { + int xt = tabPlacement == RIGHT ? w - tabAreaWidth : 0; + int yt = tabPlacement == BOTTOM ? h - tabAreaHeight : 0; + int wt = tabPlacement == TOP || tabPlacement == BOTTOM ? w : tabAreaWidth; + int ht = tabPlacement == LEFT || tabPlacement == RIGHT ? h : tabAreaHeight; + g.setColor(tabAreaBackground); + g.fillRect(xt, yt, wt, ht); + } + if (isContentOpaque()) { + int xt = tabPlacement == LEFT ? tabAreaWidth : 0; + int yt = tabPlacement == TOP ? tabAreaHeight : 0; + int wt = tabPlacement == LEFT || tabPlacement == RIGHT ? w - tabAreaWidth : w; + int ht = tabPlacement == TOP || tabPlacement == BOTTOM ? h - tabAreaHeight : h; + g.setColor(tabPane.getBackground()); + g.fillRect(xt, yt, wt, ht); + } + + Insets bi = new Insets(0, 0, 0, 0); + if (tabPane.getBorder() != null) { + bi = tabPane.getBorder().getBorderInsets(tabPane); + } + if (hasInnerBorder()) { + Color loColor = AbstractLookAndFeel.getControlDarkShadow(); + Color hiColor = AbstractLookAndFeel.getControlHighlight(); + g.setColor(loColor); + switch (tabPlacement) { + case TOP: { + int x1 = x + bi.left - 1; + int y1 = y + tabAreaHeight + bi.top - 2; + int x2 = x1 + w - bi.left - bi.right + 1; + int y2 = h - bi.bottom; + int ws = w - bi.left - bi.right + 1; + int hs = h - tabAreaHeight - bi.top - bi.bottom + 2; + + if (tabPane.getBorder() == null) { + g.drawLine(x1, y1, x2, y1); + g.setColor(hiColor); + g.drawLine(x1, y1 + 1, x2, y1 + 1); + } else { + g.drawRect(x1, y1, ws, hs); + g.setColor(hiColor); + g.drawLine(x1 + 1, y1 + 1, x2 - 1, y1 + 1); + } + break; + } + case LEFT: { + int x1 = x + tabAreaWidth + bi.left - 2; + int y1 = y + bi.top - 1; + //int x2 = w - bi.right; + int y2 = y1 + h - bi.top - bi.bottom + 1; + int ws = w - tabAreaWidth - bi.left - bi.right + 2; + int hs = h - bi.top - bi.bottom + 1; + + if (tabPane.getBorder() == null) { + g.drawLine(x1, y1, x1, y2); + g.setColor(hiColor); + g.drawLine(x1 + 1, y1, x1 + 1, y2); + } else { + g.drawRect(x1, y1, ws, hs); + g.setColor(hiColor); + g.drawLine(x1 + 1, y1 + 1, x1 + 1, y2 - 1); + } + break; + } + case BOTTOM: { + int x1 = x + bi.left - 1; + int y1 = y + bi.top - 1; + int x2 = x1 + w - bi.left - bi.right + 1; + int y2 = h - tabAreaHeight - bi.bottom; + int ws = w - bi.left - bi.right + 1; + int hs = h - tabAreaHeight - bi.top - bi.bottom + 2; + + if (tabPane.getBorder() == null) { + g.drawLine(x1, y2, x2, y2); + } else { + g.drawRect(x1, y1, ws, hs); + } + break; + } + case RIGHT: { + int x1 = x + bi.left - 1; + int y1 = y + bi.top - 1; + int x2 = w - tabAreaWidth - bi.right + 1; + int y2 = y1 + h - bi.top - bi.bottom + 1; + int ws = w - tabAreaWidth - bi.left - bi.right + 2; + int hs = h - bi.top - bi.bottom + 1; + + if (tabPane.getBorder() == null) { + g.drawLine(x2, y1, x2, y2); + } else { + g.drawRect(x1, y1, ws, hs); + } + break; + } + } + } else { + int sepHeight = tabAreaInsets.bottom; + if (sepHeight > 0) { + switch (tabPlacement) { + case TOP: { + Color colors[] = getContentBorderColors(tabPlacement); + int ys = y + tabAreaHeight - sepHeight + bi.top; + for (int i = 0; i < colors.length; i++) { + g.setColor(colors[i]); + g.drawLine(x, ys + i, x + w, ys + i); + } + break; + } + case LEFT: { + Color colors[] = getContentBorderColors(tabPlacement); + int xs = x + tabAreaWidth - sepHeight + bi.left; + for (int i = 0; i < colors.length; i++) { + g.setColor(colors[i]); + g.drawLine(xs + i, y, xs + i, y + h); + } + break; + } + case BOTTOM: { + Color colors[] = getContentBorderColors(tabPlacement); + int ys = y + h - tabAreaHeight - bi.bottom; + for (int i = 0; i < colors.length; i++) { + g.setColor(colors[i]); + g.drawLine(x, ys + i, x + w, ys + i); + } + break; + } + case RIGHT: { + Color colors[] = getContentBorderColors(tabPlacement); + int xs = x + w - tabAreaWidth - bi.right; + for (int i = 0; i < colors.length; i++) { + g.setColor(colors[i]); + g.drawLine(xs + i, y, xs + i, y + h); + } + break; + } + } + } + } + } + + protected void paintScrollContentBorder(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { + Insets bi = new Insets(0, 0, 0, 0); + if (tabPane.getBorder() != null) { + bi = tabPane.getBorder().getBorderInsets(tabPane); + } + if (tabPane.getTabPlacement() == TOP) { + paintContentBorder(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex(), x, y - bi.top, w, h); + } else if (tabPane.getTabPlacement() == BOTTOM) { + paintContentBorder(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex(), x, y + bi.bottom, w, h); + } else if (tabPane.getTabPlacement() == LEFT) { + paintContentBorder(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex(), x - bi.left, y, w, h); + } else if (tabPane.getTabPlacement() == RIGHT) { + paintContentBorder(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex(), x + bi.right, y, w, h); + } + } + + // TabbedPaneUI methods + private void ensureCurrentLayout() { + // TabPane maybe still invalid. See bug 4237677. + ((TabbedPaneLayout) tabPane.getLayout()).calculateLayoutInfo(); + } + + /** + * Returns the bounds of the specified tab index. The bounds are + * with respect to the JTabbedPane's coordinate space. + */ + public Rectangle getTabBounds(JTabbedPane pane, int i) { + ensureCurrentLayout(); + Rectangle tabRect = new Rectangle(); + return getTabBounds(i, tabRect); + } + + public int getTabRunCount(JTabbedPane pane) { + ensureCurrentLayout(); + return runCount; + } + + /** + * Returns the tab index which intersects the specified point + * in the JTabbedPane's coordinate space. + */ + public int tabForCoordinate(JTabbedPane pane, int x, int y) { + ensureCurrentLayout(); + Point p = new Point(x, y); + + if (scrollableTabLayoutEnabled()) { + translatePointToTabPanel(x, y, p); + } + int tc = tabPane.getTabCount(); + for (int i = 0; i < tc; i++) { + if (rects[i].contains(p.x, p.y)) { + return i; + } + } + return -1; + } + + /** + * Returns the bounds of the specified tab in the coordinate space + * of the JTabbedPane component. This is required because the tab rects + * are by default defined in the coordinate space of the component where + * they are rendered, which could be the JTabbedPane + * (for WRAP_TAB_LAYOUT) or a ScrollableTabPanel (SCROLL_TAB_LAYOUT). + * This method should be used whenever the tab rectangle must be relative + * to the JTabbedPane itself and the result should be placed in a + * designated Rectangle object (rather than instantiating and returning + * a new Rectangle each time). The tab index parameter must be a valid + * tabbed pane tab index (0 to tab count - 1, inclusive). The destination + * rectangle parameter must be a valid Rectangle instance. + * The handling of invalid parameters is unspecified. + * + * @param tabIndex the index of the tab + * @param dest the rectangle where the result should be placed + * @return the resulting rectangle + * + * @since 1.4 + */ + protected Rectangle getTabBounds(int tabIndex, Rectangle dest) { + dest.width = rects[tabIndex].width; + dest.height = rects[tabIndex].height; + + if (scrollableTabLayoutEnabled()) { // SCROLL_TAB_LAYOUT + // Need to translate coordinates based on viewport location & + // view position + Point vpp = tabScroller.viewport.getLocation(); + Point viewp = tabScroller.viewport.getViewPosition(); + dest.x = rects[tabIndex].x + vpp.x - viewp.x; + dest.y = rects[tabIndex].y + vpp.y - viewp.y; + + } else { // WRAP_TAB_LAYOUT + dest.x = rects[tabIndex].x; + dest.y = rects[tabIndex].y; + } + return dest; + } + + /** + * Returns the tab index which intersects the specified point + * in the coordinate space of the component where the + * tabs are actually rendered, which could be the JTabbedPane + * (for WRAP_TAB_LAYOUT) or a ScrollableTabPanel (SCROLL_TAB_LAYOUT). + */ + protected int getTabAtLocation(int x, int y) { + ensureCurrentLayout(); + int tc = tabPane.getTabCount(); + for (int i = 0; i < tc; i++) { + if (rects[i].contains(x, y)) { + return i; + } + } + return -1; + } + + /** + * Returns the index of the tab closest to the passed in location, note + * that the returned tab may not contain the location x,y. + */ + protected int getClosestTab(int x, int y) { + int min = 0; + int tc = Math.min(rects.length, tabPane.getTabCount()); + int max = tc; + int tabPlacement = tabPane.getTabPlacement(); + boolean useX = (tabPlacement == TOP || tabPlacement == BOTTOM); + int want = (useX) ? x : y; + + while (min != max) { + int current = (max + min) / 2; + int minLoc; + int maxLoc; + + if (useX) { + minLoc = rects[current].x; + maxLoc = minLoc + rects[current].width; + } else { + minLoc = rects[current].y; + maxLoc = minLoc + rects[current].height; + } + if (want < minLoc) { + max = current; + if (min == max) { + return Math.max(0, current - 1); + } + } else if (want >= maxLoc) { + min = current; + if (max - min <= 1) { + return Math.max(current + 1, tc - 1); + } + } else { + return current; + } + } + return min; + } + + /** + * Returns a point which is translated from the specified point in the + * JTabbedPane's coordinate space to the coordinate space of the + * ScrollableTabPanel. This is used for SCROLL_TAB_LAYOUT ONLY. + */ + private Point translatePointToTabPanel(int srcx, int srcy, Point dest) { + Point vpp = tabScroller.viewport.getLocation(); + Point viewp = tabScroller.viewport.getViewPosition(); + dest.x = srcx - vpp.x + viewp.x; + dest.y = srcy - vpp.y + viewp.y; + return dest; + } + + // BaseTabbedPaneUI methods + protected Component getVisibleComponent() { + return visibleComponent; + } + + protected void setVisibleComponent(Component component) { + if (visibleComponent != null && visibleComponent != component && visibleComponent.getParent() == tabPane) { + visibleComponent.setVisible(false); + } + if (component != null && !component.isVisible()) { + component.setVisible(true); + } + visibleComponent = component; + } + + protected void assureRectsCreated(int tabCount) { + int rectArrayLen = rects.length; + if (tabCount != rectArrayLen) { + Rectangle[] tempRectArray = new Rectangle[tabCount]; + System.arraycopy(rects, 0, tempRectArray, 0, Math.min(rectArrayLen, tabCount)); + rects = tempRectArray; + for (int rectIndex = rectArrayLen; rectIndex < tabCount; rectIndex++) { + rects[rectIndex] = new Rectangle(); + } + } + } + + protected void expandTabRunsArray() { + int rectLen = tabRuns.length; + int[] newArray = new int[rectLen + 10]; + System.arraycopy(tabRuns, 0, newArray, 0, runCount); + tabRuns = newArray; + } + + protected int getRunForTab(int tabCount, int tabIndex) { + for (int i = 0; i < runCount; i++) { + int first = tabRuns[i]; + int last = lastTabInRun(tabCount, i); + if (tabIndex >= first && tabIndex <= last) { + return i; + } + } + return 0; + } + + protected int lastTabInRun(int tabCount, int run) { + if (runCount == 1) { + return tabCount - 1; + } + int nextRun = (run == runCount - 1 ? 0 : run + 1); + if (tabRuns[nextRun] == 0) { + return tabCount - 1; + } + return tabRuns[nextRun] - 1; + } + + protected int getTabRunOverlay(int tabPlacement) { + return tabRunOverlay; + } + + protected int getTabRunIndent(int tabPlacement, int run) { + return 0; + } + + protected boolean shouldPadTabRun(int tabPlacement, int run) { + return runCount > 1; + } + + protected boolean shouldRotateTabRuns(int tabPlacement) { + return true; + } + + protected Icon getIconForTab(int tabIndex) { + if (tabIndex >= 0 && tabIndex < tabCount) { + return (!tabPane.isEnabled() || !tabPane.isEnabledAt(tabIndex)) ? tabPane.getDisabledIconAt(tabIndex) : tabPane.getIconAt(tabIndex); + } + return null; + } + + /** + * Returns the text View object required to render stylized text (HTML) for + * the specified tab or null if no specialized text rendering is needed + * for this tab. This is provided to support html rendering inside tabs. + * + * @param tabIndex the index of the tab + * @return the text view to render the tab's text or null if no + * specialized rendering is required + * + * @since 1.4 + */ + protected View getTextViewForTab(int tabIndex) { + if (htmlViews != null && htmlViews.size() > tabIndex) { + return (View) htmlViews.get(tabIndex); + } + return null; + } + + protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight) { + int height = 0; + Component tabComponent = getTabComponentAt(tabIndex); + if (tabComponent != null) { + height = tabComponent.getPreferredSize().height; + } else { + View v = getTextViewForTab(tabIndex); + if (v != null) { + // html + height += (int) v.getPreferredSpan(View.Y_AXIS); + } else { + // plain text + height += fontHeight; + } + Icon icon = getIconForTab(tabIndex); + if (icon != null) { + height = Math.max(height, icon.getIconHeight()); + } + } + Insets ti = getTabInsets(tabPlacement, tabIndex); + height += ti.top + ti.bottom + 2; + return height; + } + + protected int calculateMaxTabHeight(int tabPlacement) { + int tc = tabPane.getTabCount(); + int result = 0; + int fontHeight = getFontMetrics().getHeight(); + for (int i = 0; i < tc; i++) { + result = Math.max(calculateTabHeight(tabPlacement, i, fontHeight), result); + } + return result; + } + + protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics) { + Insets insets = getTabInsets(tabPlacement, tabIndex); + int width = insets.left + insets.right + 3; + Component tabComponent = getTabComponentAt(tabIndex); + if (tabComponent != null) { + width += tabComponent.getPreferredSize().width; + } else { + Icon icon = getIconForTab(tabIndex); + if (icon != null) { + width += icon.getIconWidth() + textIconGap; + } + View v = getTextViewForTab(tabIndex); + if (v != null) { + // html + width += (int) v.getPreferredSpan(View.X_AXIS); + } else { + // plain text + String title = tabPane.getTitleAt(tabIndex); + width += SwingUtilities.computeStringWidth(metrics, title); + } + } + + return width; + } + + protected int calculateMaxTabWidth(int tabPlacement) { + int tc = tabPane.getTabCount(); + int result = 0; + for (int i = 0; i < tc; i++) { + result = Math.max(calculateTabWidth(tabPlacement, i, getFontMetrics()), result); + } + return result; + } + + protected int calculateTabAreaHeight(int tabPlacement, int horizRunCount, int maxTabHeight) { + if (tabPlacement == JTabbedPane.TOP || tabPlacement == JTabbedPane.BOTTOM) { + Insets insets = getTabAreaInsets(tabPlacement); + int overlay = getTabRunOverlay(tabPlacement); + return (horizRunCount > 0 ? horizRunCount * (maxTabHeight - overlay) + overlay + insets.top + insets.bottom : 0); + } else { + return tabPane.getHeight(); + } + } + + protected int calculateTabAreaWidth(int tabPlacement, int vertRunCount, int maxTabWidth) { + if (tabPlacement == JTabbedPane.LEFT || tabPlacement == JTabbedPane.RIGHT) { + Insets insets = getTabAreaInsets(tabPlacement); + int overlay = getTabRunOverlay(tabPlacement); + return (vertRunCount > 0 ? vertRunCount * (maxTabWidth - overlay) + overlay + insets.left + insets.right : 0); + } else { + return tabPane.getWidth(); + } + } + + protected Insets getTabInsets(int tabPlacement, int tabIndex) { + return tabInsets; + } + + protected Insets getSelectedTabPadInsets(int tabPlacement) { + rotateInsets(selectedTabPadInsets, currentPadInsets, tabPlacement); + return currentPadInsets; + } + + protected Insets getTabAreaInsets(int tabPlacement) { + rotateInsets(tabAreaInsets, currentTabAreaInsets, tabPlacement); + return currentTabAreaInsets; + } + + protected Insets getContentBorderInsets(int tabPlacement) { + if (tabPane.getBorder() == null) { + return NULL_BORDER_INSETS; + } + return contentBorderInsets; + } + + protected FontMetrics getFontMetrics() { + Font font = tabPane.getFont().deriveFont(Font.BOLD); + return JTattooUtilities.getFontMetrics(tabPane, null, font); + } + + // Tab Navigation methods + protected void navigateSelectedTab(int direction) { + int tabPlacement = tabPane.getTabPlacement(); + int current = tabPane.getSelectedIndex(); + int tc = tabPane.getTabCount(); + boolean leftToRight = JTattooUtilities.isLeftToRight(tabPane); + + // If we have no tabs then don't navigate. + if (tc <= 0) { + return; + } + + int offset; + switch (tabPlacement) { + case NEXT: + selectNextTab(current); + break; + case PREVIOUS: + selectPreviousTab(current); + break; + case LEFT: + case RIGHT: + switch (direction) { + case NORTH: + selectPreviousTabInRun(current); + break; + case SOUTH: + selectNextTabInRun(current); + break; + case WEST: + offset = getTabRunOffset(tabPlacement, tc, current, false); + selectAdjacentRunTab(tabPlacement, current, offset); + break; + case EAST: + offset = getTabRunOffset(tabPlacement, tc, current, true); + selectAdjacentRunTab(tabPlacement, current, offset); + break; + default: + } + break; + case BOTTOM: + case TOP: + default: + switch (direction) { + case NORTH: + offset = getTabRunOffset(tabPlacement, tc, current, false); + selectAdjacentRunTab(tabPlacement, current, offset); + break; + case SOUTH: + offset = getTabRunOffset(tabPlacement, tc, current, true); + selectAdjacentRunTab(tabPlacement, current, offset); + break; + case EAST: + if (leftToRight) { + selectNextTabInRun(current); + } else { + selectPreviousTabInRun(current); + } + break; + case WEST: + if (leftToRight) { + selectPreviousTabInRun(current); + } else { + selectNextTabInRun(current); + } + break; + default: + } + } + } + + protected void selectNextTabInRun(int current) { + int tc = tabPane.getTabCount(); + int tabIndex = getNextTabIndexInRun(tc, current); + while (tabIndex != current && !tabPane.isEnabledAt(tabIndex)) { + tabIndex = getNextTabIndexInRun(tc, tabIndex); + } + tabPane.setSelectedIndex(tabIndex); + } + + protected void selectPreviousTabInRun(int current) { + int tc = tabPane.getTabCount(); + int tabIndex = getPreviousTabIndexInRun(tc, current); + while (tabIndex != current && !tabPane.isEnabledAt(tabIndex)) { + tabIndex = getPreviousTabIndexInRun(tc, tabIndex); + } + tabPane.setSelectedIndex(tabIndex); + } + + protected void selectNextTab(int current) { + int tabIndex = getNextTabIndex(current); + while (tabIndex != current && !tabPane.isEnabledAt(tabIndex)) { + tabIndex = getNextTabIndex(tabIndex); + } + tabPane.setSelectedIndex(tabIndex); + } + + protected void selectPreviousTab(int current) { + int tabIndex = getPreviousTabIndex(current); + while (tabIndex != current && !tabPane.isEnabledAt(tabIndex)) { + tabIndex = getPreviousTabIndex(tabIndex); + } + tabPane.setSelectedIndex(tabIndex); + } + + protected void selectAdjacentRunTab(int tabPlacement, int tabIndex, int offset) { + if (runCount < 2) { + return; + } + int newIndex; + Rectangle r = rects[tabIndex]; + switch (tabPlacement) { + case LEFT: + case RIGHT: + newIndex = getTabAtLocation(r.x + r.width / 2 + offset, + r.y + r.height / 2); + break; + case BOTTOM: + case TOP: + default: + newIndex = getTabAtLocation(r.x + r.width / 2, + r.y + r.height / 2 + offset); + } + if (newIndex != -1) { + while (!tabPane.isEnabledAt(newIndex) && newIndex != tabIndex) { + newIndex = getNextTabIndex(newIndex); + } + tabPane.setSelectedIndex(newIndex); + } + } + + protected int getTabRunOffset(int tabPlacement, int tabCount, int tabIndex, boolean forward) { + int run = getRunForTab(tabCount, tabIndex); + int offset; + switch (tabPlacement) { + case LEFT: { + if (run == 0) { + offset = (forward ? -(calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth) - maxTabWidth) : -maxTabWidth); + + } else if (run == runCount - 1) { + offset = (forward ? maxTabWidth : calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth) - maxTabWidth); + } else { + offset = (forward ? maxTabWidth : -maxTabWidth); + } + break; + } + case RIGHT: { + if (run == 0) { + offset = (forward ? maxTabWidth : calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth) - maxTabWidth); + } else if (run == runCount - 1) { + offset = (forward ? -(calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth) - maxTabWidth) : -maxTabWidth); + } else { + offset = (forward ? maxTabWidth : -maxTabWidth); + } + break; + } + case BOTTOM: { + if (run == 0) { + offset = (forward ? maxTabHeight : calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight) - maxTabHeight); + } else if (run == runCount - 1) { + offset = (forward ? -(calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight) - maxTabHeight) : -maxTabHeight); + } else { + offset = (forward ? maxTabHeight : -maxTabHeight); + } + break; + } + case TOP: + default: { + if (run == 0) { + offset = (forward ? -(calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight) - maxTabHeight) : -maxTabHeight); + } else if (run == runCount - 1) { + offset = (forward ? maxTabHeight : calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight) - maxTabHeight); + } else { + offset = (forward ? maxTabHeight : -maxTabHeight); + } + } + } + return offset; + } + + protected int getPreviousTabIndex(int base) { + int tabIndex = (base - 1 >= 0 ? base - 1 : tabPane.getTabCount() - 1); + return (tabIndex >= 0 ? tabIndex : 0); + } + + protected int getNextTabIndex(int base) { + return (base + 1) % tabPane.getTabCount(); + } + + protected int getNextTabIndexInRun(int tabCount, int base) { + if (runCount < 2) { + return getNextTabIndex(base); + } + int currentRun = getRunForTab(tabCount, base); + int next = getNextTabIndex(base); + if (next == tabRuns[getNextTabRun(currentRun)]) { + return tabRuns[currentRun]; + } + return next; + } + + protected int getPreviousTabIndexInRun(int tabCount, int base) { + if (runCount < 2) { + return getPreviousTabIndex(base); + } + int currentRun = getRunForTab(tabCount, base); + if (base == tabRuns[currentRun]) { + int previous = tabRuns[getNextTabRun(currentRun)] - 1; + return (previous != -1 ? previous : tabCount - 1); + } + return getPreviousTabIndex(base); + } + + protected int getPreviousTabRun(int baseRun) { + int runIndex = (baseRun - 1 >= 0 ? baseRun - 1 : runCount - 1); + return (runIndex >= 0 ? runIndex : 0); + } + + protected int getNextTabRun(int baseRun) { + return (baseRun + 1) % runCount; + } + + protected static void rotateInsets(Insets topInsets, Insets targetInsets, int targetPlacement) { + switch (targetPlacement) { + case LEFT: + targetInsets.top = topInsets.left; + targetInsets.left = topInsets.top; + targetInsets.bottom = topInsets.right; + targetInsets.right = topInsets.bottom; + break; + case BOTTOM: + targetInsets.top = topInsets.bottom; + targetInsets.left = topInsets.left; + targetInsets.bottom = topInsets.top; + targetInsets.right = topInsets.right; + break; + case RIGHT: + targetInsets.top = topInsets.left; + targetInsets.left = topInsets.bottom; + targetInsets.bottom = topInsets.right; + targetInsets.right = topInsets.top; + break; + case TOP: + default: + targetInsets.top = topInsets.top; + targetInsets.left = topInsets.left; + targetInsets.bottom = topInsets.bottom; + targetInsets.right = topInsets.right; + } + } + + @SuppressWarnings("deprecation") + protected boolean requestFocusForVisibleComponent() { + Component vc = getVisibleComponent(); + if (vc.isFocusTraversable()) { + vc.requestFocus(); + return true; + } else if (vc instanceof JComponent) { + if (((JComponent) vc).requestDefaultFocus()) { + return true; + } + } + return false; + } + + private static class RightAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane = (JTabbedPane) e.getSource(); + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) pane.getUI(); + ui.navigateSelectedTab(EAST); + } + }; + + private static class LeftAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane = (JTabbedPane) e.getSource(); + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) pane.getUI(); + ui.navigateSelectedTab(WEST); + } + }; + + private static class UpAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane = (JTabbedPane) e.getSource(); + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) pane.getUI(); + ui.navigateSelectedTab(NORTH); + } + }; + + private static class DownAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane = (JTabbedPane) e.getSource(); + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) pane.getUI(); + ui.navigateSelectedTab(SOUTH); + } + }; + + private static class NextAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane = (JTabbedPane) e.getSource(); + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) pane.getUI(); + ui.navigateSelectedTab(NEXT); + } + }; + + private static class PreviousAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane = (JTabbedPane) e.getSource(); + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) pane.getUI(); + ui.navigateSelectedTab(PREVIOUS); + } + }; + + private static class PageUpAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane = (JTabbedPane) e.getSource(); + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) pane.getUI(); + int tabPlacement = pane.getTabPlacement(); + if (tabPlacement == TOP || tabPlacement == BOTTOM) { + ui.navigateSelectedTab(WEST); + } else { + ui.navigateSelectedTab(NORTH); + } + } + }; + + private static class PageDownAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane = (JTabbedPane) e.getSource(); + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) pane.getUI(); + int tabPlacement = pane.getTabPlacement(); + if (tabPlacement == TOP || tabPlacement == BOTTOM) { + ui.navigateSelectedTab(EAST); + } else { + ui.navigateSelectedTab(SOUTH); + } + } + }; + + private static class RequestFocusAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane = (JTabbedPane) e.getSource(); + pane.requestFocus(); + } + }; + + private static class RequestFocusForVisibleAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane = (JTabbedPane) e.getSource(); + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) pane.getUI(); + ui.requestFocusForVisibleComponent(); + } + }; + + /** + * Selects a tab in the JTabbedPane based on the String of the + * action command. The tab selected is based on the first tab that + * has a mnemonic matching the first character of the action command. + */ + private static class SetSelectedIndexAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane = (JTabbedPane) e.getSource(); + + if (pane != null && (pane.getUI() instanceof BaseTabbedPaneUI)) { + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) pane.getUI(); + String command = e.getActionCommand(); + + if (command != null && command.length() > 0) { + int mnemonic = (int) e.getActionCommand().charAt(0); + if (mnemonic >= 'a' && mnemonic <= 'z') { + mnemonic -= ('a' - 'A'); + } + Integer index = (Integer) ui.mnemonicToIndexMap.get(mnemonic); + if (index != null && pane.isEnabledAt(index.intValue())) { + pane.setSelectedIndex(index.intValue()); + } + } + } + } + }; + + private static class ScrollTabsForwardAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane; + Object src = e.getSource(); + if (src instanceof JTabbedPane) { + pane = (JTabbedPane) src; + } else if (src instanceof ScrollableTabButton) { + pane = (JTabbedPane) ((ScrollableTabButton) src).getParent(); + } else { + return; // shouldn't happen + } + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) pane.getUI(); + + if (ui.scrollableTabLayoutEnabled()) { + ui.tabScroller.scrollForward(pane.getTabPlacement()); + } + } + } + + private static class ScrollTabsBackwardAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTabbedPane pane; + Object src = e.getSource(); + if (src instanceof JTabbedPane) { + pane = (JTabbedPane) src; + } else if (src instanceof ScrollableTabButton) { + pane = (JTabbedPane) ((ScrollableTabButton) src).getParent(); + } else { + return; // shouldn't happen + } + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) pane.getUI(); + + if (ui.scrollableTabLayoutEnabled()) { + ui.tabScroller.scrollBackward(pane.getTabPlacement()); + } + } + } + + private static class ScrollTabsPopupMenuItemAction extends AbstractAction { + + private JTabbedPane tabbedPane = null; + private int selectIndex = 0; + + public ScrollTabsPopupMenuItemAction(JTabbedPane pane, int index) { + tabbedPane = pane; + selectIndex = index; + } + + public void actionPerformed(ActionEvent e) { + tabbedPane.setSelectedIndex(selectIndex); + } + } + + private static class ScrollTabsPopupMenuAction extends AbstractAction { + + private JTabbedPane tabbedPane = null; + + public void actionPerformed(ActionEvent e) { + Object src = e.getSource(); + if (src instanceof JTabbedPane) { + tabbedPane = (JTabbedPane) src; + } else if (src instanceof ScrollablePopupMenuTabButton) { + tabbedPane = (JTabbedPane) ((ScrollablePopupMenuTabButton) src).getParent(); + } else { + return; // shouldn't happen + } + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) tabbedPane.getUI(); + if (ui.scrollableTabLayoutEnabled()) { + JPopupMenu popup = new JPopupMenu(); + for (int i = 0; i < tabbedPane.getTabCount(); i++) { + JMenuItem item = new JMenuItem(tabbedPane.getTitleAt(i)); + item.addActionListener(new ScrollTabsPopupMenuItemAction(tabbedPane, i)); + item.setEnabled(tabbedPane.isEnabledAt(i)); + popup.add(item); + } + popup.show(ui.tabScroller.popupMenuButton, 0, 0); + Point pt = ui.tabScroller.popupMenuButton.getLocationOnScreen(); + int x = -popup.getWidth() + ui.tabScroller.popupMenuButton.getWidth(); + int y = ui.tabScroller.popupMenuButton.getHeight() - 1; + popup.setLocation(pt.x + x, pt.y + y); + } + } + } + + /** + * This inner class is marked "public" due to a compiler bug. + * This class should be treated as a "protected" inner class. + * Instantiate it only within subclasses of BaseTabbedPaneUI. + */ + public class TabbedPaneLayout implements LayoutManager { + + public void addLayoutComponent(String name, Component comp) { + } + + public void removeLayoutComponent(Component comp) { + } + + public Dimension preferredLayoutSize(Container parent) { + return calculateSize(false); + } + + public Dimension minimumLayoutSize(Container parent) { + return calculateSize(true); + } + + protected Dimension calculateSize(boolean minimum) { + int tabPlacement = tabPane.getTabPlacement(); + Insets insets = tabPane.getInsets(); + Insets contentInsets = getContentBorderInsets(tabPlacement); + Insets tabAreaInsets = getTabAreaInsets(tabPlacement); + + Dimension zeroSize = new Dimension(0, 0); + int height = contentInsets.top + contentInsets.bottom; + int width = contentInsets.left + contentInsets.right; + int cWidth = 0; + int cHeight = 0; + + // Determine minimum size required to display largest + // child in each dimension + // + for (int i = 0; i < tabPane.getTabCount(); i++) { + Component component = tabPane.getComponentAt(i); + if (component != null) { + Dimension size = minimum ? component.getMinimumSize() : component.getPreferredSize(); + if (size != null) { + cHeight = Math.max(size.height, cHeight); + cWidth = Math.max(size.width, cWidth); + } + } + } + // Add content border insets to minimum size + width += cWidth; + height += cHeight; + int tabExtent; + + // Calculate how much space the tabs will need, based on the + // minimum size required to display largest child + content border + // + switch (tabPlacement) { + case LEFT: + case RIGHT: + height = Math.max(height, calculateMaxTabHeight(tabPlacement) + + tabAreaInsets.top + tabAreaInsets.bottom); + tabExtent = preferredTabAreaWidth(tabPlacement, height); + width += tabExtent; + break; + case TOP: + case BOTTOM: + default: + width = Math.max(width, calculateMaxTabWidth(tabPlacement) + + tabAreaInsets.left + tabAreaInsets.right); + tabExtent = preferredTabAreaHeight(tabPlacement, width); + height += tabExtent; + } + return new Dimension(width + insets.left + insets.right, height + insets.bottom + insets.top); + } + + protected int preferredTabAreaHeight(int tabPlacement, int width) { + FontMetrics fm = getFontMetrics(); + int tc = tabPane.getTabCount(); + int total = 0; + if (tc > 0) { + int rows = 1; + int x = 0; + int maxTabHeight = calculateMaxTabHeight(tabPlacement); + + for (int i = 0; i < tc; i++) { + int tabWidth = calculateTabWidth(tabPlacement, i, fm); + + if (x != 0 && x + tabWidth > width) { + rows++; + x = 0; + } + x += tabWidth; + } + total = calculateTabAreaHeight(tabPlacement, rows, maxTabHeight); + } + return total; + } + + protected int preferredTabAreaWidth(int tabPlacement, int height) { + FontMetrics fm = getFontMetrics(); + int tc = tabPane.getTabCount(); + int total = 0; + if (tc > 0) { + int columns = 1; + int y = 0; + int fontHeight = fm.getHeight(); + + maxTabWidth = calculateMaxTabWidth(tabPlacement); + + for (int i = 0; i < tc; i++) { + int tabHeight = calculateTabHeight(tabPlacement, i, fontHeight); + + if (y != 0 && y + tabHeight > height) { + columns++; + y = 0; + } + y += tabHeight; + } + total = calculateTabAreaWidth(tabPlacement, columns, maxTabWidth); + } + return total; + } + + @SuppressWarnings("deprecation") + public void layoutContainer(Container parent) { + /* Some of the code in this method deals with changing the + * visibility of components to hide and show the contents for the + * selected tab. This is older code that has since been duplicated + * in JTabbedPane.fireStateChanged(), so as to allow visibility + * changes to happen sooner (see the note there). This code remains + * for backward compatibility as there are some cases, such as + * subclasses that don't fireStateChanged() where it may be used. + * Any changes here need to be kept in synch with + * JTabbedPane.fireStateChanged(). + */ + + int tabPlacement = tabPane.getTabPlacement(); + Insets insets = tabPane.getInsets(); + int selectedIndex = tabPane.getSelectedIndex(); + Component visibleComponent = getVisibleComponent(); + + calculateLayoutInfo(); + + Component selectedComponent = null; + if (selectedIndex < 0) { + if (visibleComponent != null) { + // The last tab was removed, so remove the component + setVisibleComponent(null); + } + } else { + try { + selectedComponent = tabPane.getComponentAt(selectedIndex); + } catch (Exception ex) { + } + } + int cx, cy, cw, ch; + int totalTabWidth = 0; + int totalTabHeight = 0; + Insets contentInsets = getContentBorderInsets(tabPlacement); + + boolean shouldChangeFocus = false; + + // In order to allow programs to use a single component + // as the display for multiple tabs, we will not change + // the visible compnent if the currently selected tab + // has a null component. This is a bit dicey, as we don't + // explicitly state we support this in the spec, but since + // programs are now depending on this, we're making it work. + // + if (selectedComponent != null) { + if (selectedComponent != visibleComponent && visibleComponent != null) { + if (SwingUtilities.findFocusOwner(visibleComponent) != null) { + shouldChangeFocus = true; + } + } + setVisibleComponent(selectedComponent); + } + + Rectangle bounds = tabPane.getBounds(); + int numChildren = tabPane.getComponentCount(); + + if (numChildren > 0) { + + switch (tabPlacement) { + case LEFT: + totalTabWidth = calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth); + cx = insets.left + totalTabWidth + contentInsets.left; + cy = insets.top + contentInsets.top; + break; + case RIGHT: + totalTabWidth = calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth); + cx = insets.left + contentInsets.left; + cy = insets.top + contentInsets.top; + break; + case BOTTOM: + totalTabHeight = calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight); + cx = insets.left + contentInsets.left; + cy = insets.top + contentInsets.top; + break; + case TOP: + default: + totalTabHeight = calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight); + cx = insets.left + contentInsets.left; + cy = insets.top + totalTabHeight + contentInsets.top; + } + + cw = bounds.width - totalTabWidth + - insets.left - insets.right + - contentInsets.left - contentInsets.right; + ch = bounds.height - totalTabHeight + - insets.top - insets.bottom + - contentInsets.top - contentInsets.bottom; + + for (int i = 0; i < numChildren; i++) { + Component child = tabPane.getComponent(i); + if (child == tabContainer) { + + int tabContainerWidth = totalTabWidth == 0 ? cw : totalTabWidth; + int tabContainerHeight = totalTabHeight == 0 ? ch : totalTabHeight; + + int tabContainerX = 0; + int tabContainerY = 0; + if (tabPlacement == BOTTOM) { + tabContainerY = bounds.height - tabContainerHeight; + } else if (tabPlacement == RIGHT) { + tabContainerX = bounds.width - tabContainerWidth; + } + child.setBounds(tabContainerX, tabContainerY, tabContainerWidth, tabContainerHeight); + } else { + child.setBounds(cx, cy, cw, ch); + } + } + } + layoutTabComponents(); + if (shouldChangeFocus) { + if (!requestFocusForVisibleComponent()) { + tabPane.requestFocus(); + } + } + } + + public void calculateLayoutInfo() { + int tc = tabPane.getTabCount(); + assureRectsCreated(tc); + calculateTabRects(tabPane.getTabPlacement(), tc); + } + + private void layoutTabComponents() { + if (JTattooUtilities.getJavaVersion() >= 1.6) { + if (tabContainer == null) { + return; + } + Rectangle rect = new Rectangle(); + Point delta = new Point(-tabContainer.getX(), -tabContainer.getY()); + if (scrollableTabLayoutEnabled()) { + translatePointToTabPanel(0, 0, delta); + } + for (int i = 0; i < tabPane.getTabCount(); i++) { + Component tabComponent = getTabComponentAt(i); + if (tabComponent == null) { + continue; + } + getTabBounds(i, rect); + Dimension preferredSize = tabComponent.getPreferredSize(); + Insets insets = getTabInsets(tabPane.getTabPlacement(), i); + int outerX = rect.x + insets.left + delta.x; + int outerY = rect.y + insets.top + delta.y; + int outerWidth = rect.width - insets.left - insets.right; + int outerHeight = rect.height - insets.top - insets.bottom; + //centralize component + int x = outerX + (outerWidth - preferredSize.width) / 2; + int y = outerY + (outerHeight - preferredSize.height) / 2; + int tabPlacement = tabPane.getTabPlacement(); + boolean isSeleceted = i == tabPane.getSelectedIndex(); + tabComponent.setBounds(x + getTabLabelShiftX(tabPlacement, i, isSeleceted), y + getTabLabelShiftY(tabPlacement, i, isSeleceted), preferredSize.width, preferredSize.height); + } + } + } + + protected void calculateTabRects(int tabPlacement, int tabCount) { + FontMetrics fm = getFontMetrics(); + Dimension size = tabPane.getSize(); + Insets insets = tabPane.getInsets(); + Insets tabAreaInsets = getTabAreaInsets(tabPlacement); + int fontHeight = fm.getHeight(); + int selectedIndex = tabPane.getSelectedIndex(); + int tabRunOverlay; + int i, j; + int x, y; + int returnAt; + boolean verticalTabRuns = (tabPlacement == LEFT || tabPlacement == RIGHT); + boolean leftToRight = JTattooUtilities.isLeftToRight(tabPane); + + // + // Calculate bounds within which a tab run must fit + // + switch (tabPlacement) { + case LEFT: + maxTabWidth = calculateMaxTabWidth(tabPlacement); + x = insets.left + tabAreaInsets.left; + y = insets.top + tabAreaInsets.top; + returnAt = size.height - (insets.bottom + tabAreaInsets.bottom); + break; + case RIGHT: + maxTabWidth = calculateMaxTabWidth(tabPlacement); + x = size.width - insets.right - tabAreaInsets.right - maxTabWidth; + y = insets.top + tabAreaInsets.top; + returnAt = size.height - (insets.bottom + tabAreaInsets.bottom); + break; + case BOTTOM: + maxTabHeight = calculateMaxTabHeight(tabPlacement); + x = insets.left + tabAreaInsets.left; + y = size.height - insets.bottom - tabAreaInsets.bottom - maxTabHeight; + returnAt = size.width - (insets.right + tabAreaInsets.right); + break; + case TOP: + default: + maxTabHeight = calculateMaxTabHeight(tabPlacement); + x = insets.left + tabAreaInsets.left; + y = insets.top + tabAreaInsets.top; + returnAt = size.width - (insets.right + tabAreaInsets.right); + break; + } + + tabRunOverlay = getTabRunOverlay(tabPlacement); + + runCount = 0; + selectedRun = -1; + + if (tabCount == 0) { + return; + } + + // Run through tabs and partition them into runs + Rectangle rect; + for (i = 0; i < tabCount; i++) { + rect = rects[i]; + + if (!verticalTabRuns) { + // Tabs on TOP or BOTTOM.... + if (i > 0) { + rect.x = rects[i - 1].x + rects[i - 1].width; + } else { + tabRuns[0] = 0; + runCount = 1; + maxTabWidth = 0; + rect.x = x; + } + rect.width = calculateTabWidth(tabPlacement, i, fm); + maxTabWidth = Math.max(maxTabWidth, rect.width); + + // Never move a TAB down a run if it is in the first column. + // Even if there isn't enough room, moving it to a fresh + // line won't help. + if (rect.x != 2 + insets.left && rect.x + rect.width > returnAt) { + if (runCount > tabRuns.length - 1) { + expandTabRunsArray(); + } + tabRuns[runCount] = i; + runCount++; + rect.x = x; + } + // Initialize y position in case there's just one run + rect.y = y; + rect.height = maxTabHeight/* - 2*/; + + } else { + // Tabs on LEFT or RIGHT... + if (i > 0) { + rect.y = rects[i - 1].y + rects[i - 1].height; + } else { + tabRuns[0] = 0; + runCount = 1; + maxTabHeight = 0; + rect.y = y; + } + rect.height = calculateTabHeight(tabPlacement, i, fontHeight); + maxTabHeight = Math.max(maxTabHeight, rect.height); + + // Never move a TAB over a run if it is in the first run. + // Even if there isn't enough room, moving it to a fresh + // column won't help. + if (rect.y != 2 + insets.top && rect.y + rect.height > returnAt) { + if (runCount > tabRuns.length - 1) { + expandTabRunsArray(); + } + tabRuns[runCount] = i; + runCount++; + rect.y = y; + } + // Initialize x position in case there's just one column + rect.x = x; + rect.width = maxTabWidth/* - 2*/; + + } + if (i == selectedIndex) { + selectedRun = runCount - 1; + } + } + + if (runCount > 1) { + // Re-distribute tabs in case last run has leftover space + normalizeTabRuns(tabPlacement, tabCount, verticalTabRuns ? y : x, returnAt); + + selectedRun = getRunForTab(tabCount, selectedIndex); + + // Rotate run array so that selected run is first + if (shouldRotateTabRuns(tabPlacement)) { + rotateTabRuns(tabPlacement, selectedRun); + } + } + + // Step through runs from back to front to calculate + // tab y locations and to pad runs appropriately + for (i = runCount - 1; i >= 0; i--) { + int start = tabRuns[i]; + int next = tabRuns[i == (runCount - 1) ? 0 : i + 1]; + int end = (next != 0 ? next - 1 : tabCount - 1); + if (!verticalTabRuns) { + for (j = start; j <= end; j++) { + rect = rects[j]; + rect.y = y; + rect.x += getTabRunIndent(tabPlacement, i); + } + if (shouldPadTabRun(tabPlacement, i)) { + padTabRun(tabPlacement, start, end, returnAt); + } + if (tabPlacement == BOTTOM) { + y -= (maxTabHeight - tabRunOverlay); + } else { + y += (maxTabHeight - tabRunOverlay); + } + } else { + for (j = start; j <= end; j++) { + rect = rects[j]; + rect.x = x; + rect.y += getTabRunIndent(tabPlacement, i); + } + if (shouldPadTabRun(tabPlacement, i)) { + padTabRun(tabPlacement, start, end, returnAt); + } + if (tabPlacement == RIGHT) { + x -= (maxTabWidth - tabRunOverlay); + } else { + x += (maxTabWidth - tabRunOverlay); + } + } + } + + // Pad the selected tab so that it appears raised in front + padSelectedTab(tabPlacement, selectedIndex); + + // if right to left and tab placement on the top or + // the bottom, flip x positions and adjust by widths + if (!leftToRight && !verticalTabRuns) { + int rightMargin = size.width - (insets.right + tabAreaInsets.right); + for (i = 0; i < tabCount; i++) { + rects[i].x = rightMargin - rects[i].x - rects[i].width; + } + } + } + + /* + * Rotates the run-index array so that the selected run is run[0] + */ + protected void rotateTabRuns(int tabPlacement, int selectedRun) { + for (int i = 0; i < selectedRun; i++) { + int save = tabRuns[0]; + for (int j = 1; j < runCount; j++) { + tabRuns[j - 1] = tabRuns[j]; + } + tabRuns[runCount - 1] = save; + } + } + + protected void normalizeTabRuns(int tabPlacement, int tabCount, int start, int max) { + // Only normalize the runs for top & bottom; normalizing + // doesn't look right for Metal's vertical tabs + // because the last run isn't padded and it looks odd to have + // fat tabs in the first vertical runs, but slimmer ones in the + // last (this effect isn't noticeable for horizontal tabs). + if (tabPlacement == TOP || tabPlacement == BOTTOM) { + int run = runCount - 1; + boolean keepAdjusting = true; + double weight = 1.25; + + // At this point the tab runs are packed to fit as many + // tabs as possible, which can leave the last run with a lot + // of extra space (resulting in very fat tabs on the last run). + // So we'll attempt to distribute this extra space more evenly + // across the runs in order to make the runs look more consistent. + // + // Starting with the last run, determine whether the last tab in + // the previous run would fit (generously) in this run; if so, + // move tab to current run and shift tabs accordingly. Cycle + // through remaining runs using the same algorithm. + // + while (keepAdjusting) { + int last = lastTabInRun(tabCount, run); + int prevLast = lastTabInRun(tabCount, run - 1); + int end; + int prevLastLen; + + end = rects[last].x + rects[last].width; + prevLastLen = (int) (maxTabWidth * weight); + + // Check if the run has enough extra space to fit the last tab + // from the previous row... + if (max - end > prevLastLen) { + + // Insert tab from previous row and shift rest over + tabRuns[run] = prevLast; + rects[prevLast].x = start; + for (int i = prevLast + 1; i <= last; i++) { + rects[i].x = rects[i - 1].x + rects[i - 1].width; + } + + } else if (run == runCount - 1) { + // no more room left in last run, so we're done! + keepAdjusting = false; + } + if (run - 1 > 0) { + // check previous run next... + run -= 1; + } else { + // check last run again...but require a higher ratio + // of extraspace-to-tabsize because we don't want to + // end up with too many tabs on the last run! + run = runCount - 1; + weight += .25; + } + } + } + } + + protected void padTabRun(int tabPlacement, int start, int end, int max) { + Rectangle lastRect = rects[end]; + if (tabPlacement == TOP || tabPlacement == BOTTOM) { + int runWidth = (lastRect.x + lastRect.width) - rects[start].x; + int deltaWidth = max - (lastRect.x + lastRect.width); + float factor = (float) deltaWidth / (float) runWidth; + + for (int j = start; j <= end; j++) { + Rectangle pastRect = rects[j]; + if (j > start) { + pastRect.x = rects[j - 1].x + rects[j - 1].width; + } + pastRect.width += Math.round((float) pastRect.width * factor); + } + lastRect.width = max - lastRect.x; + } else { + int runHeight = (lastRect.y + lastRect.height) - rects[start].y; + int deltaHeight = max - (lastRect.y + lastRect.height); + float factor = (float) deltaHeight / (float) runHeight; + + for (int j = start; j <= end; j++) { + Rectangle pastRect = rects[j]; + if (j > start) { + pastRect.y = rects[j - 1].y + rects[j - 1].height; + } + pastRect.height += Math.round((float) pastRect.height * factor); + } + lastRect.height = max - lastRect.y; + } + } + + protected void padSelectedTab(int tabPlacement, int selectedIndex) { +// if ((selectedIndex >= 0) && (selectedIndex < rects.length)) { +// Rectangle selRect = rects[selectedIndex]; +// Insets padInsets = getSelectedTabPadInsets(tabPlacement); +// selRect.x -= padInsets.left; +// selRect.width += (padInsets.left + padInsets.right); +// selRect.y -= padInsets.top; +// selRect.height += (padInsets.top + padInsets.bottom); +// } + } + } + + private class TabbedPaneScrollLayout extends TabbedPaneLayout { + + protected int preferredTabAreaHeight(int tabPlacement, int width) { + return calculateMaxTabHeight(tabPlacement); + } + + protected int preferredTabAreaWidth(int tabPlacement, int height) { + return calculateMaxTabWidth(tabPlacement); + } + + @SuppressWarnings("deprecation") + public void layoutContainer(Container parent) { + int tabPlacement = tabPane.getTabPlacement(); + int tc = tabPane.getTabCount(); + Insets insets = tabPane.getInsets(); + int selectedIndex = tabPane.getSelectedIndex(); + Component visibleComponent = getVisibleComponent(); + + calculateLayoutInfo(); + + Component selectedComponent = null; + if (selectedIndex < 0) { + if (visibleComponent != null) { + // The last tab was removed, so remove the component + setVisibleComponent(null); + } + } else { + try { + selectedComponent = tabPane.getComponentAt(selectedIndex); + } catch (Exception ex) { +// outStream.print("----------------------------------------------------\n"); +// ex.printStackTrace(outStream); + } + } + boolean shouldChangeFocus = false; + + // In order to allow programs to use a single component + // as the display for multiple tabs, we will not change + // the visible compnent if the currently selected tab + // has a null component. This is a bit dicey, as we don't + // explicitly state we support this in the spec, but since + // programs are now depending on this, we're making it work. + // + if (selectedComponent != null) { + if (selectedComponent != visibleComponent && visibleComponent != null) { + if (SwingUtilities.findFocusOwner(visibleComponent) != null) { + shouldChangeFocus = true; + } + } + setVisibleComponent(selectedComponent); + } + int tx, ty, tw, th; // tab area bounds + int cx, cy, cw, ch; // content area bounds + Insets contentInsets = getContentBorderInsets(tabPlacement); + Rectangle bounds = tabPane.getBounds(); + int numChildren = tabPane.getComponentCount(); + + int space = 60; + if ((numChildren > 0) && (tc > 0)) { + switch (tabPlacement) { + case LEFT: + // calculate tab area bounds + tw = calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth); + th = bounds.height - insets.top - insets.bottom; + tx = insets.left; + ty = insets.top; + + // calculate content area bounds + cx = tx + tw + contentInsets.left; + cy = ty + contentInsets.top; + cw = bounds.width - insets.left - insets.right - tw - contentInsets.left - contentInsets.right; + ch = bounds.height - insets.top - insets.bottom - contentInsets.top - contentInsets.bottom; + break; + case RIGHT: + // calculate tab area bounds + tw = calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth); + th = bounds.height - insets.top - insets.bottom; + tx = bounds.width - insets.right - tw; + ty = insets.top; + + // calculate content area bounds + cx = insets.left + contentInsets.left; + cy = insets.top + contentInsets.top; + cw = bounds.width - insets.left - insets.right - tw - contentInsets.left - contentInsets.right; + ch = bounds.height - insets.top - insets.bottom - contentInsets.top - contentInsets.bottom; + break; + case BOTTOM: + // calculate tab area bounds + tw = bounds.width - insets.left - insets.right; + th = calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight); + tx = insets.left; + ty = bounds.height - insets.bottom - th; + + // calculate content area bounds + cx = insets.left + contentInsets.left; + cy = insets.top + contentInsets.top; + cw = bounds.width - insets.left - insets.right - contentInsets.left - contentInsets.right; + ch = bounds.height - insets.top - insets.bottom - th - contentInsets.top - contentInsets.bottom; + break; + case TOP: + default: + // calculate tab area bounds + tw = bounds.width - insets.left - insets.right; + th = calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight); + tx = insets.left; + ty = insets.top; + + // calculate content area bounds + cx = tx + contentInsets.left; + cy = ty + th + contentInsets.top; + cw = bounds.width - insets.left - insets.right - contentInsets.left - contentInsets.right; + ch = bounds.height - insets.top - insets.bottom - th - contentInsets.top - contentInsets.bottom; + } + for (int i = 0; i < numChildren; i++) { + Component child = tabPane.getComponent(i); + if (child instanceof ScrollableTabViewport) { + JViewport viewport = (JViewport) child; + Rectangle viewRect = viewport.getViewRect(); + int vw = tw; + int vh = th; + switch (tabPlacement) { + case LEFT: + case RIGHT: + int totalTabHeight = rects[tc - 1].y + rects[tc - 1].height; + if (totalTabHeight > th) { + // Allow space for scrollbuttons + vh = Math.max(th - space, space); + if (totalTabHeight - viewRect.y <= vh) { + // Scrolled to the end, so ensure the viewport size is + // such that the scroll offset aligns with a tab + vh = totalTabHeight - viewRect.y; + } + } + break; + case BOTTOM: + case TOP: + default: + int totalTabWidth = rects[tc - 1].x + rects[tc - 1].width; + if (totalTabWidth > tw) { + // Allow space for scrollbuttons + vw = Math.max(tw - space, space); + if (totalTabWidth - viewRect.x <= vw) { + // Scrolled to the end, so ensure the viewport size is + // such that the scroll offset aligns with a tab + vw = totalTabWidth - viewRect.x; + } + } + } + + child.setBounds(tx, ty, vw, vh); + + } else if (child instanceof ScrollableTabButton) { + ScrollableTabButton scrollbutton = (ScrollableTabButton) child; + Dimension bsize = scrollbutton.getPreferredSize(); + int bx = 0; + int by = 0; + int bw = bsize.width; + int bh = bsize.height; + boolean visible = false; + + switch (tabPlacement) { + case LEFT: + case RIGHT: + int totalTabHeight = rects[tc - 1].y + rects[tc - 1].height; + if (totalTabHeight > th) { + int dir = scrollbutton.scrollsForward() ? SOUTH : NORTH; + scrollbutton.setDirection(dir); + visible = true; + bx = tabPlacement == LEFT ? tw - insets.left - tabAreaInsets.bottom - bsize.width : bounds.width - insets.left - bsize.width; + by = dir == SOUTH ? bounds.height - insets.bottom - 2 * bsize.height - 2 : bounds.height - insets.bottom - 3 * bsize.height - 2; + } + break; + + case BOTTOM: + case TOP: + default: + int totalTabWidth = rects[tc - 1].x + rects[tc - 1].width; + if (totalTabWidth > tw) { + int dir = scrollbutton.scrollsForward() ? EAST : WEST; + scrollbutton.setDirection(dir); + visible = true; + bx = dir == EAST ? bounds.width - insets.left - 2 * bsize.width - 2 : bounds.width - insets.left - 3 * bsize.width - 2; + by = ty + (th - bsize.height - tabAreaInsets.bottom) / 2; + if (tabPlacement == BOTTOM) { + by += tabAreaInsets.bottom; + } else { + by++; + } + } + } + + child.setVisible(visible); + if (visible) { + child.setBounds(bx, by, bw, bh); + } + + } else if (child instanceof ScrollablePopupMenuTabButton) { + ScrollablePopupMenuTabButton button = (ScrollablePopupMenuTabButton) child; + Dimension bsize = button.getPreferredSize(); + int bx = 0; + int by = 0; + int bw = bsize.width; + int bh = bsize.height; + boolean visible = false; + + switch (tabPlacement) { + case LEFT: + case RIGHT: + int totalTabHeight = rects[tc - 1].y + rects[tc - 1].height; + if (totalTabHeight > th) { + visible = true; + bx = tabPlacement == LEFT ? tw - insets.left - tabAreaInsets.bottom - bsize.width : bounds.width - insets.left - bsize.width; + by = bounds.height - insets.bottom - bsize.height; + } + break; + + case BOTTOM: + case TOP: + default: + int totalTabWidth = rects[tc - 1].x + rects[tc - 1].width; + if (totalTabWidth > tw) { + visible = true; + bx = bounds.width - insets.left - bsize.width; + by = ty + (th - bsize.height - tabAreaInsets.bottom) / 2; + if (tabPlacement == BOTTOM) { + by += tabAreaInsets.bottom; + } else { + by++; + } + } + } + + child.setVisible(visible); + if (visible) { + child.setBounds(bx, by, bw, bh); + } + } else { + // All content children... + child.setBounds(cx, cy, cw, ch); + } + } + super.layoutTabComponents(); + if (shouldChangeFocus) { + if (!requestFocusForVisibleComponent()) { + tabPane.requestFocus(); + } + } + } + } + + protected void calculateTabRects(int tabPlacement, int tabCount) { + FontMetrics fm = getFontMetrics(); + Dimension size = tabPane.getSize(); + Insets insets = tabPane.getInsets(); + Insets tabAreaInsets = getTabAreaInsets(tabPlacement); + int fontHeight = fm.getHeight(); + boolean verticalTabRuns = (tabPlacement == LEFT || tabPlacement == RIGHT); + boolean leftToRight = JTattooUtilities.isLeftToRight(tabPane); + int x = tabAreaInsets.left; + int y = tabAreaInsets.top; + int totalWidth = 0; + int totalHeight = 0; + + // + // Calculate bounds within which a tab run must fit + // + switch (tabPlacement) { + case LEFT: + case RIGHT: + maxTabWidth = calculateMaxTabWidth(tabPlacement); + break; + case BOTTOM: + case TOP: + default: + maxTabHeight = calculateMaxTabHeight(tabPlacement); + } + + runCount = 0; + selectedRun = -1; + + if (tabCount == 0) { + return; + } + + selectedRun = 0; + runCount = 1; + + // Run through tabs and lay them out in a single run + Rectangle rect; + for (int i = 0; i < tabCount; i++) { + rect = rects[i]; + + if (!verticalTabRuns) { + // Tabs on TOP or BOTTOM.... + if (i > 0) { + rect.x = rects[i - 1].x + rects[i - 1].width; + } else { + tabRuns[0] = 0; + maxTabWidth = 0; + totalHeight += maxTabHeight; + rect.x = x; + } + rect.width = calculateTabWidth(tabPlacement, i, fm); + totalWidth = rect.x + rect.width; + maxTabWidth = Math.max(maxTabWidth, rect.width); + + rect.y = y; + rect.height = maxTabHeight/* - 2*/; + + } else { + // Tabs on LEFT or RIGHT... + if (i > 0) { + rect.y = rects[i - 1].y + rects[i - 1].height; + } else { + tabRuns[0] = 0; + maxTabHeight = 0; + totalWidth = maxTabWidth; + rect.y = y; + } + rect.height = calculateTabHeight(tabPlacement, i, fontHeight); + totalHeight = rect.y + rect.height; + maxTabHeight = Math.max(maxTabHeight, rect.height); + + rect.x = x; + rect.width = maxTabWidth/* - 2*/; + + } + } + + // if right to left and tab placement on the top or + // the bottom, flip x positions and adjust by widths + if (!leftToRight && !verticalTabRuns) { + int rightMargin = size.width - (insets.right + tabAreaInsets.right); + for (int i = 0; i < tabCount; i++) { + rects[i].x = rightMargin - rects[i].x - rects[i].width; + } + } + //tabPanel.setSize(totalWidth, totalHeight); + tabScroller.tabPanel.setPreferredSize(new Dimension(totalWidth, totalHeight)); + } + } + + private class ScrollableTabSupport implements ChangeListener { + + public ScrollableTabViewport viewport; + public ScrollableTabPanel tabPanel; + public ScrollableTabButton scrollForwardButton; + public ScrollableTabButton scrollBackwardButton; + public ScrollablePopupMenuTabButton popupMenuButton; + public int leadingTabIndex; + private Point tabViewPosition = new Point(0, 0); + + ScrollableTabSupport(int tabPlacement) { + viewport = new ScrollableTabViewport(); + tabPanel = new ScrollableTabPanel(); + + viewport.setView(tabPanel); + viewport.addChangeListener(this); + + if (tabPlacement == TOP || tabPlacement == BOTTOM) { + scrollForwardButton = new ScrollableTabButton(EAST); + scrollBackwardButton = new ScrollableTabButton(WEST); + + } else { // tabPlacement = LEFT || RIGHT + scrollForwardButton = new ScrollableTabButton(SOUTH); + scrollBackwardButton = new ScrollableTabButton(NORTH); + } + popupMenuButton = new ScrollablePopupMenuTabButton(); + } + + public void scrollForward(int tabPlacement) { + Dimension viewSize = viewport.getViewSize(); + Rectangle viewRect = viewport.getViewRect(); + + if (tabPlacement == TOP || tabPlacement == BOTTOM) { + if (viewRect.width >= viewSize.width - viewRect.x) { + return; // no room left to scroll + } + } else { + // tabPlacement == LEFT || tabPlacement == RIGHT + if (viewRect.height >= viewSize.height - viewRect.y) { + return; + } + } + setLeadingTabIndex(tabPlacement, leadingTabIndex + 1); + if (tabPane != null) { + tabPane.doLayout(); + } + } + + public void scrollBackward(int tabPlacement) { + if (leadingTabIndex == 0) { + return; // no room left to scroll + } + setLeadingTabIndex(tabPlacement, leadingTabIndex - 1); + if (tabPane != null) { + tabPane.doLayout(); + } + } + + public void scrollTabToVisible(int tabPlacement, int index) { + if (index <= leadingTabIndex) { + setLeadingTabIndex(tabPlacement, index); + } else { + Rectangle viewRect = viewport.getViewRect(); + switch (tabPlacement) { + case TOP: + case BOTTOM: { + int i = index; + int x = viewRect.width - rects[index].width; + while ((i > 0) && (x - rects[i - 1].width >= 0)) { + i--; + x -= rects[i].width; + } + if (leadingTabIndex < i) { + setLeadingTabIndex(tabPlacement, i); + } + break; + + } + case LEFT: + case RIGHT: { + int i = index; + int y = viewRect.height - rects[index].height; + while ((i > 0) && (y - rects[i - 1].height > 0)) { + i--; + y -= rects[i].height; + } + if (leadingTabIndex < i) { + setLeadingTabIndex(tabPlacement, i); + } + break; + } + } + } + } + + public void setLeadingTabIndex(int tabPlacement, int index) { + leadingTabIndex = index; + Dimension viewSize = viewport.getViewSize(); + Rectangle viewRect = viewport.getViewRect(); + + switch (tabPlacement) { + case TOP: + case BOTTOM: + tabViewPosition.x = leadingTabIndex == 0 ? 0 : rects[leadingTabIndex].x; + + if ((viewSize.width - tabViewPosition.x) < viewRect.width) { + // We've scrolled to the end, so adjust the viewport size + // to ensure the view position remains aligned on a tab boundary + Dimension extentSize = new Dimension(viewSize.width - tabViewPosition.x, viewRect.height); + viewport.setExtentSize(extentSize); + } + break; + case LEFT: + case RIGHT: + tabViewPosition.y = leadingTabIndex == 0 ? 0 : rects[leadingTabIndex].y; + + if ((viewSize.height - tabViewPosition.y) < viewRect.height) { + // We've scrolled to the end, so adjust the viewport size + // to ensure the view position remains aligned on a tab boundary + Dimension extentSize = new Dimension(viewRect.width, viewSize.height - tabViewPosition.y); + viewport.setExtentSize(extentSize); + } + } + viewport.setViewPosition(tabViewPosition); + } + + public void stateChanged(ChangeEvent e) { + JViewport vp = (JViewport) e.getSource(); + int tabPlacement = tabPane.getTabPlacement(); + int tc = tabPane.getTabCount(); + Rectangle vpRect = vp.getBounds(); + Dimension viewSize = vp.getViewSize(); + Rectangle viewRect = vp.getViewRect(); + + leadingTabIndex = getClosestTab(viewRect.x, viewRect.y); + if (leadingTabIndex >= rects.length) { + return; + } + + // If the tab isn't right aligned, adjust it. + if (leadingTabIndex + 1 < tc) { + switch (tabPlacement) { + case TOP: + case BOTTOM: + if (rects[leadingTabIndex].x < viewRect.x) { + leadingTabIndex++; + } + break; + case LEFT: + case RIGHT: + if (rects[leadingTabIndex].y < viewRect.y) { + leadingTabIndex++; + } + break; + } + } + Insets contentInsets = getContentBorderInsets(tabPlacement); + switch (tabPlacement) { + case LEFT: + tabPane.repaint(vpRect.x + vpRect.width, vpRect.y, contentInsets.left, vpRect.height); + scrollBackwardButton.setEnabled(viewRect.y > 0); + scrollForwardButton.setEnabled(leadingTabIndex < tc - 1 && viewSize.height - viewRect.y > viewRect.height); + break; + case RIGHT: + tabPane.repaint(vpRect.x - contentInsets.right, vpRect.y, contentInsets.right, vpRect.height); + scrollBackwardButton.setEnabled(viewRect.y > 0); + scrollForwardButton.setEnabled(leadingTabIndex < tc - 1 && viewSize.height - viewRect.y > viewRect.height); + break; + case BOTTOM: + tabPane.repaint(vpRect.x, vpRect.y - contentInsets.bottom, vpRect.width, contentInsets.bottom); + scrollBackwardButton.setEnabled(viewRect.x > 0); + scrollForwardButton.setEnabled(leadingTabIndex < tc - 1 && viewSize.width - viewRect.x > viewRect.width); + break; + case TOP: + default: + tabPane.repaint(vpRect.x, vpRect.y + vpRect.height, vpRect.width, contentInsets.top); + scrollBackwardButton.setEnabled(viewRect.x > 0); + scrollForwardButton.setEnabled(leadingTabIndex < tc - 1 && viewSize.width - viewRect.x > viewRect.width); + } + } + + } + + private class ScrollableTabViewport extends JViewport implements UIResource { + + public ScrollableTabViewport() { + setScrollMode(SIMPLE_SCROLL_MODE); + setOpaque(false); + } + + } + + private class ScrollableTabPanel extends JPanel implements UIResource { + + public ScrollableTabPanel() { + setLayout(null); + setOpaque(false); + } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + paintScrollContentBorder(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex(), 0, 0, getWidth(), getHeight()); + paintTabArea(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex()); + } + + public void doLayout() { + if (getComponentCount() > 0) { + Component child = getComponent(0); + child.setBounds(0, 0, getWidth(), getHeight()); + } + } + } + + public class ArrowButton extends JButton implements SwingConstants { + + protected int direction; + + public ArrowButton(int direction) { + super(); + this.direction = direction; + setRequestFocusEnabled(false); + if (simpleButtonBorder) { + Color cLo = getLoBorderColor(0); + Color cHi = AbstractLookAndFeel.getTheme().getControlHighlight(); + setBorder(BorderFactory.createEtchedBorder(cHi, cLo)); + } + } + + public int getDirection() { + return direction; + } + + public void setDirection(int dir) { + direction = dir; + } + + public void paint(Graphics g) { + super.paint(g); + // Draw the arrow + int w = getSize().width; + int h = getSize().height; + int size = Math.min((h - 4) / 3, (w - 4) / 3); + size = Math.max(size, 2); + paintTriangle(g, (w - size) / 2 + 1, (h - size) / 2 + 1, size); + } + + public Dimension getPreferredSize() { + return new Dimension(17, 17); + } + + public Dimension getMinimumSize() { + return new Dimension(5, 5); + } + + public Dimension getMaximumSize() { + return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + } + + @SuppressWarnings("deprecation") + public boolean isFocusTraversable() { + return false; + } + + public void paintTriangle(Graphics g, int x, int y, int size) { + Color oldColor = g.getColor(); + int mid, i, j; + size = Math.max(size, 2); + mid = (size / 2) - 1; + + Color enabledColor = AbstractLookAndFeel.getTheme().getButtonForegroundColor(); + Color disabledColor = AbstractLookAndFeel.getTheme().getDisabledForegroundColor(); + + g.translate(x, y); + if (isEnabled()) { + g.setColor(enabledColor); + } else { + g.setColor(disabledColor); + } + + switch (direction) { + case NORTH: + for (i = 0; i < size; i++) { + g.drawLine(mid - i, i, mid + i, i); + } + break; + case SOUTH: + j = 0; + for (i = size - 1; i >= 0; i--) { + g.drawLine(mid - i, j, mid + i, j); + j++; + } + break; + case WEST: + for (i = 0; i < size; i++) { + g.drawLine(i, mid - i, i, mid + i); + } + break; + case EAST: + j = 0; + for (i = size - 1; i >= 0; i--) { + g.drawLine(j, mid - i, j, mid + i); + j++; + } + break; + } + g.translate(-x, -y); + g.setColor(oldColor); + } + } + + private class ScrollableTabButton extends ArrowButton implements UIResource, SwingConstants { + + public ScrollableTabButton(int direction) { + super(direction); + } + + public boolean scrollsForward() { + return direction == EAST || direction == SOUTH; + } + } + + private class ScrollablePopupMenuTabButton extends ArrowButton implements UIResource, SwingConstants { + + public ScrollablePopupMenuTabButton() { + super(SOUTH); + } + } + +// Controller: event listeners + /** + * This inner class is marked "public" due to a compiler bug. + * This class should be treated as a "protected" inner class. + * Instantiate it only within subclasses of BaseTabbedPaneUI. + */ + public class PropertyChangeHandler implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent e) { + JTabbedPane pane = (JTabbedPane) e.getSource(); + String name = e.getPropertyName(); + boolean isScrollLayout = scrollableTabLayoutEnabled(); + if ("mnemonicAt".equals(name)) { + updateMnemonics(); + pane.repaint(); + } else if ("displayedMnemonicIndexAt".equals(name)) { + pane.repaint(); + } else if ("indexForTitle".equals(name)) { + int index = ((Integer) e.getNewValue()).intValue(); + String title = tabPane.getTitleAt(index); + if (BasicHTML.isHTMLString(title)) { + if (htmlViews == null) { // Initialize vector + htmlViews = createHTMLViewList(); + } else { // Vector already exists + View v = BasicHTML.createHTMLView(tabPane, title); + htmlViews.set(index, v); + } + } else { + if (htmlViews != null && htmlViews.get(index) != null) { + htmlViews.set(index, null); + } + } + updateMnemonics(); + } else if ("tabLayoutPolicy".equals(name)) { + BaseTabbedPaneUI.this.uninstallUI(pane); + BaseTabbedPaneUI.this.installUI(pane); + } else if ("background".equals(name) && isScrollLayout) { + Color newVal = (Color) e.getNewValue(); + tabScroller.tabPanel.setBackground(newVal); + tabScroller.viewport.setBackground(newVal); + Color newColor = selectedColor == null ? newVal : selectedColor; + tabScroller.scrollForwardButton.setBackground(newColor); + tabScroller.scrollBackwardButton.setBackground(newColor); + } else if ("indexForTabComponent".equals(name)) { + if (tabContainer != null) { + tabContainer.removeUnusedTabComponents(); + } + try { + Component tabComponent = getTabComponentAt(((Integer) e.getNewValue()).intValue()); + if (tabComponent != null) { + if (tabContainer == null) { + installTabContainer(); + } else { + addMyPropertyChangeListeners(tabComponent); + tabContainer.add(tabComponent); + } + } + } catch (Exception ex) { + } + tabPane.revalidate(); + tabPane.repaint(); + } else if ("componentOrientation".equals(name)) { + pane.revalidate(); + pane.repaint(); + } else if ("tabAreaBackground".equals(name)) { + pane.revalidate(); + pane.repaint(); + } + } + } + + public class MyTabComponentListener implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent evt) { + if ("font".equals(evt.getPropertyName()) || "text".equals(evt.getPropertyName())) { + tabPane.revalidate(); + tabPane.repaint(); + } + } + } + + /** + * This inner class is marked "public" due to a compiler bug. + * This class should be treated as a "protected" inner class. + * Instantiate it only within subclasses of BaseTabbedPaneUI. + */ + public class TabSelectionHandler implements ChangeListener { + + public void stateChanged(ChangeEvent e) { + JTabbedPane tabPane = (JTabbedPane) e.getSource(); + if (JTattooUtilities.getJavaVersion() >= 1.4) { + if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT) { + int index = tabPane.getSelectedIndex(); + if (index >= 0) { + BaseTabbedPaneUI ui = (BaseTabbedPaneUI) tabPane.getUI(); + ui.tabScroller.scrollTabToVisible(tabPane.getTabPlacement(), index); + } + } + } + tabPane.revalidate(); + tabPane.repaint(); + } + } + + public class TabComponentHandler implements ComponentListener { + + public void componentResized(ComponentEvent ce) { + SwingUtilities.invokeLater(new Runnable() { + + public void run() { + if (tabPane != null) { + tabPane.doLayout(); + } + } + }); + } + + public void componentMoved(ComponentEvent ce) { + } + + public void componentShown(ComponentEvent ce) { + + } + + public void componentHidden(ComponentEvent ce) { + } + } + + /** + * This inner class is marked "public" due to a compiler bug. + * This class should be treated as a "protected" inner class. + * Instantiate it only within subclasses of BaseTabbedPaneUI. + */ + public class MouseHandler extends MouseAdapter { + + public void mouseClicked(MouseEvent e) { + if (scrollableTabLayoutEnabled()) { + MouseListener[] ml = tabPane.getMouseListeners(); + for (int i = 0; i < ml.length; i++) { + ml[i].mouseClicked(e); + } + } + } + + public void mousePressed(MouseEvent e) { + if (scrollableTabLayoutEnabled()) { + MouseListener[] ml = tabPane.getMouseListeners(); + for (int i = 0; i < ml.length; i++) { + ml[i].mousePressed(e); + } + } + if (!tabPane.isEnabled()) { + return; + } + int tabIndex = getTabAtLocation(e.getX(), e.getY()); + if (tabIndex >= 0 && tabPane.isEnabledAt(tabIndex)) { + if (tabIndex == tabPane.getSelectedIndex()) { + if (tabPane.isRequestFocusEnabled()) { + tabPane.requestFocus(); + tabPane.repaint(getTabBounds(tabPane, tabIndex)); + } + } else { + tabPane.setSelectedIndex(tabIndex); + } + } + } + + public void mouseReleased(MouseEvent e) { + if (scrollableTabLayoutEnabled()) { + MouseListener[] ml = tabPane.getMouseListeners(); + for (int i = 0; i < ml.length; i++) { + ml[i].mouseReleased(e); + } + } + } + + public void mouseEntered(MouseEvent e) { + if (scrollableTabLayoutEnabled()) { + MouseListener[] ml = tabPane.getMouseListeners(); + for (int i = 0; i < ml.length; i++) { + ml[i].mouseEntered(e); + } + } + } + + public void mouseExited(MouseEvent e) { + if (scrollableTabLayoutEnabled()) { + MouseListener[] ml = tabPane.getMouseListeners(); + for (int i = 0; i < ml.length; i++) { + ml[i].mouseExited(e); + } + } + rolloverIndex = -1; + if (rolloverIndex != oldRolloverIndex) { + if ((oldRolloverIndex >= 0) && (oldRolloverIndex < tabPane.getTabCount())) { + tabPane.repaint(getTabBounds(tabPane, oldRolloverIndex)); + } + if ((rolloverIndex >= 0) && (rolloverIndex < tabPane.getTabCount())) { + tabPane.repaint(getTabBounds(tabPane, rolloverIndex)); + } + oldRolloverIndex = rolloverIndex; + } + } + } + + /** + * This inner class is marked "public" due to a compiler bug. + * This class should be treated as a "protected" inner class. + * Instantiate it only within subclasses of BaseTabbedPaneUI. + */ + public class MouseMotionHandler extends MouseMotionAdapter { + + public void mouseDragged(MouseEvent e) { + if (scrollableTabLayoutEnabled()) { + MouseMotionListener[] mml = tabPane.getMouseMotionListeners(); + for (int i = 0; i < mml.length; i++) { + mml[i].mouseDragged(e); + } + } + } + + public void mouseMoved(MouseEvent e) { + if (scrollableTabLayoutEnabled()) { + MouseMotionListener[] mml = tabPane.getMouseMotionListeners(); + for (int i = 0; i < mml.length; i++) { + mml[i].mouseMoved(e); + } + } + rolloverIndex = getTabAtLocation(e.getX(), e.getY()); + if (rolloverIndex != oldRolloverIndex) { + if ((oldRolloverIndex >= 0) && (oldRolloverIndex < tabPane.getTabCount())) { + tabPane.repaint(getTabBounds(tabPane, oldRolloverIndex)); + } + if ((rolloverIndex >= 0) && (rolloverIndex < tabPane.getTabCount())) { + tabPane.repaint(getTabBounds(tabPane, rolloverIndex)); + } + oldRolloverIndex = rolloverIndex; + } + } + } + + /** + * This inner class is marked "public" due to a compiler bug. + * This class should be treated as a "protected" inner class. + * Instantiate it only within subclasses of BaseTabbedPaneUI. + */ + public class FocusHandler extends FocusAdapter { + + public void focusGained(FocusEvent e) { + JTabbedPane tabPane = (JTabbedPane) e.getSource(); + int tabCount = tabPane.getTabCount(); + int selectedIndex = tabPane.getSelectedIndex(); + if (selectedIndex != -1 && tabCount > 0 && tabCount == rects.length) { + tabPane.repaint(getTabBounds(tabPane, selectedIndex)); + } + } + + public void focusLost(FocusEvent e) { + JTabbedPane tabPane = (JTabbedPane) e.getSource(); + int tabCount = tabPane.getTabCount(); + int selectedIndex = tabPane.getSelectedIndex(); + if (selectedIndex != -1 && tabCount > 0 && tabCount == rects.length) { + tabPane.repaint(getTabBounds(tabPane, selectedIndex)); + } + } + } + + /* GES 2/3/99: + The container listener code was added to support HTML + rendering of tab titles. + + Ideally, we would be able to listen for property changes + when a tab is added or its text modified. At the moment + there are no such events because the Beans spec doesn't + allow 'indexed' property changes (i.e. tab 2's text changed + from A to B). + + In order to get around this, we listen for tabs to be added + or removed by listening for the container events. we then + queue up a runnable (so the component has a chance to complete + the add) which checks the tab title of the new component to see + if it requires HTML rendering. + + The Views (one per tab title requiring HTML rendering) are + stored in the htmlViews list, which is only allocated after + the first time we run into an HTML tab. Note that this list + is kept in step with the number of pages, and nulls are added + for those pages whose tab title do not require HTML rendering. + + This makes it easy for the paint and layout code to tell + whether to invoke the HTML engine without having to check + the string during time-sensitive operations. + + When we have added a way to listen for tab additions and + changes to tab text, this code should be removed and + replaced by something which uses that. */ + private class ContainerHandler implements ContainerListener { + + public void componentAdded(ContainerEvent e) { + JTabbedPane tp = (JTabbedPane) e.getContainer(); + TabbedPaneLayout layout = (TabbedPaneLayout) tp.getLayout(); + layout.layoutContainer(tp); + + Component child = e.getChild(); + if (child instanceof UIResource) { + return; + } + int index = tp.indexOfComponent(child); + String title = tp.getTitleAt(index); + boolean isHTML = BasicHTML.isHTMLString(title); + if (isHTML) { + if (htmlViews == null) { + // Initialize vector + htmlViews = createHTMLViewList(); + } else { + // Vector already exists + View v = BasicHTML.createHTMLView(tp, title); + htmlViews.add(index, v); + } + } else { + // Not HTML + if (htmlViews != null) { + // Add placeholder + htmlViews.add(index, null); + } // else nada! + } + } + + public void componentRemoved(ContainerEvent e) { + JTabbedPane tp = (JTabbedPane) e.getContainer(); + Component child = e.getChild(); + if (child instanceof UIResource) { + return; + } + + // NOTE 4/15/2002 (joutwate): + // This fix is implemented using client properties since there is + // currently no IndexPropertyChangeEvent. Once + // IndexPropertyChangeEvents have been added this code should be + // modified to use it. + Integer indexObj = (Integer) tp.getClientProperty("__index_to_remove__"); + if (indexObj != null) { + int index = indexObj.intValue(); + if (htmlViews != null && htmlViews.size() >= index) { + htmlViews.remove(index); + } + } + } + } + + private ArrayList createHTMLViewList() { + ArrayList viewList = new ArrayList(); + int count = tabPane.getTabCount(); + for (int i = 0; i < count; i++) { + String title = tabPane.getTitleAt(i); + if (BasicHTML.isHTMLString(title)) { + viewList.add(BasicHTML.createHTMLView(tabPane, title)); + } else { + viewList.add(null); + } + } + return viewList; + } + + private class TabContainer extends JPanel implements UIResource { + + private boolean notifyTabbedPane = true; + + public TabContainer() { + super(null); + setOpaque(false); + } + + @SuppressWarnings("deprecation") + public void remove(Component comp) { + int index = tabPane.indexOfTabComponent(comp); + PropertyChangeListener[] listeners = comp.getPropertyChangeListeners(); + for (int j = 0; j < listeners.length; j++) { + if (listeners[j] instanceof MyTabComponentListener) { + comp.removePropertyChangeListener(listeners[j]); + } + } + super.remove(comp); + if (notifyTabbedPane && index != -1) { + tabPane.setTabComponentAt(index, null); + } + } + + private void removeUnusedTabComponents() { + for (int i = 0; i < getComponentCount(); i++) { + Component c = getComponent(i); + if (!(c instanceof UIResource)) { + int index = tabPane.indexOfTabComponent(c); + if (index == -1) { + PropertyChangeListener[] listeners = c.getPropertyChangeListeners(); + for (int j = 0; j < listeners.length; j++) { + if (listeners[j] instanceof MyTabComponentListener) { + c.removePropertyChangeListener(listeners[j]); + } + } + super.remove(c); + } + } + } + } + } +} diff --git a/src/com/jtattoo/plaf/BaseTableHeaderUI.java b/src/com/jtattoo/plaf/BaseTableHeaderUI.java new file mode 100644 index 0000000..5d6aa31 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseTableHeaderUI.java @@ -0,0 +1,481 @@ +/* + * Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. + * + * JTattoo is multiple licensed. If your are an open source developer you can use + * it under the terms and conditions of the GNU General Public License version 2.0 + * or later as published by the Free Software Foundation. + * + * see: gpl-2.0.txt + * + * If you pay for a license you will become a registered user who could use the + * software under the terms and conditions of the GNU Lesser General Public License + * version 2.0 or later with classpath exception as published by the Free Software + * Foundation. + * + * see: lgpl-2.0.txt + * see: classpath-exception.txt + * + * Registered users could also use JTattoo under the terms and conditions of the + * Apache License, Version 2.0 as published by the Apache Software Foundation. + * + * see: APACHE-LICENSE-2.0.txt + */ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.*; +import java.util.Enumeration; +import java.util.List; +import javax.swing.*; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicTableHeaderUI; +import javax.swing.table.*; + +/** + * + * @author Michael Hagen + */ +public class BaseTableHeaderUI extends BasicTableHeaderUI { + + private TableCellRenderer originalHeaderRenderer; + protected MouseAdapter myMouseAdapter = null; + protected MouseMotionAdapter myMouseMotionAdapter = null; + protected int rolloverCol = -1; + + public static ComponentUI createUI(JComponent h) { + return new BaseTableHeaderUI(); + } + + public void installUI(JComponent c) { + super.installUI(c); + if ((header != null) && header.getTable() != null) { + originalHeaderRenderer = header.getDefaultRenderer(); + if ((originalHeaderRenderer != null) + && "sun.swing.table.DefaultTableCellHeaderRenderer".equals(originalHeaderRenderer.getClass().getName())) { + header.setDefaultRenderer(new BaseDefaultHeaderRenderer()); + } + } + } + + public void uninstallUI(JComponent c) { + if ((header != null) && (header.getTable() != null)) { + if (header.getDefaultRenderer() instanceof BaseDefaultHeaderRenderer) { + header.setDefaultRenderer(originalHeaderRenderer); + } + } + super.uninstallUI(c); + } + + public void installListeners() { + super.installListeners(); + myMouseAdapter = new MouseAdapter() { + + public void mouseReleased(MouseEvent e) { + if ((header == null) || (header.getTable() == null)) { + return; + } + boolean rolloverEnabled = Boolean.TRUE.equals(header.getClientProperty("rolloverEnabled")); + boolean sortingAllowed = false; + if (JTattooUtilities.getJavaVersion() >= 1.6) { + sortingAllowed = header.getTable().getRowSorter() != null; + } + if (rolloverEnabled || sortingAllowed || header.getReorderingAllowed()) { + if (header.getBounds().contains(e.getPoint())) { + int oldRolloverCol = rolloverCol; + rolloverCol = header.getTable().columnAtPoint(e.getPoint()); + updateRolloverColumn(oldRolloverCol, rolloverCol); + } else { + int oldRolloverCol = rolloverCol; + rolloverCol = -1; + updateRolloverColumn(oldRolloverCol, rolloverCol); + } + } + } + + public void mouseEntered(MouseEvent e) { + if ((header == null) || (header.getTable() == null)) { + return; + } + boolean rolloverEnabled = Boolean.TRUE.equals(header.getClientProperty("rolloverEnabled")); + boolean sortingAllowed = false; + if (JTattooUtilities.getJavaVersion() >= 1.6) { + sortingAllowed = header.getTable().getRowSorter() != null; + } + if (rolloverEnabled || sortingAllowed || header.getReorderingAllowed()) { + int oldRolloverCol = rolloverCol; + rolloverCol = header.getTable().columnAtPoint(e.getPoint()); + updateRolloverColumn(oldRolloverCol, rolloverCol); + } + } + + public void mouseExited(MouseEvent e) { + if ((header == null) || (header.getTable() == null)) { + return; + } + boolean rolloverEnabled = Boolean.TRUE.equals(header.getClientProperty("rolloverEnabled")); + boolean sortingAllowed = false; + if (JTattooUtilities.getJavaVersion() >= 1.6) { + sortingAllowed = header.getTable().getRowSorter() != null; + } + if (rolloverEnabled || sortingAllowed || header.getReorderingAllowed()) { + int oldRolloverCol = rolloverCol; + rolloverCol = -1; + updateRolloverColumn(oldRolloverCol, rolloverCol); + } + } + }; + myMouseMotionAdapter = new MouseMotionAdapter() { + + public void mouseMoved(MouseEvent e) { + if ((header == null) || (header.getTable() == null)) { + return; + } + boolean rolloverEnabled = Boolean.TRUE.equals(header.getClientProperty("rolloverEnabled")); + boolean sortingAllowed = false; + if (JTattooUtilities.getJavaVersion() >= 1.6) { + sortingAllowed = header.getTable().getRowSorter() != null; + } + if (rolloverEnabled || sortingAllowed || header.getReorderingAllowed()) { + if (header.getDraggedColumn() == null) { + int oldRolloverCol = rolloverCol; + rolloverCol = header.getTable().columnAtPoint(e.getPoint()); + updateRolloverColumn(oldRolloverCol, rolloverCol); + } + } + } + + public void mouseDragged(MouseEvent e) { + if ((header == null) || (header.getTable() == null)) { + return; + } + boolean rolloverEnabled = Boolean.TRUE.equals(header.getClientProperty("rolloverEnabled")); + boolean sortingAllowed = false; + if (JTattooUtilities.getJavaVersion() >= 1.6) { + sortingAllowed = header.getTable().getRowSorter() != null; + } + if (rolloverEnabled || sortingAllowed || header.getReorderingAllowed()) { + if (header.getDraggedColumn() != null && header.getDraggedColumn().getIdentifier() != null) { + rolloverCol = header.getColumnModel().getColumnIndex(header.getDraggedColumn().getIdentifier()); + } else if (header.getResizingColumn() != null) { + rolloverCol = -1; + } + } + } + }; + header.addMouseListener(myMouseAdapter); + header.addMouseMotionListener(myMouseMotionAdapter); + } + + public void uninstallListeners() { + header.removeMouseListener(myMouseAdapter); + header.removeMouseMotionListener(myMouseMotionAdapter); + super.uninstallListeners(); + } + + protected boolean drawAlwaysActive() { + return false; + } + + protected boolean drawRolloverBar() { + return false; + } + + protected Component getHeaderRenderer(int col) { + if ((header == null) || (header.getTable() == null)) { + return null; + } + TableColumn tabCol = header.getColumnModel().getColumn(col); + TableCellRenderer renderer = tabCol.getHeaderRenderer(); + if (renderer == null) { + renderer = header.getDefaultRenderer(); + } + return renderer.getTableCellRendererComponent(header.getTable(), tabCol.getHeaderValue(), false, false, -1, col); + } + + private int getHeaderHeight() { + if ((header == null) || (header.getTable() == null)) { + return 0; + } + int height = 0; + boolean accomodatedDefault = false; + TableColumnModel columnModel = header.getColumnModel(); + for (int column = 0; column < columnModel.getColumnCount(); column++) { + TableColumn aColumn = columnModel.getColumn(column); + boolean isDefault = (aColumn.getHeaderRenderer() == null); + + if (!isDefault || !accomodatedDefault) { + Component comp = getHeaderRenderer(column); + int rendererHeight = comp.getPreferredSize().height; + height = Math.max(height, rendererHeight); + + // Configuring the header renderer to calculate its preferred size + // is expensive. Optimise this by assuming the default renderer + // always has the same height as the first non-zero height that + // it returns for a non-null/non-empty value. + if (isDefault && rendererHeight > 0) { + Object headerValue = aColumn.getHeaderValue(); + if (headerValue != null) { + headerValue = headerValue.toString(); + + if (headerValue != null && !headerValue.equals("")) { + accomodatedDefault = true; + } + } + } + } + } + return height + 2; + } + + /** + * Return the preferred size of the header. The preferred height is the maximum of the preferred heights of all of + * the components provided by the header renderers. The preferred width is the sum of the preferred widths of each + * column (plus inter-cell spacing). + * + * @return the preferredSize + */ + public Dimension getPreferredSize(JComponent c) { + if ((header == null) || (header.getTable() == null)) { + return new Dimension(0, 0); + } + long width = 0; + Enumeration enumeration = header.getColumnModel().getColumns(); + while (enumeration.hasMoreElements()) { + TableColumn aColumn = (TableColumn) enumeration.nextElement(); + width = width + aColumn.getPreferredWidth(); + } + if (width > Integer.MAX_VALUE) { + width = Integer.MAX_VALUE; + } + return new Dimension((int) width, getHeaderHeight()); + } + + protected void updateRolloverColumn(int oldColumn, int newColumn) { + if ((header == null) || (header.getTable() == null)) { + return; + } + header.repaint(header.getHeaderRect(oldColumn)); + header.repaint(header.getHeaderRect(newColumn)); + } + + protected void rolloverColumnUpdated(int oldColumn, int newColumn) { + // Empty to avoid multiple paints + } + + public void paint(Graphics g, JComponent c) { + if ((header == null) || (header.getTable() == null) || header.getColumnModel().getColumnCount() <= 0) { + return; + } + + boolean ltr = header.getComponentOrientation().isLeftToRight(); + Rectangle clip = g.getClipBounds(); + Point left = clip.getLocation(); + Point right = new Point(clip.x + clip.width - 1, clip.y); + TableColumnModel cm = header.getColumnModel(); + int cMin = header.columnAtPoint(ltr ? left : right); + int cMax = header.columnAtPoint(ltr ? right : left); + // This should never happen. + if (cMin == -1) { + cMin = 0; + } + // If the table does not have enough columns to fill the view we'll get -1. + // Replace this with the index of the last column. + if (cMax == -1) { + cMax = cm.getColumnCount() - 1; + } + + TableColumn draggedColumn = header.getDraggedColumn(); + Rectangle cellRect = header.getHeaderRect(ltr ? cMin : cMax); + int columnWidth; + TableColumn aColumn; + if (ltr) { + for (int column = cMin; column <= cMax; column++) { + aColumn = cm.getColumn(column); + columnWidth = aColumn.getWidth(); + cellRect.width = columnWidth; + if (aColumn != draggedColumn) { + paintCell(g, cellRect, column); + } + cellRect.x += columnWidth; + } + } else { + for (int column = cMax; column >= cMin; column--) { + aColumn = cm.getColumn(column); + columnWidth = aColumn.getWidth(); + cellRect.width = columnWidth; + if (aColumn != draggedColumn) { + paintCell(g, cellRect, column); + } + cellRect.x += columnWidth; + } + } + + // Paint the dragged column if we are dragging. + if (draggedColumn != null) { + int draggedColumnIndex = viewIndexForColumn(draggedColumn); + Rectangle draggedCellRect = header.getHeaderRect(draggedColumnIndex); + // Draw a gray well in place of the moving column. + g.setColor(header.getParent().getBackground()); + g.fillRect(draggedCellRect.x, draggedCellRect.y, draggedCellRect.width, draggedCellRect.height); + draggedCellRect.x += header.getDraggedDistance(); + + // Fill the background. + g.setColor(header.getBackground()); + g.fillRect(draggedCellRect.x, draggedCellRect.y, draggedCellRect.width, draggedCellRect.height); + paintCell(g, draggedCellRect, draggedColumnIndex); + } + + // Remove all components in the rendererPane. + rendererPane.removeAll(); + } + + protected void paintBackground(Graphics g, Rectangle cellRect, int col) { + Component component = getHeaderRenderer(col); + int x = cellRect.x; + int y = cellRect.y; + int w = cellRect.width; + int h = cellRect.height; + if (header.getBackground() instanceof ColorUIResource) { + if ((col == rolloverCol) && (component != null) && component.isEnabled()) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getRolloverColors(), x, y, w, h); + } else if (drawAlwaysActive() || JTattooUtilities.isFrameActive(header)) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getColHeaderColors(), x, y, w, h); + } else { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getInActiveColors(), x, y, w, h); + } + } else { + g.setColor(header.getBackground()); + g.fillRect(x, y, w, h); + } + } + + protected void paintCell(Graphics g, Rectangle cellRect, int col) { + if ((header == null) || (header.getTable() == null)) { + return; + } + Component component = getHeaderRenderer(col); + if (!(component instanceof BaseDefaultHeaderRenderer)) { + paintBackground(g, cellRect, col); + } + rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); + } + + private int viewIndexForColumn(TableColumn aColumn) { + if ((header == null) || (header.getTable() == null)) { + return -1; + } + TableColumnModel cm = header.getColumnModel(); + for (int column = 0; column < cm.getColumnCount(); column++) { + if (cm.getColumn(column) == aColumn) { + return column; + } + } + return -1; + } + +//---------------------------------------------------------------------------------------------------------------------- +// inner classes +//---------------------------------------------------------------------------------------------------------------------- + private class BaseDefaultHeaderRenderer extends DefaultTableCellRenderer { + + public BaseDefaultHeaderRenderer() { + super(); + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + return new MyRenderComponent(table, value, isSelected, hasFocus, row, column); + } + } + + private class MyRenderComponent extends JLabel { + + private JTable table = null; + private int col = 0; + + public MyRenderComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { + super(); + this.table = table; + this.col = col; + if (value != null) { + setText(value.toString()); + } else { + setText(""); + } + setOpaque(false); + if (table.getClientProperty("TableHeader.font") != null) { + setFont((Font)table.getClientProperty("TableHeader.font")); + } else { + setFont(UIManager.getFont("TableHeader.font")); + } + if (col == rolloverCol) { + setForeground(AbstractLookAndFeel.getTheme().getRolloverForegroundColor()); + } else { + setForeground(UIManager.getColor("TableHeader.foreground")); + } + setHorizontalAlignment(JLabel.CENTER); + setHorizontalTextPosition(SwingConstants.LEADING); + setBorder(UIManager.getBorder("TableHeader.cellBorder")); + if ((JTattooUtilities.getJavaVersion() >= 1.6) && (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel)) { + RowSorter rowSorter = table.getRowSorter(); + List keyList = rowSorter == null ? null : rowSorter.getSortKeys(); + if ((keyList != null) && (keyList.size() > 0)) { + RowSorter.SortKey sortKey = (RowSorter.SortKey) keyList.get(0); + if (sortKey.getColumn() == table.convertColumnIndexToModel(col)) { + AbstractIconFactory iconFactory = ((AbstractLookAndFeel) UIManager.getLookAndFeel()).getIconFactory(); + if (sortKey.getSortOrder().equals(SortOrder.ASCENDING)) { + setIcon(iconFactory.getUpArrowIcon()); + } else if (sortKey.getSortOrder().equals(SortOrder.DESCENDING)) { + setIcon(iconFactory.getDownArrowIcon()); + } + } + } + } + } + + protected void paintBackground(Graphics g) { + // BugFix: 12.12.2013 + // Currently I don't know why header is sometimes null, but if it's null it's better to ignore + // the background instead of throwing a NPE. + if (header == null) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getColHeaderColors(), 0, 0, getWidth(), getHeight()); + return; + } + int draggedColumn = -1; + if (header.getTable() != null && header.getDraggedColumn() != null) { + draggedColumn = header.getColumnModel().getColumnIndex(header.getDraggedColumn().getIdentifier()); + } + int w = getWidth(); + int h = getHeight(); + if ((table != null) && table.isEnabled() && (col == rolloverCol || col == draggedColumn)) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getRolloverColors(), 0, 0, w, h); + if (drawRolloverBar()) { + g.setColor(AbstractLookAndFeel.getFocusColor()); + g.drawLine(0, 0, w - 1, 0); + g.drawLine(0, 1, w - 1, 1); + g.drawLine(0, 2, w - 1, 2); + } + } else if (drawAlwaysActive() || JTattooUtilities.isFrameActive(header)) { + if (header.getBackground() instanceof ColorUIResource) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getColHeaderColors(), 0, 0, w, h); + } else { + g.setColor(header.getBackground()); + g.fillRect(0, 0, w, h); + } + } else { + if (header.getBackground() instanceof ColorUIResource) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getInActiveColors(), 0, 0, w, h); + } else { + g.setColor(header.getBackground()); + g.fillRect(0, 0, w, h); + } + } + } + + public void paint(Graphics g) { + paintBackground(g); + super.paint(g); + } + } +} diff --git a/src/com/jtattoo/plaf/BaseTableUI.java b/src/com/jtattoo/plaf/BaseTableUI.java new file mode 100644 index 0000000..72d728f --- /dev/null +++ b/src/com/jtattoo/plaf/BaseTableUI.java @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.FontMetrics; +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicTableUI; + +/** + * @author Michael Hagen + */ +public class BaseTableUI extends BasicTableUI { + + public static ComponentUI createUI(JComponent c) { + return new BaseTableUI(); + } + + public void installDefaults() { + super.installDefaults(); + // Setup the rowheight. The font may change if UI switches + FontMetrics fm = JTattooUtilities.getFontMetrics(table, null, table.getFont()); + table.setRowHeight(fm.getHeight() + (fm.getHeight() / 4)); + } + +} diff --git a/src/com/jtattoo/plaf/BaseTextAreaUI.java b/src/com/jtattoo/plaf/BaseTextAreaUI.java new file mode 100644 index 0000000..4190116 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseTextAreaUI.java @@ -0,0 +1,150 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.beans.PropertyChangeEvent; +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicTextAreaUI; +import javax.swing.text.DefaultEditorKit; +import javax.swing.text.JTextComponent; + +/** + * @author Michael Hagen + */ +public class BaseTextAreaUI extends BasicTextAreaUI { + + private Border orgBorder = null; + private FocusListener focusListener = null; + + public static ComponentUI createUI(JComponent c) { + return new BaseTextAreaUI(); + } + + public void installDefaults() { + super.installDefaults(); + updateBackground(); + } + + @SuppressWarnings("deprecation") + protected void installKeyboardActions() { + super.installKeyboardActions(); + if (JTattooUtilities.isMac()) { + InputMap im = (InputMap) UIManager.get("TextField.focusInputMap"); + int commandKey = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, commandKey), DefaultEditorKit.copyAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, commandKey), DefaultEditorKit.pasteAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, commandKey), DefaultEditorKit.cutAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.ALT_DOWN_MASK), DefaultEditorKit.nextWordAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, KeyEvent.ALT_DOWN_MASK), DefaultEditorKit.previousWordAction); + } + } + + protected void installListeners() { + super.installListeners(); + + if (AbstractLookAndFeel.getTheme().doShowFocusFrame()) { + focusListener = new FocusListener() { + + public void focusGained(FocusEvent e) { + if (getComponent() != null) { + orgBorder = getComponent().getBorder(); + LookAndFeel laf = UIManager.getLookAndFeel(); + if (laf instanceof AbstractLookAndFeel && orgBorder instanceof UIResource) { + Border focusBorder = ((AbstractLookAndFeel)laf).getBorderFactory().getFocusFrameBorder(); + getComponent().setBorder(focusBorder); + } + getComponent().invalidate(); + getComponent().repaint(); + } + } + + public void focusLost(FocusEvent e) { + if (getComponent() != null) { + if (orgBorder instanceof UIResource) { + getComponent().setBorder(orgBorder); + } + getComponent().invalidate(); + getComponent().repaint(); + } + } + }; + getComponent().addFocusListener(focusListener); + } + } + + protected void uninstallListeners() { + getComponent().removeFocusListener(focusListener); + focusListener = null; + super.uninstallListeners(); + } + + protected void paintBackground(Graphics g) { + g.setColor(getComponent().getBackground()); + if (AbstractLookAndFeel.getTheme().doShowFocusFrame()) { + if (getComponent().hasFocus() && getComponent().isEditable()) { + g.setColor(AbstractLookAndFeel.getTheme().getFocusBackgroundColor()); + } + } + g.fillRect(0, 0, getComponent().getWidth(), getComponent().getHeight()); + } + + protected void paintSafely(Graphics g) { + Graphics2D g2D = (Graphics2D) g; + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + super.paintSafely(g); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } + + protected void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("editable") || + evt.getPropertyName().equals("enabled")) { + updateBackground(); + } + super.propertyChange(evt); + } + + private void updateBackground() { + JTextComponent c = getComponent(); + if (c.getBackground() instanceof UIResource) { + if (!c.isEnabled() || !c.isEditable()) { + c.setBackground(AbstractLookAndFeel.getDisabledBackgroundColor()); + } else { + c.setBackground(AbstractLookAndFeel.getInputBackgroundColor()); + } + } + } +} diff --git a/src/com/jtattoo/plaf/BaseTextFieldUI.java b/src/com/jtattoo/plaf/BaseTextFieldUI.java new file mode 100644 index 0000000..f12a549 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseTextFieldUI.java @@ -0,0 +1,127 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.metal.MetalTextFieldUI; +import javax.swing.text.DefaultEditorKit; + +/** + * @author Michael Hagen + */ +public class BaseTextFieldUI extends MetalTextFieldUI { + + private Border orgBorder = null; + private FocusListener focusListener = null; + + public static ComponentUI createUI(JComponent c) { + return new BaseTextFieldUI(); + } + + @SuppressWarnings("deprecation") + protected void installKeyboardActions() { + super.installKeyboardActions(); + if (JTattooUtilities.isMac()) { + InputMap im = (InputMap) UIManager.get("TextField.focusInputMap"); + int commandKey = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, commandKey), DefaultEditorKit.copyAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, commandKey), DefaultEditorKit.pasteAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, commandKey), DefaultEditorKit.cutAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.ALT_DOWN_MASK), DefaultEditorKit.nextWordAction); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, KeyEvent.ALT_DOWN_MASK), DefaultEditorKit.previousWordAction); + } + } + + protected void installListeners() { + super.installListeners(); + + if (AbstractLookAndFeel.getTheme().doShowFocusFrame()) { + focusListener = new FocusListener() { + public void focusGained(FocusEvent e) { + if (getComponent() != null) { + orgBorder = getComponent().getBorder(); + LookAndFeel laf = UIManager.getLookAndFeel(); + if (laf instanceof AbstractLookAndFeel && orgBorder instanceof UIResource) { + Border focusBorder = ((AbstractLookAndFeel) laf).getBorderFactory().getFocusFrameBorder(); + getComponent().setBorder(focusBorder); + } + getComponent().invalidate(); + getComponent().repaint(); + } + } + + public void focusLost(FocusEvent e) { + if (getComponent() != null) { + if (orgBorder instanceof UIResource) { + getComponent().setBorder(orgBorder); + } + getComponent().invalidate(); + getComponent().repaint(); + } + } + }; + + getComponent().addFocusListener(focusListener); + } + } + + protected void uninstallListeners() { + getComponent().removeFocusListener(focusListener); + focusListener = null; + super.uninstallListeners(); + } + + protected void paintBackground(Graphics g) { + g.setColor(getComponent().getBackground()); + if (AbstractLookAndFeel.getTheme().doShowFocusFrame()) { + Boolean doShow = (Boolean) getComponent().getClientProperty("doShowFocusFrame"); + if (doShow == null || doShow.booleanValue()) { + if (getComponent().hasFocus() && getComponent().isEditable()) { + g.setColor(AbstractLookAndFeel.getTheme().getFocusBackgroundColor()); + } + } + } + g.fillRect(0, 0, getComponent().getWidth(), getComponent().getHeight()); + } + + protected void paintSafely(Graphics g) { + Graphics2D g2D = (Graphics2D) g; + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + super.paintSafely(g); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } +} diff --git a/src/com/jtattoo/plaf/BaseTitleButton.java b/src/com/jtattoo/plaf/BaseTitleButton.java new file mode 100644 index 0000000..cbb9e17 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseTitleButton.java @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import javax.swing.Action; +import javax.swing.Icon; + +/** + * @author Michael Hagen + */ +public class BaseTitleButton extends NoFocusButton { + + private float alpha = 1.0f; + + public BaseTitleButton(Action action, String accessibleName, Icon icon, float alpha) { + setContentAreaFilled(false); + setBorderPainted(false); + setAction(action); + setText(null); + setIcon(icon); + putClientProperty("paintActive", Boolean.TRUE); + getAccessibleContext().setAccessibleName(accessibleName); + this.alpha = Math.max(0.2f, alpha); + } + + public void paint(Graphics g) { + if (JTattooUtilities.isActive(this) || (alpha >= 1.0)) { + super.paint(g); + } else { + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha); + g2D.setComposite(alphaComposite); + super.paint(g); + g2D.setComposite(savedComposite); + } + } + +} diff --git a/src/com/jtattoo/plaf/BaseTitlePane.java b/src/com/jtattoo/plaf/BaseTitlePane.java new file mode 100644 index 0000000..8202fd4 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseTitlePane.java @@ -0,0 +1,994 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.*; +import java.awt.image.BufferedImage; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.*; +import javax.swing.plaf.UIResource; + +/** + * This class is a modified copy of the javax.swing.plaf.metal.MetalTitlePaneUI + * + * Class that manages a JLF awt.Window-descendant class's title bar. + *

+ * This class assumes it will be created with a particular window + * decoration style, and that if the style changes, a new one will + * be created. + * + * @version 1.12 01/23/03 + * @author Terry Kellerman + * @author Michael Hagen + * + * @since 1.4 + */ +public class BaseTitlePane extends JComponent implements TitlePane { + + public static final String PAINT_ACTIVE = "paintActive"; + public static final String ICONIFY = "Iconify"; + public static final String MAXIMIZE = "Maximize"; + public static final String CLOSE = "Close"; + protected PropertyChangeListener propertyChangeListener; + protected Action closeAction; + protected Action iconifyAction; + protected Action restoreAction; + protected Action maximizeAction; + protected JMenuBar menuBar; + protected JPanel customTitlePanel; + protected JButton iconifyButton; + protected JButton maxButton; + protected JButton closeButton; + protected Icon iconifyIcon; + protected Icon maximizeIcon; + protected Icon minimizeIcon; + protected Icon closeIcon; + protected WindowListener windowListener; + protected Window window; + protected JRootPane rootPane; + protected BaseRootPaneUI rootPaneUI; + protected int buttonsWidth; + protected int state; + // This flag is used to avoid a bug with OSX and java 1.7. The call to setExtendedState + // with both flags ICONIFY and MAXIMIZED_BOTH throws an illegal state exception, so we + // have to switch off the MAXIMIZED_BOTH flag in the iconify() method. If frame is deiconified + // we use the wasMaximized flag to restore the maximized state. + protected boolean wasMaximized; + // This flag indicates a maximize error. This occurs on multiscreen environments where the first + // screen does not have the same resolution as the second screen. In this case we only simulate the + // maximize/restore behaviour. It's not a perfect simulation (frame border will stay visible, + // and we have to restore the bounds if look and feel changes in maximized state) + protected boolean wasMaximizeError = false; + + protected BufferedImage backgroundImage = null; + protected float alphaValue = 0.85f; + + public BaseTitlePane(JRootPane root, BaseRootPaneUI ui) { + rootPane = root; + rootPaneUI = ui; + state = -1; + wasMaximized = false; + iconifyIcon = UIManager.getIcon("InternalFrame.iconifyIcon"); + maximizeIcon = UIManager.getIcon("InternalFrame.maximizeIcon"); + minimizeIcon = UIManager.getIcon("InternalFrame.minimizeIcon"); + closeIcon = UIManager.getIcon("InternalFrame.closeIcon"); + + installSubcomponents(); + installDefaults(); + setLayout(createLayout()); + } + + protected void installListeners() { + if (window != null) { + windowListener = createWindowListener(); + window.addWindowListener(windowListener); + propertyChangeListener = createWindowPropertyChangeListener(); + window.addPropertyChangeListener(propertyChangeListener); + } + } + + protected void uninstallListeners() { + if (window != null) { + window.removeWindowListener(windowListener); + window.removePropertyChangeListener(propertyChangeListener); + } + } + + protected WindowListener createWindowListener() { + return new WindowHandler(); + } + + protected PropertyChangeListener createWindowPropertyChangeListener() { + return new PropertyChangeHandler(); + } + + public JRootPane getRootPane() { + return rootPane; + } + + protected Frame getFrame() { + if (window instanceof Frame) { + return (Frame) window; + } + return null; + } + + protected Window getWindow() { + return window; + } + + protected int getWindowDecorationStyle() { + return DecorationHelper.getWindowDecorationStyle(rootPane); + } + + protected boolean isMacStyleWindowDecoration() { + return AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn(); + } + + protected Image getFrameIconImage() { + // try to find icon for dialog windows + if (getFrame() == null && JTattooUtilities.getJavaVersion() >= 1.6) { + java.util.List icons = getWindow().getIconImages(); + // No icon found ? search in window chain for an icon + if (icons == null || icons.isEmpty()) { + Window owner = getWindow().getOwner(); + while (owner != null) { + icons = owner.getIconImages(); + // found ? return the icon + if (icons != null && !icons.isEmpty()) { + return (Image)(icons.get(0)); + } + owner = owner.getOwner(); + } + } else { + return (Image)(icons.get(0)); + } + // No icon found ? return icon of the first frame + if (icons == null || icons.isEmpty()) { + if (Frame.getFrames() != null && Frame.getFrames().length > 0) { + return Frame.getFrames()[0].getIconImage(); + } + } + return null; + } else { + if (getFrame() != null) { + return getFrame().getIconImage(); + } + } + return null; + } + + public void addNotify() { + super.addNotify(); + uninstallListeners(); + window = SwingUtilities.getWindowAncestor(this); + if (window != null) { + if (window instanceof Frame) { + setState(DecorationHelper.getExtendedState((Frame) window)); + } else { + setState(0); + } + setActive(JTattooUtilities.isWindowActive(window)); + installListeners(); + } + } + + public void removeNotify() { + super.removeNotify(); + uninstallListeners(); + window = null; + } + + protected void installSubcomponents() { + createActions(); + createButtons(); + if (getWindowDecorationStyle() == BaseRootPaneUI.FRAME) { + if (!isMacStyleWindowDecoration()) { + createMenuBar(); + add(menuBar); + } + add(iconifyButton); + add(maxButton); + } + add(closeButton); + } + + protected void installDefaults() { + setFont(UIManager.getFont("InternalFrame.titleFont")); + if (rootPane.getClientProperty("customTitlePanel") instanceof JPanel) { + setCustomizedTitlePanel((JPanel)rootPane.getClientProperty("customTitlePanel")); + } + } + + protected void uninstallDefaults() { + } + + protected void createMenuBar() { + menuBar = new SystemMenuBar(); + if (getWindowDecorationStyle() == BaseRootPaneUI.FRAME) { + JMenu menu = new JMenu(" "); + + JMenuItem mi = menu.add(restoreAction); + int mnemonic = getInt("MetalTitlePane.restoreMnemonic", -1); + if (mnemonic != -1) { + mi.setMnemonic(mnemonic); + } + mi = menu.add(iconifyAction); + mnemonic = getInt("MetalTitlePane.iconifyMnemonic", -1); + if (mnemonic != -1) { + mi.setMnemonic(mnemonic); + } + + if (DecorationHelper.isFrameStateSupported(Toolkit.getDefaultToolkit(), BaseRootPaneUI.MAXIMIZED_BOTH)) { + mi = menu.add(maximizeAction); + mnemonic = getInt("MetalTitlePane.maximizeMnemonic", -1); + if (mnemonic != -1) { + mi.setMnemonic(mnemonic); + } + } + menu.addSeparator(); + mi = menu.add(closeAction); + mnemonic = getInt("MetalTitlePane.closeMnemonic", -1); + if (mnemonic != -1) { + mi.setMnemonic(mnemonic); + } + + menuBar.add(menu); + } + } + + public void setCustomizedTitlePanel(JPanel panel) { + if (customTitlePanel != null) { + remove(customTitlePanel); + customTitlePanel = null; + } + if (panel != null) { + customTitlePanel = panel; + add(customTitlePanel); + } + rootPane.putClientProperty("customTitlePanel", customTitlePanel); + revalidate(); + repaint(); + } + + public void createButtons() { + iconifyButton = new BaseTitleButton(iconifyAction, ICONIFY, iconifyIcon, 1.0f); + maxButton = new BaseTitleButton(restoreAction, MAXIMIZE, maximizeIcon, 1.0f); + closeButton = new BaseTitleButton(closeAction, CLOSE, closeIcon, 1.0f); + } + + public LayoutManager createLayout() { + return new TitlePaneLayout(); + } + + public void iconify() { + Frame frame = getFrame(); + if (frame != null) { + if (JTattooUtilities.isMac() && JTattooUtilities.getJavaVersion() >= 1.7) { + // Workarround to avoid a bug within OSX and Java 1.7 + DecorationHelper.setExtendedState(frame, state & ~BaseRootPaneUI.MAXIMIZED_BOTH | Frame.ICONIFIED); + } else { + DecorationHelper.setExtendedState(frame, state | Frame.ICONIFIED); + } + } + } + + public void maximize() { + Frame frame = getFrame(); + if (frame != null) { + validateMaximizedBounds(); + PropertyChangeListener[] pcl = frame.getPropertyChangeListeners(); + for (int i = 0; i < pcl.length; i++) { + pcl[i].propertyChange(new PropertyChangeEvent(this, "windowMaximize", Boolean.FALSE, Boolean.FALSE)); + } + DecorationHelper.setExtendedState(frame, state | BaseRootPaneUI.MAXIMIZED_BOTH); + for (int i = 0; i < pcl.length; i++) { + pcl[i].propertyChange(new PropertyChangeEvent(this, "windowMaximized", Boolean.FALSE, Boolean.FALSE)); + } + + } + } + + public void restore() { + Frame frame = getFrame(); + if (frame != null) { + wasMaximizeError = false; + PropertyChangeListener[] pcl = frame.getPropertyChangeListeners(); + for (int i = 0; i < pcl.length; i++) { + pcl[i].propertyChange(new PropertyChangeEvent(this, "windowRestore", Boolean.FALSE, Boolean.FALSE)); + } + if ((state & Frame.ICONIFIED) != 0) { + DecorationHelper.setExtendedState(frame, state & ~Frame.ICONIFIED); + } else { + DecorationHelper.setExtendedState(frame, state & ~BaseRootPaneUI.MAXIMIZED_BOTH); + } + for (int i = 0; i < pcl.length; i++) { + pcl[i].propertyChange(new PropertyChangeEvent(this, "windowRestored", Boolean.FALSE, Boolean.FALSE)); + } + } + } + + public void close() { + if (window != null) { + window.dispatchEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSING)); + } + } + + protected void validateMaximizedBounds() { + Frame frame = getFrame(); + if (frame != null && !wasMaximizeError) { + GraphicsConfiguration gc = frame.getGraphicsConfiguration(); + Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc); + Rectangle maxBounds = gc.getBounds(); + maxBounds.x = Math.max(0, screenInsets.left); + maxBounds.y = Math.max(0, screenInsets.top); + maxBounds.width -= (screenInsets.left + screenInsets.right); + maxBounds.height -= (screenInsets.top + screenInsets.bottom); + frame.setMaximizedBounds(maxBounds); + } + } + + protected void createActions() { + closeAction = new CloseAction(); + iconifyAction = new IconifyAction(); + restoreAction = new RestoreAction(); + maximizeAction = new MaximizeAction(); + } + + static int getInt(Object key, int defaultValue) { + Object value = UIManager.get(key); + if (value instanceof Integer) { + return ((Integer) value).intValue(); + } + if (value instanceof String) { + try { + return Integer.parseInt((String) value); + } catch (NumberFormatException nfe) { + } + } + return defaultValue; + } + + protected void setActive(boolean flag) { + if (getWindowDecorationStyle() == BaseRootPaneUI.FRAME) { + Boolean active = flag ? Boolean.TRUE : Boolean.FALSE; + iconifyButton.putClientProperty(PAINT_ACTIVE, active); + closeButton.putClientProperty(PAINT_ACTIVE, active); + maxButton.putClientProperty(PAINT_ACTIVE, active); + } + getRootPane().repaint(); + } + + protected boolean isActive() { + return (window == null) ? true : JTattooUtilities.isWindowActive(window); + } + + protected boolean isLeftToRight() { + return (window == null) ? getRootPane().getComponentOrientation().isLeftToRight() : window.getComponentOrientation().isLeftToRight(); + } + + public void setBackgroundImage(BufferedImage bgImage) { + backgroundImage = bgImage; + } + + public void setAlphaTransparency(float alpha) { + alphaValue = alpha; + } + + protected void setState(int state) { + setState(state, false); + } + + protected void setState(int state, boolean updateRegardless) { + if (window != null && getWindowDecorationStyle() == BaseRootPaneUI.FRAME) { + if (this.state == state && !updateRegardless) { + return; + } + + final Frame frame = getFrame(); + if (frame != null) { + + if (((state & BaseRootPaneUI.MAXIMIZED_BOTH) != 0) && (rootPane.getBorder() == null || (rootPane.getBorder() instanceof UIResource)) && frame.isShowing()) { + rootPane.setBorder(null); + } else if ((state & BaseRootPaneUI.MAXIMIZED_BOTH) == 0) { + rootPaneUI.installBorder(rootPane); + } + + if (frame.isResizable()) { + if ((state & BaseRootPaneUI.MAXIMIZED_BOTH) != 0) { + updateMaxButton(restoreAction, minimizeIcon); + maximizeAction.setEnabled(false); + restoreAction.setEnabled(true); + } else { + updateMaxButton(maximizeAction, maximizeIcon); + maximizeAction.setEnabled(true); + restoreAction.setEnabled(false); + } + if (maxButton.getParent() == null || iconifyButton.getParent() == null) { + add(maxButton); + add(iconifyButton); + revalidate(); + repaint(); + } + maxButton.setText(null); + } else { + maximizeAction.setEnabled(false); + restoreAction.setEnabled(false); + if (maxButton.getParent() != null) { + remove(maxButton); + revalidate(); + repaint(); + } + } + // BUGFIX + // When programatically maximize a frame via setExtendedState in a multiscreen environment the width + // and height may not be set correctly. We fix this issue here. + if ((state & BaseRootPaneUI.MAXIMIZED_BOTH) != 0) { + validateMaximizedBounds(); + rootPane.setBorder(null); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + GraphicsConfiguration gc = frame.getGraphicsConfiguration(); + Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc); + Rectangle maxBounds = gc.getBounds(); + maxBounds.width -= (screenInsets.left + screenInsets.right); + maxBounds.height -= (screenInsets.top + screenInsets.bottom); + if ((frame.getWidth() != maxBounds.width) || (frame.getHeight() != maxBounds.height)) { + restore(); + wasMaximizeError = true; + frame.setMaximizedBounds(null); + maximize(); + } + } + }); + } + } else { + // Not contained in a Frame + maximizeAction.setEnabled(false); + restoreAction.setEnabled(false); + iconifyAction.setEnabled(false); + remove(maxButton); + remove(iconifyButton); + revalidate(); + repaint(); + } + closeAction.setEnabled(true); + this.state = state; + } + } + + protected void updateMaxButton(Action action, Icon icon) { + maxButton.setAction(action); + maxButton.setIcon(icon); + } + + protected int getHorSpacing() { + return 3; + } + + protected int getVerSpacing() { + return 3; + } + + protected boolean centerButtons() { + return true; + } + + protected String getTitle() { + if (window instanceof Frame) { + return ((Frame) window).getTitle(); + } else if (window instanceof Dialog) { + return ((Dialog) window).getTitle(); + } + return null; + } + + public void paintBackground(Graphics g) { + if (isActive()) { + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + if (backgroundImage != null) { + g.drawImage(backgroundImage, 0, 0, null); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alphaValue); + g2D.setComposite(alpha); + } + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getWindowTitleColors(), 0, 0, getWidth(), getHeight()); + g2D.setComposite(savedComposite); + } else { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getWindowInactiveTitleColors(), 0, 0, getWidth(), getHeight()); + } + } + + protected int getIconWidth() { + Image image = getFrameIconImage(); + if (image != null) { + int h = getHeight(); + int ih = image.getHeight(null); + int iw = image.getWidth(null); + if (ih > h) { + double fac = (double) iw / (double) ih; + ih = h; + iw = (int) (fac * (double) ih); + } + return iw; + } + return 0; + } + + protected int paintIcon(Graphics g, int x) { + Image image = getFrameIconImage(); + if (image != null) { + Graphics2D g2D = (Graphics2D)g; + Object savedHint = g2D.getRenderingHint(RenderingHints.KEY_INTERPOLATION); + if (JTattooUtilities.getJavaVersion() >= 1.6) { + g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + } + int h = getHeight() - 2; + int ih = image.getHeight(null); + int iw = image.getWidth(null); + if (ih <= h) { + g2D.drawImage(image, x, (h - ih) / 2, iw, ih, null); + } else { + double fac = (double)iw / (double)ih; + ih = h; + iw = (int)(fac * (double)ih); + g2D.drawImage(image, x, 0, iw, ih, null); + } + if (savedHint != null) { + g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, savedHint); + } + return iw; + } + return 0; + } + + public void paintText(Graphics g, int x, int y, String title) { + if (isActive()) { + g.setColor(AbstractLookAndFeel.getWindowTitleForegroundColor()); + } else { + g.setColor(AbstractLookAndFeel.getWindowInactiveTitleForegroundColor()); + } + JTattooUtilities.drawString(rootPane, g, title, x, y); + } + + public void paintComponent(Graphics g) { + if (getFrame() != null) { + setState(DecorationHelper.getExtendedState(getFrame())); + } + + paintBackground(g); + + g.setFont(getFont()); + FontMetrics fm = JTattooUtilities.getFontMetrics(this, g, getFont()); + int width = getWidth(); + int height = getHeight(); + int x = 0; + int y = ((height - fm.getHeight()) / 2) + fm.getAscent(); + int titleWidth = width - buttonsWidth - 4; + String frameTitle = getTitle(); + if (isLeftToRight()) { + if (isMacStyleWindowDecoration()) { + int iconWidth = getIconWidth(); + titleWidth -= iconWidth + 4; + frameTitle = JTattooUtilities.getClippedText(frameTitle, fm, titleWidth); + int titleLength = fm.stringWidth(frameTitle); + x += buttonsWidth + ((titleWidth - titleLength) / 2); + paintIcon(g, x); + x += iconWidth + 4; + } else { + if (getWindow() instanceof JDialog) { + int iconWidth = paintIcon(g, x); + titleWidth -= iconWidth + 4; + frameTitle = JTattooUtilities.getClippedText(frameTitle, fm, titleWidth); + if (AbstractLookAndFeel.getTheme().isCenterWindowTitleOn()) { + int titleLength = fm.stringWidth(frameTitle); + x += iconWidth + 4; + x += (titleWidth - titleLength) / 2; + } else { + x += iconWidth + 4; + } + } else { + int menuBarWidth = menuBar == null ? 0 : menuBar.getWidth(); + titleWidth -= menuBarWidth + 4; + frameTitle = JTattooUtilities.getClippedText(frameTitle, fm, titleWidth); + if (AbstractLookAndFeel.getTheme().isCenterWindowTitleOn()) { + int titleLength = fm.stringWidth(frameTitle); + x += menuBarWidth + 4; + x += (titleWidth - titleLength) / 2; + } else { + x += menuBarWidth + 4; + } + } + } + } else { + int iconWidth = getIconWidth(); + if (isMacStyleWindowDecoration()) { + titleWidth -= iconWidth + 4; + frameTitle = JTattooUtilities.getClippedText(frameTitle, fm, titleWidth); + int titleLength = fm.stringWidth(frameTitle); + x = buttonsWidth + 4 + ((titleWidth - titleLength) / 2); + paintIcon(g, x + titleLength + 4); + } else { + if (getWindow() instanceof JDialog) { + x = width - iconWidth; + paintIcon(g, x); + titleWidth -= iconWidth + 4; + frameTitle = JTattooUtilities.getClippedText(frameTitle, fm, titleWidth); + int titleLength = fm.stringWidth(frameTitle); + if (AbstractLookAndFeel.getTheme().isCenterWindowTitleOn()) { + x = buttonsWidth + 4 + ((titleWidth - titleLength) / 2); + } else { + x = width - iconWidth - 4 - titleLength; + } + } else { + int menuBarWidth = menuBar == null ? 0 : menuBar.getWidth(); + titleWidth -= menuBarWidth + 4; + frameTitle = JTattooUtilities.getClippedText(frameTitle, fm, titleWidth); + int titleLength = fm.stringWidth(frameTitle); + if (AbstractLookAndFeel.getTheme().isCenterWindowTitleOn()) { + x = buttonsWidth + 4 + ((titleWidth - titleLength) / 2); + } else { + x = width - menuBarWidth - 4 - titleLength; + } + } + } + } + paintText(g, x, y, frameTitle); + } + + protected class CloseAction extends AbstractAction { + + public CloseAction() { + super(UIManager.getString("MetalTitlePane.closeTitle")); + } + + public void actionPerformed(ActionEvent e) { + close(); + } + } + + protected class IconifyAction extends AbstractAction { + + public IconifyAction() { + super(UIManager.getString("MetalTitlePane.iconifyTitle")); + } + + public void actionPerformed(ActionEvent e) { + iconify(); + } + } + + protected class RestoreAction extends AbstractAction { + + public RestoreAction() { + super(UIManager.getString("MetalTitlePane.restoreTitle")); + } + + public void actionPerformed(ActionEvent e) { + restore(); + } + } + + protected class MaximizeAction extends AbstractAction { + + public MaximizeAction() { + super(UIManager.getString("MetalTitlePane.maximizeTitle")); + } + + public void actionPerformed(ActionEvent e) { + maximize(); + } + } + +//----------------------------------------------------------------------------------------------- + protected class SystemMenuBar extends JMenuBar { + + public SystemMenuBar() { + setOpaque(false); + } + + public void paint(Graphics g) { + Image image = getFrameIconImage(); + if (image != null) { + Graphics2D g2D = (Graphics2D)g; + Object savedHint = g2D.getRenderingHint(RenderingHints.KEY_INTERPOLATION); + g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + int x = 0; + int y = 0; + int iw = image.getWidth(null); + int ih = image.getHeight(null); + if (ih > getHeight()) { + double scale = (double)(getHeight() - 2) / (double)ih; + iw = (int)(scale * iw); + ih = (int)(scale * ih); + } else { + y = (getHeight() - ih) / 2; + } + g2D.drawImage(image, x, y, iw, ih, null); + if (savedHint != null) { + g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, savedHint); + } + } else { + Icon icon = UIManager.getIcon("InternalFrame.icon"); + if (icon != null) { + icon.paintIcon(this, g, 2, 2); + } + } + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + protected int computeHeight() { + FontMetrics fm = JTattooUtilities.getFontMetrics(this, null, getFont()); + return fm.getHeight() + 6; + } + + public Dimension getPreferredSize() { + Dimension size = super.getPreferredSize(); + Image image = getFrameIconImage(); + if (image != null) { + int iw = image.getWidth(null); + int ih = image.getHeight(null); + int th = computeHeight(); + if (ih > th) { + double scale = (double)th / (double)ih; + iw = (int)(scale * iw); + ih = (int)(scale * ih); + } + return new Dimension(Math.max(iw, size.width), Math.max(ih, size.height)); + } else { + return size; + } + } + } + +//----------------------------------------------------------------------------------------------- + protected class TitlePaneLayout implements LayoutManager { + + public void addLayoutComponent(String name, Component c) { + } + + public void removeLayoutComponent(Component c) { + } + + public Dimension preferredLayoutSize(Container c) { + int height = computeHeight(); + return new Dimension(height, height); + } + + public Dimension minimumLayoutSize(Container c) { + return preferredLayoutSize(c); + } + + protected int computeHeight() { + FontMetrics fm = JTattooUtilities.getFontMetrics(BaseTitlePane.this, null, getFont()); + return fm.getHeight() + 6; + } + + public void layoutContainer(Container c) { + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + layoutMacStyle(c); + } else { + layoutDefault(c); + } + } + + public void layoutDefault(Container c) { + boolean leftToRight = isLeftToRight(); + + int spacing = getHorSpacing(); + int w = getWidth(); + int h = getHeight(); + + // assumes all buttons have the same dimensions these dimensions include the borders + int btnHeight = h - getVerSpacing(); + int btnWidth = btnHeight; + + + if (menuBar != null) { + int mw = menuBar.getPreferredSize().width; + int mh = menuBar.getPreferredSize().height; + if (leftToRight) { + menuBar.setBounds(2, (h - mh) / 2, mw, mh); + } else { + menuBar.setBounds(getWidth() - mw, (h - mh) / 2, mw, mh); + } + } + + int x = leftToRight ? w - spacing : 0; + int y = Math.max(0, ((h - btnHeight) / 2) - 1); + + if (closeButton != null) { + x += leftToRight ? -btnWidth : spacing; + closeButton.setBounds(x, y, btnWidth, btnHeight); + if (!leftToRight) { + x += btnWidth; + } + } + + if ((maxButton != null) && (maxButton.getParent() != null)) { + if (DecorationHelper.isFrameStateSupported(Toolkit.getDefaultToolkit(), BaseRootPaneUI.MAXIMIZED_BOTH)) { + x += leftToRight ? -spacing - btnWidth : spacing; + maxButton.setBounds(x, y, btnWidth, btnHeight); + if (!leftToRight) { + x += btnWidth; + } + } + } + + if ((iconifyButton != null) && (iconifyButton.getParent() != null)) { + x += leftToRight ? -spacing - btnWidth : spacing; + iconifyButton.setBounds(x, y, btnWidth, btnHeight); + if (!leftToRight) { + x += btnWidth; + } + } + + buttonsWidth = leftToRight ? w - x : x; + + if (customTitlePanel != null) { + int maxWidth = w - buttonsWidth - spacing - 20; + if (menuBar != null) { + maxWidth -= menuBar.getPreferredSize().width; + maxWidth -= spacing; + } + int cpw = Math.min(maxWidth, customTitlePanel.getPreferredSize().width); + int cph = h; + int cpx = leftToRight ? w - buttonsWidth - cpw : buttonsWidth; + int cpy = 0; + customTitlePanel.setBounds(cpx, cpy, cpw, cph); + buttonsWidth += customTitlePanel.getPreferredSize().width; + } + } + + public void layoutMacStyle(Container c) { + int spacing = getHorSpacing(); + int w = getWidth(); + int h = getHeight(); + + // assumes all buttons have the same dimensions these dimensions include the borders + int btnHeight = h - getVerSpacing() - 1; + int btnWidth = btnHeight; + + int x = 2; + int y = centerButtons() ? Math.max(0, ((h - btnHeight) / 2) - 1) : 0; + + if (closeButton != null) { + closeButton.setBounds(x, y, btnWidth, btnHeight); + x += btnWidth + spacing; + } + if ((iconifyButton != null) && (iconifyButton.getParent() != null)) { + iconifyButton.setBounds(x, y, btnWidth, btnHeight); + x += btnWidth + spacing; + } + if ((maxButton != null) && (maxButton.getParent() != null)) { + if (DecorationHelper.isFrameStateSupported(Toolkit.getDefaultToolkit(), BaseRootPaneUI.MAXIMIZED_BOTH)) { + maxButton.setBounds(x, y, btnWidth, btnHeight); + x += btnWidth + spacing; + } + } + + buttonsWidth = x; + + if (customTitlePanel != null) { + int cpx = buttonsWidth + 5; + int cpy = 0; + int cpw = customTitlePanel.getPreferredSize().width; + int cph = h; + customTitlePanel.setBounds(cpx, cpy, cpw, cph); + buttonsWidth += cpw + 5; + } + } + } + +//----------------------------------------------------------------------------------------------- + protected class PropertyChangeHandler implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent pce) { + String name = pce.getPropertyName(); + // Frame.state isn't currently bound. + if ("resizable".equals(name) || "state".equals(name)) { + Frame frame = getFrame(); + if (frame != null) { + setState(DecorationHelper.getExtendedState(frame), true); + } + if ("resizable".equals(name)) { + getRootPane().repaint(); + } + } else if ("title".equals(name)) { + repaint(); + } else if ("componentOrientation".equals(name)) { + revalidate(); + repaint(); +// // a call to setMaximizedBounds may cause an invalid frame size on multi screen environments +// // see: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6699851 +// // try and error to avoid the setMaximizedBounds bug +// } else if (!JTattooUtilities.isMac() && useMaximizedBounds && "windowMaximize".equals(name)) { +// Frame frame = getFrame(); +// if (frame != null) { +// GraphicsConfiguration gc = frame.getGraphicsConfiguration(); +// Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc); +// Rectangle screenBounds = gc.getBounds(); +// int x = Math.max(0, screenInsets.left); +// int y = Math.max(0, screenInsets.top); +// int w = screenBounds.width - (screenInsets.left + screenInsets.right); +// int h = screenBounds.height - (screenInsets.top + screenInsets.bottom); +// // Keep taskbar visible +// frame.setMaximizedBounds(new Rectangle(x, y, w, h)); +// } +// } else if (!JTattooUtilities.isMac() && useMaximizedBounds && "windowMaximized".equals(name)) { +// Frame frame = getFrame(); +// if (frame != null) { +// GraphicsConfiguration gc = frame.getGraphicsConfiguration(); +// Rectangle screenBounds = gc.getBounds(); +// if (frame.getSize().width > screenBounds.width || frame.getSize().height > screenBounds.height) { +// useMaximizedBounds = false; +// frame.setMaximizedBounds(null); +// restore(); +// maximize(); +// } +// } +// } else if (!JTattooUtilities.isMac() && "windowMoved".equals(name)) { +// useMaximizedBounds = true; + } + + if ("windowRestored".equals(name)) { + wasMaximized = false; + } else if ("windowMaximized".equals(name)) { + wasMaximized = true; + } + } + } + +//----------------------------------------------------------------------------------------------- + protected class WindowHandler extends WindowAdapter { + + public void windowDeiconified(WindowEvent e) { + if (JTattooUtilities.isMac() && JTattooUtilities.getJavaVersion() >= 1.7 && wasMaximized) { + SwingUtilities.invokeLater(new Runnable() { + + public void run() { + maximize(); + } + }); + } + } + + public void windowActivated(WindowEvent ev) { + setActive(true); + } + + public void windowDeactivated(WindowEvent ev) { + setActive(false); + } + } +} diff --git a/src/com/jtattoo/plaf/BaseToggleButtonUI.java b/src/com/jtattoo/plaf/BaseToggleButtonUI.java new file mode 100644 index 0000000..6f85400 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseToggleButtonUI.java @@ -0,0 +1,206 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import javax.swing.*; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.*; +import javax.swing.text.View; + +public class BaseToggleButtonUI extends BasicToggleButtonUI { + + private static final Rectangle viewRect = new Rectangle(); + private static final Rectangle textRect = new Rectangle(); + private static final Rectangle iconRect = new Rectangle(); + + public static ComponentUI createUI(JComponent b) { + return new BaseToggleButtonUI(); + } + + public void installDefaults(AbstractButton b) { + super.installDefaults(b); + b.setOpaque(false); + b.setRolloverEnabled(true); + } + + public void uninstallDefaults(AbstractButton b) { + super.uninstallDefaults(b); + b.setOpaque(true); + b.setRolloverEnabled(false); + } + + protected BasicButtonListener createButtonListener(AbstractButton b) { + return new BaseButtonListener(b); + } + + protected void paintBackground(Graphics g, AbstractButton b) { + if (!b.isContentAreaFilled() || (b.getParent() instanceof JMenuBar)) { + return; + } + + int width = b.getWidth(); + int height = b.getHeight(); + + ButtonModel model = b.getModel(); + Color colors[]; + if (b.isEnabled()) { + Color background = b.getBackground(); + if (background instanceof ColorUIResource) { + if (b.isRolloverEnabled() && model.isRollover()) { + colors = AbstractLookAndFeel.getTheme().getRolloverColors(); + } else if ((model.isPressed() && model.isArmed()) || model.isSelected()) { + colors = AbstractLookAndFeel.getTheme().getPressedColors(); + } else { + if (AbstractLookAndFeel.getTheme().doShowFocusFrame() && b.hasFocus()) { + colors = AbstractLookAndFeel.getTheme().getFocusColors(); + } else { + colors = AbstractLookAndFeel.getTheme().getButtonColors(); + } + } + } else { + if (model.isPressed() && model.isArmed()) { + colors = ColorHelper.createColorArr(ColorHelper.darker(background, 30), ColorHelper.darker(background, 10), 20); + } else if (b.isRolloverEnabled() && model.isRollover()) { + if (model.isSelected()) { + colors = ColorHelper.createColorArr(ColorHelper.darker(background, 20), background, 20); + } else { + colors = ColorHelper.createColorArr(ColorHelper.brighter(background, 50), ColorHelper.brighter(background, 10), 20); + } + } else if (model.isSelected()) { + colors = ColorHelper.createColorArr(ColorHelper.darker(background, 40), ColorHelper.darker(background, 20), 20); + } else { + colors = ColorHelper.createColorArr(ColorHelper.brighter(background, 30), ColorHelper.darker(background, 10), 20); + } + } + } else { // disabled + colors = AbstractLookAndFeel.getTheme().getDisabledColors(); + } + JTattooUtilities.fillHorGradient(g, colors, 1, 1, width - 2, height - 2); + } + + protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) { + ButtonModel model = b.getModel(); + FontMetrics fm = JTattooUtilities.getFontMetrics(b, g, b.getFont()); + int mnemIndex = (JTattooUtilities.getJavaVersion() >= 1.4) ? b.getDisplayedMnemonicIndex() : JTattooUtilities.findDisplayedMnemonicIndex(b.getText(), model.getMnemonic()); + if (model.isEnabled()) { + Color foreground = b.getForeground(); + Color background = b.getBackground(); + int offs = 0; + if ((model.isArmed() && model.isPressed()) || model.isSelected()) { + offs = 1; + if (foreground instanceof ColorUIResource && background instanceof ColorUIResource) { + foreground = AbstractLookAndFeel.getTheme().getPressedForegroundColor(); + } + } + if (model.isRollover()) { + if (foreground instanceof ColorUIResource && background instanceof ColorUIResource) { + foreground = AbstractLookAndFeel.getTheme().getRolloverForegroundColor(); + } + } + Object sc = b.getClientProperty("shadowColor"); + if (sc instanceof Color) { + g.setColor((Color)sc); + JTattooUtilities.drawStringUnderlineCharAt(b, g, text, mnemIndex, textRect.x + offs, textRect.y + fm.getAscent() * offs + 1); + } + g.setColor(foreground); + JTattooUtilities.drawStringUnderlineCharAt(b, g, text, mnemIndex, textRect.x + offs, textRect.y + fm.getAscent() + offs); + } else { + g.setColor(Color.white); + JTattooUtilities.drawStringUnderlineCharAt(b, g, text, mnemIndex, textRect.x + 1, textRect.y + fm.getAscent() + 1); + g.setColor(AbstractLookAndFeel.getDisabledForegroundColor()); + JTattooUtilities.drawStringUnderlineCharAt(b, g, text, mnemIndex, textRect.x, textRect.y + fm.getAscent()); + } + } + + protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect) { + g.setColor(AbstractLookAndFeel.getFocusColor()); + BasicGraphicsUtils.drawDashedRect(g, 4, 3, b.getWidth() - 8, b.getHeight() - 6); + } + + public void paint(Graphics g, JComponent c) { + Graphics2D g2D = (Graphics2D) g; + + AbstractButton b = (AbstractButton) c; + g.setFont(b.getFont()); + FontMetrics fm = JTattooUtilities.getFontMetrics(b, g, b.getFont()); + Insets insets = c.getInsets(); + + viewRect.x = insets.left; + viewRect.y = insets.top; + viewRect.width = b.getWidth() - (insets.right + viewRect.x); + viewRect.height = b.getHeight() - (insets.bottom + viewRect.y); + + textRect.x = textRect.y = textRect.width = textRect.height = 0; + iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0; + + int iconTextGap = defaultTextIconGap; + if (JTattooUtilities.getJavaVersion() >= 1.4) { + iconTextGap = b.getIconTextGap(); + } + + String text = SwingUtilities.layoutCompoundLabel( + c, fm, b.getText(), b.getIcon(), + b.getVerticalAlignment(), b.getHorizontalAlignment(), + b.getVerticalTextPosition(), b.getHorizontalTextPosition(), + viewRect, iconRect, textRect, + b.getText() == null ? 0 : iconTextGap); + + paintBackground(g, b); + + if (b.getIcon() != null) { + if (!b.isEnabled()) { + Composite savedComposite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); + g2D.setComposite(alpha); + paintIcon(g, c, iconRect); + g2D.setComposite(savedComposite); + } else { + paintIcon(g, c, iconRect); + } + } + + if (text != null && !text.equals("") && textRect != null) { + View v = (View) c.getClientProperty(BasicHTML.propertyKey); + if (v != null) { + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + v.paint(g, textRect); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } else { + paintText(g, b, textRect, text); + } + } + + if (b.isFocusPainted() && b.hasFocus()) { + paintFocus(g, b, viewRect, textRect, iconRect); + } + } +} diff --git a/src/com/jtattoo/plaf/BaseToolTipUI.java b/src/com/jtattoo/plaf/BaseToolTipUI.java new file mode 100644 index 0000000..1e41b73 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseToolTipUI.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. + * + * JTattoo is multiple licensed. If your are an open source developer you can use + * it under the terms and conditions of the GNU General Public License version 2.0 + * or later as published by the Free Software Foundation. + * + * see: gpl-2.0.txt + * + * If you pay for a license you will become a registered user who could use the + * software under the terms and conditions of the GNU Lesser General Public License + * version 2.0 or later with classpath exception as published by the Free Software + * Foundation. + * + * see: lgpl-2.0.txt + * see: classpath-exception.txt + * + * Registered users could also use JTattoo under the terms and conditions of the + * Apache License, Version 2.0 as published by the Apache Software Foundation. + * + * see: APACHE-LICENSE-2.0.txt + */ +package com.jtattoo.plaf; + +import java.awt.*; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.image.BufferedImage; +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.metal.MetalToolTipUI; + +/** + * @author Michael Hagen, Daniel Raedel + */ +public class BaseToolTipUI extends MetalToolTipUI { + + private boolean fancyLayout = false; + private ComponentListener popupWindowListener = null; + + public static ComponentUI createUI(JComponent c) { + return new BaseToolTipUI(); + } + + public void installUI(JComponent c) { + super.installUI(c); + int borderSize = AbstractLookAndFeel.getTheme().getTooltipBorderSize(); + int shadowSize = AbstractLookAndFeel.getTheme().getTooltipShadowSize(); + fancyLayout = DecorationHelper.isTranslucentWindowSupported() && ToolTipManager.sharedInstance().isLightWeightPopupEnabled(); + if (fancyLayout) { + c.setBorder(BorderFactory.createEmptyBorder(borderSize, borderSize + shadowSize, borderSize + shadowSize, borderSize + shadowSize)); + c.setOpaque(false); + Container parent = c.getParent(); + if (parent instanceof JPanel) { + ((JPanel) c.getParent()).setOpaque(false); + } + } else { + c.setBorder(BorderFactory.createEmptyBorder(borderSize, borderSize, borderSize, borderSize)); + } + } + + protected void installListeners(JComponent c) { + super.installListeners(c); + + // We must set the popup window to opaque because it is cached and reused within the PopupFactory + popupWindowListener = new ComponentAdapter() { + + public void componentHidden(ComponentEvent e) { + Window window = (Window)e.getComponent(); + DecorationHelper.setTranslucentWindow(window, false); + window.removeComponentListener(popupWindowListener); + } + }; + } + + public void paint(Graphics g, JComponent c) { + Graphics2D g2D = (Graphics2D) g; + Composite savedComposit = g2D.getComposite(); + Object savedRederingHint = g2D.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + int borderSize = AbstractLookAndFeel.getTheme().getTooltipBorderSize(); + int shadowSize = AbstractLookAndFeel.getTheme().getTooltipShadowSize(); + + int w = c.getWidth(); + int h = c.getHeight(); + Color backColor = AbstractLookAndFeel.getTheme().getTooltipBackgroundColor(); + + // We can't draw the fancyLayout if popup is medium weight + boolean mediumWeight = false; + Container parent = c.getParent(); + while (parent != null) { + if ((parent.getClass().getName().indexOf("MediumWeight") > 0)) { + mediumWeight = true; + break; + } + parent = parent.getParent(); + } + + // Paint the tooltip with a shadow border + if (!mediumWeight && fancyLayout && shadowSize > 0) { + parent = c.getParent(); + while (parent != null) { + if ((parent.getClass().getName().indexOf("HeavyWeightWindow") > 0) && (parent instanceof Window)) { + // Make the popup transparent + Window window = (Window)parent; + // Add a component listener to revert this operation if popup is closed + window.addComponentListener(popupWindowListener); + DecorationHelper.setTranslucentWindow(window, true); + break; + } + parent = parent.getParent(); + } + // draw the shadow + g2D.setColor(AbstractLookAndFeel.getTheme().getShadowColor()); + float[] composites = {0.01f, 0.02f, 0.04f, 0.06f, 0.08f, 0.12f}; + int shadowOffset = AbstractLookAndFeel.getTheme().isTooltipCastShadow() ? shadowSize : 0; + for (int i = 0; i < shadowSize; i++) { + g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, composites[i >= composites.length ? composites.length - 1 : i])); + g2D.fillRoundRect(i + shadowOffset, borderSize + i, w - (2 * i) - shadowOffset, h - borderSize - (2 * i), 12 - i, 12 - i); + + } + g2D.setComposite(savedComposit); + + // Draw background with borders + if (ColorHelper.getGrayValue(backColor) < 128) { + g2D.setColor(ColorHelper.brighter(AbstractLookAndFeel.getTheme().getBackgroundColor(), 20)); + } else { + g2D.setColor(Color.white); + + } + //g2D.fillRoundRect(shadowSize, 0, w - (2 * shadowSize) - 1, h - shadowSize - 1, 6, 6); + g2D.fillRoundRect(shadowSize, 0, w - (2 * shadowSize) - 1, h - shadowSize - 1, shadowSize, shadowSize); + g2D.setColor(ColorHelper.darker(backColor, 40)); + //g2D.drawRoundRect(shadowSize, 0, w - (2 * shadowSize) - 1, h - shadowSize - 1, 6, 6); + g2D.drawRoundRect(shadowSize, 0, w - (2 * shadowSize) - 1, h - shadowSize - 1, shadowSize, shadowSize); + g2D.setColor(ColorHelper.darker(backColor, 10)); + g2D.drawRect(borderSize + shadowSize - 1, borderSize - 1, w - (2 * borderSize) - (2 * shadowSize) + 1, h - (2 * borderSize) - shadowSize + 1); + + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, savedRederingHint); + // Draw the text. This must be done within an offscreen image because of a bug + // in the jdk, wich causes ugly antialiased font rendering when background is + // transparent and popup is heavy weight. + BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + Graphics2D big = bi.createGraphics(); + big.setClip(0, 0, w, h); + Paint savedPaint = big.getPaint(); + Color cHi; + Color cLo; + if (ColorHelper.getGrayValue(backColor) < 128) { + cHi = ColorHelper.brighter(backColor, 10); + cLo = ColorHelper.darker(backColor, 20); + } else { + cHi = ColorHelper.brighter(backColor, 40); + cLo = ColorHelper.darker(backColor, 5); + } + big.setPaint(new GradientPaint(0, borderSize, cHi, 0, h - (2 * borderSize) - shadowSize, cLo)); + big.fillRect(borderSize + shadowSize, borderSize, w - (2 * borderSize) - (2 * shadowSize), h - (2 * borderSize) - shadowSize); + + big.setPaint(savedPaint); + + if (c instanceof JToolTip) { + JToolTip tip = (JToolTip) c; + if (tip.getComponent() != null && tip.getComponent().isEnabled()) { + c.setForeground(AbstractLookAndFeel.getTheme().getTooltipForegroundColor()); + } else { + c.setForeground(AbstractLookAndFeel.getTheme().getDisabledForegroundColor()); + } + } + super.paint(big, c); + g2D.setClip(borderSize + shadowSize, borderSize, w - (2 * borderSize) - (2 * shadowSize), h - (2 * borderSize) - shadowSize); + g2D.drawImage(bi, 0, 0, null); + + } else { + // Draw background with borders + if (ColorHelper.getGrayValue(backColor) < 128) { + g2D.setColor(ColorHelper.brighter(AbstractLookAndFeel.getTheme().getBackgroundColor(), 20)); + } else { + g2D.setColor(Color.white); + } + g2D.fillRect(0, 0, w, h); + g2D.setColor(ColorHelper.darker(backColor, 40)); + g2D.drawRect(0, 0, w - 1, h - 1); + g2D.setColor(ColorHelper.darker(backColor, 10)); + g2D.drawRect(borderSize - 1, borderSize - 1, w - (2 * borderSize - 1), h - (2 * borderSize - 1)); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, savedRederingHint); + + Paint savedPaint = g2D.getPaint(); + Color cHi; + Color cLo; + if (ColorHelper.getGrayValue(backColor) < 128) { + cHi = ColorHelper.brighter(backColor, 10); + cLo = ColorHelper.darker(backColor, 20); + } else { + cHi = ColorHelper.brighter(backColor, 40); + cLo = ColorHelper.darker(backColor, 5); + } + g2D.setPaint(new GradientPaint(0, borderSize, cHi, 0, h - (2 * borderSize), cLo)); + g2D.fillRect(borderSize, borderSize, w - (2 * borderSize), h - (2 * borderSize)); + g2D.setPaint(savedPaint); + + super.paint(g, c); + } + } +} diff --git a/src/com/jtattoo/plaf/BaseTreeUI.java b/src/com/jtattoo/plaf/BaseTreeUI.java new file mode 100644 index 0000000..c1cc5d2 --- /dev/null +++ b/src/com/jtattoo/plaf/BaseTreeUI.java @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicTreeUI; + +/** + * author Michael Hagen + */ +public class BaseTreeUI extends BasicTreeUI { + + public static ComponentUI createUI(JComponent c) { + return new BaseTreeUI(); + } + + protected void paintVerticalLine(Graphics g, JComponent c, int x, int top, int bottom) { + drawDashedVerticalLine(g, x, top, bottom); + } + + protected void paintHorizontalLine(Graphics g, JComponent c, int y, int left, int right) { + drawDashedHorizontalLine(g, y, left, right); + } +} + + diff --git a/src/com/jtattoo/plaf/ColorHelper.java b/src/com/jtattoo/plaf/ColorHelper.java new file mode 100644 index 0000000..2be0bb8 --- /dev/null +++ b/src/com/jtattoo/plaf/ColorHelper.java @@ -0,0 +1,205 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.Color; + +/** + * A helper class for handling color values. + * + * @author Michael Hagen + */ +public class ColorHelper { + + /** + * Avoid creation of this class. This class only contains static helper methods, so creation of an object + * is not necessary. + */ + private ColorHelper() { + } + + /** + * Creates a color object. + * + * @param r the Red component + * @param g the Green component + * @param b the Blue component + * + * @return a color object + */ + public static Color createColor(int r, int g, int b) { + return new Color(((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF))); + } + + /** + * Creates an array of color values. The colors created will be a gradient from color c1 to color c1 with a count + * of steps values. + * + * @param c1 the starting color + * @param c2 the ending color + * @param steps the number of steps between c1 and c2 (the size of the created array) + * + * @return the array of color values + */ + public static Color[] createColorArr(Color c1, Color c2, int steps) { + if (c1 == null || c2 == null) { + return null; + } + + Color colors[] = new Color[steps]; + double r = c1.getRed(); + double g = c1.getGreen(); + double b = c1.getBlue(); + double dr = ((double) c2.getRed() - r) / steps; + double dg = ((double) c2.getGreen() - g) / steps; + double db = ((double) c2.getBlue() - b) / steps; + colors[0] = c1; + for (int i = 1; i < steps - 1; i++) { + r += dr; + g += dg; + b += db; + colors[i] = createColor((int) r, (int) g, (int) b); + } + colors[steps - 1] = c2; + return colors; + } + + /** + * Creates a color that is the brighter version of the color parameter c. + * + * @param c the color + * @param p the factor of the brightness in percent from 0 to 100 + * @return a new color value that is a brighter version of the color parameter c + */ + public static Color brighter(Color c, double p) { + if (c == null) { + return null; + } + + double r = c.getRed(); + double g = c.getGreen(); + double b = c.getBlue(); + + double rd = 255.0 - r; + double gd = 255.0 - g; + double bd = 255.0 - b; + + r += (rd * p) / 100.0; + g += (gd * p) / 100.0; + b += (bd * p) / 100.0; + return createColor((int) r, (int) g, (int) b); + } + + /** + * Creates a color that is the darker version of the color parameter c. + * + * @param c the color + * @param p the factor to shade the color c in percent from 0 to 100 + * + * @return a new color value that is a darker version of the color parameter c + */ + public static Color darker(Color c, double p) { + if (c == null) { + return null; + } + + double r = c.getRed(); + double g = c.getGreen(); + double b = c.getBlue(); + + r -= (r * p) / 100.0; + g -= (g * p) / 100.0; + b -= (b * p) / 100.0; + + return createColor((int) r, (int) g, (int) b); + } + + /** + * Returns a color value which is the media between the colors c1 and c1 + * + * @param c1 the first color + * @param c2 the second color + * + * @return the median color value of the two colors c1 and c1 + */ + public static Color median(Color c1, Color c2) { + if ((c1 == null || c2 == null)) { + return null; + } + + int r = (c1.getRed() + c2.getRed()) / 2; + int g = (c1.getGreen() + c2.getGreen()) / 2; + int b = (c1.getBlue() + c2.getBlue()) / 2; + return createColor(r, g, b); + } + + /** + * Returns a value between 0 and 255 which represents the gray value of the color parameter. + * + * @param c the color you want to calculate the gray value + * + * @return the gray value + */ + public static int getGrayValue(Color c) { + if (c == null) { + return 0; + } + + double r = c.getRed(); + double g = c.getGreen(); + double b = c.getBlue(); + return Math.min(255, (int) (r * 0.28 + g * 0.59 + b * 0.13)); + } + + /** + * Returns a value between 0 and 255 which represents the median gray value of the color array. + * + * @param ca the color array you want to calculate the gray value + * + * @return the gray value + */ + public static int getGrayValue(Color[] ca) { + int sum = 0; + for (int i = 0; i < ca.length; i++) { + sum += getGrayValue(ca[i]); + } + return (sum / ca.length); + } + + /** + * Returns a gray version of the color parameter c, which means all parts (r,g,b) do have the same value. + * + * @param c the color + * + * @return a gray version of the color parameter c. + */ + public static Color toGray(Color c) { + if (c == null) { + return null; + } + + int gray = getGrayValue(c); + return new Color(gray, gray, gray, c.getAlpha()); + } +} diff --git a/src/com/jtattoo/plaf/DecorationHelper.java b/src/com/jtattoo/plaf/DecorationHelper.java new file mode 100644 index 0000000..a5b0939 --- /dev/null +++ b/src/com/jtattoo/plaf/DecorationHelper.java @@ -0,0 +1,146 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.lang.reflect.Method; +import javax.swing.*; + +/** + * @author Michael Hagen + */ +public class DecorationHelper { + + private DecorationHelper() { + } + + public static void decorateWindows(Boolean decorate) { + if (JTattooUtilities.getJavaVersion() >= 1.4) { + try { + Class classParams[] = {Boolean.TYPE}; + Method m = JFrame.class.getMethod("setDefaultLookAndFeelDecorated", classParams); + Object methodParams[] = {decorate}; + m.invoke(null, methodParams); + m = JDialog.class.getMethod("setDefaultLookAndFeelDecorated", classParams); + m.invoke(null, methodParams); + System.setProperty("sun.awt.noerasebackground", "true"); + System.setProperty("sun.awt.erasebackgroundonresize", "false"); + } catch (Exception ex) { + } + } + } + + public static int getWindowDecorationStyle(JRootPane root) { + if (JTattooUtilities.getJavaVersion() >= 1.4) { + try { + Class paramTypes[] = null; + Object args[] = null; + Method m = root.getClass().getMethod("getWindowDecorationStyle", paramTypes); + Integer i = (Integer) m.invoke(root, args); + return i.intValue(); + } catch (Exception ex) { + } + } + return 0; + } + + @SuppressWarnings("unchecked") + public static int getExtendedState(Frame frame) { + if (JTattooUtilities.getJavaVersion() >= 1.4) { + try { + Class paramTypes[] = null; + Object args[] = null; + Method m = frame.getClass().getMethod("getExtendedState", paramTypes); + Integer i = (Integer) m.invoke(frame, args); + return i.intValue(); + } catch (Exception ex) { + } + } + return 0; + } + + @SuppressWarnings("unchecked") + public static void setExtendedState(Frame frame, int state) { + if (JTattooUtilities.getJavaVersion() >= 1.4) { + try { + Class classParams[] = {Integer.TYPE}; + Method m = frame.getClass().getMethod("setExtendedState", classParams); + Object methodParams[] = {state}; + m.invoke(frame, methodParams); + } catch (Exception ex) { + } + } + } + + @SuppressWarnings("unchecked") + public static boolean isFrameStateSupported(Toolkit tk, int state) { + if (JTattooUtilities.getJavaVersion() >= 1.4) { + try { + Class classParams[] = {Integer.TYPE}; + Method m = tk.getClass().getMethod("isFrameStateSupported", classParams); + Object methodParams[] = {state}; + Boolean b = (Boolean) m.invoke(tk, methodParams); + return b.booleanValue(); + } catch (Exception ex) { + } + } + return false; + } + + public static boolean isTranslucentWindowSupported() { + return (JTattooUtilities.getJavaVersion() >= 1.6010) && (JTattooUtilities.isMac() || JTattooUtilities.isWindows()); + } + + @SuppressWarnings("unchecked") + public static void setTranslucentWindow(Window wnd, boolean translucent) { + if (isTranslucentWindowSupported()) { + if (JTattooUtilities.getJavaVersion() >= 1.7) { + if (translucent) { + if (wnd.getBackground() == null || !wnd.getBackground().equals(new Color(0, 0, 0, 0))) { + wnd.setBackground(new Color(0, 0, 0, 0)); + } + } else { + if (wnd.getBackground() == null || !wnd.getBackground().equals(new Color(0, 0, 0, 0xff))) { + wnd.setBackground(new Color(0, 0, 0, 0xff)); + } + } + } else if (JTattooUtilities.getJavaVersion() >= 1.6010) { + try { + Class clazz = Class.forName("com.sun.awt.AWTUtilities"); + Class classParams[] = {Window.class, Boolean.TYPE}; + Method method = clazz.getMethod("setWindowOpaque", classParams); + if (translucent) { + Object methodParams[] = {wnd, Boolean.FALSE}; + method.invoke(wnd, methodParams); + } else { + Object methodParams[] = {wnd, Boolean.TRUE}; + method.invoke(wnd, methodParams); + } + } catch (Exception ex) { + } + } + } + } + +} diff --git a/src/com/jtattoo/plaf/JTattooUtilities.java b/src/com/jtattoo/plaf/JTattooUtilities.java new file mode 100644 index 0000000..d00dd7c --- /dev/null +++ b/src/com/jtattoo/plaf/JTattooUtilities.java @@ -0,0 +1,577 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import java.lang.reflect.Method; +import javax.swing.*; +import javax.swing.plaf.basic.BasicGraphicsUtils; + +/** + * @author Michael Hagen + */ +public class JTattooUtilities { + + private static final boolean isWindows = System.getProperty("os.name").toLowerCase().indexOf("windows") != -1; + private static final boolean isOS2 = System.getProperty("os.name").toLowerCase().indexOf("os/2") != -1; + private static final boolean isMac = System.getProperty("os.name").toLowerCase().indexOf("mac") != -1; + private static final boolean isLinux = System.getProperty("os.name").toLowerCase().indexOf("linux") != -1; + private static final boolean isSunOS = System.getProperty("os.name").toLowerCase().indexOf("sunos") != -1; + private static final boolean isAIX = System.getProperty("os.name").toLowerCase().indexOf("aix") != -1; + private static final boolean isHPUX = System.getProperty("os.name").toLowerCase().indexOf("hpux") != -1; + private static final boolean isFreeBSD = System.getProperty("os.name").toLowerCase().indexOf("freebsd") != -1; + private static final boolean isHiresScreen = Toolkit.getDefaultToolkit().getScreenSize().width > 1280; + private static Double javaVersion = null; + private static Double osVersion = null; + private static final String ELLIPSIS = "..."; + + public static double getJavaVersion() { + if (javaVersion == null) { + try { + String ver = System.getProperty("java.version"); + String version = ""; + boolean firstPoint = true; + for (int i = 0; i < ver.length(); i++) { + if (ver.charAt(i) == '.') { + if (firstPoint) { + version += ver.charAt(i); + } + firstPoint = false; + } else if (Character.isDigit(ver.charAt(i))) { + version += ver.charAt(i); + } + } + javaVersion = Double.parseDouble(version); + } catch (Exception ex) { + javaVersion = 1.3d; + } + } + return javaVersion.doubleValue(); + } + + public static double getOSVersion() { + if (osVersion == null) { + try { + String ver = System.getProperties().getProperty("os.version"); + String version = ""; + boolean firstPoint = true; + for (int i = 0; i < ver.length(); i++) { + if (ver.charAt(i) == '.') { + if (firstPoint) { + version += ver.charAt(i); + } + firstPoint = false; + } else if (Character.isDigit(ver.charAt(i))) { + version += ver.charAt(i); + } + } + osVersion = Double.parseDouble(version); + } catch (Exception ex) { + osVersion = 1.0d; + } + } + return osVersion.doubleValue(); + } + + public static boolean isWindows() { + return isWindows; + } + + public static boolean isOS2() { + return isOS2; + } + + public static boolean isMac() { + return isMac; + } + + public static boolean isLinux() { + return isLinux; + } + + public static boolean isSunOS() { + return isSunOS; + } + + public static boolean isAIX() { + return isAIX; + } + + public static boolean isHPUX() { + return isHPUX; + } + + public static boolean isFreeBSD() { + return isFreeBSD; + } + + public static boolean isHiresScreen() { + return isHiresScreen; + } + + public static boolean isLeftToRight(Component c) { + if (c == null) { + return true; + } + return c.getComponentOrientation().isLeftToRight(); + } + + public static boolean isActive(JComponent c) { + if (c == null) { + return false; + } + boolean active = true; + if (c instanceof JInternalFrame) { + active = ((JInternalFrame) c).isSelected(); + } + if (active) { + Container parent = c.getParent(); + while (parent != null) { + if (parent instanceof JInternalFrame) { + active = ((JInternalFrame) parent).isSelected(); + break; + } + parent = parent.getParent(); + } + } + if (active) { + active = isFrameActive(c); + } + return active; + } + + public static boolean isFrameActive(Component c) { + if (c == null) { + return false; + } + Window w = SwingUtilities.getWindowAncestor(c); + if (w != null) { + if (w.getClass().getName().indexOf("Popup") >= 0) { + return true; + } else { + return isWindowActive(w); + } + } + + return true; + } + + public static boolean isWindowActive(Window window) { + if (getJavaVersion() >= 1.4) { + try { + Class paramTypes[] = null; + Object args[] = null; + Method m = window.getClass().getMethod("isActive", paramTypes); + Boolean b = (Boolean) m.invoke(window, args); + return b.booleanValue(); + } catch (Exception ex) { + } + } + return true; + } + + public static Container getRootContainer(Component c) { + if (c == null) { + return null; + } + Container parent = c.getParent(); + while ((parent != null) && !(parent instanceof JPopupMenu) && !(parent instanceof JInternalFrame) && !(parent instanceof Window) && (parent.getParent() != null)) { + parent = parent.getParent(); + } + return parent; + } + + public static Dimension getFrameSize(Component c) { + Container parent = getRootContainer(c); + if (parent != null) { + return parent.getSize(); + } + return Toolkit.getDefaultToolkit().getScreenSize(); + } + + public static Point getRelLocation(Component c) { + if (c == null || !c.isShowing()) { + return new Point(0, 0); + } + + Container parent = getRootContainer(c); + if ((parent != null) && parent.isShowing()) { + Point p1 = c.getLocationOnScreen(); + Point p2 = parent.getLocationOnScreen(); + return new Point(p1.x - p2.x, p1.y - p2.y); + } + + return new Point(0, 0); + } + + public static String getClippedText(String text, FontMetrics fm, int maxWidth) { + if ((text == null) || (text.length() == 0)) { + return ""; + } + int width = SwingUtilities.computeStringWidth(fm, text); + if (width > maxWidth) { + int totalWidth = SwingUtilities.computeStringWidth(fm, ELLIPSIS); + for (int i = 0; i < text.length(); i++) { + totalWidth += fm.charWidth(text.charAt(i)); + if (totalWidth > maxWidth) { + return text.substring(0, i) + ELLIPSIS; + } + } + } + return text; + } + + public static int findDisplayedMnemonicIndex(String text, int mnemonic) { + if (text == null || mnemonic == '\0') { + return -1; + } + + char uc = Character.toUpperCase((char)mnemonic); + char lc = Character.toLowerCase((char)mnemonic); + + int uci = text.indexOf(uc); + int lci = text.indexOf(lc); + + if (uci == -1) { + return lci; + } else if(lci == -1) { + return uci; + } else { + return (lci < uci) ? lci : uci; + } + } + + @SuppressWarnings("unchecked") + public static FontMetrics getFontMetrics(JComponent c, Graphics g, Font f) { + FontMetrics fm = null; + if (getJavaVersion() >= 1.6 && getJavaVersion() <= 1.9) { + try { + Class swingUtilities2Class = Class.forName("sun.swing.SwingUtilities2"); + Class classParams[] = {JComponent.class, Graphics.class, Font.class}; + Method m = swingUtilities2Class.getMethod("getFontMetrics", classParams); + Object methodParams[] = {c, g, f}; + fm = (FontMetrics)m.invoke(null, methodParams); + } catch (Exception ex) { + // Nothing to do + } + } + if (fm == null) { + if (g == null) { + if (c != null) { + g = c.getGraphics(); + } + } + if (g != null) { + if (f != null) { + fm = g.getFontMetrics(f); + } else { + fm = g.getFontMetrics(); + } + } else if (c != null) { + if (f != null) { + fm = c.getFontMetrics(f); + } else { + fm = c.getFontMetrics(c.getFont()); + } + } + } + return fm; + } + + @SuppressWarnings("unchecked") + public static void drawString(JComponent c, Graphics g, String text, int x, int y) { + Graphics2D g2D = (Graphics2D) g; + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + if (getJavaVersion() >= 1.6) { + try { + Class swingUtilities2Class = Class.forName("sun.swing.SwingUtilities2"); + Class classParams[] = {JComponent.class, Graphics.class, String.class, Integer.TYPE, Integer.TYPE}; + Method m = swingUtilities2Class.getMethod("drawString", classParams); + Object methodParams[] = {c, g, text, x, y}; + m.invoke(null, methodParams); + } catch (Exception ex) { + g.drawString(text, x, y); + } + } else { + g.drawString(text, x, y); + } + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } + + @SuppressWarnings("unchecked") + public static void drawStringUnderlineCharAt(JComponent c, Graphics g, String text, int underlinedIndex, int x, int y) { + Graphics2D g2D = (Graphics2D) g; + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + if (getJavaVersion() >= 1.6 && getJavaVersion() <= 1.9) { + try { + Class swingUtilities2Class = Class.forName("sun.swing.SwingUtilities2"); + Class classParams[] = {JComponent.class, Graphics.class, String.class, Integer.TYPE, Integer.TYPE, Integer.TYPE}; + Method m = swingUtilities2Class.getMethod("drawStringUnderlineCharAt", classParams); + Object methodParams[] = {c, g, text, underlinedIndex, x, y}; + m.invoke(null, methodParams); + } catch (Exception ex) { + BasicGraphicsUtils.drawString(g, text, underlinedIndex, x, y); + } + } else if (getJavaVersion() >= 1.4) { + BasicGraphicsUtils.drawStringUnderlineCharAt(g, text, underlinedIndex, x, y); + } else { + BasicGraphicsUtils.drawString(g, text, underlinedIndex, x, y); + } + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } + + public static void fillHorGradient(Graphics g, Color[] colors, int x, int y, int w, int h) { + if (colors != null) { + int steps = colors.length; + double dy = (double) h / (double) (steps); + if (dy <= 2.001) { + int y1 = y; + for (int i = 0; i < steps; i++) { + int y2 = y + (int) Math.round((double) i * dy); + g.setColor(colors[i]); + if (i == (steps - 1)) { + g.fillRect(x, y1, w, y + h - y1); + } else { + g.fillRect(x, y1, w, y2 - y1); + } + y1 = y2; + } + } else { + smoothFillHorGradient(g, colors, x, y, w, h); + } + } + } + + public static void smoothFillHorGradient(Graphics g, Color[] colors, int x, int y, int w, int h) { + if (colors != null) { + Graphics2D g2D = (Graphics2D) g; + Paint savedPaint = g2D.getPaint(); + int steps = colors.length; + double dy = (double) h / (double) (steps - 1); + int y1 = y; + for (int i = 0; i < steps; i++) { + int y2 = y + (int) Math.round((double) i * dy); + if (i == (steps - 1)) { + g2D.setPaint(null); + g2D.setColor(colors[i]); + g2D.fillRect(x, y1, w, y + h - y1); + } else { + g2D.setPaint(new GradientPaint(0, y1, colors[i], 0, y2, colors[i + 1])); + g2D.fillRect(x, y1, w, y2 - y1); + } + y1 = y2; + } + g2D.setPaint(savedPaint); + } + } + + public static void fillInverseHorGradient(Graphics g, Color[] colors, int x, int y, int w, int h) { + if (colors != null) { + int steps = colors.length; + double dy = (double) h / (double) steps; + if (dy <= 2.001) { + int y1 = y; + for (int i = 0; i < steps; i++) { + int y2 = y + (int) Math.round((double) i * dy); + g.setColor(colors[colors.length - i - 1]); + if (i == (steps - 1)) { + g.fillRect(x, y1, w, y + h - y1); + } else { + g.fillRect(x, y1, w, y2 - y1); + } + y1 = y2; + } + } else { + smoothFillInverseHorGradient(g, colors, x, y, w, h); + } + } + } + + public static void smoothFillInverseHorGradient(Graphics g, Color[] colors, int x, int y, int w, int h) { + if (colors != null) { + Graphics2D g2D = (Graphics2D) g; + Paint savedPaint = g2D.getPaint(); + int steps = colors.length; + double dy = (double) h / (double) steps; + int y1 = y; + for (int i = 0; i < steps; i++) { + int y2 = y + (int) Math.round((double) i * dy); + g.setColor(colors[colors.length - i - 1]); + if (i == (steps - 1)) { + g2D.setPaint(null); + g2D.setColor(colors[colors.length - i - 1]); + g.fillRect(x, y1, w, y + h - y1); + } else { + g2D.setPaint(new GradientPaint(0, y1, colors[colors.length - i - 1], 0, y2, colors[colors.length - i - 2])); + g.fillRect(x, y1, w, y2 - y1); + } + y1 = y2; + } + g2D.setPaint(savedPaint); + } + } + + public static void fillVerGradient(Graphics g, Color[] colors, int x, int y, int w, int h) { + if (colors != null) { + int steps = colors.length; + double dx = (double) w / (double) steps; + int x1 = x; + for (int i = 0; i < steps; i++) { + int x2 = x + (int) Math.round((double) i * dx); + g.setColor(colors[i]); + if (i == (steps - 1)) { + g.fillRect(x1, y, x + w - x1, h); + } else { + g.fillRect(x1, y, x2 - x1, h); + } + x1 = x2; + } + } + } + + public static void fillInverseVerGradient(Graphics g, Color[] colors, int x, int y, int w, int h) { + if (colors != null) { + int steps = colors.length; + double dx = (double) w / (double) steps; + int x1 = x; + for (int i = 0; i < steps; i++) { + int x2 = x + (int) Math.round((double) i * dx); + g.setColor(colors[colors.length - i - 1]); + if (i == (steps - 1)) { + g.fillRect(x1, y, x + w - x1, h); + } else { + g.fillRect(x1, y, x2 - x1, h); + } + x1 = x2; + } + } + } + + public static void fillComponent(Graphics g, Component c, Icon texture) { + int x = 0; + int y = 0; + int w = c.getWidth(); + int h = c.getHeight(); + if (texture != null) { + int tw = texture.getIconWidth(); + int th = texture.getIconHeight(); + Point p = JTattooUtilities.getRelLocation(c); + y = -p.y; + while (y < h) { + x = -p.x; + while (x < w) { + texture.paintIcon(c, g, x, y); + x += tw; + } + y += th; + } + } else { + g.setColor(c.getBackground()); + g.fillRect(x, y, w, h); + } + } + + //------------------------------------------------------------------------------------------- + + public static void drawBorder(Graphics g, Color c, int x, int y, int w, int h) { + g.setColor(c); + g.drawRect(x, y, w - 1, h - 1); + } + + public static void draw3DBorder(Graphics g, Color c1, Color c2, int x, int y, int w, int h) { + int x2 = x + w - 1; + int y2 = y + h - 1; + g.setColor(c1); + g.drawLine(x, y, x2 - 1, y); + g.drawLine(x, y + 1, x, y2); + g.setColor(c2); + g.drawLine(x, y2, x2 - 1, y2); + g.drawLine(x2, y, x2, y2); + } + + public static void drawRoundBorder(Graphics g, Color c, int x, int y, int w, int h, int r) { + Graphics2D g2D = (Graphics2D) g; + Object savedRederingHint = g2D.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2D.setColor(c); + g2D.drawRoundRect(x, y, w - 1, h - 1, r, r); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, savedRederingHint); + } + + public static void drawRound3DBorder(Graphics g, Color c1, Color c2, int x, int y, int w, int h) { + Graphics2D g2D = (Graphics2D) g; + int x2 = x + w; + int y2 = y + h; + int d = h; + int r = h / 2; + Color cm = ColorHelper.median(c1, c2); + Color c1m = ColorHelper.median(c1, cm); + Color c2m = ColorHelper.median(c2, cm); + + Object savedRederingHint = g2D.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + // oben + g2D.setColor(c1); + g2D.drawLine(x + r, y, x2 - r, y); + // rechts + g2D.drawLine(x, y + r, x, y2 - r); + // unten + g2D.setColor(c2); + g2D.drawLine(x + r, y2, x2 - r, y2); + // links + g2D.drawLine(x2, y + r, x2, y2 - r); + + // links + g2D.setColor(c1); + g2D.drawArc(x, y, d, d, 90, 45); + g2D.setColor(c1m); + g2D.drawArc(x, y, d, d, 135, 45); + g2D.setColor(cm); + g2D.drawArc(x, y, d, d, 180, 45); + g2D.setColor(c2m); + g2D.drawArc(x, y, d, d, 225, 45); + // rechts + g2D.setColor(c1m); + g2D.drawArc(x2 - d, y, d, d, 45, 45); + g2D.setColor(cm); + g2D.drawArc(x2 - d, y, d, d, 0, 45); + g2D.setColor(c2m); + g2D.drawArc(x2 - d, y, d, d, -45, 45); + g2D.setColor(c2); + g2D.drawArc(x2 - d, y, d, d, -90, 45); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, savedRederingHint); + } +} diff --git a/src/com/jtattoo/plaf/LazyImageIcon.java b/src/com/jtattoo/plaf/LazyImageIcon.java new file mode 100644 index 0000000..fd20a79 --- /dev/null +++ b/src/com/jtattoo/plaf/LazyImageIcon.java @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import javax.swing.Icon; +import javax.swing.ImageIcon; + +/** + * + * @author Michael Hagen + */ +public class LazyImageIcon implements Icon { + + private String name = null; + private ImageIcon icon = null; + + public LazyImageIcon(String name) { + this.name = name; + } + + private Icon getIcon() { + if (icon == null) { + try { + icon = new ImageIcon(LazyImageIcon.class.getResource(name)); + } catch (Throwable t) { + System.out.println("ERROR: loading image " + name + " failed!"); + } + } + return icon; + } + + public Image getImage() { + if (getIcon() != null) { + return icon.getImage(); + } + return null; + } + + public int getIconHeight() { + if (getIcon() != null) { + return icon.getIconHeight(); + } else { + return 16; + } + } + + public int getIconWidth() { + if (getIcon() != null) { + return icon.getIconWidth(); + } else { + return 16; + } + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + if (getIcon() != null) { + icon.paintIcon(c, g, x, y); + } else { + g.setColor(Color.red); + g.fillRect(x, y, 16, 16); + g.setColor(Color.white); + g.drawLine(x, y, x + 15, y + 15); + g.drawLine(x + 15, y, x, y + 15); + } + } + +} diff --git a/src/com/jtattoo/plaf/LazyMenuArrowImageIcon.java b/src/com/jtattoo/plaf/LazyMenuArrowImageIcon.java new file mode 100644 index 0000000..ec5bd0d --- /dev/null +++ b/src/com/jtattoo/plaf/LazyMenuArrowImageIcon.java @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import javax.swing.Icon; +import javax.swing.ImageIcon; + +/** + * + * @author Michael Hagen + */ +public class LazyMenuArrowImageIcon implements Icon { + + private String leftToRightName = null; + private String rightToLefttName = null; + private Icon leftToRightIcon = null; + private Icon rightToLeftIcon = null; + + public LazyMenuArrowImageIcon(String leftToRightName, String rightToLefttName) { + this.leftToRightName = leftToRightName; + this.rightToLefttName = rightToLefttName; + } + + private Icon getLeftToRightIcon() { + if (leftToRightIcon == null) { + try { + leftToRightIcon = new ImageIcon(LazyMenuArrowImageIcon.class.getResource(leftToRightName)); + } catch (Throwable t) { + System.out.println("ERROR: loading image " + leftToRightName + " failed!"); + } + } + return leftToRightIcon; + } + + private Icon getRightToLeftIcon() { + if (rightToLeftIcon == null) { + try { + rightToLeftIcon = new ImageIcon(LazyMenuArrowImageIcon.class.getResource(rightToLefttName)); + } catch (Throwable t) { + System.out.println("ERROR: loading image " + rightToLefttName + " failed!"); + } + } + return rightToLeftIcon; + } + + private Icon getIcon(Component c) { + if (JTattooUtilities.isLeftToRight(c)) { + return getLeftToRightIcon(); + } else { + return getRightToLeftIcon(); + } + } + + public int getIconHeight() { + Icon ico = getIcon(null); + if (ico != null) { + return ico.getIconHeight(); + } else { + return 16; + } + } + + public int getIconWidth() { + Icon ico = getIcon(null); + if (ico != null) { + return ico.getIconWidth(); + } else { + return 16; + } + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + Icon ico = getIcon(c); + if (ico != null) { + ico.paintIcon(c, g, x, y); + } else { + g.setColor(Color.red); + g.fillRect(x, y, 16, 16); + g.setColor(Color.white); + g.drawLine(x, y, x + 15, y + 15); + g.drawLine(x + 15, y, x, y + 15); + } + } + +} diff --git a/src/com/jtattoo/plaf/NoFocusButton.java b/src/com/jtattoo/plaf/NoFocusButton.java new file mode 100644 index 0000000..56a7f5c --- /dev/null +++ b/src/com/jtattoo/plaf/NoFocusButton.java @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import javax.swing.Icon; +import javax.swing.JButton; + +/** + * @author Michael Hagen + */ +public class NoFocusButton extends JButton { + + public NoFocusButton() { + super(); + init(); + } + + public NoFocusButton(Icon ico) { + super(ico); + init(); + } + + private void init() { + setFocusPainted(false); + setRolloverEnabled(true); + if (JTattooUtilities.getJavaVersion() >= 1.4) { + setFocusable(false); + } + } + + @SuppressWarnings("deprecation") + public boolean isFocusTraversable() { + return false; + } + + public void requestFocus() { + } +} diff --git a/src/com/jtattoo/plaf/TitlePane.java b/src/com/jtattoo/plaf/TitlePane.java new file mode 100644 index 0000000..850404a --- /dev/null +++ b/src/com/jtattoo/plaf/TitlePane.java @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +/** + * + * @author Michael Hagen + */ +public interface TitlePane { + + public void iconify(); + public void maximize(); + public void restore(); + public void close(); + +} diff --git a/src/com/jtattoo/plaf/XPScrollBarUI.java b/src/com/jtattoo/plaf/XPScrollBarUI.java new file mode 100644 index 0000000..1658f91 --- /dev/null +++ b/src/com/jtattoo/plaf/XPScrollBarUI.java @@ -0,0 +1,148 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import javax.swing.*; +import javax.swing.plaf.ComponentUI; + +/** + * + * @author Michael Hagen + */ +public class XPScrollBarUI extends BaseScrollBarUI { + + protected static Color rolloverColors[] = null; + protected static Color dragColors[] = null; + + public static ComponentUI createUI(JComponent c) { + return new XPScrollBarUI(); + } + + protected void installDefaults() { + super.installDefaults(); + Color colors[] = AbstractLookAndFeel.getTheme().getThumbColors(); + rolloverColors = new Color[colors.length]; + dragColors = new Color[colors.length]; + for (int i = 0; i < colors.length; i++) { + rolloverColors[i] = ColorHelper.brighter(colors[i], 16); + dragColors[i] = ColorHelper.darker(colors[i], 8); + } + } + + protected Color getFrameColor() { + return Color.white; + } + + protected Color[] getThumbColors() { + if (isDragging) { + return dragColors; + } + if (isRollover) { + return rolloverColors; + } + return AbstractLookAndFeel.getTheme().getThumbColors(); + } + + protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) { + if (!c.isEnabled()) { + return; + } + + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + + int x = thumbBounds.x; + int y = thumbBounds.y; + int width = thumbBounds.width; + int height = thumbBounds.height; + + g.translate(x, y); + + Color[] colors = getThumbColors(); + if (scrollbar.getOrientation() == JScrollBar.VERTICAL) { + JTattooUtilities.fillVerGradient(g, colors, 0, 0, width, height); + if (!AbstractLookAndFeel.getTheme().isMacStyleScrollBarOn()) { + int dx = 6; + int dy = height / 2 - 3; + int dw = width - 13; + Color c1 = ColorHelper.brighter(colors[0], 60); + Color c2 = ColorHelper.darker(colors[0], 30); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f); + g2D.setComposite(alpha); + for (int i = 0; i < 4; i++) { + g.setColor(c1); + g.drawLine(dx, dy, dx + dw, dy); + dy++; + g.setColor(c2); + g.drawLine(dx, dy, dx + dw, dy); + dy++; + } + } + } else { + JTattooUtilities.fillHorGradient(g, colors, 0, 0, width, height); + if (!AbstractLookAndFeel.getTheme().isMacStyleScrollBarOn()) { + int dx = width / 2 - 3; + int dy = 6; + int dh = height - 13; + Color c1 = ColorHelper.brighter(colors[0], 60); + Color c2 = ColorHelper.darker(colors[0], 30); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f); + g2D.setComposite(alpha); + for (int i = 0; i < 4; i++) { + g.setColor(c1); + g.drawLine(dx, dy, dx, dy + dh); + dx++; + g.setColor(c2); + g.drawLine(dx, dy, dx, dy + dh); + dx++; + } + } + } + + g.setColor(getFrameColor()); + g.drawLine(1, 1, width - 2, 1); + g.drawLine(1, 2, 1, height - 3); + g.drawLine(width - 2, 2, width - 2, height - 3); + g.drawLine(2, height - 2, width - 3, height - 2); + + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); + g2D.setComposite(alpha); + Color fc = colors[colors.length - 1]; + g2D.setColor(fc); + g.drawLine(2, 2, width - 3, 2); + g.drawLine(2, 3, 2, height - 3); + + g.setColor(ColorHelper.darker(fc, 40)); + g.drawLine(width - 1, 2, width - 1, height - 3); + g.drawLine(3, height - 1, width - 3, height - 1); + alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f); + g2D.setComposite(alpha); + g.drawLine(1, height - 2, 2, height - 1); + g.drawLine(width - 1, height - 2, width - 2, height - 1); + + g.translate(-x, -y); + g2D.setComposite(savedComposite); + } +} diff --git a/src/com/jtattoo/plaf/XPScrollButton.java b/src/com/jtattoo/plaf/XPScrollButton.java new file mode 100644 index 0000000..9edbcf1 --- /dev/null +++ b/src/com/jtattoo/plaf/XPScrollButton.java @@ -0,0 +1,160 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf; + +import java.awt.*; +import javax.swing.Icon; +import javax.swing.UIManager; + +/** + * @author Michael Hagen + */ +public abstract class XPScrollButton extends BaseScrollButton { + + public XPScrollButton(int direction, int width) { + super(direction, width); + } + + private Icon getUpArrowIcon() { + if (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel) { + AbstractLookAndFeel laf = (AbstractLookAndFeel)UIManager.getLookAndFeel(); + return laf.getIconFactory().getUpArrowIcon(); + } + return null; + } + + private Icon getDownArrowIcon() { + if (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel) { + AbstractLookAndFeel laf = (AbstractLookAndFeel)UIManager.getLookAndFeel(); + return laf.getIconFactory().getDownArrowIcon(); + } + return null; + } + + private Icon getLeftArrowIcon() { + if (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel) { + AbstractLookAndFeel laf = (AbstractLookAndFeel)UIManager.getLookAndFeel(); + return laf.getIconFactory().getLeftArrowIcon(); + } + return null; + } + + private Icon getRightArrowIcon() { + if (UIManager.getLookAndFeel() instanceof AbstractLookAndFeel) { + AbstractLookAndFeel laf = (AbstractLookAndFeel)UIManager.getLookAndFeel(); + return laf.getIconFactory().getRightArrowIcon(); + } + return null; + } + + public Color getFrameColor() { + return Color.white; + } + + public void paint(Graphics g) { + Graphics2D g2D = (Graphics2D) g; + Composite savedComposite = g2D.getComposite(); + Paint savedPaint = g2D.getPaint(); + + boolean isPressed = getModel().isPressed(); + boolean isRollover = getModel().isRollover(); + + int width = getWidth(); + int height = getHeight(); + + Color[] tc = AbstractLookAndFeel.getTheme().getThumbColors(); + Color c1 = tc[0]; + Color c2 = tc[tc.length - 1]; + if (isPressed) { + c1 = ColorHelper.darker(c1, 5); + c2 = ColorHelper.darker(c2, 5); + } else if (isRollover) { + c1 = ColorHelper.brighter(c1, 20); + c2 = ColorHelper.brighter(c2, 20); + } + + g2D.setPaint(new GradientPaint(0, 0, c1, width, height, c2)); + g.fillRect(0, 0, width, height); + g2D.setPaint(savedPaint); + + g.setColor(getFrameColor()); + g.drawLine(1, 1, width - 2, 1); + g.drawLine(1, 1, 1, height - 3); + g.drawLine(width - 2, 1, width - 2, height - 3); + g.drawLine(2, height - 2, width - 3, height - 2); + + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); + g2D.setComposite(alpha); + g2D.setColor(c2); + g.drawLine(2, 2, width - 3, 2); + g.drawLine(2, 3, 2, height - 3); + + g.setColor(ColorHelper.darker(c2, 40)); + g.drawLine(width - 1, 2, width - 1, height - 3); + g.drawLine(3, height - 1, width - 3, height - 1); + alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f); + g2D.setComposite(alpha); + g.drawLine(1, height - 2, 2, height - 1); + g.drawLine(width - 1, height - 2, width - 2, height - 1); + + g2D.setComposite(savedComposite); + + int x; + int y; + Icon icon; + // paint the icon + if (getDirection() == NORTH) { + icon = getUpArrowIcon(); + x = (width / 2) - (icon.getIconWidth() / 2); + y = (height / 2) - (icon.getIconHeight() / 2); + } else if (getDirection() == SOUTH) { + icon = getDownArrowIcon(); + x = (width / 2) - (icon.getIconWidth() / 2); + y = (height / 2) - (icon.getIconHeight() / 2) + 1; + } else if (getDirection() == WEST) { + icon = getLeftArrowIcon(); + x = (width / 2) - (icon.getIconWidth() / 2); + y = (height / 2) - (icon.getIconHeight() / 2); + } else { + icon = getRightArrowIcon(); + x = (width / 2) - (icon.getIconWidth() / 2) + 1; + y = (height / 2) - (icon.getIconHeight() / 2); + } + icon.paintIcon(this, g, x, y); + } + + public Dimension getPreferredSize() { + if (getDirection() == NORTH) { + return new Dimension(buttonWidth, buttonWidth); + } else if (getDirection() == SOUTH) { + return new Dimension(buttonWidth, buttonWidth); + } else if (getDirection() == EAST) { + return new Dimension(buttonWidth, buttonWidth); + } else if (getDirection() == WEST) { + return new Dimension(buttonWidth, buttonWidth); + } else { + return new Dimension(0, 0); + } + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiBorderFactory.java b/src/com/jtattoo/plaf/hifi/HiFiBorderFactory.java new file mode 100644 index 0000000..5a35445 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiBorderFactory.java @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.AbstractBorderFactory; +import javax.swing.border.Border; + +/** + * @author Michael Hagen + */ +public class HiFiBorderFactory implements AbstractBorderFactory { + + private static HiFiBorderFactory instance = null; + + private HiFiBorderFactory() { + } + + public static synchronized HiFiBorderFactory getInstance() { + if (instance == null) { + instance = new HiFiBorderFactory(); + } + return instance; + } + + public Border getFocusFrameBorder() { + return HiFiBorders.getFocusFrameBorder(); + } + + public Border getButtonBorder() { + return HiFiBorders.getButtonBorder(); + } + + public Border getToggleButtonBorder() { + return HiFiBorders.getToggleButtonBorder(); + } + + public Border getTextBorder() { + return HiFiBorders.getTextBorder(); + } + + public Border getSpinnerBorder() { + return HiFiBorders.getSpinnerBorder(); + } + + public Border getTextFieldBorder() { + return HiFiBorders.getTextFieldBorder(); + } + + public Border getComboBoxBorder() { + return HiFiBorders.getComboBoxBorder(); + } + + public Border getTableHeaderBorder() { + return HiFiBorders.getTableHeaderBorder(); + } + + public Border getTableScrollPaneBorder() { + return HiFiBorders.getTableScrollPaneBorder(); + } + + public Border getScrollPaneBorder() { + return HiFiBorders.getScrollPaneBorder(); + } + + public Border getTabbedPaneBorder() { + return HiFiBorders.getTabbedPaneBorder(); + } + + public Border getMenuBarBorder() { + return HiFiBorders.getMenuBarBorder(); + } + + public Border getMenuItemBorder() { + return HiFiBorders.getMenuItemBorder(); + } + + public Border getPopupMenuBorder() { + return HiFiBorders.getPopupMenuBorder(); + } + + public Border getInternalFrameBorder() { + return HiFiBorders.getInternalFrameBorder(); + } + + public Border getPaletteBorder() { + return HiFiBorders.getPaletteBorder(); + } + + public Border getToolBarBorder() { + return HiFiBorders.getToolBarBorder(); + } + + public Border getProgressBarBorder() { + return HiFiBorders.getProgressBarBorder(); + } + + public Border getDesktopIconBorder() { + return HiFiBorders.getDesktopIconBorder(); + } +} + diff --git a/src/com/jtattoo/plaf/hifi/HiFiBorders.java b/src/com/jtattoo/plaf/hifi/HiFiBorders.java new file mode 100644 index 0000000..87da22b --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiBorders.java @@ -0,0 +1,329 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.*; +import java.awt.*; +import javax.swing.*; +import javax.swing.border.AbstractBorder; +import javax.swing.border.Border; +import javax.swing.plaf.UIResource; + +/** + * @author Michael Hagen + */ +public class HiFiBorders extends BaseBorders { + + //------------------------------------------------------------------------------------ + // Lazy access methods + //------------------------------------------------------------------------------------ + public static Border getButtonBorder() { + if (buttonBorder == null) { + buttonBorder = new ButtonBorder(); + } + return buttonBorder; + } + + public static Border getToggleButtonBorder() { + return getButtonBorder(); + } + + public static Border getRolloverToolButtonBorder() { + if (rolloverToolButtonBorder == null) { + rolloverToolButtonBorder = new RolloverToolButtonBorder(); + } + return rolloverToolButtonBorder; + } + + public static Border getScrollPaneBorder() { + if (scrollPaneBorder == null) { + scrollPaneBorder = new ScrollPaneBorder(); + } + return scrollPaneBorder; + } + + public static Border getTableScrollPaneBorder() { + if (tableScrollPaneBorder == null) { + tableScrollPaneBorder = new ScrollPaneBorder(); + } + return tableScrollPaneBorder; + } + + public static Border getInternalFrameBorder() { + if (internalFrameBorder == null) { + internalFrameBorder = new InternalFrameBorder(); + } + return internalFrameBorder; + } + + public static Border getToolBarBorder() { + if (toolBarBorder == null) { + toolBarBorder = new ToolBarBorder(); + } + return toolBarBorder; + } + +//------------------------------------------------------------------------------------ +// Implementation of border classes +//------------------------------------------------------------------------------------ + public static class ButtonBorder implements Border, UIResource { + + private static final Insets insets = new Insets(4, 8, 4, 8); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + Graphics2D g2D = (Graphics2D) g; + g.translate(x, y); + + Color hiFrameColor = ColorHelper.brighter(AbstractLookAndFeel.getTheme().getButtonBackgroundColor(), 14); + Color frameColor = ColorHelper.brighter(AbstractLookAndFeel.getTheme().getButtonBackgroundColor(), 6); + Color loFrameColor = ColorHelper.darker(AbstractLookAndFeel.getTheme().getButtonBackgroundColor(), 50); + + g.setColor(hiFrameColor); + g.drawLine(1, 0, w - 3, 0); + g.drawLine(0, 1, 0, h - 3); + g.setColor(frameColor); + g.drawLine(w - 2, 0, w - 2, h - 2); + g.drawLine(1, h - 2, w - 3, h - 2); + + Composite composite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); + g2D.setComposite(alpha); + g2D.setColor(loFrameColor); + g.drawLine(1, 1, w - 3, 1); + g.drawLine(1, 2, 1, h - 3); + g.setColor(Color.black); + g.drawLine(w - 1, 1, w - 1, h - 1); + g.drawLine(1, h - 1, w - 1, h - 1); + alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f); + g2D.setComposite(alpha); + g.drawLine(1, h - 2, 2, h - 1); + g2D.setComposite(composite); + + g.translate(-x, -y); + } + + public Insets getBorderInsets(Component c) { + return insets; + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + public boolean isBorderOpaque() { + return true; + } + } // class ButtonBorder + +//------------------------------------------------------------------------------------------------- + public static class RolloverToolButtonBorder implements Border, UIResource { + + private static final Insets insets = new Insets(2, 2, 2, 2); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + Graphics2D g2D = (Graphics2D) g; + Composite composite = g2D.getComposite(); + Color c1 = null; + Color c2 = null; + if (JTattooUtilities.isActive((JComponent) c)) { + c1 = ColorHelper.brighter(AbstractLookAndFeel.getFrameColor(), 60); + c2 = AbstractLookAndFeel.getFrameColor(); + } else { + c1 = AbstractLookAndFeel.getFrameColor(); + c2 = ColorHelper.darker(AbstractLookAndFeel.getFrameColor(), 20); + } + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f); + g2D.setComposite(alpha); + JTattooUtilities.draw3DBorder(g, c1, c2, 0, 0, w, h); + alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f); + g2D.setComposite(alpha); + JTattooUtilities.draw3DBorder(g, c2, c1, 1, 1, w - 2, h - 2); + g2D.setComposite(composite); + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + public boolean isBorderOpaque() { + return true; + } + } // class RolloverToolButtonBorder + +//------------------------------------------------------------------------------------------------- + public static class ScrollPaneBorder implements Border, UIResource { + + private static final Insets insets = new Insets(1, 1, 1, 1); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + Color frameColor = AbstractLookAndFeel.getTheme().getFrameColor(); + JTattooUtilities.draw3DBorder(g, frameColor, ColorHelper.brighter(frameColor, 10), x, y, w, h); + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + public boolean isBorderOpaque() { + return true; + } + } // class ScrollPaneBorder + +//------------------------------------------------------------------------------------------------- + public static class TabbedPaneBorder implements Border, UIResource { + + private static final Insets insets = new Insets(1, 1, 1, 1); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + Color frameColor = AbstractLookAndFeel.getTheme().getFrameColor(); + JTattooUtilities.draw3DBorder(g, frameColor, ColorHelper.brighter(frameColor, 10), x, y, w, h); + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + public boolean isBorderOpaque() { + return true; + } + } // class TabbedPaneBorder + +//------------------------------------------------------------------------------------------------- + public static class InternalFrameBorder extends BaseInternalFrameBorder { + + public InternalFrameBorder() { + insets.top = 3; + } + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + boolean active = isActive(c); + int th = getTitleHeight(c); + Color titleColor = AbstractLookAndFeel.getTheme().getWindowInactiveTitleColors()[0]; + Color borderColor = AbstractLookAndFeel.getWindowInactiveTitleColorDark(); + Color frameColor = AbstractLookAndFeel.getWindowInactiveBorderColor(); + if (active) { + titleColor = AbstractLookAndFeel.getTheme().getWindowTitleColors()[0]; + borderColor = AbstractLookAndFeel.getWindowTitleColorDark(); + frameColor = AbstractLookAndFeel.getWindowBorderColor(); + } + g.setColor(titleColor); + g.fillRect(x, y + 1, w, insets.top - 1); + g.setColor(borderColor); + g.fillRect(x + 1, y + h - dw, w - 2, dw - 1); + if (active) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getWindowTitleColors(), 1, insets.top, dw, th + 1); + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getWindowTitleColors(), w - dw, insets.top, dw, th + 1); + } else { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getWindowInactiveTitleColors(), 1, insets.top, dw - 1, th + 1); + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getWindowInactiveTitleColors(), w - dw, insets.top, dw - 1, th + 1); + } + g.setColor(borderColor); + g.fillRect(1, insets.top + th + 1, dw - 1, h - th - dw); + g.fillRect(w - dw, insets.top + th + 1, dw - 1, h - th - dw); + g.setColor(frameColor); + g.drawRect(x, y, w - 1, h - 1); + } + } // class InternalFrameBorder + + public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants { + + private static final LazyImageIcon HOR_RUBBER_ICON = new LazyImageIcon("hifi/icons/HorRubber.gif"); + private static final LazyImageIcon VER_RUBBER_ICON = new LazyImageIcon("hifi/icons/VerRubber.gif"); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + if (((JToolBar) c).isFloatable()) { + if (((JToolBar) c).getOrientation() == HORIZONTAL) { + int x1 = 4; + int y1 = (h - HOR_RUBBER_ICON.getIconHeight()) / 2; + HOR_RUBBER_ICON.paintIcon(c, g, x1, y1); + } else { + int x1 = (w - VER_RUBBER_ICON.getIconWidth()) / 2 + 2; + int y1 = 4; + VER_RUBBER_ICON.paintIcon(c, g, x1, y1); + } + } + } + + public Insets getBorderInsets(Component c) { + Insets insets = new Insets(2, 2, 2, 2); + if (((JToolBar) c).isFloatable()) { + if (((JToolBar) c).getOrientation() == HORIZONTAL) { + if (JTattooUtilities.isLeftToRight(c)) { + insets.left = 15; + } else { + insets.right = 15; + } + } else { + insets.top = 15; + } + } + Insets margin = ((JToolBar) c).getMargin(); + if (margin != null) { + insets.left += margin.left; + insets.top += margin.top; + insets.right += margin.right; + insets.bottom += margin.bottom; + } + return insets; + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + Insets insets = getBorderInsets(c); + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + } // class ToolBarBorder +} // class HiFiBorders + diff --git a/src/com/jtattoo/plaf/hifi/HiFiButtonUI.java b/src/com/jtattoo/plaf/hifi/HiFiButtonUI.java new file mode 100644 index 0000000..ddaebdf --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiButtonUI.java @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.*; +import java.awt.*; +import java.awt.geom.Area; +import java.awt.geom.Rectangle2D; +import javax.swing.*; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; + +/** + * @author Michael Hagen + */ +public class HiFiButtonUI extends BaseButtonUI { + + public static ComponentUI createUI(JComponent c) { + return new HiFiButtonUI(); + } + + protected void paintBackground(Graphics g, AbstractButton b) { + if (!b.isContentAreaFilled() || (b.getParent() instanceof JMenuBar)) { + return; + } + int width = b.getWidth(); + int height = b.getHeight(); + Graphics2D g2D = (Graphics2D) g; + Shape savedClip = g.getClip(); + if ((b.getBorder() != null) && b.isBorderPainted() && (b.getBorder() instanceof UIResource)) { + Area clipArea = new Area(new Rectangle2D.Double(1, 1, width - 2, height - 2)); + if (savedClip != null) { + clipArea.intersect(new Area(savedClip)); + } + g2D.setClip(clipArea); + } + super.paintBackground(g, b); + g2D.setClip(savedClip); + } + + protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) { + ButtonModel model = b.getModel(); + FontMetrics fm = JTattooUtilities.getFontMetrics(b, g, b.getFont()); + int mnemIndex; + if (JTattooUtilities.getJavaVersion() >= 1.4) { + mnemIndex = b.getDisplayedMnemonicIndex(); + } else { + mnemIndex = JTattooUtilities.findDisplayedMnemonicIndex(b.getText(), model.getMnemonic()); + } + int offs = 0; + if (model.isArmed() && model.isPressed()) { + offs = 1; + } + + Graphics2D g2D = (Graphics2D) g; + Composite composite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f); + g2D.setComposite(alpha); + Color foreground = b.getForeground(); + Color background = b.getBackground(); + if (background instanceof ColorUIResource) { + if (model.isPressed() && model.isArmed()) { + foreground = AbstractLookAndFeel.getTheme().getSelectionForegroundColor(); + } else if (model.isRollover()) { + foreground = AbstractLookAndFeel.getTheme().getRolloverForegroundColor(); + } + } + if (!model.isEnabled()) { + foreground = AbstractLookAndFeel.getTheme().getDisabledForegroundColor(); + } + if (ColorHelper.getGrayValue(foreground) > 64) { + g2D.setColor(Color.black); + } else { + g2D.setColor(Color.white); + } + JTattooUtilities.drawStringUnderlineCharAt(b, g, text, mnemIndex, textRect.x + offs + 1, textRect.y + offs + fm.getAscent() + 1); + g2D.setComposite(composite); + g2D.setColor(foreground); + JTattooUtilities.drawStringUnderlineCharAt(b, g, text, mnemIndex, textRect.x + offs, textRect.y + offs + fm.getAscent()); + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiCheckBoxUI.java b/src/com/jtattoo/plaf/hifi/HiFiCheckBoxUI.java new file mode 100644 index 0000000..31a8e73 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiCheckBoxUI.java @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import javax.swing.*; +import javax.swing.plaf.ComponentUI; + +/** + * @author Michael Hagen + */ +public class HiFiCheckBoxUI extends HiFiRadioButtonUI { + + private static HiFiCheckBoxUI checkBoxUI = null; + + public static ComponentUI createUI(JComponent b) { + if (checkBoxUI == null) { + checkBoxUI = new HiFiCheckBoxUI(); + } + return checkBoxUI; + } + + public void installDefaults(AbstractButton b) { + super.installDefaults(b); + icon = UIManager.getIcon("CheckBox.icon"); + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiComboBoxUI.java b/src/com/jtattoo/plaf/hifi/HiFiComboBoxUI.java new file mode 100644 index 0000000..778bbdc --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiComboBoxUI.java @@ -0,0 +1,98 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.BaseComboBoxUI; +import com.jtattoo.plaf.NoFocusButton; +import java.awt.*; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.border.AbstractBorder; +import javax.swing.plaf.ComponentUI; + +/** + * @author Michael Hagen + */ +public class HiFiComboBoxUI extends BaseComboBoxUI { + + public static ComponentUI createUI(JComponent c) { + return new HiFiComboBoxUI(); + } + + public JButton createArrowButton() { + JButton button = new NoFocusButton(HiFiIcons.getComboBoxIcon()); + button.setBorder(new ArrowButtonBorder()); + return button; + } + + protected void setButtonBorder() { + } + +//-------------------------------------------------------------------------------------------------- + static class ArrowButtonBorder extends AbstractBorder { + + private static final Insets insets = new Insets(1, 3, 1, 2); + private static final Color frameLoColor = new Color(120, 120, 120); + private static final Color frameLowerColor = new Color(104, 104, 104); + private static final Color frameLowerLoColor = new Color(64, 64, 64); + private static final Color frameLowestColor = new Color(32, 32, 32); + + public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { + Graphics2D g2D = (Graphics2D) g; + g.translate(x, y); + + g.setColor(frameLoColor); + g.drawLine(1, 0, w - 1, 0); + g.drawLine(1, 1, 1, h - 2); + g.setColor(frameLowerColor); + g.drawLine(w - 1, 1, w - 1, h - 2); + g.drawLine(2, h - 1, w - 2, h - 1); + + Composite composite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); + g2D.setComposite(alpha); + g.setColor(frameLowestColor); + g.drawLine(2, 1, w - 2, 1); + g.drawLine(2, 2, 2, h - 3); + g.setColor(frameLowerLoColor); + g.drawLine(0, 0, 0, h); + g2D.setComposite(composite); + + g.translate(-x, -y); + } + + public Insets getBorderInsets(Component c) { + return new Insets(insets.top, insets.left, insets.bottom, insets.right); + } + + public Insets getBorderInsets(Component c, Insets borderInsets) { + borderInsets.left = insets.left; + borderInsets.top = insets.top; + borderInsets.right = insets.right; + borderInsets.bottom = insets.bottom; + return borderInsets; + } + + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiDefaultTheme.java b/src/com/jtattoo/plaf/hifi/HiFiDefaultTheme.java new file mode 100644 index 0000000..ed71878 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiDefaultTheme.java @@ -0,0 +1,161 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.AbstractTheme; +import com.jtattoo.plaf.ColorHelper; +import java.awt.Color; +import java.awt.Font; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.FontUIResource; + +/** + * @author Michael Hagen + */ +public class HiFiDefaultTheme extends AbstractTheme { + + public HiFiDefaultTheme() { + super(); + // Setup theme with defaults + setUpColor(); + // Overwrite defaults with user props + loadProperties(); + // Setup the color arrays + setUpColorArrs(); + } + + public String getPropertyFileName() { + return "HiFiTheme.properties"; + } + + public void setUpColor() { + super.setUpColor(); + + // Defaults for HiFiLookAndFeel + textShadow = true; + foregroundColor = extraLightGray; + disabledForegroundColor = gray; + disabledBackgroundColor = new ColorUIResource(48, 48, 48); + + backgroundColor = new ColorUIResource(48, 48, 48); + backgroundColorLight = new ColorUIResource(48, 48, 48); + backgroundColorDark = new ColorUIResource(16, 16, 16); + alterBackgroundColor = new ColorUIResource(64, 64, 64); + selectionForegroundColor = white; + selectionBackgroundColor = new ColorUIResource(40, 40, 40); + frameColor = black; + gridColor = black; + focusCellColor = orange; + + inputBackgroundColor = new ColorUIResource(80, 80, 80); + inputForegroundColor = foregroundColor; + + rolloverForegroundColor = extraLightGray; + rolloverColor = new ColorUIResource(112, 112, 112); + rolloverColorLight = new ColorUIResource(128, 128, 128); + rolloverColorDark = new ColorUIResource(96, 96, 96); + + pressedForegroundColor = foregroundColor; + + buttonForegroundColor = foregroundColor; + buttonBackgroundColor = new ColorUIResource(96, 96, 96); + buttonColorLight = new ColorUIResource(96, 96, 96); + buttonColorDark = new ColorUIResource(32, 32, 32); + + controlForegroundColor = foregroundColor; + controlBackgroundColor = new ColorUIResource(64, 64, 64); // netbeans use this for selected tab in the toolbar + controlColorLight = new ColorUIResource(96, 96, 96); + controlColorDark = new ColorUIResource(32, 32, 32); + controlHighlightColor = new ColorUIResource(96, 96, 96); + controlShadowColor = new ColorUIResource(32, 32, 32); + controlDarkShadowColor = black; + + windowTitleForegroundColor = foregroundColor; + windowTitleBackgroundColor = new ColorUIResource(32, 32, 32); + windowTitleColorLight = new ColorUIResource(96, 96, 96); + windowTitleColorDark = new ColorUIResource(32, 32, 32);//new ColorUIResource(16, 16, 16); + windowBorderColor = black; + windowIconColor = lightGray; + windowIconShadowColor = black; + windowIconRolloverColor = orange; + + windowInactiveTitleForegroundColor = new ColorUIResource(196, 196, 196); + windowInactiveTitleBackgroundColor = new ColorUIResource(64, 64, 64); + windowInactiveTitleColorLight = new ColorUIResource(64, 64, 64); + windowInactiveTitleColorDark = new ColorUIResource(32, 32, 32); + windowInactiveBorderColor = black; + + menuForegroundColor = foregroundColor; + menuBackgroundColor = new ColorUIResource(32, 32, 32); + menuSelectionForegroundColor = white; + menuSelectionBackgroundColor = new ColorUIResource(96, 96, 96); + menuColorLight = new ColorUIResource(96, 96, 96); + menuColorDark = new ColorUIResource(32, 32, 32); + + toolbarBackgroundColor = new ColorUIResource(48, 48, 48); + toolbarColorLight = new ColorUIResource(96, 96, 96); + toolbarColorDark = new ColorUIResource(32, 32, 32); + + tabAreaBackgroundColor = backgroundColor; + tabSelectionForegroundColor = selectionForegroundColor; + + desktopColor = new ColorUIResource(64, 64, 64); + + tooltipForegroundColor = white; + tooltipBackgroundColor = new ColorUIResource(24, 24, 24); + + controlFont = new FontUIResource("Dialog", Font.BOLD, 12); + systemFont = new FontUIResource("Dialog", Font.BOLD, 12); + userFont = new FontUIResource("Dialog", Font.BOLD, 12); + menuFont = new FontUIResource("Dialog", Font.BOLD, 12); + windowTitleFont = new FontUIResource("Dialog", Font.BOLD, 12); + smallFont = new FontUIResource("Dialog", Font.PLAIN, 10); + } + + public void setUpColorArrs() { + super.setUpColorArrs(); + DEFAULT_COLORS = ColorHelper.createColorArr(controlColorLight, controlColorDark, 20); + HIDEFAULT_COLORS = ColorHelper.createColorArr(ColorHelper.brighter(controlColorLight, 15), ColorHelper.brighter(controlColorDark, 15), 20); + ACTIVE_COLORS = DEFAULT_COLORS; + INACTIVE_COLORS = ColorHelper.createColorArr(new Color(64, 64, 64), new Color(32, 32, 32), 20); + SELECTED_COLORS = HIDEFAULT_COLORS; + BUTTON_COLORS = ColorHelper.createColorArr(buttonColorLight, buttonColorDark, 20); + ROLLOVER_COLORS = HIDEFAULT_COLORS; + PRESSED_COLORS = ColorHelper.createColorArr(black, controlColorDark, 20); + + //DISABLED_COLORS = ColorHelper.createColorArr(ColorHelper.darker(controlColorLight, 10), ColorHelper.darker(controlColorDark, 10), 20); + DISABLED_COLORS = ColorHelper.createColorArr(ColorHelper.brighter(controlColorDark, 5), ColorHelper.darker(controlColorDark, 10), 20); + + WINDOW_TITLE_COLORS = ColorHelper.createColorArr(windowTitleColorLight, windowTitleColorDark, 20); + WINDOW_INACTIVE_TITLE_COLORS = ColorHelper.createColorArr(windowInactiveTitleColorLight, windowInactiveTitleColorDark, 20); + MENUBAR_COLORS = DEFAULT_COLORS; + TOOLBAR_COLORS = MENUBAR_COLORS; + TRACK_COLORS = ColorHelper.createColorArr(ColorHelper.darker(backgroundColor, 10), ColorHelper.brighter(backgroundColor, 5), 20); + SLIDER_COLORS = DEFAULT_COLORS; + PROGRESSBAR_COLORS = DEFAULT_COLORS; + THUMB_COLORS = DEFAULT_COLORS; + TAB_COLORS = DEFAULT_COLORS; + COL_HEADER_COLORS = DEFAULT_COLORS; + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiIconFactory.java b/src/com/jtattoo/plaf/hifi/HiFiIconFactory.java new file mode 100644 index 0000000..8478a5c --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiIconFactory.java @@ -0,0 +1,217 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.AbstractIconFactory; +import javax.swing.Icon; + +/** + * @author Michael Hagen + */ +public class HiFiIconFactory implements AbstractIconFactory { + + private static HiFiIconFactory instance = null; + + private HiFiIconFactory() { + } + + public static synchronized HiFiIconFactory getInstance() { + if (instance == null) { + instance = new HiFiIconFactory(); + } + return instance; + } + + public Icon getOptionPaneErrorIcon() { + return HiFiIcons.getOptionPaneErrorIcon(); + } + + public Icon getOptionPaneWarningIcon() { + return HiFiIcons.getOptionPaneWarningIcon(); + } + + public Icon getOptionPaneInformationIcon() { + return HiFiIcons.getOptionPaneInformationIcon(); + } + + public Icon getOptionPaneQuestionIcon() { + return HiFiIcons.getOptionPaneQuestionIcon(); + } + + public Icon getFileChooserUpFolderIcon() { + return HiFiIcons.getFileChooserUpFolderIcon(); + } + + public Icon getFileChooserHomeFolderIcon() { + return HiFiIcons.getFileChooserHomeFolderIcon(); + } + + public Icon getFileChooserNewFolderIcon() { + return HiFiIcons.getFileChooserNewFolderIcon(); + } + + public Icon getFileChooserListViewIcon() { + return HiFiIcons.getFileChooserListViewIcon(); + } + + public Icon getFileChooserDetailViewIcon() { + return HiFiIcons.getFileChooserDetailViewIcon(); + } + + public Icon getFileViewComputerIcon() { + return HiFiIcons.getFileViewComputerIcon(); + } + + public Icon getFileViewFloppyDriveIcon() { + return HiFiIcons.getFileViewFloppyDriveIcon(); + } + + public Icon getFileViewHardDriveIcon() { + return HiFiIcons.getFileViewHardDriveIcon(); + } + + public Icon getMenuIcon() { + return HiFiIcons.getMenuIcon(); + } + + public Icon getIconIcon() { + return HiFiIcons.getIconIcon(); + } + + public Icon getMaxIcon() { + return HiFiIcons.getMaxIcon(); + } + + public Icon getMinIcon() { + return HiFiIcons.getMinIcon(); + } + + public Icon getCloseIcon() { + return HiFiIcons.getCloseIcon(); + } + + public Icon getPaletteCloseIcon() { + return HiFiIcons.getPaletteCloseIcon(); + } + + public Icon getRadioButtonIcon() { + return HiFiIcons.getRadioButtonIcon(); + } + + public Icon getCheckBoxIcon() { + return HiFiIcons.getCheckBoxIcon(); + } + + public Icon getComboBoxIcon() { + return HiFiIcons.getComboBoxIcon(); + } + + public Icon getTreeOpenIcon() { + return HiFiIcons.getTreeOpenedIcon(); + } + + public Icon getTreeCloseIcon() { + return HiFiIcons.getTreeClosedIcon(); + } + + public Icon getTreeLeafIcon() { + return HiFiIcons.getTreeLeafIcon(); + } + + public Icon getTreeCollapsedIcon() { + return HiFiIcons.getTreeCollapsedIcon(); + } + + public Icon getTreeExpandedIcon() { + return HiFiIcons.getTreeExpandedIcon(); + } + + public Icon getMenuArrowIcon() { + return HiFiIcons.getMenuArrowIcon(); + } + + public Icon getMenuCheckBoxIcon() { + return HiFiIcons.getMenuCheckBoxIcon(); + } + + public Icon getMenuRadioButtonIcon() { + return HiFiIcons.getMenuRadioButtonIcon(); + } + + public Icon getUpArrowIcon() { + return HiFiIcons.getUpArrowIcon(); + } + + public Icon getDownArrowIcon() { + return HiFiIcons.getDownArrowIcon(); + } + + public Icon getLeftArrowIcon() { + return HiFiIcons.getLeftArrowIcon(); + } + + public Icon getRightArrowIcon() { + return HiFiIcons.getRightArrowIcon(); + } + + public Icon getSplitterDownArrowIcon() { + return HiFiIcons.getSplitterDownArrowIcon(); + } + + public Icon getSplitterHorBumpIcon() { + return HiFiIcons.getSplitterHorBumpIcon(); + } + + public Icon getSplitterLeftArrowIcon() { + return HiFiIcons.getSplitterLeftArrowIcon(); + } + + public Icon getSplitterRightArrowIcon() { + return HiFiIcons.getSplitterRightArrowIcon(); + } + + public Icon getSplitterUpArrowIcon() { + return HiFiIcons.getSplitterUpArrowIcon(); + } + + public Icon getSplitterVerBumpIcon() { + return HiFiIcons.getSplitterVerBumpIcon(); + } + + public Icon getThumbHorIcon() { + return HiFiIcons.getThumbHorIcon(); + } + + public Icon getThumbVerIcon() { + return HiFiIcons.getThumbVerIcon(); + } + + public Icon getThumbHorIconRollover() { + return HiFiIcons.getThumbHorIconRollover(); + } + + public Icon getThumbVerIconRollover() { + return HiFiIcons.getThumbVerIconRollover(); + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiIcons.java b/src/com/jtattoo/plaf/hifi/HiFiIcons.java new file mode 100644 index 0000000..325e42a --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiIcons.java @@ -0,0 +1,480 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.*; +import java.awt.*; +import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; +import java.io.Serializable; +import javax.swing.*; +import javax.swing.plaf.UIResource; + +/** + * @author Michael Hagen + */ +public class HiFiIcons extends BaseIcons { + + public static Icon getComboBoxIcon() { + return getDownArrowIcon(); + } + + public static Icon getIconIcon() { + if (iconIcon == null) { + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + iconIcon = new MacIconIcon(); + } else { + Color iconColor = AbstractLookAndFeel.getTheme().getWindowIconColor(); + Color iconShadowColor = AbstractLookAndFeel.getTheme().getWindowIconShadowColor(); + Color iconRolloverColor = AbstractLookAndFeel.getTheme().getWindowIconRolloverColor(); + iconIcon = new BaseIcons.IconSymbol(iconColor, iconShadowColor, iconRolloverColor, new Insets(-1, -1, 0, 0)); + } + } + return iconIcon; + } + + public static Icon getMinIcon() { + if (minIcon == null) { + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + minIcon = new MacMinIcon(); + } else { + Color iconColor = AbstractLookAndFeel.getTheme().getWindowIconColor(); + Color iconShadowColor = AbstractLookAndFeel.getTheme().getWindowIconShadowColor(); + Color iconRolloverColor = AbstractLookAndFeel.getTheme().getWindowIconRolloverColor(); + minIcon = new BaseIcons.MinSymbol(iconColor, iconShadowColor, iconRolloverColor, new Insets(-1, -1, 0, 0)); + } + } + return minIcon; + } + + public static Icon getMaxIcon() { + if (maxIcon == null) { + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + maxIcon = new MacMaxIcon(); + } else { + Color iconColor = AbstractLookAndFeel.getTheme().getWindowIconColor(); + Color iconShadowColor = AbstractLookAndFeel.getTheme().getWindowIconShadowColor(); + Color iconRolloverColor = AbstractLookAndFeel.getTheme().getWindowIconRolloverColor(); + maxIcon = new BaseIcons.MaxSymbol(iconColor, iconShadowColor, iconRolloverColor, new Insets(-1, -1, 0, 0)); + } + } + return maxIcon; + } + + public static Icon getCloseIcon() { + if (closeIcon == null) { + if (AbstractLookAndFeel.getTheme().isMacStyleWindowDecorationOn()) { + closeIcon = new MacCloseIcon(); + } else { + Color iconColor = AbstractLookAndFeel.getTheme().getWindowIconColor(); + Color iconShadowColor = AbstractLookAndFeel.getTheme().getWindowIconShadowColor(); + Color iconRolloverColor = AbstractLookAndFeel.getTheme().getWindowIconRolloverColor(); + closeIcon = new BaseIcons.CloseSymbol(iconColor, iconShadowColor, iconRolloverColor, new Insets(-1, -1, 0, 0)); + } + } + return closeIcon; + } + + public static Icon getRadioButtonIcon() { + if (radioButtonIcon == null) { + radioButtonIcon = new RadioButtonIcon(); + } + return radioButtonIcon; + } + + public static Icon getCheckBoxIcon() { + if (checkBoxIcon == null) { + checkBoxIcon = new CheckBoxIcon(); + } + return checkBoxIcon; + } + + public static Icon getTreeExpandedIcon() { + if (treeExpandedIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + treeExpandedIcon = new LazyImageIcon("hifi/icons/small/tree_expanded_9x9.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + treeExpandedIcon = new LazyImageIcon("hifi/icons/medium/tree_expanded_11x11.png"); + } else { + treeExpandedIcon = new LazyImageIcon("hifi/icons/large/tree_expanded_14x14.png"); + } + } + return treeExpandedIcon; + } + + public static Icon getTreeCollapsedIcon() { + if (treeCollapsedIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + treeCollapsedIcon = new LazyImageIcon("hifi/icons/small/tree_collapsed_9x9.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + treeCollapsedIcon = new LazyImageIcon("hifi/icons/medium/tree_collapsed_11x11.png"); + } else { + treeCollapsedIcon = new LazyImageIcon("hifi/icons/large/tree_collapsed_14x14.png"); + } + } + return treeCollapsedIcon; + } + + public static Icon getMenuArrowIcon() { + if (menuArrowIcon == null) { + menuArrowIcon = new LazyMenuArrowImageIcon("hifi/icons/medium/arrow_right_8x9.png", "hifi/icons/medium/arrow_left8x9.png"); + } + return menuArrowIcon; + } + + public static Icon getSplitterUpArrowIcon() { + if (splitterUpArrowIcon == null) { + splitterUpArrowIcon = new LazyImageIcon("hifi/icons/SplitterUpArrow.gif"); + } + return splitterUpArrowIcon; + } + + public static Icon getSplitterDownArrowIcon() { + if (splitterDownArrowIcon == null) { + splitterDownArrowIcon = new LazyImageIcon("hifi/icons/SplitterDownArrow.gif"); + } + return splitterDownArrowIcon; + } + + public static Icon getSplitterLeftArrowIcon() { + if (splitterLeftArrowIcon == null) { + splitterLeftArrowIcon = new LazyImageIcon("hifi/icons/SplitterLeftArrow.gif"); + } + return splitterLeftArrowIcon; + } + + public static Icon getSplitterRightArrowIcon() { + if (splitterRightArrowIcon == null) { + splitterRightArrowIcon = new LazyImageIcon("hifi/icons/SplitterRightArrow.gif"); + } + return splitterRightArrowIcon; + } + + public static Icon getSplitterHorBumpIcon() { + if (splitterHorBumpIcon == null) { + splitterHorBumpIcon = new LazyImageIcon("hifi/icons/SplitterHorBumps.gif"); + } + return splitterHorBumpIcon; + } + + public static Icon getSplitterVerBumpIcon() { + if (splitterVerBumpIcon == null) { + splitterVerBumpIcon = new LazyImageIcon("hifi/icons/SplitterVerBumps.gif"); + } + return splitterVerBumpIcon; + } + + public static Icon getThumbHorIcon() { + if (thumbHorIcon == null) { + thumbHorIcon = new LazyImageIcon("hifi/icons/thumb_hor.gif"); + } + return thumbHorIcon; + } + + public static Icon getThumbVerIcon() { + if (thumbVerIcon == null) { + thumbVerIcon = new LazyImageIcon("hifi/icons/thumb_ver.gif"); + } + return thumbVerIcon; + } + + public static Icon getThumbHorIconRollover() { + if (thumbHorIconRollover == null) { + thumbHorIconRollover = new LazyImageIcon("hifi/icons/thumb_hor_rollover.gif"); + } + return thumbHorIconRollover; + } + + public static Icon getThumbVerIconRollover() { + if (thumbVerIconRollover == null) { + thumbVerIconRollover = new LazyImageIcon("hifi/icons/thumb_ver_rollover.gif"); + } + return thumbVerIconRollover; + } + + public static Icon getUpArrowIcon() { + if (upArrowIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + upArrowIcon = new LazyImageIcon("hifi/icons/small/arrow_up_7x6.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + upArrowIcon = new LazyImageIcon("hifi/icons/medium/arrow_up_9x8.png"); + } else { + upArrowIcon = new LazyImageIcon("hifi/icons/large/arrow_up_11x10.png"); + } + } + return upArrowIcon; + } + + public static Icon getDownArrowIcon() { + if (downArrowIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + downArrowIcon = new LazyImageIcon("hifi/icons/small/arrow_down_7x6.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + downArrowIcon = new LazyImageIcon("hifi/icons/medium/arrow_down_9x8.png"); + } else { + downArrowIcon = new LazyImageIcon("hifi/icons/large/arrow_down_11x10.png"); + } + } + return downArrowIcon; + } + + public static Icon getLeftArrowIcon() { + if (leftArrowIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + leftArrowIcon = new LazyImageIcon("hifi/icons/small/arrow_left_6x7.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + leftArrowIcon = new LazyImageIcon("hifi/icons/medium/arrow_left_8x9.png"); + } else { + leftArrowIcon = new LazyImageIcon("hifi/icons/large/arrow_left_10x11.png"); + } + } + return leftArrowIcon; + } + + public static Icon getRightArrowIcon() { + if (rightArrowIcon == null) { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + rightArrowIcon = new LazyImageIcon("hifi/icons/small/arrow_right_6x7.png"); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + rightArrowIcon = new LazyImageIcon("hifi/icons/medium/arrow_right_8x9.png"); + } else { + rightArrowIcon = new LazyImageIcon("hifi/icons/large/arrow_right_10x11.png"); + } + } + return rightArrowIcon; + } + +//---------------------------------------------------------------------------------------------------------------------- +// inner classes +//---------------------------------------------------------------------------------------------------------------------- + + private static class CheckBoxIcon implements Icon, UIResource, Serializable { + + private static final int GAP = 2; + private static final Icon SMALL_CHECK_ICON = new LazyImageIcon("hifi/icons/small/check_symbol_12x11.png"); + private static final Icon SMALL_CHECK_INVERSE_ICON = new LazyImageIcon("icons/small/check_symbol_10x10.png"); + private static final Icon SMALL_CHECK_DISABLED_ICON = new LazyImageIcon("icons/small/check_symbol_disabled_10x10.png"); + private static final Icon MEDIUM_CHECK_ICON = new LazyImageIcon("hifi/icons/medium/check_symbol_14x13.png"); + private static final Icon MEDIUM_CHECK_INVERSE_ICON = new LazyImageIcon("icons/medium/check_symbol_12x12.png"); + private static final Icon MEDIUM_CHECK_DISABLED_ICON = new LazyImageIcon("icons/medium/check_symbol_disabled_12x12.png"); + private static final Icon LARGE_CHECK_ICON = new LazyImageIcon("hifi/icons/large/check_symbol_16x15.png"); + private static final Icon LARGE_CHECK_INVERSE_ICON = new LazyImageIcon("icons/large/check_symbol_14x14.png"); + private static final Icon LARGE_CHECK_DISABLED_ICON = new LazyImageIcon("icons/large/check_symbol_disabled_14x14.png"); + + public void paintIcon(Component c, Graphics g, int x, int y) { + if (!JTattooUtilities.isLeftToRight(c)) { + x += GAP; + } + int w = getIconWidth() - GAP; + int h = getIconHeight(); + AbstractButton button = (AbstractButton) c; + ButtonModel model = button.getModel(); + Graphics2D g2D = (Graphics2D) g; + if (button.isEnabled()) { + if ((button.isRolloverEnabled() && model.isRollover())) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getRolloverColors(), x + 1, y + 1, w - 1, h - 1); + } else { + if (AbstractLookAndFeel.getTheme().doShowFocusFrame() && button.hasFocus()) { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getFocusColors(), x + 1, y + 1, w - 1, h - 1); + } else { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getCheckBoxColors(), x + 1, y + 1, w - 1, h - 1); + } + } + } else { + JTattooUtilities.fillHorGradient(g, AbstractLookAndFeel.getTheme().getDisabledColors(), x + 1, y + 1, w - 1, h - 1); + } + + Color frameColor = ColorHelper.brighter(AbstractLookAndFeel.getTheme().getButtonBackgroundColor(), 6); + Color loFrameColor = ColorHelper.darker(AbstractLookAndFeel.getTheme().getButtonBackgroundColor(), 50); + + g.setColor(frameColor); + g.drawRect(x, y, w, h); + Composite savedComposite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); + g2D.setComposite(alpha); + g.setColor(loFrameColor); + g.drawLine(x + 1, y + 1, x + w - 1, y + 1); + g.drawLine(x + 1, y + 1, x + 1, y + h - 1); + g2D.setComposite(savedComposite); + + Icon checkIcon; + Icon checkDisabledIcon; + Icon checkInverseIcon; + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + checkIcon = SMALL_CHECK_ICON; + checkDisabledIcon = SMALL_CHECK_DISABLED_ICON; + checkInverseIcon = SMALL_CHECK_INVERSE_ICON; + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + checkIcon = MEDIUM_CHECK_ICON; + checkDisabledIcon = MEDIUM_CHECK_DISABLED_ICON; + checkInverseIcon = MEDIUM_CHECK_INVERSE_ICON; + } else { + checkIcon = LARGE_CHECK_ICON; + checkDisabledIcon = LARGE_CHECK_DISABLED_ICON; + checkInverseIcon = LARGE_CHECK_INVERSE_ICON; + } + int xi = x + ((w - checkIcon.getIconWidth()) / 2) + 1; + int yi = y + ((h - checkIcon.getIconHeight()) / 2); + int gv = ColorHelper.getGrayValue(AbstractLookAndFeel.getButtonForegroundColor()); + if (model.isPressed() && model.isArmed()) { + Color bc = gv > 128 ? AbstractLookAndFeel.getTheme().getSelectionForegroundColor() : AbstractLookAndFeel.getTheme().getSelectionBackgroundColor(); + Color fc = gv > 128 ? ColorHelper.brighter(bc, 20) : ColorHelper.darker(bc, 40); + g.setColor(fc); + g.drawRect(x + 4, y + 4, w - 8, h - 8); + g.setColor(bc); + g.fillRect(x + 5, y + 5, w - 9, h - 9); + } else if (model.isSelected()) { + if (!model.isEnabled()) { + checkDisabledIcon.paintIcon(c, g, xi + 1, yi); + } else { + if (gv > 128) { + checkIcon.paintIcon(c, g, xi, yi); + } else { + checkInverseIcon.paintIcon(c, g, xi + 1, yi + 1); + } + } + } + } + + public int getIconWidth() { + int w; + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + w = 15; + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + w = 17; + } else { + w = 19; + } + return w + GAP; + } + + public int getIconHeight() { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + return 15; + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + return 17; + } else { + return 19; + } + } + } + +//---------------------------------------------------------------------------------------------------------------------- + private static class RadioButtonIcon implements Icon, UIResource, Serializable { + + private static final int GAP = 2; + + public void paintIcon(Component c, Graphics g, int x, int y) { + if (!JTattooUtilities.isLeftToRight(c)) { + x += GAP; + } + int w = getIconWidth() - GAP; + int h = getIconHeight(); + + Graphics2D g2D = (Graphics2D) g; + AbstractButton button = (AbstractButton) c; + ButtonModel model = button.getModel(); + Color colors[]; + if (button.isEnabled()) { + if ((button.isRolloverEnabled() && model.isRollover()) || (model.isPressed() && model.isArmed())) { + colors = AbstractLookAndFeel.getTheme().getRolloverColors(); + } else { + if (AbstractLookAndFeel.getTheme().doShowFocusFrame() && button.hasFocus()) { + colors = AbstractLookAndFeel.getTheme().getFocusColors(); + } else { + colors = AbstractLookAndFeel.getTheme().getCheckBoxColors(); + } + } + } else { + colors = AbstractLookAndFeel.getTheme().getDisabledColors(); + } + + Color frameColor = ColorHelper.brighter(AbstractLookAndFeel.getTheme().getButtonBackgroundColor(), 6); + Shape savedClip = g.getClip(); + Area clipArea = new Area(new Ellipse2D.Double(x, y, w + 1, h + 1)); + if (savedClip != null) { + clipArea.intersect(new Area(savedClip)); + } + g2D.setClip(clipArea); + JTattooUtilities.fillHorGradient(g, colors, x, y, w, h); + g2D.setClip(savedClip); + + Object savedRederingHint = g2D.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setColor(frameColor); + g.drawOval(x, y, w, h); + + if (model.isSelected()) { + if (model.isEnabled()) { + Color fc = AbstractLookAndFeel.getForegroundColor(); + if (ColorHelper.getGrayValue(colors[0]) < 128) { + if (ColorHelper.getGrayValue(fc) < 128) { + g2D.setColor(Color.white); + } else { + g2D.setColor(fc); + } + } else { + if (ColorHelper.getGrayValue(fc) > 128) { + g2D.setColor(Color.black); + } else { + g2D.setColor(fc); + } + } + } else { + g.setColor(AbstractLookAndFeel.getDisabledForegroundColor()); + } + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + g2D.fillOval(x + 4, y + 4, w - 7, h - 7); + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + g2D.fillOval(x + 4, y + 4, w - 7, h - 7); + } else { + g2D.fillOval(x + 5, y + 5, w - 9, h - 9); + } + } + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, savedRederingHint); + } + + public int getIconWidth() { + int w; + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + w = 14; + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + w = 16; + } else { + w = 18; + } + return w + GAP; + } + + public int getIconHeight() { + if (AbstractLookAndFeel.getTheme().isSmallFontSize()) { + return 14; + } else if (AbstractLookAndFeel.getTheme().isMediumFontSize()) { + return 16; + } else { + return 18; + } + } + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiInternalFrameTitlePane.java b/src/com/jtattoo/plaf/hifi/HiFiInternalFrameTitlePane.java new file mode 100644 index 0000000..1184ccb --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiInternalFrameTitlePane.java @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.*; +import java.awt.Color; +import java.awt.Graphics; +import javax.swing.JInternalFrame; + +/** + * @author Michael Hagen + */ +public class HiFiInternalFrameTitlePane extends BaseInternalFrameTitlePane { + + public HiFiInternalFrameTitlePane(JInternalFrame f) { + super(f); + } + + protected boolean centerButtons() { + return false; + } + + public void paintText(Graphics g, int x, int y, String title) { + g.setColor(Color.black); + JTattooUtilities.drawString(frame, g, title, x + 1, y); + if (isActive()) { + g.setColor(AbstractLookAndFeel.getWindowTitleForegroundColor()); + } else { + g.setColor(AbstractLookAndFeel.getWindowInactiveTitleForegroundColor()); + } + JTattooUtilities.drawString(frame, g, title, x, y - 1); + } + + public void paintBorder(Graphics g) { + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiInternalFrameUI.java b/src/com/jtattoo/plaf/hifi/HiFiInternalFrameUI.java new file mode 100644 index 0000000..3d946e4 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiInternalFrameUI.java @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.BaseInternalFrameUI; +import javax.swing.JComponent; +import javax.swing.JInternalFrame; +import javax.swing.plaf.ComponentUI; + +/** + * @author Michael Hagen + */ +public class HiFiInternalFrameUI extends BaseInternalFrameUI { + + public HiFiInternalFrameUI(JInternalFrame b) { + super(b); + } + + public static ComponentUI createUI(JComponent c) { + return new HiFiInternalFrameUI((JInternalFrame) c); + } + + protected JComponent createNorthPane(JInternalFrame w) { + titlePane = new HiFiInternalFrameTitlePane(w); + return titlePane; + } +} + diff --git a/src/com/jtattoo/plaf/hifi/HiFiLabelUI.java b/src/com/jtattoo/plaf/hifi/HiFiLabelUI.java new file mode 100644 index 0000000..6476882 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiLabelUI.java @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.*; +import java.awt.Color; +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicLabelUI; + +/** + * @author Michael Hagen + */ +public class HiFiLabelUI extends BasicLabelUI { + + private static HiFiLabelUI hifiLabelUI = null; + + public static ComponentUI createUI(JComponent c) { + if (hifiLabelUI == null) { + hifiLabelUI = new HiFiLabelUI(); + } + return hifiLabelUI; + } + + protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) { + int mnemIndex = -1; + if (JTattooUtilities.getJavaVersion() >= 1.4) { + mnemIndex = l.getDisplayedMnemonicIndex(); + } else { + mnemIndex = JTattooUtilities.findDisplayedMnemonicIndex(l.getText(), l.getDisplayedMnemonic()); + } + Color fc = l.getForeground(); + if (AbstractLookAndFeel.getTheme().isTextShadowOn() && ColorHelper.getGrayValue(fc) > 128) { + g.setColor(Color.black); + JTattooUtilities.drawStringUnderlineCharAt(l, g, s, mnemIndex, textX + 1, textY + 1); + } + g.setColor(fc); + JTattooUtilities.drawStringUnderlineCharAt(l, g, s, mnemIndex, textX, textY); + } + + protected void paintDisabledText(JLabel l, Graphics g, String s, int textX, int textY) { + int mnemIndex = -1; + if (JTattooUtilities.getJavaVersion() >= 1.4) { + mnemIndex = l.getDisplayedMnemonicIndex(); + } else { + mnemIndex = JTattooUtilities.findDisplayedMnemonicIndex(l.getText(), l.getDisplayedMnemonic()); + } + g.setColor(Color.black); + JTattooUtilities.drawStringUnderlineCharAt(l, g, s, mnemIndex, textX + 1, textY + 1); + g.setColor(AbstractLookAndFeel.getDisabledForegroundColor()); + JTattooUtilities.drawStringUnderlineCharAt(l, g, s, mnemIndex, textX, textY); + } +} + diff --git a/src/com/jtattoo/plaf/hifi/HiFiLookAndFeel.java b/src/com/jtattoo/plaf/hifi/HiFiLookAndFeel.java new file mode 100644 index 0000000..230c141 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiLookAndFeel.java @@ -0,0 +1,211 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.*; +import java.util.*; +import javax.swing.UIDefaults; + +/** + * @author Michael Hagen + */ +public class HiFiLookAndFeel extends AbstractLookAndFeel { + + private static HiFiDefaultTheme myTheme = null; + + private static final ArrayList themesList = new ArrayList(); + private static final HashMap themesMap = new HashMap(); + private static final Properties defaultProps = new Properties(); + private static final Properties smallFontProps = new Properties(); + private static final Properties largeFontProps = new Properties(); + private static final Properties giantFontProps = new Properties(); + + static { + smallFontProps.setProperty("controlTextFont", "Dialog bold 10"); + smallFontProps.setProperty("systemTextFont", "Dialog bold 10"); + smallFontProps.setProperty("userTextFont", "Dialog 10"); + smallFontProps.setProperty("menuTextFont", "Dialog bold 10"); + smallFontProps.setProperty("windowTitleFont", "Dialog bold 10"); + smallFontProps.setProperty("subTextFont", "Dialog 8"); + + largeFontProps.setProperty("controlTextFont", "Dialog bold 14"); + largeFontProps.setProperty("systemTextFont", "Dialog bold 14"); + largeFontProps.setProperty("userTextFont", "Dialog bold 14"); + largeFontProps.setProperty("menuTextFont", "Dialog bold 14"); + largeFontProps.setProperty("windowTitleFont", "Dialog bold 14"); + largeFontProps.setProperty("subTextFont", "Dialog 12"); + + giantFontProps.setProperty("controlTextFont", "Dialog 18"); + giantFontProps.setProperty("systemTextFont", "Dialog 18"); + giantFontProps.setProperty("userTextFont", "Dialog 18"); + giantFontProps.setProperty("menuTextFont", "Dialog 18"); + giantFontProps.setProperty("windowTitleFont", "Dialog 18"); + giantFontProps.setProperty("subTextFont", "Dialog 16"); + + themesList.add("Default"); + themesList.add("Small-Font"); + themesList.add("Large-Font"); + themesList.add("Giant-Font"); + + themesMap.put("Default", defaultProps); + themesMap.put("Small-Font", smallFontProps); + themesMap.put("Large-Font", largeFontProps); + themesMap.put("Giant-Font", giantFontProps); + } + + public static java.util.List getThemes() { + return themesList; + } + + public static Properties getThemeProperties(String name) { + return ((Properties) themesMap.get(name)); + } + + public static void setTheme(String name) { + setTheme((Properties) themesMap.get(name)); + if (myTheme != null) { + AbstractTheme.setInternalName(name); + } + } + + public static void setTheme(String name, String licenseKey, String logoString) { + Properties props = (Properties) themesMap.get(name); + if (props != null) { + props.put("licenseKey", licenseKey); + props.put("logoString", logoString); + setTheme(props); + if (myTheme != null) { + AbstractTheme.setInternalName(name); + } + } + } + + public static void setTheme(Properties themesProps) { + currentThemeName = "hifiTheme"; + if (myTheme == null) { + myTheme = new HiFiDefaultTheme(); + } + if ((myTheme != null) && (themesProps != null)) { + myTheme.setUpColor(); + myTheme.setProperties(themesProps); + myTheme.setUpColorArrs(); + AbstractLookAndFeel.setTheme(myTheme); + } + } + + public static void setCurrentTheme(Properties themesProps) { + setTheme(themesProps); + } + + public String getName() { + return "HiFi"; + } + + public String getID() { + return "HiFi"; + } + + public String getDescription() { + return "The HiFi Look and Feel"; + } + + public boolean isNativeLookAndFeel() { + return false; + } + + public boolean isSupportedLookAndFeel() { + return true; + } + + public AbstractBorderFactory getBorderFactory() { + return HiFiBorderFactory.getInstance(); + } + + public AbstractIconFactory getIconFactory() { + return HiFiIconFactory.getInstance(); + } + + protected void createDefaultTheme() { + if (myTheme == null) { + myTheme = new HiFiDefaultTheme(); + } + setTheme(myTheme); + } + + protected void initComponentDefaults(UIDefaults table) { + super.initComponentDefaults(table); + table.put("ScrollBar.incrementButtonGap", -1); + table.put("ScrollBar.decrementButtonGap", -1); + } + + protected void initClassDefaults(UIDefaults table) { + if (!"hifiTheme".equals(currentThemeName)) { + setTheme("Default"); + } + super.initClassDefaults(table); + Object[] uiDefaults = { + // BaseLookAndFeel classes + "SeparatorUI", BaseSeparatorUI.class.getName(), + "TextFieldUI", BaseTextFieldUI.class.getName(), + "TextAreaUI", BaseTextAreaUI.class.getName(), + "EditorPaneUI", BaseEditorPaneUI.class.getName(), + "PasswordFieldUI", BasePasswordFieldUI.class.getName(), + "ToolTipUI", BaseToolTipUI.class.getName(), + "TreeUI", BaseTreeUI.class.getName(), + "TableUI", BaseTableUI.class.getName(), + "TableHeaderUI", BaseTableHeaderUI.class.getName(), + "SplitPaneUI", BaseSplitPaneUI.class.getName(), + "ProgressBarUI", BaseProgressBarUI.class.getName(), + "FileChooserUI", BaseFileChooserUI.class.getName(), + "MenuUI", BaseMenuUI.class.getName(), + "PopupMenuUI", BasePopupMenuUI.class.getName(), + "MenuItemUI", BaseMenuItemUI.class.getName(), + "CheckBoxMenuItemUI", BaseCheckBoxMenuItemUI.class.getName(), + "RadioButtonMenuItemUI", BaseRadioButtonMenuItemUI.class.getName(), + "PopupMenuSeparatorUI", BaseSeparatorUI.class.getName(), + "DesktopPaneUI", BaseDesktopPaneUI.class.getName(), + + // HiFiLookAndFeel classes + "LabelUI", HiFiLabelUI.class.getName(), + "CheckBoxUI", HiFiCheckBoxUI.class.getName(), + "RadioButtonUI", HiFiRadioButtonUI.class.getName(), + "ButtonUI", HiFiButtonUI.class.getName(), + "ToggleButtonUI", HiFiToggleButtonUI.class.getName(), + "ComboBoxUI", HiFiComboBoxUI.class.getName(), + "SliderUI", HiFiSliderUI.class.getName(), + "PanelUI", HiFiPanelUI.class.getName(), + "ScrollPaneUI", HiFiScrollPaneUI.class.getName(), + "TabbedPaneUI", HiFiTabbedPaneUI.class.getName(), + "ScrollBarUI", HiFiScrollBarUI.class.getName(), + "ToolBarUI", HiFiToolBarUI.class.getName(), + "MenuBarUI", HiFiMenuBarUI.class.getName(), + "InternalFrameUI", HiFiInternalFrameUI.class.getName(), + "RootPaneUI", HiFiRootPaneUI.class.getName(),}; + table.putDefaults(uiDefaults); + if (JTattooUtilities.getJavaVersion() >= 1.5) { + table.put("FormattedTextFieldUI", BaseFormattedTextFieldUI.class.getName()); + table.put("SpinnerUI", BaseSpinnerUI.class.getName()); + } + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiMenuBarUI.java b/src/com/jtattoo/plaf/hifi/HiFiMenuBarUI.java new file mode 100644 index 0000000..ab406ef --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiMenuBarUI.java @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.JMenuBar; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicMenuBarUI; + + +/** + * @author Michael Hagen + */ +public class HiFiMenuBarUI extends BasicMenuBarUI { + + public static ComponentUI createUI(JComponent c) { + return new HiFiMenuBarUI(); + } + + public void installUI(JComponent c) { + super.installUI(c); + if ((c != null) && (c instanceof JMenuBar)) { + ((JMenuBar) c).setBorder(HiFiBorders.getMenuBarBorder()); + } + } + + public void paint(Graphics g, JComponent c) { + HiFiUtils.fillComponent(g, c); + } +} \ No newline at end of file diff --git a/src/com/jtattoo/plaf/hifi/HiFiPanelUI.java b/src/com/jtattoo/plaf/hifi/HiFiPanelUI.java new file mode 100644 index 0000000..bb063bb --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiPanelUI.java @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.BasePanelUI; +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.ComponentUI; + +/** + * @author Michael Hagen + */ +public class HiFiPanelUI extends BasePanelUI { + + private static HiFiPanelUI panelUI = null; + + public static ComponentUI createUI(JComponent c) { + if (panelUI == null) { + panelUI = new HiFiPanelUI(); + } + return panelUI; + } + + public void update(Graphics g, JComponent c) { + if (c.isOpaque() && c.getBackground() instanceof ColorUIResource && c.getClientProperty("backgroundTexture") == null) { + HiFiUtils.fillComponent(g, c); + } else { + super.update(g, c); + } + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiRadioButtonUI.java b/src/com/jtattoo/plaf/hifi/HiFiRadioButtonUI.java new file mode 100644 index 0000000..554a5fd --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiRadioButtonUI.java @@ -0,0 +1,90 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.*; +import java.awt.*; +import javax.swing.*; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicHTML; +import javax.swing.text.View; + +/** + * @author Michael Hagen + */ +public class HiFiRadioButtonUI extends BaseRadioButtonUI { + + private static HiFiRadioButtonUI radioButtonUI = null; + + public static ComponentUI createUI(JComponent c) { + if (radioButtonUI == null) { + radioButtonUI = new HiFiRadioButtonUI(); + } + return radioButtonUI; + } + + protected void paintText(Graphics g, JComponent c, String text, Rectangle textRect) { + View v = (View) c.getClientProperty(BasicHTML.propertyKey); + if (v != null) { + v.paint(g, textRect); + } else { + AbstractButton b = (AbstractButton) c; + ButtonModel model = b.getModel(); + int mnemIndex = -1; + if (JTattooUtilities.getJavaVersion() >= 1.4) { + mnemIndex = b.getDisplayedMnemonicIndex(); + } else { + mnemIndex = JTattooUtilities.findDisplayedMnemonicIndex(b.getText(), model.getMnemonic()); + } + g.setFont(b.getFont()); + FontMetrics fm = JTattooUtilities.getFontMetrics(b, g, b.getFont()); + if (model.isEnabled()) { + Color fc = b.getForeground(); + if (AbstractLookAndFeel.getTheme().isTextShadowOn() && ColorHelper.getGrayValue(fc) > 128) { + g.setColor(Color.black); + JTattooUtilities.drawStringUnderlineCharAt(c, g, text, mnemIndex, textRect.x + 1, textRect.y + 1 + fm.getAscent()); + } + g.setColor(fc); + JTattooUtilities.drawStringUnderlineCharAt(c, g, text, mnemIndex, textRect.x, textRect.y + fm.getAscent()); + } else { + g.setColor(Color.black); + JTattooUtilities.drawStringUnderlineCharAt(c, g, text, mnemIndex, textRect.x + 1, textRect.y + 1 + fm.getAscent()); + g.setColor(AbstractLookAndFeel.getDisabledForegroundColor()); + JTattooUtilities.drawStringUnderlineCharAt(c, g, text, mnemIndex, textRect.x, textRect.y + fm.getAscent()); + } + } + } + + public void paintBackground(Graphics g, JComponent c) { + if (c.isOpaque()) { + if ((c.getBackground() instanceof ColorUIResource) && c.getBackground().equals(AbstractLookAndFeel.getBackgroundColor())) { + HiFiUtils.fillComponent(g, c); + } else { + g.setColor(c.getBackground()); + g.fillRect(0, 0, c.getWidth(), c.getHeight()); + } + } + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiRootPaneUI.java b/src/com/jtattoo/plaf/hifi/HiFiRootPaneUI.java new file mode 100644 index 0000000..4a7b17d --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiRootPaneUI.java @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.BaseRootPaneUI; +import javax.swing.JComponent; +import javax.swing.JRootPane; +import javax.swing.plaf.ComponentUI; + +/** + * @author Michael Hagen + */ +public class HiFiRootPaneUI extends BaseRootPaneUI { + + public static ComponentUI createUI(JComponent c) { + return new HiFiRootPaneUI(); + } + + public JComponent createTitlePane(JRootPane root) { + return new HiFiTitlePane(root, this); + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiScrollBarUI.java b/src/com/jtattoo/plaf/hifi/HiFiScrollBarUI.java new file mode 100644 index 0000000..29d4177 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiScrollBarUI.java @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.*; +import java.awt.Color; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; + +/** + * + * @author Michael Hagen + */ +public class HiFiScrollBarUI extends XPScrollBarUI { + + public static ComponentUI createUI(JComponent c) { + return new HiFiScrollBarUI(); + } + + protected void installDefaults() { + super.installDefaults(); + Color colors[] = AbstractLookAndFeel.getTheme().getThumbColors(); + rolloverColors = new Color[colors.length]; + dragColors = new Color[colors.length]; + for (int i = 0; i < colors.length; i++) { + rolloverColors[i] = ColorHelper.brighter(colors[i], 8); + dragColors[i] = ColorHelper.darker(colors[i], 8); + } + } + + protected JButton createDecreaseButton(int orientation) { + if (AbstractLookAndFeel.getTheme().isMacStyleScrollBarOn()) { + return super.createDecreaseButton(orientation); + } else { + return new HiFiScrollButton(orientation, scrollBarWidth); + } + } + + protected JButton createIncreaseButton(int orientation) { + if (AbstractLookAndFeel.getTheme().isMacStyleScrollBarOn()) { + return super.createIncreaseButton(orientation); + } else { + return new HiFiScrollButton(orientation, scrollBarWidth); + } + } + + protected Color getFrameColor() { + Color frameColor = ColorHelper.brighter(AbstractLookAndFeel.getTheme().getButtonBackgroundColor(), 8); + if (isDragging) { + return ColorHelper.darker(frameColor, 8); + } else if (isRollover) { + return ColorHelper.brighter(frameColor, 16); + } else { + return frameColor; + } + } + +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiScrollButton.java b/src/com/jtattoo/plaf/hifi/HiFiScrollButton.java new file mode 100644 index 0000000..c254421 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiScrollButton.java @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.*; +import java.awt.Color; + +/** + * @author Michael Hagen + */ +public class HiFiScrollButton extends XPScrollButton { + + public HiFiScrollButton(int direction, int width) { + super(direction, width); + } + + public Color getFrameColor() { + Color frameColor = ColorHelper.brighter(AbstractLookAndFeel.getTheme().getButtonBackgroundColor(), 8); + if (getModel().isPressed()) { + return ColorHelper.darker(frameColor, 8); + } else if (getModel().isRollover()) { + return ColorHelper.brighter(frameColor, 16); + } else { + return frameColor; + } + } + +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiScrollPaneUI.java b/src/com/jtattoo/plaf/hifi/HiFiScrollPaneUI.java new file mode 100644 index 0000000..af97343 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiScrollPaneUI.java @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.BaseScrollPaneUI; +import javax.swing.*; +import javax.swing.plaf.ComponentUI; + +/** + * @author Michael Hagen + */ +public class HiFiScrollPaneUI extends BaseScrollPaneUI { + + public static ComponentUI createUI(JComponent c) { + return new HiFiScrollPaneUI(); + } + + public void installDefaults(JScrollPane p) { + super.installDefaults(p); + p.getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE); + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiSliderUI.java b/src/com/jtattoo/plaf/hifi/HiFiSliderUI.java new file mode 100644 index 0000000..f245cf0 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiSliderUI.java @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.BaseSliderUI; +import java.awt.Component; +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.JSlider; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.ComponentUI; + +/** + * @author Michael Hagen + */ +public class HiFiSliderUI extends BaseSliderUI { + + public HiFiSliderUI(JSlider slider) { + super(slider); + } + + public static ComponentUI createUI(JComponent c) { + return new HiFiSliderUI((JSlider) c); + } + + public void paintBackground(Graphics g, JComponent c) { + if (c.isOpaque()) { + Component parent = c.getParent(); + if ((parent != null) && (parent.getBackground() instanceof ColorUIResource)) { + HiFiUtils.fillComponent(g, c); + } else { + if (parent != null) { + g.setColor(parent.getBackground()); + } else { + g.setColor(c.getBackground()); + } + g.fillRect(0, 0, c.getWidth(), c.getHeight()); + } + } + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiTabbedPaneUI.java b/src/com/jtattoo/plaf/hifi/HiFiTabbedPaneUI.java new file mode 100644 index 0000000..91ec0fb --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiTabbedPaneUI.java @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.*; +import java.awt.*; +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.text.View; + +/** + * @author Michael Hagen + */ +public class HiFiTabbedPaneUI extends BaseTabbedPaneUI { + + public static ComponentUI createUI(JComponent c) { + return new HiFiTabbedPaneUI(); + } + + protected Color[] getContentBorderColors(int tabPlacement) { + Color SEP_COLORS[] = { + ColorHelper.darker(AbstractLookAndFeel.getBackgroundColor(), 40), + ColorHelper.brighter(AbstractLookAndFeel.getBackgroundColor(), 20), + ColorHelper.darker(AbstractLookAndFeel.getBackgroundColor(), 20), + ColorHelper.darker(AbstractLookAndFeel.getBackgroundColor(), 40), + ColorHelper.darker(AbstractLookAndFeel.getBackgroundColor(), 60), + }; + return SEP_COLORS; + } + + protected void paintText(Graphics g, int tabPlacement, Font font, FontMetrics metrics, int tabIndex, String title, Rectangle textRect, boolean isSelected) { + Color backColor = tabPane.getBackgroundAt(tabIndex); + if (!(backColor instanceof UIResource)) { + super.paintText(g, tabPlacement, font, metrics, tabIndex, title, textRect, isSelected); + return; + } + g.setFont(font); + View v = getTextViewForTab(tabIndex); + if (v != null) { + // html + Graphics2D g2D = (Graphics2D) g; + Object savedRenderingHint = null; + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + savedRenderingHint = g2D.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, AbstractLookAndFeel.getTheme().getTextAntiAliasingHint()); + } + v.paint(g, textRect); + if (AbstractLookAndFeel.getTheme().isTextAntiAliasingOn()) { + g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, savedRenderingHint); + } + } else { + // plain text + int mnemIndex = -1; + if (JTattooUtilities.getJavaVersion() >= 1.4) { + mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex); + } + + Graphics2D g2D = (Graphics2D) g; + Composite composite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f); + g2D.setComposite(alpha); + Color fc = tabPane.getForegroundAt(tabIndex); + if (isSelected) { + fc = AbstractLookAndFeel.getTheme().getTabSelectionForegroundColor(); + } + if (!tabPane.isEnabled() || !tabPane.isEnabledAt(tabIndex)) { + fc = AbstractLookAndFeel.getTheme().getDisabledForegroundColor(); + } + if (ColorHelper.getGrayValue(fc) > 128) { + g2D.setColor(Color.black); + } else { + g2D.setColor(Color.white); + } + JTattooUtilities.drawStringUnderlineCharAt(tabPane, g, title, mnemIndex, textRect.x + 1, textRect.y + 1 + metrics.getAscent()); + g2D.setComposite(composite); + g2D.setColor(fc); + JTattooUtilities.drawStringUnderlineCharAt(tabPane, g, title, mnemIndex, textRect.x, textRect.y + metrics.getAscent()); + } + } + +} \ No newline at end of file diff --git a/src/com/jtattoo/plaf/hifi/HiFiTitlePane.java b/src/com/jtattoo/plaf/hifi/HiFiTitlePane.java new file mode 100644 index 0000000..42adf50 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiTitlePane.java @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.*; +import java.awt.Color; +import java.awt.Graphics; +import javax.swing.JRootPane; + +/** + * @author Michael Hagen + */ +public class HiFiTitlePane extends BaseTitlePane { + + public HiFiTitlePane(JRootPane root, BaseRootPaneUI ui) { + super(root, ui); + } + + protected boolean centerButtons() { + return false; + } + + public void paintText(Graphics g, int x, int y, String title) { + g.setColor(Color.black); + JTattooUtilities.drawString(rootPane, g, title, x + 1, y + 1); + if (isActive()) { + g.setColor(AbstractLookAndFeel.getWindowTitleForegroundColor()); + } else { + g.setColor(AbstractLookAndFeel.getWindowInactiveTitleForegroundColor()); + } + JTattooUtilities.drawString(rootPane, g, title, x, y); + } + + protected void paintBorder(Graphics g) { + } + +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiToggleButtonUI.java b/src/com/jtattoo/plaf/hifi/HiFiToggleButtonUI.java new file mode 100644 index 0000000..e2ccd52 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiToggleButtonUI.java @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.*; +import java.awt.*; +import javax.swing.*; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.ComponentUI; + +/** + * @author Michael Hagen + */ +public class HiFiToggleButtonUI extends BaseToggleButtonUI { + + public static ComponentUI createUI(JComponent c) { + return new HiFiToggleButtonUI(); + } + + protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) { + ButtonModel model = b.getModel(); + FontMetrics fm = JTattooUtilities.getFontMetrics(b, g, b.getFont()); + int mnemIndex = (JTattooUtilities.getJavaVersion() >= 1.4) ? b.getDisplayedMnemonicIndex() : JTattooUtilities.findDisplayedMnemonicIndex(b.getText(), model.getMnemonic()); + int offs = 0; + if (model.isArmed() && model.isPressed()) { + offs = 1; + } + + Graphics2D g2D = (Graphics2D) g; + Composite composite = g2D.getComposite(); + AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f); + g2D.setComposite(alpha); + Color foreground = b.getForeground(); + Color background = b.getBackground(); + if ((model.isPressed() && model.isArmed()) || model.isSelected()) { + if (foreground instanceof ColorUIResource && background instanceof ColorUIResource) { + foreground = AbstractLookAndFeel.getTheme().getPressedForegroundColor(); + } + } + if (!model.isEnabled()) { + foreground = AbstractLookAndFeel.getTheme().getDisabledForegroundColor(); + } + if (ColorHelper.getGrayValue(foreground) > 128) { + g2D.setColor(Color.black); + } else { + g2D.setColor(Color.white); + } + JTattooUtilities.drawStringUnderlineCharAt(b, g, text, mnemIndex, textRect.x + offs + 1, textRect.y + offs + fm.getAscent() + 1); + g2D.setComposite(composite); + g2D.setColor(foreground); + JTattooUtilities.drawStringUnderlineCharAt(b, g, text, mnemIndex, textRect.x + offs, textRect.y + offs + fm.getAscent()); + } +} diff --git a/src/com/jtattoo/plaf/hifi/HiFiToolBarUI.java b/src/com/jtattoo/plaf/hifi/HiFiToolBarUI.java new file mode 100644 index 0000000..68c7bf7 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiToolBarUI.java @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.AbstractToolBarUI; +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.border.Border; +import javax.swing.plaf.ComponentUI; + +/** + * @author Michael Hagen + */ +public class HiFiToolBarUI extends AbstractToolBarUI { + + public static ComponentUI createUI(JComponent c) { + return new HiFiToolBarUI(); + } + + public Border getRolloverBorder() { + return HiFiBorders.getRolloverToolButtonBorder(); + } + + public Border getNonRolloverBorder() { + return HiFiBorders.getToolButtonBorder(); + } + + public boolean isButtonOpaque() { + return true; + } + + public void paint(Graphics g, JComponent c) { + HiFiUtils.fillComponent(g, c); + } +} + diff --git a/src/com/jtattoo/plaf/hifi/HiFiUtils.java b/src/com/jtattoo/plaf/hifi/HiFiUtils.java new file mode 100644 index 0000000..3161296 --- /dev/null +++ b/src/com/jtattoo/plaf/hifi/HiFiUtils.java @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2002 and later by MH Software-Entwicklung. All Rights Reserved. +* +* JTattoo is multiple licensed. If your are an open source developer you can use +* it under the terms and conditions of the GNU General Public License version 2.0 +* or later as published by the Free Software Foundation. +* +* see: gpl-2.0.txt +* +* If you pay for a license you will become a registered user who could use the +* software under the terms and conditions of the GNU Lesser General Public License +* version 2.0 or later with classpath exception as published by the Free Software +* Foundation. +* +* see: lgpl-2.0.txt +* see: classpath-exception.txt +* +* Registered users could also use JTattoo under the terms and conditions of the +* Apache License, Version 2.0 as published by the Apache Software Foundation. +* +* see: APACHE-LICENSE-2.0.txt +*/ + +package com.jtattoo.plaf.hifi; + +import com.jtattoo.plaf.AbstractLookAndFeel; +import com.jtattoo.plaf.JTattooUtilities; +import java.awt.*; + +/** + * @author Michael Hagen + */ +public class HiFiUtils { + + private HiFiUtils() { + } + + public static void fillComponent(Graphics g, Component c) { + if (AbstractLookAndFeel.getTheme().isBackgroundPatternOn()) { + int w = c.getWidth(); + int h = c.getHeight(); + Point p = JTattooUtilities.getRelLocation(c); + int y = 2 - (p.y % 3); + g.setColor(AbstractLookAndFeel.getTheme().getBackgroundColorLight()); + g.fillRect(0, 0, w, h); + g.setColor(AbstractLookAndFeel.getTheme().getBackgroundColorDark()); + while (y < h) { + g.drawLine(0, y, w, y); + y += 3; + } + } else { + g.setColor(c.getBackground()); + g.fillRect(0, 0, c.getWidth(), c.getHeight()); + } + } +}