mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 22:10:54 +03:00
Compare commits
1800 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df6256d989 | ||
|
|
c27db56321 | ||
|
|
97bed8554a | ||
|
|
751c0e16e9 | ||
|
|
936de60700 | ||
|
|
f6b64d48ec | ||
|
|
b043da7d4c | ||
|
|
7e47cc2443 | ||
|
|
b8b45f9442 | ||
|
|
66337f9af6 | ||
|
|
54646706a0 | ||
|
|
e8ee037d09 | ||
|
|
6d705e568a | ||
|
|
e768791eba | ||
|
|
2aff7c97f9 | ||
|
|
ca6fc7773e | ||
|
|
a1395a5490 | ||
|
|
61dd4d71d6 | ||
|
|
6beda53238 | ||
|
|
941441d7e1 | ||
|
|
d10ea41b47 | ||
|
|
9458870f70 | ||
|
|
095794bbd1 | ||
|
|
c7fc0aa936 | ||
|
|
a8d98ced61 | ||
|
|
831b3d851a | ||
|
|
8c891c7016 | ||
|
|
5c4706cbc9 | ||
|
|
db66a6c4f0 | ||
|
|
0517e4fc02 | ||
|
|
dd7fa4a87d | ||
|
|
e5956900ea | ||
|
|
3755593c14 | ||
|
|
8ddd3b6d68 | ||
|
|
840083940d | ||
|
|
0cdfd29ecf | ||
|
|
bb32c727b6 | ||
|
|
f978c04750 | ||
|
|
b6a504e121 | ||
|
|
5fae367fab | ||
|
|
6e807f44b2 | ||
|
|
53ebed7f89 | ||
|
|
1c10c41808 | ||
|
|
01170b669b | ||
|
|
b56215e5e3 | ||
|
|
221e801561 | ||
|
|
90edbe23d7 | ||
|
|
5b16a814c8 | ||
|
|
ef01721464 | ||
|
|
efd8cf8236 | ||
|
|
8dbfc6d5d6 | ||
|
|
ef343397d4 | ||
|
|
cae02d31db | ||
|
|
96c78cbc16 | ||
|
|
f8c769644d | ||
|
|
0bd1e413b0 | ||
|
|
07c9ad484a | ||
|
|
5fd5b1206e | ||
|
|
8e107647bd | ||
|
|
12b7389376 | ||
|
|
45332c8126 | ||
|
|
02a9d4e31d | ||
|
|
a4377e81cb | ||
|
|
8d2ed3faf6 | ||
|
|
e7dacb8fef | ||
|
|
60e2ffac5f | ||
|
|
73c37b2018 | ||
|
|
1b3cc223da | ||
|
|
51be7ad832 | ||
|
|
f93d035e4e | ||
|
|
a3885d7a48 | ||
|
|
bbf2331766 | ||
|
|
2164bd363b | ||
|
|
6205e18c45 | ||
|
|
959b3e46fa | ||
|
|
09d8d09aad | ||
|
|
70336e31c7 | ||
|
|
600e0f3d67 | ||
|
|
023e356057 | ||
|
|
27786ec00a | ||
|
|
e52e72c5a8 | ||
|
|
802dd08ce7 | ||
|
|
568ec5a1a2 | ||
|
|
035d196392 | ||
|
|
dd3ffc64b9 | ||
|
|
c9a38f0a13 | ||
|
|
78461a9d5a | ||
|
|
79b8fb910a | ||
|
|
405e3df1f0 | ||
|
|
f7126d154f | ||
|
|
d8df8c9631 | ||
|
|
37b35f9063 | ||
|
|
f61a7288eb | ||
|
|
47a1122f04 | ||
|
|
e1bfabbce5 | ||
|
|
9708fec0e0 | ||
|
|
7f4efaf0a3 | ||
|
|
269eb0ba29 | ||
|
|
428c6b7813 | ||
|
|
db2452a4ec | ||
|
|
7dac3825d7 | ||
|
|
7c99872278 | ||
|
|
64c7318cfc | ||
|
|
a9d6483829 | ||
|
|
13a6b92e47 | ||
|
|
9ba008002b | ||
|
|
8914cf78a1 | ||
|
|
d360375b4f | ||
|
|
1caab194af | ||
|
|
31754eba5d | ||
|
|
3cfa16b8b7 | ||
|
|
f80d2bacf4 | ||
|
|
5df3717d94 | ||
|
|
68897f04a2 | ||
|
|
4cb6aeae36 | ||
|
|
0a765a35bf | ||
|
|
6c0b122fbc | ||
|
|
4da2bd90cb | ||
|
|
f0275192c6 | ||
|
|
df905a1d73 | ||
|
|
ad8ad06f44 | ||
|
|
d6b9e2df62 | ||
|
|
5c9b36556f | ||
|
|
80a8348a99 | ||
|
|
005c9f471e | ||
|
|
b40532a830 | ||
|
|
fc7a4408e9 | ||
|
|
93b5f0081d | ||
|
|
ce049ea3ee | ||
|
|
fcc39b2db5 | ||
|
|
cb70fb4e82 | ||
|
|
2593a43d72 | ||
|
|
e44ff5b72a | ||
|
|
22cb1b50a6 | ||
|
|
a42c413705 | ||
|
|
d59d38dc7c | ||
|
|
77582be7fd | ||
|
|
0cb50355b7 | ||
|
|
a2d66e91ff | ||
|
|
ccdb981917 | ||
|
|
d80b581ace | ||
|
|
53efb6711d | ||
|
|
1de6e875f9 | ||
|
|
95a15c3cf8 | ||
|
|
ab320684f5 | ||
|
|
a284b69a1e | ||
|
|
b590f41254 | ||
|
|
a97076ead5 | ||
|
|
0b6df8be1c | ||
|
|
150bab0b57 | ||
|
|
d3355eda65 | ||
|
|
fbf10e553d | ||
|
|
fb37be5734 | ||
|
|
54e6cefa67 | ||
|
|
33b25c1129 | ||
|
|
44d8545c09 | ||
|
|
7a2808243c | ||
|
|
1be84de26b | ||
|
|
78e37f7ab4 | ||
|
|
e49459fd8b | ||
|
|
52f6e7fc32 | ||
|
|
c8ea61dc79 | ||
|
|
16a769ea61 | ||
|
|
6b880af447 | ||
|
|
475781db91 | ||
|
|
4dae082cd5 | ||
|
|
57405b2f56 | ||
|
|
88576f68fd | ||
|
|
aa4e013097 | ||
|
|
d67cfc911b | ||
|
|
00a3ad738f | ||
|
|
1d39d34d7c | ||
|
|
5f6013edd4 | ||
|
|
3e198ecd28 | ||
|
|
d48b98f582 | ||
|
|
9b839231f7 | ||
|
|
dd80614465 | ||
|
|
8c2be1b406 | ||
|
|
8152b7dad6 | ||
|
|
fb4fe175d9 | ||
|
|
5e03eb9b51 | ||
|
|
ef25575f85 | ||
|
|
b77b338c7a | ||
|
|
0e4fe4e9bb | ||
|
|
f742f83834 | ||
|
|
e6e4e53a73 | ||
|
|
7c594ba7a9 | ||
|
|
0156a9a9d5 | ||
|
|
3facbc0900 | ||
|
|
78cef1b3c7 | ||
|
|
d907c469ed | ||
|
|
cc238d3e34 | ||
|
|
0f9b38895e | ||
|
|
8fa1eae352 | ||
|
|
e13fb25f14 | ||
|
|
e36f942129 | ||
|
|
d34619824c | ||
|
|
80297f113f | ||
|
|
80f51bfe1e | ||
|
|
f8b9f4c1fa | ||
|
|
587f431ef4 | ||
|
|
65a4f66d2c | ||
|
|
a253b6c0cf | ||
|
|
efcbc1fbdb | ||
|
|
e560f9cbd6 | ||
|
|
80235d53f4 | ||
|
|
892b9a732e | ||
|
|
d8a0a015e4 | ||
|
|
e60e3b9fae | ||
|
|
6715f01b8c | ||
|
|
465af9bc41 | ||
|
|
d10bcfc72f | ||
|
|
942e5b9cd1 | ||
|
|
51a90d32f8 | ||
|
|
ac46632e73 | ||
|
|
1192bef1ae | ||
|
|
b9ec382589 | ||
|
|
5ecf19ef4f | ||
|
|
9636809b4d | ||
|
|
ba1c1ed952 | ||
|
|
7452390614 | ||
|
|
69042e42b7 | ||
|
|
1e93deab2a | ||
|
|
16ea809bb3 | ||
|
|
78aa4343b7 | ||
|
|
6815109e15 | ||
|
|
e34fbcec58 | ||
|
|
bb2a21270b | ||
|
|
49b9ec9025 | ||
|
|
a2e896e102 | ||
|
|
2e1ef647a9 | ||
|
|
f0c314df80 | ||
|
|
4db39828ef | ||
|
|
b2d40825ac | ||
|
|
6df5d3334e | ||
|
|
0e982df90c | ||
|
|
3834d93c9d | ||
|
|
16920a5b82 | ||
|
|
d66e35fdde | ||
|
|
d93dde0a03 | ||
|
|
2d232124dd | ||
|
|
ac6702fcf7 | ||
|
|
c4b016c9c8 | ||
|
|
6baa583a28 | ||
|
|
82df2ecfa9 | ||
|
|
06b3de720a | ||
|
|
b0edd5659f | ||
|
|
bb5c2eea10 | ||
|
|
e31e4dfe3a | ||
|
|
caf2cd8487 | ||
|
|
15c6f11a5e | ||
|
|
a4ea88f4be | ||
|
|
36d5747fbf | ||
|
|
3d8c535ffa | ||
|
|
1c067d0284 | ||
|
|
b6be0462a5 | ||
|
|
cce91ea16d | ||
|
|
d756041b06 | ||
|
|
2d0eb0a05b | ||
|
|
02f3239669 | ||
|
|
14a9240c45 | ||
|
|
c659638fb4 | ||
|
|
fd15b63044 | ||
|
|
263e6c34b5 | ||
|
|
eb62a3dc17 | ||
|
|
161ee090a8 | ||
|
|
560ec437b9 | ||
|
|
ccd0597b35 | ||
|
|
c5c0a3768a | ||
|
|
5aa2d24d58 | ||
|
|
ae28c595f9 | ||
|
|
1d08ddda60 | ||
|
|
578379fd00 | ||
|
|
7c9f550d4c | ||
|
|
84d4510d70 | ||
|
|
fa194ec258 | ||
|
|
fd56de403d | ||
|
|
85fde46504 | ||
|
|
b283178979 | ||
|
|
e0dddfceba | ||
|
|
bddef38a7c | ||
|
|
b5f2f77944 | ||
|
|
fca0718ed0 | ||
|
|
0d44ade6ea | ||
|
|
08ca2aa266 | ||
|
|
fe15758e59 | ||
|
|
674efae184 | ||
|
|
4a65bc88d5 | ||
|
|
a8f3d59729 | ||
|
|
6018f83a22 | ||
|
|
0b6247851b | ||
|
|
8640dee053 | ||
|
|
824db2e3bd | ||
|
|
c2c79c4676 | ||
|
|
4795fe5687 | ||
|
|
d508f339c1 | ||
|
|
c7054537e7 | ||
|
|
b98b904023 | ||
|
|
253df9325d | ||
|
|
78a9cc1d0c | ||
|
|
b25fcc3381 | ||
|
|
a2c0df5891 | ||
|
|
dc33c26960 | ||
|
|
51d7bc2c37 | ||
|
|
cdbdccf1ad | ||
|
|
397c369114 | ||
|
|
6f9bbb184a | ||
|
|
b12c818862 | ||
|
|
9118dcf925 | ||
|
|
d333d0c9e4 | ||
|
|
7f9cf6f45c | ||
|
|
9b465cb550 | ||
|
|
9144b7206e | ||
|
|
dd14843f2e | ||
|
|
09a18b2305 | ||
|
|
31f2feee2e | ||
|
|
218bb62bfd | ||
|
|
694c2ad767 | ||
|
|
97943fcd38 | ||
|
|
77f33467d2 | ||
|
|
651454170d | ||
|
|
7ca48bd136 | ||
|
|
968e508bb5 | ||
|
|
a6d318a197 | ||
|
|
cd20f4086b | ||
|
|
ebd5905947 | ||
|
|
817a3c62bb | ||
|
|
f8f58400fe | ||
|
|
ef06840649 | ||
|
|
b17c14d62e | ||
|
|
19dba94064 | ||
|
|
601e24f9e7 | ||
|
|
c7f323ee13 | ||
|
|
e4522f3af4 | ||
|
|
79af461a5b | ||
|
|
2e8e07faf6 | ||
|
|
ecdb000818 | ||
|
|
999fd0d4da | ||
|
|
705dd9558f | ||
|
|
97ca866ffa | ||
|
|
543b977db7 | ||
|
|
ebb8a6d025 | ||
|
|
506543281e | ||
|
|
60322be22a | ||
|
|
e1f30f24a8 | ||
|
|
1759f6b25c | ||
|
|
6578f25cc9 | ||
|
|
8c26e0323f | ||
|
|
a5575894ab | ||
|
|
357823a027 | ||
|
|
a6d3f6b3eb | ||
|
|
ae4c69e75c | ||
|
|
31cadc532b | ||
|
|
6e8443473b | ||
|
|
cca4ab3cd8 | ||
|
|
dab0ee3306 | ||
|
|
c6d1ed91a7 | ||
|
|
a613a244f4 | ||
|
|
268fe15004 | ||
|
|
7bc9be686f | ||
|
|
751919ec5a | ||
|
|
da913b426e | ||
|
|
d8ef99cd8f | ||
|
|
d08a6d7dd3 | ||
|
|
896e9bca8e | ||
|
|
1df9597bb1 | ||
|
|
eaf55f2099 | ||
|
|
5018a1f9eb | ||
|
|
71ba8f55a7 | ||
|
|
b65db707ed | ||
|
|
ed62266a43 | ||
|
|
49913b7dad | ||
|
|
3eeeb9e00b | ||
|
|
bfb1642284 | ||
|
|
0544a605c3 | ||
|
|
3f5acda132 | ||
|
|
02b1ba2926 | ||
|
|
7f7f9e3c7c | ||
|
|
6fcee03752 | ||
|
|
5782ceeb5d | ||
|
|
f752db5892 | ||
|
|
bce58bc97b | ||
|
|
d373687bc4 | ||
|
|
e5e510c825 | ||
|
|
29064ec72f | ||
|
|
953eee1dc8 | ||
|
|
75f76f4875 | ||
|
|
ecfbe68c33 | ||
|
|
7f02eb9cf0 | ||
|
|
4ab90065dc | ||
|
|
d3e39a1359 | ||
|
|
60e5861de4 | ||
|
|
ca7f5045ae | ||
|
|
299bd67151 | ||
|
|
4d4bb3fd7f | ||
|
|
7fd64a1b73 | ||
|
|
e3e8765b91 | ||
|
|
b0997fb5d2 | ||
|
|
435cf05f9f | ||
|
|
37dab9fb22 | ||
|
|
943dfe0619 | ||
|
|
be7114d3e6 | ||
|
|
fb44c8fbe4 | ||
|
|
94375b7d36 | ||
|
|
8b585deb78 | ||
|
|
4d8b544aed | ||
|
|
548d651d29 | ||
|
|
0b342acec9 | ||
|
|
cc6d3c1b1a | ||
|
|
74a748d92e | ||
|
|
1de81d0af5 | ||
|
|
ff9ef21f67 | ||
|
|
266a546478 | ||
|
|
87407ca832 | ||
|
|
90282d4436 | ||
|
|
abbe6d6c1f | ||
|
|
a28f701e6f | ||
|
|
4cdc995a7f | ||
|
|
713a01bfa9 | ||
|
|
ac291b688d | ||
|
|
84f7e244f2 | ||
|
|
4a8207f367 | ||
|
|
9cfd4d27e9 | ||
|
|
1b23cfd747 | ||
|
|
c708205593 | ||
|
|
a22c6c8013 | ||
|
|
b576f473e5 | ||
|
|
0b127caa83 | ||
|
|
5801bf3bdf | ||
|
|
4507ce359d | ||
|
|
3e14f28dc2 | ||
|
|
a9dcf09d13 | ||
|
|
c8998c2bcf | ||
|
|
10bf1295bc | ||
|
|
1e869973d4 | ||
|
|
731c8962c9 | ||
|
|
294b8bb789 | ||
|
|
4f9b819f48 | ||
|
|
5318d5fa8e | ||
|
|
98b156bdde | ||
|
|
511dd02107 | ||
|
|
f1f7a2e7b6 | ||
|
|
d557cf5427 | ||
|
|
2b1c55ee67 | ||
|
|
925ddaa63a | ||
|
|
2b60b18d47 | ||
|
|
d502406fa2 | ||
|
|
afdbf711f7 | ||
|
|
39d2941099 | ||
|
|
b4f7b1d71d | ||
|
|
69061cd41c | ||
|
|
8ba7f7f961 | ||
|
|
5e5aa17e14 | ||
|
|
551f5fc929 | ||
|
|
4e7b0d11d0 | ||
|
|
06bc53692a | ||
|
|
007ee38cb4 | ||
|
|
2a732306a1 | ||
|
|
82192bef91 | ||
|
|
0c51dfe19c | ||
|
|
24a9fa1ccc | ||
|
|
14b06507cb | ||
|
|
b46233087b | ||
|
|
28fb2e2a08 | ||
|
|
943e211cf1 | ||
|
|
ad0a13004e | ||
|
|
04bb6a5275 | ||
|
|
d3c917eac1 | ||
|
|
4c13271a5b | ||
|
|
20027c2db7 | ||
|
|
6affc70a66 | ||
|
|
ab4c9bdeda | ||
|
|
b4a9c9b7f5 | ||
|
|
5e20d50abf | ||
|
|
53abbbbe56 | ||
|
|
1938cb586d | ||
|
|
50490ece84 | ||
|
|
f291cc2bd3 | ||
|
|
2542c8bd53 | ||
|
|
b457fd634e | ||
|
|
041fd0e0cd | ||
|
|
a983edde1e | ||
|
|
7eb642dd13 | ||
|
|
e0bc93371e | ||
|
|
db56486506 | ||
|
|
c99be13697 | ||
|
|
0830c78728 | ||
|
|
edade93054 | ||
|
|
8a72b30cbc | ||
|
|
ed9cb0f918 | ||
|
|
7e0915cb9c | ||
|
|
a51294d570 | ||
|
|
d962f218a1 | ||
|
|
7b248427f0 | ||
|
|
b99fb8b11f | ||
|
|
26250e790f | ||
|
|
b26dbe81f4 | ||
|
|
903212345b | ||
|
|
025f6564dc | ||
|
|
35f97368fa | ||
|
|
09e5c86488 | ||
|
|
8998371cae | ||
|
|
29e1dc6b55 | ||
|
|
439e63b52f | ||
|
|
eea341fb33 | ||
|
|
359eedf773 | ||
|
|
866751ffc1 | ||
|
|
38a3a0768d | ||
|
|
03b42749cd | ||
|
|
60fd78e082 | ||
|
|
9edaf58929 | ||
|
|
5000186f85 | ||
|
|
cacf0ea987 | ||
|
|
067501cbe7 | ||
|
|
9fe0cf496b | ||
|
|
9d0823038e | ||
|
|
5a05efefdd | ||
|
|
988d171bdd | ||
|
|
e6f72bf343 | ||
|
|
89c5a0c57b | ||
|
|
d97146393c | ||
|
|
1c52f1f76c | ||
|
|
9bd3a68115 | ||
|
|
f58780d36b | ||
|
|
6eb15ab437 | ||
|
|
00dc7004f5 | ||
|
|
8ec0e57235 | ||
|
|
d75dc9e70c | ||
|
|
ec2fccbb0e | ||
|
|
34861166e8 | ||
|
|
584fa0a26e | ||
|
|
6c48489d89 | ||
|
|
ba9c884a0c | ||
|
|
360f0bafe0 | ||
|
|
4327c13dca | ||
|
|
4f2256f713 | ||
|
|
5167cd368f | ||
|
|
ef7289d11a | ||
|
|
cb11d98bf7 | ||
|
|
992349da8c | ||
|
|
2e7637f274 | ||
|
|
1f8eaf4a64 | ||
|
|
46ac7a9dc7 | ||
|
|
0d86d39217 | ||
|
|
1f591f3d1b | ||
|
|
30c6ddba37 | ||
|
|
406eeaec96 | ||
|
|
2fe5652bc6 | ||
|
|
39bf68a6bd | ||
|
|
a7a4a19824 | ||
|
|
7f906ba0ea | ||
|
|
07bf6e4506 | ||
|
|
a331760321 | ||
|
|
d9c240d729 | ||
|
|
d9526c19e7 | ||
|
|
1798ccd284 | ||
|
|
ab1ce7fab1 | ||
|
|
e9b2f17171 | ||
|
|
d3bf4433b7 | ||
|
|
ba0f43455b | ||
|
|
638af4bcd7 | ||
|
|
5eab843d97 | ||
|
|
c55f0e239e | ||
|
|
32d9381745 | ||
|
|
77fc564e70 | ||
|
|
3b84314c45 | ||
|
|
5729c20386 | ||
|
|
a4d70d8095 | ||
|
|
8fcce349d5 | ||
|
|
5a94676a3a | ||
|
|
f32d72ee62 | ||
|
|
e35fc8620c | ||
|
|
277c288952 | ||
|
|
240b08e55c | ||
|
|
fe7f345661 | ||
|
|
c8db01c958 | ||
|
|
f456185f7d | ||
|
|
801b555835 | ||
|
|
eee177e64b | ||
|
|
63639f8e96 | ||
|
|
de1b0b1bb6 | ||
|
|
bbdd7fc2b4 | ||
|
|
6addb5c4b4 | ||
|
|
b47e0c88d6 | ||
|
|
d06993d940 | ||
|
|
d31f167b9e | ||
|
|
f12ee6c167 | ||
|
|
983b341f33 | ||
|
|
f3e6642f05 | ||
|
|
0a63990d21 | ||
|
|
6909bb4b03 | ||
|
|
620aa8bcee | ||
|
|
6db39d1860 | ||
|
|
1762ead89f | ||
|
|
d13ddeb944 | ||
|
|
1b5da0e1d1 | ||
|
|
7a2d0e7fcb | ||
|
|
477c3b6b1e | ||
|
|
95312c3650 | ||
|
|
98a3c4b0f5 | ||
|
|
6e990a7e31 | ||
|
|
8e49904f8d | ||
|
|
69f52c8abd | ||
|
|
d7b0754327 | ||
|
|
2a00de11f1 | ||
|
|
923cc51f3e | ||
|
|
c8f7478170 | ||
|
|
9006e835c6 | ||
|
|
f801d61929 | ||
|
|
a143e5777c | ||
|
|
bffac60bf8 | ||
|
|
bf500e46e7 | ||
|
|
4a2f79f390 | ||
|
|
c24ce7c5bc | ||
|
|
8a6a0c7971 | ||
|
|
de6e5bd800 | ||
|
|
e18a04f9e6 | ||
|
|
14fc652f4b | ||
|
|
9a876e747a | ||
|
|
f8ee8b27fb | ||
|
|
ce1a1487aa | ||
|
|
fe1e364a1d | ||
|
|
eabb052107 | ||
|
|
734f3621f1 | ||
|
|
ae8323e2f8 | ||
|
|
9612a81f2e | ||
|
|
2945a36cef | ||
|
|
b84dc5bfcc | ||
|
|
60486fd880 | ||
|
|
891091cebc | ||
|
|
1493ddcf41 | ||
|
|
4299c50537 | ||
|
|
14577c396d | ||
|
|
e9b566241d | ||
|
|
d39b08c035 | ||
|
|
69ac683c8c | ||
|
|
eafd0b3d06 | ||
|
|
310a4989dc | ||
|
|
3d0df51839 | ||
|
|
ede02aaaa5 | ||
|
|
beff149004 | ||
|
|
07db6e8fb0 | ||
|
|
46852c0780 | ||
|
|
a5e41c573f | ||
|
|
ed91aa4648 | ||
|
|
9a94395d30 | ||
|
|
04aa61c2bb | ||
|
|
035a13df54 | ||
|
|
e8a6f0ca3d | ||
|
|
1fc519b9de | ||
|
|
2bcf38e2e3 | ||
|
|
8eb44a68cb | ||
|
|
30c7b442a8 | ||
|
|
cee2211108 | ||
|
|
b7bcbccd45 | ||
|
|
d2ccb97eba | ||
|
|
39d56f2603 | ||
|
|
83e904dd2d | ||
|
|
110c787eba | ||
|
|
7c7ff289de | ||
|
|
617a35c51b | ||
|
|
73487ccf65 | ||
|
|
712bff9c99 | ||
|
|
eedfcf86aa | ||
|
|
f730848928 | ||
|
|
61d0574c5c | ||
|
|
2f01e01ec1 | ||
|
|
cbcf66df7f | ||
|
|
cfaeea039b | ||
|
|
a891d1eb54 | ||
|
|
4372052ef0 | ||
|
|
8734b062dc | ||
|
|
343451de65 | ||
|
|
144d65c776 | ||
|
|
a6815574f7 | ||
|
|
e5a116a0d4 | ||
|
|
0beef6b108 | ||
|
|
7341008449 | ||
|
|
49bd53194a | ||
|
|
baf4437efc | ||
|
|
b244f80f81 | ||
|
|
e41c91a42b | ||
|
|
b9a2e3ceac | ||
|
|
fa7dd3bdc4 | ||
|
|
9a8c68b846 | ||
|
|
698e33ddf4 | ||
|
|
909258ba14 | ||
|
|
2ad6bd1d23 | ||
|
|
510ffd41d8 | ||
|
|
4f00591c4e | ||
|
|
5b65ed87cd | ||
|
|
b0121c422d | ||
|
|
a9e9fad222 | ||
|
|
b5fc07acc7 | ||
|
|
140ebfdb92 | ||
|
|
37d0179de1 | ||
|
|
823d4b0fe2 | ||
|
|
dd1eacf4f0 | ||
|
|
86c33dd686 | ||
|
|
c6757cc61b | ||
|
|
a38cf284dd | ||
|
|
575b8e3f7f | ||
|
|
bc443f47f1 | ||
|
|
b631bcc0db | ||
|
|
5ccd92ece6 | ||
|
|
2f3c8868a7 | ||
|
|
6f7b5e8005 | ||
|
|
10d1e4b798 | ||
|
|
9d5934df14 | ||
|
|
be507de6c1 | ||
|
|
e5d3c08821 | ||
|
|
027b4ab7da | ||
|
|
fefea0d7ec | ||
|
|
33f30bfd19 | ||
|
|
e9d4b9961a | ||
|
|
b94248fe79 | ||
|
|
225975e0dd | ||
|
|
eac7492143 | ||
|
|
b3c40bf448 | ||
|
|
02f7cd77f4 | ||
|
|
7f8f3aa99b | ||
|
|
0bcdc14909 | ||
|
|
526c25a02b | ||
|
|
f48da9dab1 | ||
|
|
2e8dfda12e | ||
|
|
63da576d85 | ||
|
|
0ab4206540 | ||
|
|
212ae90401 | ||
|
|
d4e5d0be45 | ||
|
|
3520a0f1fb | ||
|
|
036090a947 | ||
|
|
dc570c683a | ||
|
|
9f85d34c91 | ||
|
|
16bf1fb6c3 | ||
|
|
47c4d508e0 | ||
|
|
e5d9060623 | ||
|
|
fdf28fc385 | ||
|
|
9015a4d56b | ||
|
|
38301454a6 | ||
|
|
9b3a22c4ca | ||
|
|
548dbc3649 | ||
|
|
3474129812 | ||
|
|
63193feebe | ||
|
|
51f22bfe75 | ||
|
|
7d0f7e1c8e | ||
|
|
dd8ab242fb | ||
|
|
60f3428da7 | ||
|
|
c6fec0a131 | ||
|
|
fdc43fc0d3 | ||
|
|
0b880aa335 | ||
|
|
74f50ec992 | ||
|
|
1bdf4532db | ||
|
|
f97783ddef | ||
|
|
1024d6fc07 | ||
|
|
3ec59d0c58 | ||
|
|
c43249316c | ||
|
|
ed5180ffd6 | ||
|
|
e9ec769340 | ||
|
|
5e16ff8dff | ||
|
|
364b6631ea | ||
|
|
48a18e53e3 | ||
|
|
bcc8282d73 | ||
|
|
15017ed49c | ||
|
|
50d36fe91b | ||
|
|
23e67a2908 | ||
|
|
0dab1b73cc | ||
|
|
3c086a92e2 | ||
|
|
647d72514b | ||
|
|
15328b4fd7 | ||
|
|
b49a498f9c | ||
|
|
8d14d5f87c | ||
|
|
a6db352ecd | ||
|
|
ccbb26c176 | ||
|
|
8f6af73541 | ||
|
|
a59f17fdb2 | ||
|
|
14222e40ad | ||
|
|
7d48bf06fe | ||
|
|
1d06a2c2e8 | ||
|
|
cf141f0e55 | ||
|
|
9113c31612 | ||
|
|
00b4e0a6fd | ||
|
|
e3cac95d37 | ||
|
|
64d850c583 | ||
|
|
2fe1b9e726 | ||
|
|
1315d847b9 | ||
|
|
b5954102b6 | ||
|
|
1c8ba0c538 | ||
|
|
be18317a6d | ||
|
|
88d2b8266e | ||
|
|
949ca5ddff | ||
|
|
3eb53b9648 | ||
|
|
e4a03ede1f | ||
|
|
cb65dc0e9d | ||
|
|
8ec907050e | ||
|
|
15ba00a902 | ||
|
|
89d0c301c2 | ||
|
|
2f47466f3b | ||
|
|
d70eca9774 | ||
|
|
95ce92fa18 | ||
|
|
b3db52b2ed | ||
|
|
c40912013d | ||
|
|
1c08e98c1c | ||
|
|
3f202a7cdc | ||
|
|
6f3aea8fc1 | ||
|
|
0896143838 | ||
|
|
ea94899a28 | ||
|
|
d2109cef86 | ||
|
|
cda146366c | ||
|
|
678b879a01 | ||
|
|
4c885c5e7b | ||
|
|
d5002b1c33 | ||
|
|
4f8b6d6b28 | ||
|
|
66dab41539 | ||
|
|
9e4940228d | ||
|
|
cbb11ebb03 | ||
|
|
073a25f381 | ||
|
|
40592ab876 | ||
|
|
bbfe624b51 | ||
|
|
a2af9e4c65 | ||
|
|
0123a8895f | ||
|
|
53854a4d13 | ||
|
|
4fdd44858f | ||
|
|
3c58879ce5 | ||
|
|
a7c6a881b3 | ||
|
|
ef065d31a0 | ||
|
|
d059d6b448 | ||
|
|
2d0a6f1bec | ||
|
|
a3cc5a1938 | ||
|
|
435068515a | ||
|
|
956001dbd7 | ||
|
|
460f0d9dee | ||
|
|
5155ec93c9 | ||
|
|
8bb8883e22 | ||
|
|
ffb7a6dfbb | ||
|
|
176de6f245 | ||
|
|
11f9740dbf | ||
|
|
42a91ba26c | ||
|
|
234003e2b1 | ||
|
|
534384438b | ||
|
|
ab51f35d5d | ||
|
|
511a4044d7 | ||
|
|
821efaff40 | ||
|
|
91bc994532 | ||
|
|
1323b46ac7 | ||
|
|
3a8b30ca8e | ||
|
|
923d58519f | ||
|
|
eabb1f84f6 | ||
|
|
cfbe44b946 | ||
|
|
81c35eab46 | ||
|
|
a1c7c29113 | ||
|
|
1293e2a074 | ||
|
|
b5deca7f22 | ||
|
|
604ba236c0 | ||
|
|
14df490b2a | ||
|
|
dd2f73e8ad | ||
|
|
56bfdc8ef9 | ||
|
|
91dbf1e144 | ||
|
|
e07ae90d09 | ||
|
|
5ef0c9aae1 | ||
|
|
aefed7c481 | ||
|
|
0d66d9f9a3 | ||
|
|
d0ffc4f979 | ||
|
|
f149d2b7cd | ||
|
|
21a12b8dd4 | ||
|
|
6c8b8e8949 | ||
|
|
539737d1c5 | ||
|
|
33ff5828da | ||
|
|
1fb0783808 | ||
|
|
b5e7aa8553 | ||
|
|
1d3ce76b27 | ||
|
|
0101171159 | ||
|
|
8b8ed0b9ff | ||
|
|
413b60e630 | ||
|
|
10b2a94c70 | ||
|
|
e337e5bbd8 | ||
|
|
6e55e0a183 | ||
|
|
8ee1d26935 | ||
|
|
80bdf69eaf | ||
|
|
18e838bffd | ||
|
|
d95b1b0ec4 | ||
|
|
d16a3c117b | ||
|
|
d04ec982ab | ||
|
|
cce99c803e | ||
|
|
19ed538573 | ||
|
|
a1f78345e6 | ||
|
|
f8c7ccf064 | ||
|
|
4d5242cd61 | ||
|
|
7ad176f98d | ||
|
|
57df7d28b5 | ||
|
|
f784ff2c84 | ||
|
|
a0f6affb68 | ||
|
|
0c679167fa | ||
|
|
4fe707e519 | ||
|
|
d83704b7cb | ||
|
|
2177ee45cc | ||
|
|
ccd4f99aea | ||
|
|
cd6b55c846 | ||
|
|
d923c8df81 | ||
|
|
59879f493e | ||
|
|
06cab0d4b5 | ||
|
|
a16db38a6f | ||
|
|
de93e19a80 | ||
|
|
47bb7d0de7 | ||
|
|
896e808db4 | ||
|
|
6fe6d1ffa0 | ||
|
|
4c6f7a66e2 | ||
|
|
4b5646ec88 | ||
|
|
66a5f350da | ||
|
|
f9e34cbab7 | ||
|
|
634f7b5ba3 | ||
|
|
7dbc6ff8a3 | ||
|
|
afccdc4749 | ||
|
|
c98ec041d4 | ||
|
|
9e0c62092e | ||
|
|
9aea006f50 | ||
|
|
c16c3759cf | ||
|
|
cbc1fe27ef | ||
|
|
f57dbf94c8 | ||
|
|
c0f15d2e6f | ||
|
|
cb525fafb6 | ||
|
|
5cae3a8141 | ||
|
|
8594e78287 | ||
|
|
5b8f922273 | ||
|
|
847b41752c | ||
|
|
7c08489cb3 | ||
|
|
605c77ecbc | ||
|
|
fd0c2a5cd1 | ||
|
|
a80790fc8e | ||
|
|
206d449d0d | ||
|
|
2323dc099f | ||
|
|
642583479f | ||
|
|
082e5842d0 | ||
|
|
c67ba02839 | ||
|
|
4c6cb7618f | ||
|
|
c15100f129 | ||
|
|
6dfb3cc84e | ||
|
|
18d8c7d086 | ||
|
|
ab3adf4ae3 | ||
|
|
7e6619af00 | ||
|
|
a7e2a10403 | ||
|
|
3a784375d0 | ||
|
|
b8c9433259 | ||
|
|
815d9d6012 | ||
|
|
feb91aa056 | ||
|
|
cd264586ca | ||
|
|
c6d561f2df | ||
|
|
6167c5f855 | ||
|
|
1a31cb96b8 | ||
|
|
9b8df64c35 | ||
|
|
a47565afec | ||
|
|
c2ee815cbe | ||
|
|
e45a2df6b6 | ||
|
|
a19979c233 | ||
|
|
e2a297fa40 | ||
|
|
df13b338b2 | ||
|
|
da9d7a0dee | ||
|
|
0374c65159 | ||
|
|
71b1e07ba6 | ||
|
|
c3781dc4b5 | ||
|
|
dc92d0913c | ||
|
|
a5adf29001 | ||
|
|
8861bfe4fa | ||
|
|
c8d280f418 | ||
|
|
09c98359af | ||
|
|
6f8a7471c2 | ||
|
|
4c141fe47c | ||
|
|
b37ff348fb | ||
|
|
09798d33b0 | ||
|
|
717ab95fbe | ||
|
|
3f616e3608 | ||
|
|
c590157561 | ||
|
|
2b50431081 | ||
|
|
6d38e44f91 | ||
|
|
9bc656a5c5 | ||
|
|
700bb9b567 | ||
|
|
8ccda81d9a | ||
|
|
3818790ced | ||
|
|
c34ce389a4 | ||
|
|
15718cdb46 | ||
|
|
10746a454a | ||
|
|
f0fd02e81f | ||
|
|
bfaac6d164 | ||
|
|
a909f1012a | ||
|
|
201581a07c | ||
|
|
8cef5ecf7e | ||
|
|
2c1075f471 | ||
|
|
1f5e08fdc6 | ||
|
|
c0408045ef | ||
|
|
c58f5a6ca7 | ||
|
|
ae445c9343 | ||
|
|
ad7ff2ba0b | ||
|
|
4b7ef6e853 | ||
|
|
87f2acc2d9 | ||
|
|
ec2fef02ed | ||
|
|
ebe0d74dbe | ||
|
|
029dc51f8b | ||
|
|
3fc85cd7b2 | ||
|
|
a46bdef079 | ||
|
|
3de489f693 | ||
|
|
eddb9eee46 | ||
|
|
5b0c96cd6d | ||
|
|
15ac77107f | ||
|
|
a7c906091c | ||
|
|
de870c546c | ||
|
|
2f3427e6ad | ||
|
|
203426bd55 | ||
|
|
16242080e0 | ||
|
|
57655d8859 | ||
|
|
62ffd57108 | ||
|
|
8db05f47b5 | ||
|
|
c684761eef | ||
|
|
0a8ece8c9c | ||
|
|
01058bde1b | ||
|
|
9c2c03cddb | ||
|
|
f0778a83a0 | ||
|
|
b86ae1f122 | ||
|
|
dfd6831b02 | ||
|
|
a4ddc13c1a | ||
|
|
fd63a1b7c2 | ||
|
|
d83c3689d0 | ||
|
|
d52bf9d318 | ||
|
|
80f56dec15 | ||
|
|
358c226b96 | ||
|
|
9de9983416 | ||
|
|
c9da4fcaf1 | ||
|
|
932ca6f9d4 | ||
|
|
4487c9985c | ||
|
|
a53ce99977 | ||
|
|
5444719895 | ||
|
|
b66139281d | ||
|
|
8925c27eb9 | ||
|
|
99be346387 | ||
|
|
81d46ba8ee | ||
|
|
ef4c467b20 | ||
|
|
44d196fb8c | ||
|
|
867c4fff58 | ||
|
|
5643546117 | ||
|
|
549832ba96 | ||
|
|
a8744b2bb4 | ||
|
|
e292d3444c | ||
|
|
ee6a1da709 | ||
|
|
8c15bc746b | ||
|
|
aebb083180 | ||
|
|
5438549b6d | ||
|
|
0077708235 | ||
|
|
2fd99ec9f3 | ||
|
|
0d266c4990 | ||
|
|
0982675b5f | ||
|
|
3bac5d3c80 | ||
|
|
58338f4848 | ||
|
|
9c261d3a3f | ||
|
|
5441ac6640 | ||
|
|
015b04a29a | ||
|
|
12ec0abf54 | ||
|
|
c8d461cdee | ||
|
|
faecffeadd | ||
|
|
b3c76c21b4 | ||
|
|
1697735162 | ||
|
|
ecb94bac6d | ||
|
|
7ebeacf16e | ||
|
|
d0079ab66b | ||
|
|
147e400bd6 | ||
|
|
c44905ea5e | ||
|
|
98b9df06fe | ||
|
|
02473080a5 | ||
|
|
c6beb9dc0a | ||
|
|
dcce14b122 | ||
|
|
a2ac24ac74 | ||
|
|
600f812f45 | ||
|
|
e945f46f25 | ||
|
|
c78c653b0a | ||
|
|
e0b3663239 | ||
|
|
3cc9c98040 | ||
|
|
ec8213b891 | ||
|
|
ae61383742 | ||
|
|
cc90a2ad75 | ||
|
|
28634cda56 | ||
|
|
3b71fcd690 | ||
|
|
5923ac65df | ||
|
|
faffc9393d | ||
|
|
6da220f36c | ||
|
|
21d78671d6 | ||
|
|
af5a0ec0b7 | ||
|
|
ff214455a3 | ||
|
|
3e941e3e42 | ||
|
|
2f876d553f | ||
|
|
b208017117 | ||
|
|
a1dab94a61 | ||
|
|
e55b2afd60 | ||
|
|
535c3ddf6c | ||
|
|
3008d99fcd | ||
|
|
fd37339e2f | ||
|
|
e29eca203c | ||
|
|
f1fd6dcdd2 | ||
|
|
2975ed2eae | ||
|
|
5a27d03faa | ||
|
|
8bcf9dbcaf | ||
|
|
56ebd26361 | ||
|
|
b0426b81a7 | ||
|
|
368fbcdeb0 | ||
|
|
30747b7776 | ||
|
|
4eb4ddf5d8 | ||
|
|
b1d24680b2 | ||
|
|
ef38f3805e | ||
|
|
2f5ca20ca4 | ||
|
|
f29d3d84d4 | ||
|
|
02132c5fcd | ||
|
|
7057e3c6ad | ||
|
|
a8f4c8e843 | ||
|
|
a2b6e66a13 | ||
|
|
e3b3cc2896 | ||
|
|
a5b2c50f24 | ||
|
|
5ebdf64d30 | ||
|
|
2640ab2e8b | ||
|
|
e29436da04 | ||
|
|
7b35325f9a | ||
|
|
f2ab7fafcf | ||
|
|
e3cda9905a | ||
|
|
a8423f7741 | ||
|
|
5a9e620c17 | ||
|
|
9f41ec3986 | ||
|
|
5a2c0672d4 | ||
|
|
38d853b5b2 | ||
|
|
5166d4bb0f | ||
|
|
2ffd5437a9 | ||
|
|
797830ff96 | ||
|
|
008ecabd21 | ||
|
|
2cdcde8a5e | ||
|
|
e7ec3988e2 | ||
|
|
093dd9f3ef | ||
|
|
b491202ec7 | ||
|
|
8603ca827e | ||
|
|
6b148a59da | ||
|
|
de6d45fee6 | ||
|
|
65e2071937 | ||
|
|
8a6242d9ea | ||
|
|
82294b68eb | ||
|
|
c232de1996 | ||
|
|
dc18c8178d | ||
|
|
6662714277 | ||
|
|
c404a0d1a9 | ||
|
|
990da2b412 | ||
|
|
1b974379c8 | ||
|
|
835faf9773 | ||
|
|
80deecb73e | ||
|
|
64328ab9cc | ||
|
|
eafad942e7 | ||
|
|
eb5a3168b9 | ||
|
|
ac8225d8fb | ||
|
|
6f71e4ada0 | ||
|
|
7ed90cddf8 | ||
|
|
283ba83cef | ||
|
|
468c66e842 | ||
|
|
f22862b0a4 | ||
|
|
9e731cb67a | ||
|
|
7f911b61a2 | ||
|
|
cace4a9bfd | ||
|
|
0992e97a1a | ||
|
|
eee101f279 | ||
|
|
4b9f204951 | ||
|
|
019804407b | ||
|
|
65b54ced7a | ||
|
|
a308114b2f | ||
|
|
41da023bdd | ||
|
|
19fcb6a82c | ||
|
|
14c837ad05 | ||
|
|
9da634e225 | ||
|
|
0d91116e62 | ||
|
|
a31a8a03c1 | ||
|
|
e8d5210606 | ||
|
|
7b11e29122 | ||
|
|
df7f693cf4 | ||
|
|
14ddc2f629 | ||
|
|
6669d0e59d | ||
|
|
8d80176a79 | ||
|
|
e1dc302592 | ||
|
|
84dbe39185 | ||
|
|
4af2c31dab | ||
|
|
332f05b6e1 | ||
|
|
8b4786ad18 | ||
|
|
7e8aaffb92 | ||
|
|
7720d42584 | ||
|
|
293b76f04b | ||
|
|
a1b0c0bbd4 | ||
|
|
46d3204bc3 | ||
|
|
c25ff57b61 | ||
|
|
71e61f8f27 | ||
|
|
6914a6132c | ||
|
|
b72916187a | ||
|
|
7c9bbe6aef | ||
|
|
27eeb0a636 | ||
|
|
cf436962f8 | ||
|
|
7fb7a1ac85 | ||
|
|
15a714faed | ||
|
|
ea2412d3a7 | ||
|
|
40321856f2 | ||
|
|
262ae7865b | ||
|
|
84cc86bef7 | ||
|
|
1ba27730d6 | ||
|
|
6568cee2e8 | ||
|
|
5496a60f62 | ||
|
|
5c7378cf94 | ||
|
|
fe15f44e96 | ||
|
|
273d762cd3 | ||
|
|
211030b5b6 | ||
|
|
212c553904 | ||
|
|
dffe4f4451 | ||
|
|
fd99af5fe6 | ||
|
|
aee539bbef | ||
|
|
e7cdc9cf8c | ||
|
|
2443547b3b | ||
|
|
8424300b5f | ||
|
|
81822cf7f6 | ||
|
|
907956994f | ||
|
|
9246cc0607 | ||
|
|
9f81d147d1 | ||
|
|
b9bd26b2fb | ||
|
|
1838174678 | ||
|
|
0880a3380c | ||
|
|
2aad301938 | ||
|
|
e18e8e3158 | ||
|
|
ff55cc1a2a | ||
|
|
d081b9e182 | ||
|
|
5e5b9f0990 | ||
|
|
97577e835e | ||
|
|
732ca8be56 | ||
|
|
1381a34752 | ||
|
|
dd96712c2a | ||
|
|
2ad0aba382 | ||
|
|
8e77eb0519 | ||
|
|
049dae6584 | ||
|
|
1fffc67d13 | ||
|
|
8500781cd5 | ||
|
|
6a8bf2acc5 | ||
|
|
c45a769aa3 | ||
|
|
16d2e27d05 | ||
|
|
10c948d33c | ||
|
|
7ccd32dfbd | ||
|
|
99c99b9218 | ||
|
|
e0b0617ad2 | ||
|
|
5add723852 | ||
|
|
14ec6f6471 | ||
|
|
c4a1341aa9 | ||
|
|
fc68dfd7bc | ||
|
|
436fc545c0 | ||
|
|
023d781daf | ||
|
|
576c0048d0 | ||
|
|
4f79cdad50 | ||
|
|
954cae8738 | ||
|
|
b203ad63ee | ||
|
|
a560be11ed | ||
|
|
506a1e6b62 | ||
|
|
626601f6aa | ||
|
|
9ad32125c0 | ||
|
|
ebd6375672 | ||
|
|
502731d3b0 | ||
|
|
283535c429 | ||
|
|
5cef1f6730 | ||
|
|
7d14fbe739 | ||
|
|
e9e1e350eb | ||
|
|
566e42cc40 | ||
|
|
0abfb5922a | ||
|
|
4af8d2f1c5 | ||
|
|
d2d4f73834 | ||
|
|
53fce4e81d | ||
|
|
08c439b46e | ||
|
|
934eb9fc1d | ||
|
|
fd208a3879 | ||
|
|
10b131e111 | ||
|
|
c4c6faa943 | ||
|
|
c7a8d1e1b7 | ||
|
|
b36ac1b824 | ||
|
|
bc6cb492f1 | ||
|
|
ce503cedc3 | ||
|
|
c900c9cc82 | ||
|
|
87b73f26f5 | ||
|
|
221a18c119 | ||
|
|
be529655d6 | ||
|
|
2a0403a988 | ||
|
|
815e23b930 | ||
|
|
f1c08e7769 | ||
|
|
571f028ca3 | ||
|
|
16d51fe6b4 | ||
|
|
ddf9ed06ab | ||
|
|
1907f80024 | ||
|
|
8c0ccdd227 | ||
|
|
dc098025b6 | ||
|
|
c11222b5c7 | ||
|
|
03bc6eb69b | ||
|
|
1aa339de02 | ||
|
|
531bb2a968 | ||
|
|
800dbf3ba9 | ||
|
|
ff545e6ecd | ||
|
|
961fe38c7e | ||
|
|
19426394e2 | ||
|
|
069a4e8f0b | ||
|
|
a76b02b828 | ||
|
|
fbb9bf5f0c | ||
|
|
f632c355e8 | ||
|
|
e75caf5833 | ||
|
|
b0c8f2cefd | ||
|
|
2136d9f13d | ||
|
|
83fdeb7e0c | ||
|
|
26c77b3118 | ||
|
|
578d445ecb | ||
|
|
3bbc9517af | ||
|
|
a4d7f278cf | ||
|
|
bf0ffc6ac2 | ||
|
|
ace07cd9cb | ||
|
|
a341179426 | ||
|
|
298f0dfd63 | ||
|
|
b8f953cd26 | ||
|
|
a9cfe69ba7 | ||
|
|
b3e0b99e8d | ||
|
|
5bd40baed2 | ||
|
|
d3a70b8bb2 | ||
|
|
71e698603d | ||
|
|
659ead903c | ||
|
|
070c435f40 | ||
|
|
b668a526e3 | ||
|
|
01287d0669 | ||
|
|
ff481d759f | ||
|
|
71248f1708 | ||
|
|
0a0f834f23 | ||
|
|
06cad7ecd8 | ||
|
|
ceba3e2f95 | ||
|
|
61c2fd8794 | ||
|
|
db933fee4f | ||
|
|
2656c2dc40 | ||
|
|
01cfe33865 | ||
|
|
d79a31cc79 | ||
|
|
9efab8b892 | ||
|
|
aae845247a | ||
|
|
3f45a9a75f | ||
|
|
c9016155ae | ||
|
|
1019e8f4af | ||
|
|
8e423b4552 | ||
|
|
0e288c955c | ||
|
|
465dc8a66c | ||
|
|
7e5c599cc0 | ||
|
|
a961001a4b | ||
|
|
0a181f6407 | ||
|
|
27a347db34 | ||
|
|
b228dbb2df | ||
|
|
09cffc4340 | ||
|
|
e79880d305 | ||
|
|
34266761d1 | ||
|
|
77f17eaa3e | ||
|
|
ac70342cb3 | ||
|
|
d2f16dcaf3 | ||
|
|
abcce2bf68 | ||
|
|
514487074b | ||
|
|
f014e2473f | ||
|
|
80981f7027 | ||
|
|
8e6e971b51 | ||
|
|
4bd3b889dc | ||
|
|
464787dc1e | ||
|
|
a2541a9659 | ||
|
|
099dd87241 | ||
|
|
38eb914420 | ||
|
|
162215b1cf | ||
|
|
c6883f7a92 | ||
|
|
584286b794 | ||
|
|
a48713b7ca | ||
|
|
8f10c2d8bf | ||
|
|
5c0de9aa1c | ||
|
|
5553fd6538 | ||
|
|
e3ed47b37c | ||
|
|
976353d770 | ||
|
|
6fc216dff5 | ||
|
|
3f3961d255 | ||
|
|
875637bc6d | ||
|
|
395333cb3d | ||
|
|
870d039541 | ||
|
|
e8c8bece3f | ||
|
|
bd2f5dd6fe | ||
|
|
73f78d47ae | ||
|
|
8f60755f02 | ||
|
|
44c455419b | ||
|
|
129bc9b3ae | ||
|
|
08ba7dd065 | ||
|
|
dd2cf50a39 | ||
|
|
06eeced5b2 | ||
|
|
be23e5709d | ||
|
|
2735185eb9 | ||
|
|
41dd0acfa3 | ||
|
|
115a2df2b0 | ||
|
|
fcbb3aeed1 | ||
|
|
e9cb85127a | ||
|
|
c9c703fe98 | ||
|
|
0141dfbea2 | ||
|
|
fb7dafbc39 | ||
|
|
0660f9a511 | ||
|
|
a39ae5a8c5 | ||
|
|
03e22e3dbf | ||
|
|
d5e9fd0e5c | ||
|
|
141138ebea | ||
|
|
9026efeb26 | ||
|
|
2ab023beb0 | ||
|
|
8e471fd720 | ||
|
|
13cbbd8bc1 | ||
|
|
b08ccc9767 | ||
|
|
801a7023a4 | ||
|
|
dd06b554da | ||
|
|
23f0504b30 | ||
|
|
262d172cde | ||
|
|
be81cb7876 | ||
|
|
aaf9bd33cb | ||
|
|
7381e2141f | ||
|
|
3923d941c1 | ||
|
|
d134c33499 | ||
|
|
a2b615d4a7 | ||
|
|
37ecd9bd4f | ||
|
|
2e1acb7871 | ||
|
|
2250185487 | ||
|
|
97a1bf90a4 | ||
|
|
73cb63c9f9 | ||
|
|
f61f6b6006 | ||
|
|
7d3ffbc45a | ||
|
|
93ac6fa88a | ||
|
|
09d19a13b7 | ||
|
|
9eaee8d2c4 | ||
|
|
4da0c342f8 | ||
|
|
70fed22737 | ||
|
|
acb62e347a | ||
|
|
78d06d82d6 | ||
|
|
4777bdd250 | ||
|
|
266e9d92d5 | ||
|
|
54c14d0dc8 | ||
|
|
d59d353c2e | ||
|
|
204da2175b | ||
|
|
a8f659f2ac | ||
|
|
a878ebc368 | ||
|
|
152f235ca1 | ||
|
|
d094709dc8 | ||
|
|
97d5792341 | ||
|
|
9429ba7d48 | ||
|
|
af89dd13c1 | ||
|
|
60c6c5b37a | ||
|
|
5ed40cab1d | ||
|
|
1bebfe9cf2 | ||
|
|
e2618c37a2 | ||
|
|
f2ab848c46 | ||
|
|
93b82c0e97 | ||
|
|
4ac5ad06f2 | ||
|
|
a3788038bb | ||
|
|
12af2de99e | ||
|
|
225b722b1b | ||
|
|
1d9c8ca65e | ||
|
|
e51ffe2a1c | ||
|
|
c706a79f74 | ||
|
|
2608061d48 | ||
|
|
df1634de3d | ||
|
|
4aeabea3fe | ||
|
|
eb30f9d5bf | ||
|
|
de718f847c | ||
|
|
8ee6588d46 | ||
|
|
7c25f087fb | ||
|
|
d0b0f098d9 | ||
|
|
8835e20bfc | ||
|
|
92258f3ba3 | ||
|
|
1bda7595dd | ||
|
|
60557fc8c8 | ||
|
|
1a4a7831f6 | ||
|
|
d1415a8c53 | ||
|
|
0d4f33ac6e | ||
|
|
87100bef7b | ||
|
|
958dfa8ae9 | ||
|
|
d3752573e7 | ||
|
|
cfd07cbcc8 | ||
|
|
33e6ce1673 | ||
|
|
00ccda83f9 | ||
|
|
8d66cce6eb | ||
|
|
ba35fb7525 | ||
|
|
4fd2b24b10 | ||
|
|
5f7a33b085 | ||
|
|
65bc5b1f31 | ||
|
|
dd155e9f89 | ||
|
|
5c4ef3b0f5 | ||
|
|
2129a48cc8 | ||
|
|
c0f2784599 | ||
|
|
fee00b2acb | ||
|
|
ae8093313e | ||
|
|
5a4e321f78 | ||
|
|
9d1ed241b9 | ||
|
|
b63cd241d2 | ||
|
|
1e4f2d85a2 | ||
|
|
5cb7be4a64 | ||
|
|
0cd9068c0e | ||
|
|
9d6afe3bde | ||
|
|
52702b5267 | ||
|
|
cd144ff067 | ||
|
|
dd9784b3f2 | ||
|
|
d781b3d4a7 | ||
|
|
790f490674 | ||
|
|
004a5cb765 | ||
|
|
408b2d8376 | ||
|
|
3aa53ff3be | ||
|
|
73b642799d | ||
|
|
b522500379 | ||
|
|
f736ed401f | ||
|
|
c02f824d74 | ||
|
|
6f9a61de56 | ||
|
|
4cebeda37a | ||
|
|
4275005a64 | ||
|
|
5f40ab130e | ||
|
|
7489526eb7 | ||
|
|
e439d91763 | ||
|
|
793969e39b | ||
|
|
9f7ffe8d77 | ||
|
|
eecb867227 | ||
|
|
bff9f135e6 | ||
|
|
03627281d7 | ||
|
|
c83b4093f0 | ||
|
|
7f9f22df3e | ||
|
|
fd48582a9f | ||
|
|
e5761128f9 | ||
|
|
87dd5a9ebb | ||
|
|
11950f8b4d | ||
|
|
f2ddfadc9d | ||
|
|
b1a7983f18 | ||
|
|
b319cb278b | ||
|
|
78e3d781fc | ||
|
|
34834917b0 | ||
|
|
9446c287e9 | ||
|
|
31b0cf396e | ||
|
|
00bb13c230 | ||
|
|
3bf09ee731 | ||
|
|
5b07941c4c | ||
|
|
23c30ec46d | ||
|
|
22c06300f1 | ||
|
|
37cca1b106 | ||
|
|
f0a49c806e | ||
|
|
a1d5f65588 | ||
|
|
b6789e14a4 | ||
|
|
c72ee30a25 | ||
|
|
686d667c4f | ||
|
|
26d603db5d | ||
|
|
409840aef9 | ||
|
|
1f3c264afe | ||
|
|
cd69d9a1a7 | ||
|
|
a000c8fd99 | ||
|
|
84d05603ef | ||
|
|
9d046ecd1d | ||
|
|
030e1809f3 | ||
|
|
5853bd4a96 | ||
|
|
10695ff51b | ||
|
|
f421659fea | ||
|
|
df4f51eff3 | ||
|
|
7e61d6a850 | ||
|
|
0910bd23c4 | ||
|
|
5a29753912 | ||
|
|
a467356437 | ||
|
|
094967f52a | ||
|
|
757b0812ba | ||
|
|
8f4f5d8c92 | ||
|
|
4e266483ba | ||
|
|
7433dc9cf3 | ||
|
|
409a773e36 | ||
|
|
48bdd5c3df | ||
|
|
5796057a75 | ||
|
|
c8248e91ca | ||
|
|
7317ce44e7 | ||
|
|
10e2a5b1eb | ||
|
|
e675d1b7e2 | ||
|
|
499c4dadd5 | ||
|
|
f550f84acd | ||
|
|
8021f1a7fc | ||
|
|
d50fe606ee | ||
|
|
281f014aa0 | ||
|
|
2f6da3e84a | ||
|
|
f9accc2a7a | ||
|
|
fe15078bbd | ||
|
|
27d4b5eba7 | ||
|
|
e378576632 | ||
|
|
74909da110 | ||
|
|
655bf112ac | ||
|
|
5c3638a5a4 | ||
|
|
2459a3654b | ||
|
|
e9a3456cf5 | ||
|
|
2bcdf774ff | ||
|
|
ef01f23384 | ||
|
|
ab7bbb6593 | ||
|
|
f2dad88875 | ||
|
|
c474565ff5 | ||
|
|
fd9dbbd7e6 | ||
|
|
43ab095e0f | ||
|
|
41e2888bf1 | ||
|
|
e7d5e22960 | ||
|
|
3f3884193d | ||
|
|
dfccabc2b9 | ||
|
|
af7c181596 | ||
|
|
8e84112837 | ||
|
|
822cd16daa | ||
|
|
33ea84004d | ||
|
|
8dbbe20840 | ||
|
|
d990ccc4ab | ||
|
|
9f16249898 | ||
|
|
62fc3139cf | ||
|
|
452452dcc9 | ||
|
|
b6fb06bc65 | ||
|
|
aac6bd1b7c | ||
|
|
d260001cbd | ||
|
|
9c470d77cb | ||
|
|
269075657d | ||
|
|
d0029beb22 | ||
|
|
4b4837e3a1 | ||
|
|
d0160b8b6d | ||
|
|
ea351935b2 | ||
|
|
20ccc2951e | ||
|
|
6f9bad1bdf | ||
|
|
39a0d514a8 | ||
|
|
ad82c591cc | ||
|
|
32ceb168d5 | ||
|
|
16146f4c88 | ||
|
|
60febbf3f8 | ||
|
|
4960b30cfb | ||
|
|
56c161fea0 | ||
|
|
27c439d728 | ||
|
|
78d5e03a66 | ||
|
|
f25e647b6a | ||
|
|
e44212fc65 | ||
|
|
a483403774 | ||
|
|
69750dba19 | ||
|
|
af962b99be | ||
|
|
2399e54a4b | ||
|
|
aea5e8eb16 | ||
|
|
a3a60c1c4b | ||
|
|
c141cb6c6c | ||
|
|
62765ab6ca | ||
|
|
e4f7fed523 | ||
|
|
bf8cc268cc | ||
|
|
8450e74832 | ||
|
|
475b258e4a | ||
|
|
f20803ae57 | ||
|
|
3fcb17931a | ||
|
|
736c7b8377 | ||
|
|
05743e2d8b | ||
|
|
6cd2c7f26d | ||
|
|
469e5bd179 | ||
|
|
dbeb3f04e7 | ||
|
|
e9b17ac24a | ||
|
|
65fbcedaa4 | ||
|
|
c4183ada11 | ||
|
|
27f9614633 | ||
|
|
2211cc5596 | ||
|
|
46f0393648 | ||
|
|
b4c1a97687 | ||
|
|
adcef385b0 | ||
|
|
48e38b2855 | ||
|
|
2cc8327a08 | ||
|
|
404e80082c | ||
|
|
3fbc21347a | ||
|
|
d76f0e2241 | ||
|
|
e5fcc59805 | ||
|
|
de82dac873 | ||
|
|
a14ef72177 | ||
|
|
6ee5234351 | ||
|
|
398a041ddf | ||
|
|
02bb73c335 | ||
|
|
f37c4cdc4d | ||
|
|
d5c9bcddc8 | ||
|
|
f3f8c81518 | ||
|
|
a99ffd4821 | ||
|
|
7b5a9d9949 | ||
|
|
feb8d0591e | ||
|
|
2197808631 | ||
|
|
36b3ccc34f | ||
|
|
a5b69d712c | ||
|
|
8edcca9745 | ||
|
|
f3b1f4b608 | ||
|
|
879a8aaa6d | ||
|
|
900d005d89 | ||
|
|
c8225171a3 | ||
|
|
c513c052fc | ||
|
|
711c4dd2b5 | ||
|
|
81f1ebd1db | ||
|
|
c722934510 | ||
|
|
3ffe8e225d | ||
|
|
6d86cf8f9c | ||
|
|
e6e19110b2 | ||
|
|
b5c13bd1b3 | ||
|
|
b129fe437c | ||
|
|
645be4bfa3 | ||
|
|
321c49ee32 | ||
|
|
84db2f9b65 | ||
|
|
6ba1a419bc | ||
|
|
3de329a332 | ||
|
|
f175c36736 | ||
|
|
f1de65b471 | ||
|
|
5069013e6e | ||
|
|
c0642ed620 | ||
|
|
a145673dd1 | ||
|
|
223af48c09 | ||
|
|
d72cfc37d6 | ||
|
|
3ba8133890 | ||
|
|
a907cd7f46 | ||
|
|
3b740cb494 | ||
|
|
0f0f21a7b1 | ||
|
|
537f6703c0 | ||
|
|
da0c562ac2 | ||
|
|
0bef71907c | ||
|
|
0ebd43bc5f | ||
|
|
3092fced3c | ||
|
|
a02784fcba | ||
|
|
924abde89e | ||
|
|
f011468819 | ||
|
|
11f459d5b0 | ||
|
|
974f7d5d68 | ||
|
|
e60db4ff90 | ||
|
|
ebe1cd3367 | ||
|
|
30db9d13a5 | ||
|
|
368611359c | ||
|
|
746918c054 | ||
|
|
6572198178 | ||
|
|
f69b3f56dd | ||
|
|
c379f2f3b0 | ||
|
|
e7194e43b4 | ||
|
|
883b282cd8 | ||
|
|
7c2b2d7f26 | ||
|
|
08f525de5f | ||
|
|
433659a5df | ||
|
|
7f50a30b29 | ||
|
|
d5944779e8 | ||
|
|
fdaea31475 | ||
|
|
a66ebd29b4 | ||
|
|
f3006467e9 | ||
|
|
aa52af4c8f | ||
|
|
2e0fde464d | ||
|
|
9bf0124950 | ||
|
|
eaa6db1d19 | ||
|
|
2ec142f000 | ||
|
|
ec572436a9 | ||
|
|
6e5e548c9d | ||
|
|
61c3bbad60 | ||
|
|
bc10c4e871 | ||
|
|
8b8d84c2a3 | ||
|
|
5743b5d59f | ||
|
|
9450ba5e46 | ||
|
|
cfcbf3e61c | ||
|
|
136481c110 | ||
|
|
7f43b3003c | ||
|
|
1b0c2687c8 | ||
|
|
aeb80f862b | ||
|
|
1de367e19e | ||
|
|
62895a602f | ||
|
|
6438e890bb | ||
|
|
7d72b13ac9 | ||
|
|
a2e21cb07b | ||
|
|
06766cb4db | ||
|
|
72e8ab70a3 | ||
|
|
0f38af5922 | ||
|
|
4181759008 | ||
|
|
fff0e5e946 | ||
|
|
be88eeb343 | ||
|
|
342b932f9e | ||
|
|
964dc14a8a | ||
|
|
b56f462626 | ||
|
|
4477b4c44e | ||
|
|
714c6e2920 | ||
|
|
0853a1aa2e | ||
|
|
f9d2312b3a | ||
|
|
f53f205f52 | ||
|
|
41ecbccc76 | ||
|
|
5a952c187c | ||
|
|
0a86d00c1e | ||
|
|
b3e9d82537 | ||
|
|
0970dceee2 | ||
|
|
ffef71d6db | ||
|
|
0ede8cd5b9 | ||
|
|
c1a9f48e6b | ||
|
|
3f7215c602 | ||
|
|
8b5e3e344a | ||
|
|
212ff012d6 | ||
|
|
7c77b857f6 | ||
|
|
423c01074a | ||
|
|
2dbd584e28 | ||
|
|
250f435ceb | ||
|
|
fa4e409555 | ||
|
|
dfc3b7c796 | ||
|
|
41df9859ad | ||
|
|
a8b8cbdf8c | ||
|
|
fe2909c56a | ||
|
|
3a2fe06c34 | ||
|
|
873e8604ce | ||
|
|
2cfcd0facf | ||
|
|
b49eff348d | ||
|
|
42d801f123 | ||
|
|
5e33182de3 | ||
|
|
012d86066d | ||
|
|
ff510095a3 | ||
|
|
10283d022f | ||
|
|
d55abd1b00 | ||
|
|
87845fc6f5 | ||
|
|
340c0d647c | ||
|
|
49a574a8d7 | ||
|
|
9216997bba | ||
|
|
267567d0a0 | ||
|
|
230bc28ddd | ||
|
|
57c9ffc2ba |
228
.editorconfig
228
.editorconfig
@@ -6,3 +6,231 @@ insert_final_newline = true
|
||||
charset = latin1
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.java]
|
||||
indent_style = tab
|
||||
ij_continuation_indent_size = 4
|
||||
ij_java_align_consecutive_assignments = false
|
||||
ij_java_align_consecutive_variable_declarations = false
|
||||
ij_java_align_group_field_declarations = false
|
||||
ij_java_align_multiline_annotation_parameters = false
|
||||
ij_java_align_multiline_array_initializer_expression = false
|
||||
ij_java_align_multiline_assignment = false
|
||||
ij_java_align_multiline_binary_operation = false
|
||||
ij_java_align_multiline_chained_methods = false
|
||||
ij_java_align_multiline_extends_list = false
|
||||
ij_java_align_multiline_for = true
|
||||
ij_java_align_multiline_method_parentheses = false
|
||||
ij_java_align_multiline_parameters = false
|
||||
ij_java_align_multiline_parameters_in_calls = false
|
||||
ij_java_align_multiline_parenthesized_expression = false
|
||||
ij_java_align_multiline_resources = false
|
||||
ij_java_align_multiline_ternary_operation = false
|
||||
ij_java_align_multiline_text_blocks = false
|
||||
ij_java_align_multiline_throws_list = false
|
||||
ij_java_align_subsequent_simple_methods = false
|
||||
ij_java_align_throws_keyword = false
|
||||
ij_java_annotation_parameter_wrap = off
|
||||
ij_java_array_initializer_new_line_after_left_brace = false
|
||||
ij_java_array_initializer_right_brace_on_new_line = false
|
||||
ij_java_array_initializer_wrap = normal
|
||||
ij_java_assert_statement_colon_on_next_line = false
|
||||
ij_java_assert_statement_wrap = off
|
||||
ij_java_assignment_wrap = off
|
||||
ij_java_binary_operation_sign_on_next_line = false
|
||||
ij_java_binary_operation_wrap = off
|
||||
ij_java_blank_lines_after_anonymous_class_header = 0
|
||||
ij_java_blank_lines_after_class_header = 0
|
||||
ij_java_blank_lines_after_imports = 1
|
||||
ij_java_blank_lines_after_package = 1
|
||||
ij_java_blank_lines_around_class = 1
|
||||
ij_java_blank_lines_around_field = 0
|
||||
ij_java_blank_lines_around_field_in_interface = 0
|
||||
ij_java_blank_lines_around_initializer = 1
|
||||
ij_java_blank_lines_around_method = 1
|
||||
ij_java_blank_lines_around_method_in_interface = 1
|
||||
ij_java_blank_lines_before_class_end = 0
|
||||
ij_java_blank_lines_before_imports = 1
|
||||
ij_java_blank_lines_before_method_body = 0
|
||||
ij_java_blank_lines_before_package = 0
|
||||
ij_java_block_brace_style = next_line_if_wrapped
|
||||
ij_java_block_comment_at_first_column = true
|
||||
ij_java_call_parameters_new_line_after_left_paren = false
|
||||
ij_java_call_parameters_right_paren_on_new_line = false
|
||||
ij_java_call_parameters_wrap = normal
|
||||
ij_java_case_statement_on_separate_line = true
|
||||
ij_java_catch_on_new_line = false
|
||||
ij_java_class_annotation_wrap = split_into_lines
|
||||
ij_java_class_brace_style = next_line
|
||||
ij_java_class_count_to_use_import_on_demand = 99
|
||||
ij_java_class_names_in_javadoc = 1
|
||||
ij_java_do_not_indent_top_level_class_members = false
|
||||
ij_java_do_not_wrap_after_single_annotation = false
|
||||
ij_java_do_while_brace_force = never
|
||||
ij_java_doc_add_blank_line_after_description = true
|
||||
ij_java_doc_add_blank_line_after_param_comments = false
|
||||
ij_java_doc_add_blank_line_after_return = false
|
||||
ij_java_doc_add_p_tag_on_empty_lines = true
|
||||
ij_java_doc_align_exception_comments = true
|
||||
ij_java_doc_align_param_comments = true
|
||||
ij_java_doc_do_not_wrap_if_one_line = false
|
||||
ij_java_doc_enable_formatting = true
|
||||
ij_java_doc_enable_leading_asterisks = true
|
||||
ij_java_doc_indent_on_continuation = false
|
||||
ij_java_doc_keep_empty_lines = true
|
||||
ij_java_doc_keep_empty_parameter_tag = true
|
||||
ij_java_doc_keep_empty_return_tag = true
|
||||
ij_java_doc_keep_empty_throws_tag = true
|
||||
ij_java_doc_keep_invalid_tags = true
|
||||
ij_java_doc_param_description_on_new_line = false
|
||||
ij_java_doc_preserve_line_breaks = false
|
||||
ij_java_doc_use_throws_not_exception_tag = true
|
||||
ij_java_else_on_new_line = false
|
||||
ij_java_enum_constants_wrap = off
|
||||
ij_java_extends_keyword_wrap = split_into_lines
|
||||
ij_java_extends_list_wrap = normal
|
||||
ij_java_field_annotation_wrap = split_into_lines
|
||||
ij_java_finally_on_new_line = false
|
||||
ij_java_for_brace_force = never
|
||||
ij_java_for_statement_new_line_after_left_paren = false
|
||||
ij_java_for_statement_right_paren_on_new_line = false
|
||||
ij_java_for_statement_wrap = off
|
||||
ij_java_generate_final_locals = false
|
||||
ij_java_generate_final_parameters = false
|
||||
ij_java_if_brace_force = never
|
||||
ij_java_imports_layout = java.**,javax.**,*,$*
|
||||
ij_java_indent_case_from_switch = true
|
||||
ij_java_insert_inner_class_imports = false
|
||||
ij_java_insert_override_annotation = true
|
||||
ij_java_keep_blank_lines_before_right_brace = 1
|
||||
ij_java_keep_blank_lines_between_package_declaration_and_header = 1
|
||||
ij_java_keep_blank_lines_in_code = 1
|
||||
ij_java_keep_blank_lines_in_declarations = 1
|
||||
ij_java_keep_control_statement_in_one_line = false
|
||||
ij_java_keep_first_column_comment = false
|
||||
ij_java_keep_indents_on_empty_lines = false
|
||||
ij_java_keep_line_breaks = false
|
||||
ij_java_keep_multiple_expressions_in_one_line = false
|
||||
ij_java_keep_simple_blocks_in_one_line = false
|
||||
ij_java_keep_simple_classes_in_one_line = false
|
||||
ij_java_keep_simple_lambdas_in_one_line = false
|
||||
ij_java_keep_simple_methods_in_one_line = false
|
||||
ij_java_label_indent_absolute = false
|
||||
ij_java_label_indent_size = 0
|
||||
ij_java_lambda_brace_style = end_of_line
|
||||
ij_java_layout_static_imports_separately = true
|
||||
ij_java_line_comment_add_space = false
|
||||
ij_java_line_comment_at_first_column = true
|
||||
ij_java_method_annotation_wrap = split_into_lines
|
||||
ij_java_method_brace_style = next_line_if_wrapped
|
||||
ij_java_method_call_chain_wrap = normal
|
||||
ij_java_method_parameters_new_line_after_left_paren = false
|
||||
ij_java_method_parameters_right_paren_on_new_line = false
|
||||
ij_java_method_parameters_wrap = normal
|
||||
ij_java_modifier_list_wrap = false
|
||||
ij_java_names_count_to_use_import_on_demand = 3
|
||||
ij_java_parameter_annotation_wrap = off
|
||||
ij_java_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_java_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_java_place_assignment_sign_on_next_line = false
|
||||
ij_java_prefer_longer_names = true
|
||||
ij_java_prefer_parameters_wrap = false
|
||||
ij_java_repeat_synchronized = true
|
||||
ij_java_replace_instanceof_and_cast = false
|
||||
ij_java_replace_null_check = true
|
||||
ij_java_replace_sum_lambda_with_method_ref = true
|
||||
ij_java_resource_list_new_line_after_left_paren = false
|
||||
ij_java_resource_list_right_paren_on_new_line = false
|
||||
ij_java_resource_list_wrap = normal
|
||||
ij_java_space_after_closing_angle_bracket_in_type_argument = false
|
||||
ij_java_space_after_colon = true
|
||||
ij_java_space_after_comma = true
|
||||
ij_java_space_after_comma_in_type_arguments = true
|
||||
ij_java_space_after_for_semicolon = true
|
||||
ij_java_space_after_quest = true
|
||||
ij_java_space_after_type_cast = true
|
||||
ij_java_space_before_annotation_array_initializer_left_brace = true
|
||||
ij_java_space_before_annotation_parameter_list = false
|
||||
ij_java_space_before_array_initializer_left_brace = true
|
||||
ij_java_space_before_catch_keyword = true
|
||||
ij_java_space_before_catch_left_brace = true
|
||||
ij_java_space_before_catch_parentheses = false
|
||||
ij_java_space_before_class_left_brace = true
|
||||
ij_java_space_before_colon = true
|
||||
ij_java_space_before_colon_in_foreach = true
|
||||
ij_java_space_before_comma = false
|
||||
ij_java_space_before_do_left_brace = true
|
||||
ij_java_space_before_else_keyword = true
|
||||
ij_java_space_before_else_left_brace = true
|
||||
ij_java_space_before_finally_keyword = true
|
||||
ij_java_space_before_finally_left_brace = true
|
||||
ij_java_space_before_for_left_brace = true
|
||||
ij_java_space_before_for_parentheses = false
|
||||
ij_java_space_before_for_semicolon = false
|
||||
ij_java_space_before_if_left_brace = true
|
||||
ij_java_space_before_if_parentheses = false
|
||||
ij_java_space_before_method_call_parentheses = false
|
||||
ij_java_space_before_method_left_brace = true
|
||||
ij_java_space_before_method_parentheses = false
|
||||
ij_java_space_before_opening_angle_bracket_in_type_parameter = false
|
||||
ij_java_space_before_quest = true
|
||||
ij_java_space_before_switch_left_brace = true
|
||||
ij_java_space_before_switch_parentheses = false
|
||||
ij_java_space_before_synchronized_left_brace = true
|
||||
ij_java_space_before_synchronized_parentheses = false
|
||||
ij_java_space_before_try_left_brace = true
|
||||
ij_java_space_before_try_parentheses = false
|
||||
ij_java_space_before_type_parameter_list = false
|
||||
ij_java_space_before_while_keyword = true
|
||||
ij_java_space_before_while_left_brace = true
|
||||
ij_java_space_before_while_parentheses = false
|
||||
ij_java_space_inside_one_line_enum_braces = false
|
||||
ij_java_space_within_empty_array_initializer_braces = false
|
||||
ij_java_space_within_empty_method_call_parentheses = false
|
||||
ij_java_space_within_empty_method_parentheses = false
|
||||
ij_java_spaces_around_additive_operators = true
|
||||
ij_java_spaces_around_assignment_operators = true
|
||||
ij_java_spaces_around_bitwise_operators = true
|
||||
ij_java_spaces_around_equality_operators = true
|
||||
ij_java_spaces_around_lambda_arrow = true
|
||||
ij_java_spaces_around_logical_operators = true
|
||||
ij_java_spaces_around_method_ref_dbl_colon = false
|
||||
ij_java_spaces_around_multiplicative_operators = true
|
||||
ij_java_spaces_around_relational_operators = true
|
||||
ij_java_spaces_around_shift_operators = true
|
||||
ij_java_spaces_around_type_bounds_in_type_parameters = true
|
||||
ij_java_spaces_around_unary_operator = false
|
||||
ij_java_spaces_within_angle_brackets = false
|
||||
ij_java_spaces_within_annotation_parentheses = true
|
||||
ij_java_spaces_within_array_initializer_braces = true
|
||||
ij_java_spaces_within_braces = false
|
||||
ij_java_spaces_within_brackets = false
|
||||
ij_java_spaces_within_cast_parentheses = false
|
||||
ij_java_spaces_within_catch_parentheses = true
|
||||
ij_java_spaces_within_for_parentheses = true
|
||||
ij_java_spaces_within_if_parentheses = true
|
||||
ij_java_spaces_within_method_call_parentheses = true
|
||||
ij_java_spaces_within_method_parentheses = true
|
||||
ij_java_spaces_within_parentheses = false
|
||||
ij_java_spaces_within_switch_parentheses = true
|
||||
ij_java_spaces_within_synchronized_parentheses = true
|
||||
ij_java_spaces_within_try_parentheses = true
|
||||
ij_java_spaces_within_while_parentheses = true
|
||||
ij_java_special_else_if_treatment = true
|
||||
ij_java_subclass_name_suffix = Impl
|
||||
ij_java_ternary_operation_signs_on_next_line = true
|
||||
ij_java_ternary_operation_wrap = on_every_item
|
||||
ij_java_test_name_suffix = Test
|
||||
ij_java_throws_keyword_wrap = normal
|
||||
ij_java_throws_list_wrap = normal
|
||||
ij_java_use_external_annotations = false
|
||||
ij_java_use_fq_class_names = false
|
||||
ij_java_use_relative_indents = false
|
||||
ij_java_use_single_class_imports = true
|
||||
ij_java_variable_annotation_wrap = off
|
||||
ij_java_visibility = public
|
||||
ij_java_while_brace_force = never
|
||||
ij_java_while_on_new_line = false
|
||||
ij_java_wrap_comments = false
|
||||
ij_java_wrap_first_method_in_call_chain = false
|
||||
ij_java_wrap_long_lines = false
|
||||
|
||||
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -15,8 +15,12 @@
|
||||
# BINARY FILES:
|
||||
# Disable line ending normalize on checkin.
|
||||
|
||||
*.dll binary
|
||||
*.dylib binary
|
||||
*.gif binary
|
||||
*.jar binary
|
||||
*.lib binary
|
||||
*.png binary
|
||||
*.sketch binary
|
||||
*.so binary
|
||||
*.zip binary
|
||||
|
||||
8
.gitbugtraq
Normal file
8
.gitbugtraq
Normal file
@@ -0,0 +1,8 @@
|
||||
# links issue numbers in git commit messages to issue tracker
|
||||
# https://github.com/mstrap/bugtraq
|
||||
# for SmartGit - https://www.syntevo.com/smartgit/
|
||||
|
||||
[bugtraq]
|
||||
url = "https://github.com/JFormDesigner/FlatLaf/issues/%BUGID%"
|
||||
loglinkregex = "#[0-9]{1,5}"
|
||||
logregex = "[0-9]{1,5}"
|
||||
139
.github/workflows/ci.yml
vendored
Normal file
139
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
# https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
tags:
|
||||
- '[0-9]*'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
# test against
|
||||
# - Java 8 (minimum requirement)
|
||||
# - Java LTS versions (11, 17, ...)
|
||||
# - lastest Java version(s)
|
||||
java:
|
||||
- 8
|
||||
- 11 # LTS
|
||||
- 17 # LTS
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
if: matrix.java == '8'
|
||||
|
||||
- name: Setup Java ${{ matrix.java }}
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
distribution: adopt # Java 8 and 11 are pre-installed on ubuntu-latest
|
||||
cache: gradle
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
if: matrix.java == '11'
|
||||
with:
|
||||
name: FlatLaf-build-artifacts
|
||||
path: |
|
||||
flatlaf-*/build/libs
|
||||
!**/*-javadoc.jar
|
||||
!**/*-sources.jar
|
||||
|
||||
|
||||
snapshot:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: |
|
||||
github.event_name == 'push' &&
|
||||
(github.ref == 'refs/heads/main' || startsWith( github.ref, 'refs/heads/develop-' )) &&
|
||||
github.repository == 'JFormDesigner/FlatLaf'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Java 11
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: adopt # pre-installed on ubuntu-latest
|
||||
cache: gradle
|
||||
|
||||
- name: Publish snapshot to oss.sonatype.org
|
||||
run: ./gradlew publish :flatlaf-theme-editor:build -Dorg.gradle.internal.publish.checksums.insecure=true
|
||||
env:
|
||||
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
||||
|
||||
- name: Upload theme editor
|
||||
uses: sebastianpopp/ftp-action@releases/v2
|
||||
with:
|
||||
host: ${{ secrets.FTP_SERVER }}
|
||||
user: ${{ secrets.FTP_USERNAME }}
|
||||
password: ${{ secrets.FTP_PASSWORD }}
|
||||
forceSsl: true
|
||||
localDir: "flatlaf-theme-editor/build/libs"
|
||||
remoteDir: "snapshots"
|
||||
options: "--only-newer --no-recursion --verbose=1"
|
||||
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: |
|
||||
github.event_name == 'push' &&
|
||||
startsWith( github.ref, 'refs/tags/' ) &&
|
||||
github.repository == 'JFormDesigner/FlatLaf'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Java 11
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: adopt # pre-installed on ubuntu-latest
|
||||
cache: gradle
|
||||
|
||||
- name: Release a new stable version to Maven Central
|
||||
run: ./gradlew publish :flatlaf-demo:build :flatlaf-theme-editor:build -Drelease=true
|
||||
env:
|
||||
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||
SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}
|
||||
|
||||
- name: Upload demo
|
||||
uses: sebastianpopp/ftp-action@releases/v2
|
||||
with:
|
||||
host: ${{ secrets.FTP_SERVER }}
|
||||
user: ${{ secrets.FTP_USERNAME }}
|
||||
password: ${{ secrets.FTP_PASSWORD }}
|
||||
forceSsl: true
|
||||
localDir: "flatlaf-demo/build/libs"
|
||||
remoteDir: "."
|
||||
options: "--only-newer --no-recursion --verbose=1"
|
||||
|
||||
- name: Upload theme editor
|
||||
uses: sebastianpopp/ftp-action@releases/v2
|
||||
with:
|
||||
host: ${{ secrets.FTP_SERVER }}
|
||||
user: ${{ secrets.FTP_USERNAME }}
|
||||
password: ${{ secrets.FTP_PASSWORD }}
|
||||
forceSsl: true
|
||||
localDir: "flatlaf-theme-editor/build/libs"
|
||||
remoteDir: "."
|
||||
options: "--only-newer --no-recursion --verbose=1"
|
||||
49
.github/workflows/natives.yml
vendored
Normal file
49
.github/workflows/natives.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
# https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
|
||||
name: Native Libraries
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
tags:
|
||||
- '[0-9]*'
|
||||
paths:
|
||||
- 'flatlaf-natives/flatlaf-natives-windows/**'
|
||||
- '.github/workflows/natives.yml'
|
||||
- 'gradle/wrapper/gradle-wrapper.properties'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- 'flatlaf-natives/flatlaf-natives-windows/**'
|
||||
- '.github/workflows/natives.yml'
|
||||
- 'gradle/wrapper/gradle-wrapper.properties'
|
||||
|
||||
jobs:
|
||||
Windows:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
|
||||
- name: Setup Java 11
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: adopt
|
||||
cache: gradle
|
||||
|
||||
- name: Build with Gradle
|
||||
# --no-daemon is necessary on Windows otherwise caching Gradle would fail with:
|
||||
# tar.exe: Couldn't open ~/.gradle/caches/modules-2/modules-2.lock: Permission denied
|
||||
run: ./gradlew :flatlaf-natives-windows:build --no-daemon
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: FlatLaf-natives-windows-build-artifacts
|
||||
path: |
|
||||
flatlaf-natives/flatlaf-natives-windows/build
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -9,3 +9,5 @@ out/
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.vs/
|
||||
.vscode/
|
||||
|
||||
29
.travis.yml
29
.travis.yml
@@ -1,29 +0,0 @@
|
||||
language: java
|
||||
sudo: false
|
||||
|
||||
jdk:
|
||||
- openjdk8
|
||||
- openjdk9
|
||||
- openjdk11
|
||||
- openjdk13
|
||||
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.gradle/caches/
|
||||
- $HOME/.gradle/wrapper/
|
||||
|
||||
before_install:
|
||||
- ./gradlew --version
|
||||
- java -version
|
||||
|
||||
deploy:
|
||||
provider: script
|
||||
script: ./gradlew bintrayUpload
|
||||
skip_cleanup: true # to upload artifacts created during the build
|
||||
on:
|
||||
branch: master
|
||||
jdk: openjdk11
|
||||
tags: true
|
||||
1378
CHANGELOG.md
1378
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
216
README.md
216
README.md
@@ -1,44 +1,222 @@
|
||||
FlatLaf - Flat Look and Feel
|
||||
============================
|
||||
|
||||
**FlatLaf** is a modern open-source cross-platform Look and Feel for Java
|
||||
desktop applications.
|
||||
**FlatLaf** is a modern **open-source** cross-platform Look and Feel for Java
|
||||
Swing desktop applications.
|
||||
|
||||
It looks mostly "flat" (no shadows or gradients), clean, simple and elegant.
|
||||
It looks almost flat (no shadows or gradients), clean, simple and elegant.
|
||||
FlatLaf comes with **Light**, **Dark**, **IntelliJ** and **Darcula** themes,
|
||||
scales on **HiDPI** displays and runs on Java 8 or newer.
|
||||
|
||||
The look is heavily inspired by **Darcula** and **IntelliJ** themes from
|
||||
IntelliJ IDEA 2019.2+ and uses mostly the same colors and icons.
|
||||
IntelliJ IDEA 2019.2+ and uses almost the same colors and icons.
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
IntelliJ Platform Themes
|
||||
------------------------
|
||||
|
||||
FlatLaf can use 3rd party themes created for IntelliJ Platform (see
|
||||
[IntelliJ Themes Pack](flatlaf-intellij-themes)):
|
||||
|
||||

|
||||
|
||||
|
||||
Demo
|
||||
----
|
||||
|
||||
Download
|
||||
[flatlaf-demo-0.10.jar](https://download.formdev.com/flatlaf/flatlaf-demo-0.10.jar)
|
||||
and run it with `java -jar flatlaf-demo-0.10.jar` (or double-click it). Requires
|
||||
Java 8 or newer.
|
||||
[](https://download.formdev.com/flatlaf/flatlaf-demo-latest.jar)
|
||||
|
||||
Run demo with `java -jar flatlaf-demo-<version>.jar` (or double-click it).
|
||||
Requires Java 8 or newer.
|
||||
|
||||
|
||||
Download
|
||||
--------
|
||||
|
||||
[  ](https://bintray.com/jformdesigner/flatlaf/flatlaf-core/_latestVersion)
|
||||
FlatLaf binaries are available on **Maven Central**.
|
||||
|
||||
For Maven or Gradle use:
|
||||
If you use Maven or Gradle, add a dependency with following coordinates to your
|
||||
build script:
|
||||
|
||||
Repository: jcenter (https://jcenter.bintray.com/)
|
||||
Group Id: com.formdev.flatlaf
|
||||
Artifact Id: flatlaf-core
|
||||
Version: 0.10
|
||||
groupId: com.formdev
|
||||
artifactId: flatlaf
|
||||
version: (see button below)
|
||||
|
||||
Otherwise download `flatlaf-<version>.jar` here:
|
||||
|
||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf)
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
### Snapshots
|
||||
|
||||
FlatLaf is open source licensed under the [Apache 2.0 License](LICENSE)
|
||||
FlatLaf snapshot binaries are available on
|
||||
[Sonatype OSSRH](https://oss.sonatype.org/content/repositories/snapshots/com/formdev/flatlaf/).
|
||||
To access the latest snapshot, change the FlatLaf version in your dependencies
|
||||
to `<version>-SNAPSHOT` (e.g. `0.27-SNAPSHOT`) and add the repository
|
||||
`https://oss.sonatype.org/content/repositories/snapshots/` to your build (see
|
||||
[Maven](https://maven.apache.org/guides/mini/guide-multiple-repositories.html)
|
||||
and
|
||||
[Gradle](https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:declaring_custom_repository)
|
||||
docs).
|
||||
|
||||
|
||||
Addons
|
||||
------
|
||||
|
||||
- [IntelliJ Themes Pack](flatlaf-intellij-themes) - bundles many popular
|
||||
open-source 3rd party themes
|
||||
- [Extras](flatlaf-extras) - SVG icon, tri-state check box, UI inspectors, and
|
||||
more
|
||||
- [SwingX](flatlaf-swingx) - support for SwingX components
|
||||
- [JIDE Common Layer](flatlaf-jide-oss) - support for JIDE Common Layer
|
||||
components
|
||||
|
||||
|
||||
Getting started
|
||||
---------------
|
||||
|
||||
To use FlatLaf, add following code to your main method before you create any
|
||||
Swing component:
|
||||
|
||||
~~~java
|
||||
FlatLightLaf.setup();
|
||||
|
||||
// create UI here...
|
||||
~~~
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
For more information and documentation visit
|
||||
[FlatLaf Home](https://www.formdev.com/flatlaf/):
|
||||
|
||||
- [Themes](https://www.formdev.com/flatlaf/themes/)
|
||||
- [Customizing](https://www.formdev.com/flatlaf/customizing/)
|
||||
- [How to Customize](https://www.formdev.com/flatlaf/how-to-customize/)
|
||||
- [Properties Files](https://www.formdev.com/flatlaf/properties-files/)
|
||||
- [Components UI Properties](https://www.formdev.com/flatlaf/components/)
|
||||
- [Typography](https://www.formdev.com/flatlaf/typography/)
|
||||
- [Client Properties](https://www.formdev.com/flatlaf/client-properties/)
|
||||
- [System Properties](https://www.formdev.com/flatlaf/system-properties/)
|
||||
|
||||
|
||||
Theme Editor
|
||||
------------
|
||||
|
||||
The Theme Editor that supports editing FlatLaf theme properties files. See
|
||||
[Theme Editor documentation](https://www.formdev.com/flatlaf/theme-editor/) for
|
||||
details and downloads.
|
||||
|
||||

|
||||
|
||||
|
||||
Buzz
|
||||
----
|
||||
|
||||
- [What others say about FlatLaf on Twitter](https://twitter.com/search?f=live&q=flatlaf)
|
||||
- [FlatLaf 1.0 announcement on Reddit](https://www.reddit.com/r/java/comments/lsbcwe/flatlaf_10_swing_look_and_feel/)
|
||||
- [FlatLaf announcement on Reddit](https://www.reddit.com/r/java/comments/dl0hu3/flatlaf_flat_look_and_feel/)
|
||||
|
||||
|
||||
Applications using FlatLaf
|
||||
--------------------------
|
||||
|
||||
-  [MooInfo](https://github.com/rememberber/MooInfo) -
|
||||
visual implementation of OSHI, to view information about the system and
|
||||
hardware
|
||||
-  [Jailer](https://github.com/Wisser/Jailer) 11.2 -
|
||||
database subsetting and relational data browsing tool
|
||||
- [Apache NetBeans](https://netbeans.apache.org/) 11.3 - IDE for Java, PHP, HTML
|
||||
and much more
|
||||
- [jclasslib bytecode viewer](https://github.com/ingokegel/jclasslib) 5.5
|
||||
- [KeyStore Explorer](https://keystore-explorer.org/) 5.4.3
|
||||
- 
|
||||
[install4j](https://www.ej-technologies.com/products/install4j/overview.html)
|
||||
9.0 (**commercial**) - the powerful multi-platform Java installer builder
|
||||
-  [DbVisualizer](https://www.dbvis.com/) 12.0
|
||||
(**commercial**) - the universal database tool for developers, analysts and
|
||||
DBAs
|
||||
-  [MagicPlot](https://magicplot.com/) 3.0
|
||||
(**commercial**) - Software for nonlinear fitting, plotting and data analysis
|
||||
- 
|
||||
[Thermo-Calc](https://thermocalc.com/products/thermo-calc/) 2021a
|
||||
(**commercial**) - Thermodynamics and Properties Software
|
||||
- [OWASP ZAP](https://www.zaproxy.org/) 2.10 - the worlds most widely used web
|
||||
app scanner
|
||||
- 
|
||||
[Burp Suite Professional and Community Edition](https://portswigger.net/burp/pro)
|
||||
2020.11.2 (**commercial**) - the leading software for web security testing
|
||||
- 
|
||||
[BurpCustomizer](https://github.com/CoreyD97/BurpCustomizer) - adds more
|
||||
FlatLaf themes to Burp Suite
|
||||
- [JOSM](https://josm.openstreetmap.de/) - an extensible editor for
|
||||
[OpenStreetMap](https://www.openstreetmap.org/) (requires FlatLaf JOSM plugin)
|
||||
- [jAlbum](https://jalbum.net/) 21 (**commercial**) - creates photo album
|
||||
websites
|
||||
-  [PDF Studio](https://www.qoppa.com/pdfstudio/) 2021
|
||||
(**commercial**) - create, review and edit PDF documents
|
||||
- [XMLmind XML Editor](https://www.xmlmind.com/xmleditor/) 9.3 (**commercial**)
|
||||
- [Total Validator](https://www.totalvalidator.com/) 15 (**commercial**) -
|
||||
checks your website
|
||||
- [j-lawyer](https://github.com/jlawyerorg/j-lawyer-org) - Kanzleisoftware
|
||||
- [MegaMek](https://github.com/MegaMek/megamek),
|
||||
[MegaMekLab](https://github.com/MegaMek/megameklab) and
|
||||
[MekHQ](https://github.com/MegaMek/mekhq) v0.47.5+ - a sci-fi tabletop
|
||||
BattleTech simulator suite handling battles, unit building, and campaigns
|
||||
- [GUIslice Builder](https://github.com/ImpulseAdventure/GUIslice-Builder)
|
||||
0.13.b024 - GUI builder for
|
||||
[GUIslice](https://github.com/ImpulseAdventure/GUIslice), a lightweight GUI
|
||||
framework for embedded displays
|
||||
- [Rest Suite](https://github.com/supanadit/restsuite) - Rest API testing
|
||||
- [ControllerBuddy](https://github.com/bwRavencl/ControllerBuddy) - advanced
|
||||
gamepad mapping software
|
||||
- [SpringRemote](https://github.com/HaleyWang/SpringRemote) - remote Linux SSH
|
||||
connections manager
|
||||
- [jEnTunnel](https://github.com/ggrandes/jentunnel) - manage SSH Tunnels made
|
||||
easy
|
||||
- [mendelson AS2](https://sourceforge.net/projects/mec-as2/),
|
||||
[AS4](https://sourceforge.net/projects/mendelson-as4/) and
|
||||
[OFTP2](https://sourceforge.net/projects/mendelson-oftp2/) (open-source) and
|
||||
[mendelson AS2](https://mendelson-e-c.com/as2/),
|
||||
[AS4](https://mendelson-e-c.com/as4/) and
|
||||
[OFTP2](https://mendelson-e-c.com/oftp2) (**commercial**)
|
||||
-  [IGMAS+](https://www.gfz-potsdam.de/igmas) -
|
||||
Interactive Gravity and Magnetic Application System
|
||||
- [MeteoInfo](https://github.com/meteoinfo/MeteoInfo) 2.2 - GIS and scientific
|
||||
computation environment for meteorological community
|
||||
- [lsfusion platform](https://github.com/lsfusion/platform) 4 - information
|
||||
systems development platform
|
||||
- [JPass](https://github.com/gaborbata/jpass) - password manager with strong
|
||||
encryption
|
||||
- [Jes - Die Java-EÜR](https://www.jes-eur.de)
|
||||
- [Mapton](https://mapton.org/) 2.0
|
||||
([source code](https://github.com/trixon/mapton)) - some kind of map
|
||||
application (based on NetBeans platform)
|
||||
- [Pseudo Assembler IDE](https://github.com/tomasz-herman/PseudoAssemblerIDE) -
|
||||
IDE for Pseudo-Assembler
|
||||
- [Linotte](https://github.com/cpc6128/LangageLinotte) 3.1 - French programming
|
||||
language created to learn programming
|
||||
- [MEKA](https://github.com/Waikato/meka) 1.9.3 - multi-label classifiers and
|
||||
evaluation procedures using the Weka machine learning framework
|
||||
- [Shutter Encoder](https://www.shutterencoder.com/) 14.2
|
||||
([source code](https://github.com/paulpacifico/shutter-encoder)) -
|
||||
professional video converter and compression tool (screenshots show **old**
|
||||
look)
|
||||
- [Sound Analysis](https://github.com/tomasz-herman/SoundAnalysis) - analyze
|
||||
sound files in time or frequency domain
|
||||
- [RemoteLight](https://github.com/Drumber/RemoteLight) - multifunctional LED
|
||||
control software
|
||||
- [ThunderFocus](https://github.com/marcocipriani01/ThunderFocus) -
|
||||
Arduino-based telescope focuser
|
||||
- [Novel-Grabber](https://github.com/Flameish/Novel-Grabber) - download novels
|
||||
from any webnovel and lightnovel site
|
||||
- [lectureStudio](https://www.lecturestudio.org/) 4.3.1060 - digitize your
|
||||
lectures with ease
|
||||
- [Android Tool](https://github.com/fast-geek/Android-Tool) - makes popular adb
|
||||
and fastboot commands easier to use
|
||||
- and more...
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -14,7 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
version = "0.10"
|
||||
val releaseVersion = "2.0.1"
|
||||
val developmentVersion = "2.1-SNAPSHOT"
|
||||
|
||||
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion
|
||||
|
||||
allprojects {
|
||||
version = rootProject.version
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
// check required Java version
|
||||
if( JavaVersion.current() < JavaVersion.VERSION_1_8 )
|
||||
@@ -27,3 +38,44 @@ println( "FlatLaf Version: ${version}" )
|
||||
println( "Gradle ${gradle.gradleVersion} at ${gradle.gradleHomeDir}" )
|
||||
println( "Java ${System.getProperty( "java.version" )}" )
|
||||
println()
|
||||
|
||||
|
||||
allprojects {
|
||||
tasks {
|
||||
withType<JavaCompile>().configureEach {
|
||||
sourceCompatibility = "1.8"
|
||||
targetCompatibility = "1.8"
|
||||
|
||||
options.encoding = "ISO-8859-1"
|
||||
options.isDeprecation = false
|
||||
}
|
||||
|
||||
withType<Jar>().configureEach {
|
||||
// manifest for all created JARs
|
||||
manifest.attributes(
|
||||
"Implementation-Vendor" to "FormDev Software GmbH",
|
||||
"Implementation-Copyright" to "Copyright (C) 2019-${java.time.LocalDate.now().year} FormDev Software GmbH. All rights reserved.",
|
||||
"Implementation-Version" to project.version
|
||||
)
|
||||
|
||||
// add META-INF/LICENSE to all created JARs
|
||||
from( "${rootDir}/LICENSE" ) {
|
||||
into( "META-INF" )
|
||||
}
|
||||
}
|
||||
|
||||
withType<Javadoc>().configureEach {
|
||||
options {
|
||||
this as StandardJavadocDocletOptions
|
||||
|
||||
title = "${project.name} $version"
|
||||
header = title
|
||||
isUse = true
|
||||
tags = listOf( "uiDefault", "clientProperty" )
|
||||
addStringOption( "Xdoclint:all,-missing", "-Xdoclint:all,-missing" )
|
||||
links( "https://docs.oracle.com/en/java/javase/11/docs/api/" )
|
||||
}
|
||||
isFailOnError = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
24
buildSrc/build.gradle.kts
Normal file
24
buildSrc/build.gradle.kts
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
// required for kotlin-dsl or embedded-kotlin plugins
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
80
buildSrc/src/main/java/ReorderJarEntries.java
Normal file
80
buildSrc/src/main/java/ReorderJarEntries.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* Reorders entries in a JAR file so that .properties files are placed before .class files,
|
||||
* which is necessary to workaround an issue in NetBeans 11.3 (and older).
|
||||
* See issues #13 and #93.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class ReorderJarEntries
|
||||
{
|
||||
public static void reorderJarEntries( File jarFile )
|
||||
throws IOException
|
||||
{
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream( (int) jarFile.length() + 1000 );
|
||||
|
||||
try( ZipOutputStream zipOutStream = new ZipOutputStream( outStream ) ) {
|
||||
// 1st pass: copy .properties files
|
||||
copyFiles( zipOutStream, jarFile, name -> name.endsWith( ".properties" ) );
|
||||
|
||||
// 2st pass: copy other files
|
||||
copyFiles( zipOutStream, jarFile, name -> !name.endsWith( ".properties" ) );
|
||||
}
|
||||
|
||||
// replace JAR
|
||||
Files.write( jarFile.toPath(), outStream.toByteArray(),
|
||||
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING );
|
||||
}
|
||||
|
||||
private static void copyFiles( ZipOutputStream dest, File jarFile, Predicate<String> filter )
|
||||
throws IOException
|
||||
{
|
||||
try( ZipInputStream zipInputStream = new ZipInputStream( new FileInputStream( jarFile ) ) ) {
|
||||
ZipEntry entry;
|
||||
while( (entry = zipInputStream.getNextEntry()) != null ) {
|
||||
if( filter.test( entry.getName() ) ) {
|
||||
dest.putNextEntry( entry );
|
||||
copyFile( zipInputStream, dest );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyFile( InputStream src, OutputStream dest )
|
||||
throws IOException
|
||||
{
|
||||
byte[] buf = new byte[8*1024];
|
||||
int len;
|
||||
while( (len = src.read( buf )) > 0 )
|
||||
dest.write( buf, 0, len );
|
||||
dest.flush();
|
||||
}
|
||||
}
|
||||
48
buildSrc/src/main/kotlin/flatlaf-java9.gradle.kts
Normal file
48
buildSrc/src/main/kotlin/flatlaf-java9.gradle.kts
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
java
|
||||
}
|
||||
|
||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
||||
sourceSets {
|
||||
create( "java9" ) {
|
||||
java {
|
||||
setSrcDirs( listOf( "src/main/java9" ) )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
add( "java9Implementation", sourceSets.main.get().output )
|
||||
}
|
||||
|
||||
tasks {
|
||||
named<JavaCompile>( "compileJava9Java" ) {
|
||||
sourceCompatibility = "9"
|
||||
targetCompatibility = "9"
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest.attributes( "Multi-Release" to "true" )
|
||||
|
||||
into( "META-INF/versions/9" ) {
|
||||
from( sourceSets["java9"].output )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
71
buildSrc/src/main/kotlin/flatlaf-module-info.gradle.kts
Normal file
71
buildSrc/src/main/kotlin/flatlaf-module-info.gradle.kts
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
open class ModuleInfoExtension {
|
||||
var paths: ArrayList<String> = ArrayList()
|
||||
|
||||
fun dependsOn( vararg paths: String ) {
|
||||
this.paths.addAll( paths )
|
||||
}
|
||||
}
|
||||
|
||||
val extension = project.extensions.create<ModuleInfoExtension>( "flatlafModuleInfo" )
|
||||
|
||||
|
||||
plugins {
|
||||
java
|
||||
}
|
||||
|
||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
||||
sourceSets {
|
||||
create( "module-info" ) {
|
||||
java {
|
||||
// include "src/main/java" and "src/main/java9" here to get compile errors if classes are
|
||||
// used from other modules that are not specified in module dependencies
|
||||
setSrcDirs( listOf( "src/main/module-info", "src/main/java", "src/main/java9" ) )
|
||||
|
||||
// exclude Java 8 source file if an equally named Java 9+ source file exists
|
||||
exclude {
|
||||
if( it.isDirectory )
|
||||
return@exclude false
|
||||
val java9file = file( "${projectDir}/src/main/java9/${it.path}" )
|
||||
java9file.exists() && java9file != it.file
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
named<JavaCompile>( "compileModuleInfoJava" ) {
|
||||
sourceCompatibility = "9"
|
||||
targetCompatibility = "9"
|
||||
|
||||
dependsOn( extension.paths )
|
||||
|
||||
options.compilerArgs.add( "--module-path" )
|
||||
options.compilerArgs.add( configurations.runtimeClasspath.get().asPath
|
||||
+ File.pathSeparator + configurations.compileClasspath.get().asPath )
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest.attributes( "Multi-Release" to "true" )
|
||||
|
||||
from( sourceSets["module-info"].output ) {
|
||||
include( "module-info.class" )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
112
buildSrc/src/main/kotlin/flatlaf-publish.gradle.kts
Normal file
112
buildSrc/src/main/kotlin/flatlaf-publish.gradle.kts
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
open class PublishExtension {
|
||||
var artifactId: String? = null
|
||||
var name: String? = null
|
||||
var description: String? = null
|
||||
}
|
||||
|
||||
val extension = project.extensions.create<PublishExtension>( "flatlafPublish" )
|
||||
|
||||
|
||||
plugins {
|
||||
`maven-publish`
|
||||
signing
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>( "maven" ) {
|
||||
afterEvaluate {
|
||||
artifactId = extension.artifactId
|
||||
}
|
||||
groupId = "com.formdev"
|
||||
|
||||
from( components["java"] )
|
||||
|
||||
pom {
|
||||
afterEvaluate {
|
||||
this@pom.name.set( extension.name )
|
||||
this@pom.description.set( extension.description )
|
||||
}
|
||||
url.set( "https://github.com/JFormDesigner/FlatLaf" )
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name.set( "The Apache License, Version 2.0" )
|
||||
url.set( "https://www.apache.org/licenses/LICENSE-2.0.txt" )
|
||||
}
|
||||
}
|
||||
|
||||
developers {
|
||||
developer {
|
||||
name.set( "Karl Tauber" )
|
||||
organization.set( "FormDev Software GmbH" )
|
||||
organizationUrl.set( "https://www.formdev.com/" )
|
||||
}
|
||||
}
|
||||
|
||||
scm {
|
||||
connection.set( "scm:git:git://github.com/JFormDesigner/FlatLaf.git" )
|
||||
url.set( "https://github.com/JFormDesigner/FlatLaf" )
|
||||
}
|
||||
|
||||
issueManagement {
|
||||
system.set( "GitHub" )
|
||||
url.set( "https://github.com/JFormDesigner/FlatLaf/issues" )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = "OSSRH"
|
||||
|
||||
val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
|
||||
val snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
|
||||
url = uri( if( java.lang.Boolean.getBoolean( "release" ) ) releasesRepoUrl else snapshotsRepoUrl )
|
||||
|
||||
credentials {
|
||||
// get from gradle.properties
|
||||
val ossrhUsername: String? by project
|
||||
val ossrhPassword: String? by project
|
||||
|
||||
username = System.getenv( "OSSRH_USERNAME" ) ?: ossrhUsername
|
||||
password = System.getenv( "OSSRH_PASSWORD" ) ?: ossrhPassword
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signing {
|
||||
// get from gradle.properties
|
||||
val signingKey: String? by project
|
||||
val signingPassword: String? by project
|
||||
|
||||
val key = System.getenv( "SIGNING_KEY" ) ?: signingKey
|
||||
val password = System.getenv( "SIGNING_PASSWORD" ) ?: signingPassword
|
||||
|
||||
useInMemoryPgpKeys( key, password )
|
||||
sign( publishing.publications["maven"] )
|
||||
}
|
||||
|
||||
// disable signing of snapshots
|
||||
tasks.withType<Sign>().configureEach {
|
||||
onlyIf { java.lang.Boolean.getBoolean( "release" ) }
|
||||
}
|
||||
377
flatlaf-core/.settings/org.eclipse.jdt.core.prefs
Normal file
377
flatlaf-core/.settings/org.eclipse.jdt.core.prefs
Normal file
@@ -0,0 +1,377 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.align_with_spaces=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=48
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_record_components=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=33
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=33
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration=33
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=33
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=32
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=32
|
||||
org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block=next_line_on_wrap
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line_on_wrap
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line_on_wrap
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_record_constructor=next_line_on_wrap
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_record_declaration=next_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
|
||||
org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=true
|
||||
org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_source_code=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
|
||||
org.eclipse.jdt.core.formatter.comment.indent_root_tags=false
|
||||
org.eclipse.jdt.core.formatter.comment.indent_tag_description=false
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags=do not insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.comment.line_length=80
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
|
||||
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation=1
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=1
|
||||
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
|
||||
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
|
||||
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
|
||||
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_not_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
|
||||
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
|
||||
org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.lineSplit=120
|
||||
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block=0
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block=0
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block=0
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=tab
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.jdt.core.formatter.text_block_indentation=0
|
||||
org.eclipse.jdt.core.formatter.use_on_off_tags=false
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_logical_operator=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
|
||||
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
|
||||
org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
|
||||
3
flatlaf-core/.settings/org.eclipse.jdt.ui.prefs
Normal file
3
flatlaf-core/.settings/org.eclipse.jdt.ui.prefs
Normal file
@@ -0,0 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
formatter_profile=_FlatLaf
|
||||
formatter_settings_version=19
|
||||
4
flatlaf-core/README.md
Normal file
4
flatlaf-core/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
FlatLaf Core
|
||||
============
|
||||
|
||||
This sub-project contains the FlatLaf core source code.
|
||||
@@ -5,7 +5,7 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -14,133 +14,114 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
version = rootProject.version
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
id( "com.jfrog.bintray" ) version "1.8.4"
|
||||
`flatlaf-module-info`
|
||||
`flatlaf-java9`
|
||||
`flatlaf-publish`
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
||||
sourceSets {
|
||||
create( "module-info" ) {
|
||||
java {
|
||||
// include "src/main/java" here to get compile errors if classes are
|
||||
// used from other modules that are not specified in module dependencies
|
||||
setSrcDirs( listOf( "src/main/module-info", "src/main/java" ) )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val sigtest = configurations.create( "sigtest" )
|
||||
|
||||
dependencies {
|
||||
testImplementation( "com.miglayout:miglayout-swing:5.2" )
|
||||
testImplementation( "com.jgoodies:jgoodies-forms:1.9.0" )
|
||||
testImplementation( "org.junit.jupiter:junit-jupiter-api:5.7.2" )
|
||||
testImplementation( "org.junit.jupiter:junit-jupiter-params" )
|
||||
testRuntimeOnly( "org.junit.jupiter:junit-jupiter-engine" )
|
||||
|
||||
// https://github.com/jtulach/netbeans-apitest
|
||||
sigtest( "org.netbeans.tools:sigtest-maven-plugin:1.4" )
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
tasks {
|
||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
||||
named<JavaCompile>( "compileModuleInfoJava" ) {
|
||||
sourceCompatibility = "9"
|
||||
targetCompatibility = "9"
|
||||
}
|
||||
compileJava {
|
||||
// generate JNI headers
|
||||
options.headerOutputDirectory.set( buildDir.resolve( "generated/jni-headers" ) )
|
||||
}
|
||||
|
||||
|
||||
processResources {
|
||||
// build native libraries
|
||||
dependsOn( ":flatlaf-natives-windows:assemble" )
|
||||
}
|
||||
|
||||
jar {
|
||||
archiveBaseName.set( "flatlaf" )
|
||||
|
||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
||||
manifest.attributes(
|
||||
"Multi-Release" to "true"
|
||||
)
|
||||
doLast {
|
||||
ReorderJarEntries.reorderJarEntries( outputs.files.singleFile );
|
||||
}
|
||||
}
|
||||
|
||||
into( "META-INF/versions/9" ) {
|
||||
from( sourceSets["module-info"].output )
|
||||
include( "module-info.class" )
|
||||
named<Jar>( "sourcesJar" ) {
|
||||
archiveBaseName.set( "flatlaf" )
|
||||
}
|
||||
|
||||
named<Jar>( "javadocJar" ) {
|
||||
archiveBaseName.set( "flatlaf" )
|
||||
}
|
||||
|
||||
check {
|
||||
dependsOn( "sigtestCheck" )
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
||||
}
|
||||
|
||||
register( "sigtestGenerate" ) {
|
||||
group = "verification"
|
||||
dependsOn( "jar" )
|
||||
|
||||
doLast {
|
||||
ant.withGroovyBuilder {
|
||||
"taskdef"(
|
||||
"name" to "sigtest",
|
||||
"classname" to "org.netbeans.apitest.Sigtest",
|
||||
"classpath" to sigtest.asPath )
|
||||
|
||||
"sigtest"(
|
||||
"action" to "generate",
|
||||
"fileName" to "${project.name}-sigtest.txt",
|
||||
"classpath" to jar.get().outputs.files.asPath,
|
||||
"packages" to "com.formdev.flatlaf,com.formdev.flatlaf.util",
|
||||
"version" to version,
|
||||
"release" to "1.8", // Java version
|
||||
"failonerror" to "true" )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
javadoc {
|
||||
options {
|
||||
this as StandardJavadocDocletOptions
|
||||
tags = listOf( "uiDefault", "clientProperty" )
|
||||
}
|
||||
isFailOnError = false
|
||||
}
|
||||
register( "sigtestCheck" ) {
|
||||
group = "verification"
|
||||
dependsOn( "jar" )
|
||||
|
||||
register( "sourcesJar", Jar::class ) {
|
||||
archiveBaseName.set( "flatlaf" )
|
||||
archiveClassifier.set( "sources" )
|
||||
doLast {
|
||||
ant.withGroovyBuilder {
|
||||
"taskdef"(
|
||||
"name" to "sigtest",
|
||||
"classname" to "org.netbeans.apitest.Sigtest",
|
||||
"classpath" to sigtest.asPath )
|
||||
|
||||
from( sourceSets.main.get().allJava )
|
||||
}
|
||||
|
||||
register( "javadocJar", Jar::class ) {
|
||||
archiveBaseName.set( "flatlaf" )
|
||||
archiveClassifier.set( "javadoc" )
|
||||
|
||||
from( javadoc )
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>( "maven" ) {
|
||||
artifactId = "flatlaf-core"
|
||||
groupId = "com.formdev.flatlaf"
|
||||
|
||||
from( components["java"] )
|
||||
|
||||
artifact( tasks["sourcesJar"] )
|
||||
artifact( tasks["javadocJar"] )
|
||||
|
||||
pom {
|
||||
name.set( "FlatLaf" )
|
||||
description.set( "Flat Look and Feel" )
|
||||
url.set( "https://github.com/JFormDesigner/FlatLaf" )
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name.set( "The Apache License, Version 2.0" )
|
||||
url.set( "http://www.apache.org/licenses/LICENSE-2.0.txt" )
|
||||
}
|
||||
}
|
||||
|
||||
scm {
|
||||
url.set( "https://github.com/JFormDesigner/FlatLaf" )
|
||||
}
|
||||
"sigtest"(
|
||||
"action" to "check",
|
||||
"fileName" to "${project.name}-sigtest.txt",
|
||||
"classpath" to jar.get().outputs.files.asPath,
|
||||
"packages" to "com.formdev.flatlaf,com.formdev.flatlaf.util",
|
||||
"version" to version,
|
||||
"release" to "1.8", // Java version
|
||||
"failonerror" to "true" )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bintray {
|
||||
user = System.getenv( "BINTRAY_USER" ) ?: System.getProperty( "bintray.user" )
|
||||
key = System.getenv( "BINTRAY_KEY" ) ?: System.getProperty( "bintray.key" )
|
||||
|
||||
setPublications( "maven" )
|
||||
|
||||
with( pkg ) {
|
||||
repo = "flatlaf"
|
||||
name = "flatlaf-core"
|
||||
setLicenses( "Apache-2.0" )
|
||||
vcsUrl = "https://github.com/JFormDesigner/FlatLaf"
|
||||
|
||||
with( version ) {
|
||||
name = project.version.toString()
|
||||
}
|
||||
|
||||
publish = true
|
||||
}
|
||||
flatlafPublish {
|
||||
artifactId = "flatlaf"
|
||||
name = "FlatLaf"
|
||||
description = "Flat Look and Feel"
|
||||
}
|
||||
|
||||
1124
flatlaf-core/flatlaf-core-sigtest.txt
Normal file
1124
flatlaf-core/flatlaf-core-sigtest.txt
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -16,21 +16,54 @@
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* A Flat LaF that has a dark color scheme and looks like Darcula LaF.
|
||||
* <p>
|
||||
* The UI defaults are loaded from {@code FlatDarculaLaf.properties},
|
||||
* {@code FlatDarkLaf.properties} and {@code FlatLaf.properties}.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatDarculaLaf
|
||||
extends FlatDarkLaf
|
||||
{
|
||||
public static final String NAME = "FlatLaf Darcula";
|
||||
|
||||
/**
|
||||
* Sets the application look and feel to this LaF
|
||||
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||
*/
|
||||
public static boolean setup() {
|
||||
return setup( new FlatDarculaLaf() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #setup()} instead; this method will be removed in a future version
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean install() {
|
||||
return setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds this look and feel to the set of available look and feels.
|
||||
* <p>
|
||||
* Useful if your application uses {@link UIManager#getInstalledLookAndFeels()}
|
||||
* to query available LaFs and display them to the user in a combobox.
|
||||
*/
|
||||
public static void installLafInfo() {
|
||||
installLafInfo( NAME, FlatDarculaLaf.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Flat Darcula";
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Flat Darcula Look and Feel";
|
||||
return "FlatLaf Darcula Look and Feel";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,21 +16,58 @@
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* A Flat LaF that has a dark color scheme.
|
||||
* <p>
|
||||
* The UI defaults are loaded from {@code FlatDarkLaf.properties} and {@code FlatLaf.properties}.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatDarkLaf
|
||||
extends FlatLaf
|
||||
{
|
||||
public static final String NAME = "FlatLaf Dark";
|
||||
|
||||
/**
|
||||
* Sets the application look and feel to this LaF
|
||||
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||
*/
|
||||
public static boolean setup() {
|
||||
return setup( new FlatDarkLaf() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #setup()} instead; this method will be removed in a future version
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean install() {
|
||||
return setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds this look and feel to the set of available look and feels.
|
||||
* <p>
|
||||
* Useful if your application uses {@link UIManager#getInstalledLookAndFeels()}
|
||||
* to query available LaFs and display them to the user in a combobox.
|
||||
*/
|
||||
public static void installLafInfo() {
|
||||
installLafInfo( NAME, FlatDarkLaf.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Flat Dark";
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Flat Dark Look and Feel";
|
||||
return "FlatLaf Dark Look and Feel";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDark() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2019 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.io.InputStream;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
/**
|
||||
* Addon for FlatLaf UI defaults.
|
||||
*
|
||||
* Allows loading of additional .properties files from addon JARs.
|
||||
* {@link java.util.ServiceLoader} is used to load extensions of this class from addon JARs.
|
||||
* <p>
|
||||
* If you extend this class in a addon JAR, you also have to add a text file named
|
||||
* {@code META-INF/services/com.formdev.flatlaf.FlatDefaultsAddon}
|
||||
* to the addon JAR. The file must contain a single line with the class name.
|
||||
* <p>
|
||||
* See 'flatlaf-swingx' addon for an example
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public abstract class FlatDefaultsAddon
|
||||
{
|
||||
/**
|
||||
* Finds an addon .properties file for the given LaF class and returns
|
||||
* it as input stream. Or {@code null} if not found.
|
||||
* <p>
|
||||
* This default implementation finds addon .properties file for the given LaF class
|
||||
* in the same package as the subclass.
|
||||
* <p>
|
||||
* Override this method to load addon .properties files from other locations.
|
||||
*/
|
||||
public InputStream getDefaults( Class<?> lafClass ) {
|
||||
Class<?> addonClass = this.getClass();
|
||||
String propertiesName = '/' + addonClass.getPackage().getName().replace( '.', '/' )
|
||||
+ '/' + lafClass.getSimpleName() + ".properties";
|
||||
return addonClass.getResourceAsStream( propertiesName );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows modifying UI defaults after loading UI defaults.
|
||||
* The default implementation does nothing.
|
||||
*/
|
||||
public void afterDefaultsLoading( LookAndFeel laf, UIDefaults defaults ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the priority used to sort addon loading.
|
||||
* The order is only important if you want overwrite UI defaults of other addons.
|
||||
* Lower numbers mean higher priority.
|
||||
* Returns 10000 by default.
|
||||
*/
|
||||
public int getPriority() {
|
||||
return 10000;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
/**
|
||||
* Default color palette for action icons and object icons.
|
||||
* <p>
|
||||
* The idea is to use only this well defined set of colors in SVG icons and
|
||||
* then they are replaced at runtime to dark variants or to other theme colors.
|
||||
* Then a single SVG icon (light variant) can be used for dark themes too.
|
||||
* IntelliJ Platform uses this mechanism to allow themes to change IntelliJ Platform icons.
|
||||
* <p>
|
||||
* Use the {@code *_DARK} colors only in {@code *_dark.svg} files.
|
||||
* <p>
|
||||
* The colors are based on IntelliJ Platform
|
||||
* <a href="https://jetbrains.design/intellij/principles/icons/#action-icons">Action icons</a>
|
||||
* and
|
||||
* <a href="https://jetbrains.design/intellij/principles/icons/#noun-icons">Noun icons</a>
|
||||
* <p>
|
||||
* These colors may be changed by IntelliJ Platform themes.
|
||||
* <p>
|
||||
* You may use these colors also in your application (outside of SVG icons), but do
|
||||
* not use the RGB values defined in this enum.<br>
|
||||
* Instead use {@code UIManager.getColor( FlatIconColors.ACTIONS_GREY.key )}.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public enum FlatIconColors
|
||||
{
|
||||
// colors for action icons
|
||||
// see https://jetbrains.design/intellij/principles/icons/#action-icons
|
||||
ACTIONS_RED ( 0xDB5860, "Actions.Red", true, false ),
|
||||
ACTIONS_RED_DARK ( 0xC75450, "Actions.Red", false, true ),
|
||||
ACTIONS_YELLOW ( 0xEDA200, "Actions.Yellow", true, false ),
|
||||
ACTIONS_YELLOW_DARK ( 0xF0A732, "Actions.Yellow", false, true ),
|
||||
ACTIONS_GREEN ( 0x59A869, "Actions.Green", true, false ),
|
||||
ACTIONS_GREEN_DARK ( 0x499C54, "Actions.Green", false, true ),
|
||||
ACTIONS_BLUE ( 0x389FD6, "Actions.Blue", true, false ),
|
||||
ACTIONS_BLUE_DARK ( 0x3592C4, "Actions.Blue", false, true ),
|
||||
ACTIONS_GREY ( 0x6E6E6E, "Actions.Grey", true, false ),
|
||||
ACTIONS_GREY_DARK ( 0xAFB1B3, "Actions.Grey", false, true ),
|
||||
ACTIONS_GREYINLINE ( 0x7F8B91, "Actions.GreyInline", true, false ),
|
||||
ACTIONS_GREYINLINE_DARK ( 0x7F8B91, "Actions.GreyInline", false, true ),
|
||||
|
||||
// colors for object icons
|
||||
// see https://jetbrains.design/intellij/principles/icons/#noun-icons
|
||||
OBJECTS_GREY ( 0x9AA7B0, "Objects.Grey" ),
|
||||
OBJECTS_BLUE ( 0x40B6E0, "Objects.Blue" ),
|
||||
OBJECTS_GREEN ( 0x62B543, "Objects.Green" ),
|
||||
OBJECTS_YELLOW ( 0xF4AF3D, "Objects.Yellow" ),
|
||||
OBJECTS_YELLOW_DARK ( 0xD9A343, "Objects.YellowDark" ),
|
||||
OBJECTS_PURPLE ( 0xB99BF8, "Objects.Purple" ),
|
||||
OBJECTS_PINK ( 0xF98B9E, "Objects.Pink" ),
|
||||
OBJECTS_RED ( 0xF26522, "Objects.Red" ),
|
||||
OBJECTS_RED_STATUS ( 0xE05555, "Objects.RedStatus" ),
|
||||
OBJECTS_GREEN_ANDROID ( 0xA4C639, "Objects.GreenAndroid" ),
|
||||
OBJECTS_BLACK_TEXT ( 0x231F20, "Objects.BlackText" );
|
||||
|
||||
public final int rgb;
|
||||
public final String key;
|
||||
|
||||
public final boolean light;
|
||||
public final boolean dark;
|
||||
|
||||
FlatIconColors( int rgb, String key ) {
|
||||
this( rgb, key, true, true );
|
||||
}
|
||||
|
||||
FlatIconColors( int rgb, String key, boolean light, boolean dark ) {
|
||||
this.rgb = rgb;
|
||||
this.key = key;
|
||||
this.light = light;
|
||||
this.dark = dark;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,660 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import javax.swing.InputMap;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIDefaults.LazyValue;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.InputMapUIResource;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import static javax.swing.text.DefaultEditorKit.*;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
class FlatInputMaps
|
||||
{
|
||||
static void initInputMaps( UIDefaults defaults ) {
|
||||
initBasicInputMaps( defaults );
|
||||
initTextComponentInputMaps( defaults );
|
||||
|
||||
if( SystemInfo.isMacOS )
|
||||
initMacInputMaps( defaults );
|
||||
}
|
||||
|
||||
private static void initBasicInputMaps( UIDefaults defaults ) {
|
||||
if( SystemInfo.isMacOS ) {
|
||||
defaults.put( "Button.focusInputMap", new UIDefaults.LazyInputMap( new Object[] {
|
||||
"SPACE", "pressed",
|
||||
"released SPACE", "released"
|
||||
} ) );
|
||||
}
|
||||
|
||||
modifyInputMap( defaults, "ComboBox.ancestorInputMap",
|
||||
"SPACE", "spacePopup",
|
||||
|
||||
"UP", mac( "selectPrevious2", "selectPrevious" ),
|
||||
"DOWN", mac( "selectNext2", "selectNext" ),
|
||||
"KP_UP", mac( "selectPrevious2", "selectPrevious" ),
|
||||
"KP_DOWN", mac( "selectNext2", "selectNext" ),
|
||||
|
||||
mac( "alt UP", null ), "togglePopup",
|
||||
mac( "alt DOWN", null ), "togglePopup",
|
||||
mac( "alt KP_UP", null ), "togglePopup",
|
||||
mac( "alt KP_DOWN", null ), "togglePopup"
|
||||
);
|
||||
|
||||
if( !SystemInfo.isMacOS ) {
|
||||
modifyInputMap( defaults, "FileChooser.ancestorInputMap",
|
||||
"F2", "editFileName",
|
||||
"BACK_SPACE", "Go Up"
|
||||
);
|
||||
}
|
||||
|
||||
// join ltr and rtl bindings to fix up/down/etc keys in right-to-left component orientation
|
||||
Object[] bindings = (Object[]) defaults.get( "PopupMenu.selectedWindowInputMapBindings" );
|
||||
Object[] rtlBindings = (Object[]) defaults.get( "PopupMenu.selectedWindowInputMapBindings.RightToLeft" );
|
||||
if( bindings != null && rtlBindings != null ) {
|
||||
Object[] newBindings = new Object[bindings.length + rtlBindings.length];
|
||||
System.arraycopy( bindings, 0, newBindings, 0, bindings.length );
|
||||
System.arraycopy( rtlBindings, 0, newBindings, bindings.length, rtlBindings.length );
|
||||
defaults.put( "PopupMenu.selectedWindowInputMapBindings.RightToLeft", newBindings );
|
||||
}
|
||||
|
||||
modifyInputMap( defaults, "TabbedPane.ancestorInputMap",
|
||||
"ctrl TAB", "navigateNext",
|
||||
"shift ctrl TAB", "navigatePrevious"
|
||||
);
|
||||
|
||||
// swap Home/End with Ctrl+Home/End to make it consistent with List and Tree
|
||||
modifyInputMap( () -> {
|
||||
return UIManager.getBoolean( "Table.consistentHomeEndKeyBehavior" );
|
||||
},
|
||||
defaults, "Table.ancestorInputMap",
|
||||
"HOME", "selectFirstRow",
|
||||
"END", "selectLastRow",
|
||||
"shift HOME", "selectFirstRowExtendSelection",
|
||||
"shift END", "selectLastRowExtendSelection",
|
||||
mac( "ctrl HOME", null ), "selectFirstColumn",
|
||||
mac( "ctrl END", null ), "selectLastColumn",
|
||||
mac( "shift ctrl HOME", null ), "selectFirstColumnExtendSelection",
|
||||
mac( "shift ctrl END", null ), "selectLastColumnExtendSelection"
|
||||
);
|
||||
|
||||
if( !SystemInfo.isMacOS ) {
|
||||
modifyInputMap( defaults, "Tree.focusInputMap",
|
||||
"ADD", "expand",
|
||||
"SUBTRACT", "collapse"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initTextComponentInputMaps( UIDefaults defaults ) {
|
||||
Object[] commonTextComponentBindings = {
|
||||
// move caret one character (without selecting text)
|
||||
"LEFT", backwardAction,
|
||||
"RIGHT", forwardAction,
|
||||
"KP_LEFT", backwardAction,
|
||||
"KP_RIGHT", forwardAction,
|
||||
|
||||
// move caret one character and select text
|
||||
"shift LEFT", selectionBackwardAction,
|
||||
"shift RIGHT", selectionForwardAction,
|
||||
"shift KP_LEFT", selectionBackwardAction,
|
||||
"shift KP_RIGHT", selectionForwardAction,
|
||||
|
||||
// move caret to word (without selecting text)
|
||||
mac( "ctrl LEFT", "alt LEFT" ), previousWordAction,
|
||||
mac( "ctrl RIGHT", "alt RIGHT" ), nextWordAction,
|
||||
mac( "ctrl KP_LEFT", "alt KP_LEFT" ), previousWordAction,
|
||||
mac( "ctrl KP_RIGHT", "alt KP_RIGHT" ), nextWordAction,
|
||||
|
||||
// move caret to word and select text
|
||||
mac( "ctrl shift LEFT", "shift alt LEFT" ), selectionPreviousWordAction,
|
||||
mac( "ctrl shift RIGHT", "shift alt RIGHT" ), selectionNextWordAction,
|
||||
mac( "ctrl shift KP_LEFT", "shift alt KP_LEFT" ), selectionPreviousWordAction,
|
||||
mac( "ctrl shift KP_RIGHT", "shift alt KP_RIGHT" ), selectionNextWordAction,
|
||||
|
||||
// move caret to line begin/end (without selecting text)
|
||||
mac( "HOME", "meta LEFT" ), beginLineAction,
|
||||
mac( "END", "meta RIGHT" ), endLineAction,
|
||||
|
||||
// move caret to line begin/end and select text
|
||||
mac( "shift HOME", "shift meta LEFT" ), selectionBeginLineAction,
|
||||
mac( "shift END", "shift meta RIGHT" ), selectionEndLineAction,
|
||||
|
||||
// select all/none
|
||||
mac( "ctrl A", "meta A" ), selectAllAction,
|
||||
mac( "ctrl BACK_SLASH", "meta BACK_SLASH" ), "unselect", // DefaultEditorKit.unselectAction
|
||||
|
||||
// delete previous/next character
|
||||
"BACK_SPACE", deletePrevCharAction,
|
||||
"shift BACK_SPACE", deletePrevCharAction,
|
||||
"ctrl H", deletePrevCharAction,
|
||||
"DELETE", deleteNextCharAction,
|
||||
|
||||
// delete previous/next word
|
||||
mac( "ctrl BACK_SPACE", "alt BACK_SPACE" ), deletePrevWordAction,
|
||||
mac( "ctrl DELETE", "alt DELETE" ), deleteNextWordAction,
|
||||
|
||||
// clipboard
|
||||
mac( "ctrl X", "meta X" ), cutAction,
|
||||
mac( "ctrl C", "meta C" ), copyAction,
|
||||
mac( "ctrl V", "meta V" ), pasteAction,
|
||||
"CUT", cutAction,
|
||||
"COPY", copyAction,
|
||||
"PASTE", pasteAction,
|
||||
mac( "shift DELETE", null ), cutAction,
|
||||
mac( "control INSERT", null ), copyAction,
|
||||
mac( "shift INSERT", null ), pasteAction,
|
||||
|
||||
// misc
|
||||
"control shift O", "toggle-componentOrientation", // DefaultEditorKit.toggleComponentOrientation
|
||||
};
|
||||
|
||||
Object[] macCommonTextComponentBindings = SystemInfo.isMacOS ? new Object[] {
|
||||
// move caret one character (without selecting text)
|
||||
"ctrl B", backwardAction,
|
||||
"ctrl F", forwardAction,
|
||||
|
||||
// move caret to document begin/end (without selecting text)
|
||||
"HOME", beginAction,
|
||||
"END", endAction,
|
||||
"meta UP", beginAction,
|
||||
"meta DOWN", endAction,
|
||||
"meta KP_UP", beginAction,
|
||||
"meta KP_DOWN", endAction,
|
||||
"ctrl P", beginAction,
|
||||
"ctrl N", endAction,
|
||||
"ctrl V", endAction,
|
||||
|
||||
// move caret to line begin/end (without selecting text)
|
||||
"meta KP_LEFT", beginLineAction,
|
||||
"meta KP_RIGHT", endLineAction,
|
||||
"ctrl A", beginLineAction,
|
||||
"ctrl E", endLineAction,
|
||||
|
||||
// move caret to document begin/end and select text
|
||||
"shift meta UP", selectionBeginAction,
|
||||
"shift meta DOWN", selectionEndAction,
|
||||
"shift meta KP_UP", selectionBeginAction,
|
||||
"shift meta KP_DOWN", selectionEndAction,
|
||||
"shift HOME", selectionBeginAction,
|
||||
"shift END", selectionEndAction,
|
||||
|
||||
// move caret to line begin/end and select text
|
||||
"shift meta KP_LEFT", selectionBeginLineAction,
|
||||
"shift meta KP_RIGHT", selectionEndLineAction,
|
||||
"shift UP", selectionBeginLineAction,
|
||||
"shift DOWN", selectionEndLineAction,
|
||||
"shift KP_UP", selectionBeginLineAction,
|
||||
"shift KP_DOWN", selectionEndLineAction,
|
||||
|
||||
// delete previous/next word
|
||||
"ctrl W", deletePrevWordAction,
|
||||
"ctrl D", deleteNextCharAction,
|
||||
} : null;
|
||||
|
||||
Object[] singleLineTextComponentBindings = {
|
||||
"ENTER", JTextField.notifyAction,
|
||||
};
|
||||
|
||||
Object[] macSingleLineTextComponentBindings = SystemInfo.isMacOS ? new Object[] {
|
||||
// move caret to line begin/end (without selecting text)
|
||||
"UP", beginLineAction,
|
||||
"DOWN", endLineAction,
|
||||
"KP_UP", beginLineAction,
|
||||
"KP_DOWN", endLineAction,
|
||||
} : null;
|
||||
|
||||
Object[] formattedTextComponentBindings = {
|
||||
// reset
|
||||
"ESCAPE", "reset-field-edit",
|
||||
|
||||
// increment/decrement
|
||||
"UP", "increment",
|
||||
"DOWN", "decrement",
|
||||
"KP_UP", "increment",
|
||||
"KP_DOWN", "decrement",
|
||||
};
|
||||
|
||||
Object[] passwordTextComponentBindings = {
|
||||
// move caret to line begin/end (without selecting text)
|
||||
mac( "ctrl LEFT", "alt LEFT" ), beginLineAction,
|
||||
mac( "ctrl RIGHT", "alt RIGHT" ), endLineAction,
|
||||
mac( "ctrl KP_LEFT", "alt KP_LEFT" ), beginLineAction,
|
||||
mac( "ctrl KP_RIGHT", "alt KP_RIGHT" ), endLineAction,
|
||||
|
||||
// move caret to line begin/end and select text
|
||||
mac( "ctrl shift LEFT", "shift alt LEFT" ), selectionBeginLineAction,
|
||||
mac( "ctrl shift RIGHT", "shift alt RIGHT" ), selectionEndLineAction,
|
||||
mac( "ctrl shift KP_LEFT", "shift alt KP_LEFT" ), selectionBeginLineAction,
|
||||
mac( "ctrl shift KP_RIGHT", "shift alt KP_RIGHT" ), selectionEndLineAction,
|
||||
|
||||
// delete previous/next word
|
||||
mac( "ctrl BACK_SPACE", "alt BACK_SPACE" ), null,
|
||||
mac( "ctrl DELETE", "alt DELETE" ), null,
|
||||
};
|
||||
|
||||
Object[] multiLineTextComponentBindings = {
|
||||
// move caret one line (without selecting text)
|
||||
"UP", upAction,
|
||||
"DOWN", downAction,
|
||||
"KP_UP", upAction,
|
||||
"KP_DOWN", downAction,
|
||||
|
||||
// move caret one line and select text
|
||||
"shift UP", selectionUpAction,
|
||||
"shift DOWN", selectionDownAction,
|
||||
"shift KP_UP", selectionUpAction,
|
||||
"shift KP_DOWN", selectionDownAction,
|
||||
|
||||
// move caret one page (without selecting text)
|
||||
"PAGE_UP", pageUpAction,
|
||||
"PAGE_DOWN", pageDownAction,
|
||||
|
||||
// move caret one page and select text
|
||||
"shift PAGE_UP", "selection-page-up", // DefaultEditorKit.selectionPageUpAction
|
||||
"shift PAGE_DOWN", "selection-page-down", // DefaultEditorKit.selectionPageDownAction
|
||||
mac( "ctrl shift PAGE_UP", "shift meta PAGE_UP" ), "selection-page-left", // DefaultEditorKit.selectionPageLeftAction
|
||||
mac( "ctrl shift PAGE_DOWN", "shift meta PAGE_DOWN" ), "selection-page-right", // DefaultEditorKit.selectionPageRightAction
|
||||
|
||||
// move caret to document begin/end (without selecting text)
|
||||
mac( "ctrl HOME", "meta UP" ), beginAction,
|
||||
mac( "ctrl END", "meta DOWN" ), endAction,
|
||||
|
||||
// move caret to document begin/end and select text
|
||||
mac( "ctrl shift HOME", "shift meta UP" ), selectionBeginAction,
|
||||
mac( "ctrl shift END", "shift meta DOWN" ), selectionEndAction,
|
||||
|
||||
// misc
|
||||
"ENTER", insertBreakAction,
|
||||
"TAB", insertTabAction,
|
||||
|
||||
// links
|
||||
mac( "ctrl T", "meta T" ), "next-link-action",
|
||||
mac( "ctrl shift T", "shift meta T" ), "previous-link-action",
|
||||
mac( "ctrl SPACE", "meta SPACE" ), "activate-link-action",
|
||||
};
|
||||
|
||||
Object[] macMultiLineTextComponentBindings = SystemInfo.isMacOS ? new Object[] {
|
||||
// move caret one line (without selecting text)
|
||||
"ctrl N", downAction,
|
||||
"ctrl P", upAction,
|
||||
|
||||
// move caret to beginning/end of paragraph and select text
|
||||
"shift alt UP", selectionBeginParagraphAction,
|
||||
"shift alt DOWN", selectionEndParagraphAction,
|
||||
"shift alt KP_UP", selectionBeginParagraphAction,
|
||||
"shift alt KP_DOWN", selectionEndParagraphAction,
|
||||
|
||||
// move caret one page (without selecting text)
|
||||
"ctrl V", pageDownAction,
|
||||
} : null;
|
||||
|
||||
defaults.put( "TextField.focusInputMap", new LazyInputMapEx(
|
||||
commonTextComponentBindings,
|
||||
macCommonTextComponentBindings,
|
||||
singleLineTextComponentBindings,
|
||||
macSingleLineTextComponentBindings
|
||||
) );
|
||||
defaults.put( "FormattedTextField.focusInputMap", new LazyInputMapEx(
|
||||
commonTextComponentBindings,
|
||||
macCommonTextComponentBindings,
|
||||
singleLineTextComponentBindings,
|
||||
macSingleLineTextComponentBindings,
|
||||
formattedTextComponentBindings
|
||||
) );
|
||||
defaults.put( "PasswordField.focusInputMap", new LazyInputMapEx(
|
||||
commonTextComponentBindings,
|
||||
macCommonTextComponentBindings,
|
||||
singleLineTextComponentBindings,
|
||||
macSingleLineTextComponentBindings,
|
||||
passwordTextComponentBindings
|
||||
) );
|
||||
|
||||
Object multiLineInputMap = new LazyInputMapEx(
|
||||
commonTextComponentBindings,
|
||||
macCommonTextComponentBindings,
|
||||
multiLineTextComponentBindings,
|
||||
macMultiLineTextComponentBindings
|
||||
);
|
||||
defaults.put( "TextArea.focusInputMap", multiLineInputMap );
|
||||
defaults.put( "TextPane.focusInputMap", multiLineInputMap );
|
||||
defaults.put( "EditorPane.focusInputMap", multiLineInputMap );
|
||||
}
|
||||
|
||||
private static void initMacInputMaps( UIDefaults defaults ) {
|
||||
// list
|
||||
modifyInputMap( defaults, "List.focusInputMap",
|
||||
"meta A", "selectAll",
|
||||
"meta C", "copy",
|
||||
"meta V", "paste",
|
||||
"meta X", "cut",
|
||||
|
||||
// let parent scroll pane do the macOS typical scrolling without changing selection
|
||||
"HOME", null,
|
||||
"END", null,
|
||||
"PAGE_UP", null,
|
||||
"PAGE_DOWN", null,
|
||||
|
||||
"ctrl A", null,
|
||||
"ctrl BACK_SLASH", null,
|
||||
"ctrl C", null,
|
||||
"ctrl DOWN", null,
|
||||
"ctrl END", null,
|
||||
"ctrl HOME", null,
|
||||
"ctrl INSERT", null,
|
||||
"ctrl KP_DOWN", null,
|
||||
"ctrl KP_LEFT", null,
|
||||
"ctrl KP_RIGHT", null,
|
||||
"ctrl KP_UP", null,
|
||||
"ctrl LEFT", null,
|
||||
"ctrl PAGE_DOWN", null,
|
||||
"ctrl PAGE_UP", null,
|
||||
"ctrl RIGHT", null,
|
||||
"ctrl SLASH", null,
|
||||
"ctrl SPACE", null,
|
||||
"ctrl UP", null,
|
||||
"ctrl V", null,
|
||||
"ctrl X", null,
|
||||
"SPACE", null,
|
||||
"shift ctrl DOWN", null,
|
||||
"shift ctrl END", null,
|
||||
"shift ctrl HOME", null,
|
||||
"shift ctrl KP_DOWN", null,
|
||||
"shift ctrl KP_LEFT", null,
|
||||
"shift ctrl KP_RIGHT", null,
|
||||
"shift ctrl KP_UP", null,
|
||||
"shift ctrl LEFT", null,
|
||||
"shift ctrl PAGE_DOWN", null,
|
||||
"shift ctrl PAGE_UP", null,
|
||||
"shift ctrl RIGHT", null,
|
||||
"shift ctrl SPACE", null,
|
||||
"shift ctrl UP", null,
|
||||
"shift DELETE", null,
|
||||
"shift INSERT", null,
|
||||
"shift SPACE", null
|
||||
);
|
||||
modifyInputMap( defaults, "List.focusInputMap.RightToLeft",
|
||||
"ctrl KP_LEFT", null,
|
||||
"ctrl KP_RIGHT", null,
|
||||
"ctrl LEFT", null,
|
||||
"ctrl RIGHT", null,
|
||||
"shift ctrl KP_LEFT", null,
|
||||
"shift ctrl KP_RIGHT", null,
|
||||
"shift ctrl LEFT", null,
|
||||
"shift ctrl RIGHT", null
|
||||
);
|
||||
|
||||
// scrollpane
|
||||
modifyInputMap( defaults, "ScrollPane.ancestorInputMap",
|
||||
"END", "scrollEnd",
|
||||
"HOME", "scrollHome",
|
||||
|
||||
"ctrl END", null,
|
||||
"ctrl HOME", null,
|
||||
"ctrl PAGE_DOWN", null,
|
||||
"ctrl PAGE_UP", null
|
||||
);
|
||||
modifyInputMap( defaults, "ScrollPane.ancestorInputMap.RightToLeft",
|
||||
"ctrl PAGE_DOWN", null,
|
||||
"ctrl PAGE_UP", null
|
||||
);
|
||||
|
||||
// tabbedpane
|
||||
modifyInputMap( defaults, "TabbedPane.ancestorInputMap",
|
||||
"ctrl UP", null,
|
||||
"ctrl KP_UP", null
|
||||
);
|
||||
modifyInputMap( defaults, "TabbedPane.focusInputMap",
|
||||
"ctrl DOWN", null,
|
||||
"ctrl KP_DOWN", null
|
||||
);
|
||||
|
||||
// table
|
||||
modifyInputMap( defaults, "Table.ancestorInputMap",
|
||||
"alt TAB", "focusHeader",
|
||||
"shift alt TAB", "focusHeader",
|
||||
"meta A", "selectAll",
|
||||
"meta C", "copy",
|
||||
"meta V", "paste",
|
||||
"meta X", "cut",
|
||||
|
||||
// let parent scroll pane do the macOS typical scrolling without changing selection
|
||||
"HOME", null,
|
||||
"END", null,
|
||||
"PAGE_UP", null,
|
||||
"PAGE_DOWN", null,
|
||||
|
||||
"ctrl A", null,
|
||||
"ctrl BACK_SLASH", null,
|
||||
"ctrl C", null,
|
||||
"ctrl DOWN", null,
|
||||
"ctrl END", null,
|
||||
"ctrl HOME", null,
|
||||
"ctrl INSERT", null,
|
||||
"ctrl KP_DOWN", null,
|
||||
"ctrl KP_LEFT", null,
|
||||
"ctrl KP_RIGHT", null,
|
||||
"ctrl KP_UP", null,
|
||||
"ctrl LEFT", null,
|
||||
"ctrl PAGE_DOWN", null,
|
||||
"ctrl PAGE_UP", null,
|
||||
"ctrl RIGHT", null,
|
||||
"ctrl SLASH", null,
|
||||
"ctrl SPACE", null,
|
||||
"ctrl UP", null,
|
||||
"ctrl V", null,
|
||||
"ctrl X", null,
|
||||
"F2", null,
|
||||
"F8", null,
|
||||
"SPACE", null,
|
||||
"shift ctrl DOWN", null,
|
||||
"shift ctrl END", null,
|
||||
"shift ctrl HOME", null,
|
||||
"shift ctrl KP_DOWN", null,
|
||||
"shift ctrl KP_LEFT", null,
|
||||
"shift ctrl KP_RIGHT", null,
|
||||
"shift ctrl KP_UP", null,
|
||||
"shift ctrl LEFT", null,
|
||||
"shift ctrl PAGE_DOWN", null,
|
||||
"shift ctrl PAGE_UP", null,
|
||||
"shift ctrl RIGHT", null,
|
||||
"shift ctrl SPACE", null,
|
||||
"shift ctrl UP", null,
|
||||
"shift DELETE", null,
|
||||
"shift INSERT", null,
|
||||
"shift SPACE", null
|
||||
);
|
||||
modifyInputMap( defaults, "Table.ancestorInputMap.RightToLeft",
|
||||
"ctrl KP_LEFT", null,
|
||||
"ctrl KP_RIGHT", null,
|
||||
"ctrl LEFT", null,
|
||||
"ctrl RIGHT", null,
|
||||
"shift ctrl KP_LEFT", null,
|
||||
"shift ctrl KP_RIGHT", null,
|
||||
"shift ctrl LEFT", null,
|
||||
"shift ctrl RIGHT", null
|
||||
);
|
||||
|
||||
// tree node expanding/collapsing
|
||||
modifyInputMap( defaults, "Tree.focusInputMap",
|
||||
"LEFT", "selectParent",
|
||||
"RIGHT", "selectChild",
|
||||
"KP_LEFT", "selectParent",
|
||||
"KP_RIGHT", "selectChild",
|
||||
"shift LEFT", "selectParent",
|
||||
"shift RIGHT", "selectChild",
|
||||
"shift KP_LEFT", "selectParent",
|
||||
"shift KP_RIGHT", "selectChild",
|
||||
"alt LEFT", "selectParent",
|
||||
"alt RIGHT", "selectChild",
|
||||
"alt KP_LEFT", "selectParent",
|
||||
"alt KP_RIGHT", "selectChild",
|
||||
|
||||
"shift HOME", "selectFirstExtendSelection",
|
||||
"shift END", "selectLastExtendSelection",
|
||||
|
||||
"meta A", "selectAll",
|
||||
"meta C", "copy",
|
||||
"meta V", "paste",
|
||||
"meta X", "cut",
|
||||
|
||||
// let parent scroll pane do the macOS typical scrolling without changing selection
|
||||
"HOME", null,
|
||||
"END", null,
|
||||
"PAGE_UP", null,
|
||||
"PAGE_DOWN", null,
|
||||
|
||||
"ctrl LEFT", null,
|
||||
"ctrl RIGHT", null,
|
||||
"ctrl KP_LEFT", null,
|
||||
"ctrl KP_RIGHT", null,
|
||||
|
||||
"ctrl A", null,
|
||||
"ctrl BACK_SLASH", null,
|
||||
"ctrl C", null,
|
||||
"ctrl DOWN", null,
|
||||
"ctrl END", null,
|
||||
"ctrl HOME", null,
|
||||
"ctrl INSERT", null,
|
||||
"ctrl KP_DOWN", null,
|
||||
"ctrl KP_UP", null,
|
||||
"ctrl PAGE_DOWN", null,
|
||||
"ctrl PAGE_UP", null,
|
||||
"ctrl SLASH", null,
|
||||
"ctrl SPACE", null,
|
||||
"ctrl UP", null,
|
||||
"ctrl V", null,
|
||||
"ctrl X", null,
|
||||
"F2", null,
|
||||
"SPACE", null,
|
||||
"shift ctrl DOWN", null,
|
||||
"shift ctrl END", null,
|
||||
"shift ctrl HOME", null,
|
||||
"shift ctrl KP_DOWN", null,
|
||||
"shift ctrl KP_UP", null,
|
||||
"shift ctrl PAGE_DOWN", null,
|
||||
"shift ctrl PAGE_UP", null,
|
||||
"shift ctrl SPACE", null,
|
||||
"shift ctrl UP", null,
|
||||
"shift DELETE", null,
|
||||
"shift INSERT", null,
|
||||
"shift PAGE_DOWN", null,
|
||||
"shift PAGE_UP", null,
|
||||
"shift SPACE", null
|
||||
);
|
||||
defaults.put( "Tree.focusInputMap.RightToLeft", new UIDefaults.LazyInputMap( new Object[] {
|
||||
"LEFT", "selectChild",
|
||||
"RIGHT", "selectParent",
|
||||
"KP_LEFT", "selectChild",
|
||||
"KP_RIGHT", "selectParent",
|
||||
"shift LEFT", "selectChild",
|
||||
"shift RIGHT", "selectParent",
|
||||
"shift KP_LEFT", "selectChild",
|
||||
"shift KP_RIGHT", "selectParent",
|
||||
"alt LEFT", "selectChild",
|
||||
"alt RIGHT", "selectParent",
|
||||
"alt KP_LEFT", "selectChild",
|
||||
"alt KP_RIGHT", "selectParent"
|
||||
} ) );
|
||||
}
|
||||
|
||||
private static void modifyInputMap( UIDefaults defaults, String key, Object... bindings ) {
|
||||
modifyInputMap( null, defaults, key, bindings );
|
||||
}
|
||||
|
||||
private static void modifyInputMap( BooleanSupplier condition, UIDefaults defaults, String key, Object... bindings ) {
|
||||
// Note: not using `defaults.get(key)` here because this would resolve a lazy value
|
||||
defaults.put( key, new LazyModifyInputMap( condition, defaults.remove( key ), bindings ) );
|
||||
}
|
||||
|
||||
private static <T> T mac( T value, T macValue ) {
|
||||
return SystemInfo.isMacOS ? macValue : value;
|
||||
}
|
||||
|
||||
//---- class LazyInputMapEx -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Lazily creates a input map.
|
||||
* Similar to {@link UIDefaults.LazyInputMap}, but can use multiple bindings arrays.
|
||||
*/
|
||||
private static class LazyInputMapEx
|
||||
implements LazyValue
|
||||
{
|
||||
private final Object[][] bindingsArray;
|
||||
|
||||
LazyInputMapEx( Object[]... bindingsArray ) {
|
||||
this.bindingsArray = bindingsArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createValue( UIDefaults table ) {
|
||||
InputMap inputMap = new InputMapUIResource();
|
||||
for( Object[] bindings : bindingsArray )
|
||||
LookAndFeel.loadKeyBindings( inputMap, bindings );
|
||||
return inputMap;
|
||||
}
|
||||
}
|
||||
|
||||
//---- class LazyModifyInputMap -------------------------------------------
|
||||
|
||||
/**
|
||||
* Takes a (lazy) base input map and lazily applies modifications to it specified in bindings.
|
||||
*/
|
||||
private static class LazyModifyInputMap
|
||||
implements LazyValue
|
||||
{
|
||||
private final BooleanSupplier condition;
|
||||
private final Object baseInputMap;
|
||||
private final Object[] bindings;
|
||||
|
||||
LazyModifyInputMap( BooleanSupplier condition, Object baseInputMap, Object[] bindings ) {
|
||||
this.condition = condition;
|
||||
this.baseInputMap = baseInputMap;
|
||||
this.bindings = bindings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createValue( UIDefaults table ) {
|
||||
// get base input map
|
||||
InputMap inputMap = (baseInputMap instanceof LazyValue)
|
||||
? (InputMap) ((LazyValue)baseInputMap).createValue( table )
|
||||
: (InputMap) baseInputMap;
|
||||
|
||||
if( condition != null && !condition.getAsBoolean() )
|
||||
return inputMap;
|
||||
|
||||
// modify input map (replace or remove)
|
||||
for( int i = 0; i < bindings.length; i += 2 ) {
|
||||
KeyStroke keyStroke = KeyStroke.getKeyStroke( (String) bindings[i] );
|
||||
if( bindings[i + 1] != null )
|
||||
inputMap.put( keyStroke, bindings[i + 1] );
|
||||
else
|
||||
inputMap.remove( keyStroke );
|
||||
}
|
||||
|
||||
return inputMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,21 +16,54 @@
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* A Flat LaF that has a light color scheme and looks like IntelliJ LaF.
|
||||
* <p>
|
||||
* The UI defaults are loaded from {@code FlatIntelliJLaf.properties},
|
||||
* {@code FlatLightLaf.properties} and {@code FlatLaf.properties}.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatIntelliJLaf
|
||||
extends FlatLightLaf
|
||||
{
|
||||
public static final String NAME = "FlatLaf IntelliJ";
|
||||
|
||||
/**
|
||||
* Sets the application look and feel to this LaF
|
||||
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||
*/
|
||||
public static boolean setup() {
|
||||
return setup( new FlatIntelliJLaf() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #setup()} instead; this method will be removed in a future version
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean install() {
|
||||
return setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds this look and feel to the set of available look and feels.
|
||||
* <p>
|
||||
* Useful if your application uses {@link UIManager#getInstalledLookAndFeels()}
|
||||
* to query available LaFs and display them to the user in a combobox.
|
||||
*/
|
||||
public static void installLafInfo() {
|
||||
installLafInfo( NAME, FlatIntelliJLaf.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Flat IntelliJ";
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Flat IntelliJ Look and Feel";
|
||||
return "FlatLaf IntelliJ Look and Feel";
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,21 +16,58 @@
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* A Flat LaF that has a light color scheme.
|
||||
* <p>
|
||||
* The UI defaults are loaded from {@code FlatLightLaf.properties} and {@code FlatLaf.properties}.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatLightLaf
|
||||
extends FlatLaf
|
||||
{
|
||||
public static final String NAME = "FlatLaf Light";
|
||||
|
||||
/**
|
||||
* Sets the application look and feel to this LaF
|
||||
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||
*/
|
||||
public static boolean setup() {
|
||||
return setup( new FlatLightLaf() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #setup()} instead; this method will be removed in a future version
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean install() {
|
||||
return setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds this look and feel to the set of available look and feels.
|
||||
* <p>
|
||||
* Useful if your application uses {@link UIManager#getInstalledLookAndFeels()}
|
||||
* to query available LaFs and display them to the user in a combobox.
|
||||
*/
|
||||
public static void installLafInfo() {
|
||||
installLafInfo( NAME, FlatLightLaf.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Flat Light";
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Flat Light Look and Feel";
|
||||
return "FlatLaf Light Look and Feel";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDark() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* A Flat LaF that is able to load UI defaults from properties passed to the constructor.
|
||||
* <p>
|
||||
* Specify the base theme in the properties with {@code @baseTheme=<baseTheme>}.
|
||||
* Allowed values for {@code <baseTheme>} are {@code light} (the default), {@code dark},
|
||||
* {@code intellij} or {@code darcula}.
|
||||
* <p>
|
||||
* The properties are applied after loading the base theme and may overwrite base properties.
|
||||
* All features of FlatLaf properties files are available.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatPropertiesLaf
|
||||
extends FlatLaf
|
||||
{
|
||||
private final String name;
|
||||
private final String baseTheme;
|
||||
private final boolean dark;
|
||||
private final Properties properties;
|
||||
|
||||
public FlatPropertiesLaf( String name, File propertiesFile )
|
||||
throws IOException
|
||||
{
|
||||
this( name, new FileInputStream( propertiesFile ) );
|
||||
}
|
||||
|
||||
public FlatPropertiesLaf( String name, InputStream in )
|
||||
throws IOException
|
||||
{
|
||||
this( name, loadProperties( in ) );
|
||||
}
|
||||
|
||||
private static Properties loadProperties( InputStream in )
|
||||
throws IOException
|
||||
{
|
||||
Properties properties = new Properties();
|
||||
try( InputStream in2 = in ) {
|
||||
properties.load( in2 );
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
public FlatPropertiesLaf( String name, Properties properties ) {
|
||||
this.name = name;
|
||||
this.properties = properties;
|
||||
|
||||
baseTheme = properties.getProperty( "@baseTheme", "light" );
|
||||
dark = "dark".equalsIgnoreCase( baseTheme ) || "darcula".equalsIgnoreCase( baseTheme );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDark() {
|
||||
return dark;
|
||||
}
|
||||
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArrayList<Class<?>> getLafClassesForDefaultsLoading() {
|
||||
ArrayList<Class<?>> lafClasses = new ArrayList<>();
|
||||
lafClasses.add( FlatLaf.class );
|
||||
switch( baseTheme.toLowerCase() ) {
|
||||
default:
|
||||
case "light":
|
||||
lafClasses.add( FlatLightLaf.class );
|
||||
break;
|
||||
|
||||
case "dark":
|
||||
lafClasses.add( FlatDarkLaf.class );
|
||||
break;
|
||||
|
||||
case "intellij":
|
||||
lafClasses.add( FlatLightLaf.class );
|
||||
lafClasses.add( FlatIntelliJLaf.class );
|
||||
break;
|
||||
|
||||
case "darcula":
|
||||
lafClasses.add( FlatDarkLaf.class );
|
||||
lafClasses.add( FlatDarculaLaf.class );
|
||||
break;
|
||||
}
|
||||
return lafClasses;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Properties getAdditionalDefaults() {
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Defines/documents own system properties used in FlatLaf.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public interface FlatSystemProperties
|
||||
{
|
||||
/**
|
||||
* Specifies a custom scale factor used to scale the UI.
|
||||
* <p>
|
||||
* If Java runtime scales (Java 9 or later), this scale factor is applied on top
|
||||
* of the Java system scale factor. Java 8 does not scale and this scale factor
|
||||
* replaces the user scale factor that FlatLaf computes based on the font.
|
||||
* To replace the Java 9+ system scale factor, use system property "sun.java2d.uiScale",
|
||||
* which has the same syntax as this one.
|
||||
* <p>
|
||||
* Since FlatLaf 1.1.2: Scale factors less then 100% are allowed.
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> e.g. {@code 1.5}, {@code 1.5x}, {@code 150%} or {@code 144dpi} (96dpi is 100%)<br>
|
||||
*/
|
||||
String UI_SCALE = "flatlaf.uiScale";
|
||||
|
||||
/**
|
||||
* Specifies whether user scaling mode is enabled.
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> {@code true}
|
||||
*/
|
||||
String UI_SCALE_ENABLED = "flatlaf.uiScale.enabled";
|
||||
|
||||
/**
|
||||
* Specifies whether values smaller than 100% are allowed for the user scale factor
|
||||
* (see {@link UIScale#getUserScaleFactor()}).
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> {@code false}
|
||||
*
|
||||
* @since 1.1.2
|
||||
*/
|
||||
String UI_SCALE_ALLOW_SCALE_DOWN = "flatlaf.uiScale.allowScaleDown";
|
||||
|
||||
/**
|
||||
* Specifies whether Ubuntu font should be used on Ubuntu Linux.
|
||||
* By default, if not running in a JetBrains Runtime, the Liberation Sans font
|
||||
* is used because there are rendering issues (in Java) with Ubuntu fonts.
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> {@code false}
|
||||
*/
|
||||
String USE_UBUNTU_FONT = "flatlaf.useUbuntuFont";
|
||||
|
||||
/**
|
||||
* Specifies whether native window decorations should be used
|
||||
* when creating {@code JFrame} or {@code JDialog}.
|
||||
* <p>
|
||||
* Setting this to {@code true} forces using native window decorations
|
||||
* even if they are not enabled by the application.<br>
|
||||
* Setting this to {@code false} disables using native window decorations.
|
||||
* <p>
|
||||
* This system property has higher priority than client property
|
||||
* {@link FlatClientProperties#USE_WINDOW_DECORATIONS} and
|
||||
* UI default {@code TitlePane.useWindowDecorations}.
|
||||
* <p>
|
||||
* (requires Window 10/11)
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> none
|
||||
*/
|
||||
String USE_WINDOW_DECORATIONS = "flatlaf.useWindowDecorations";
|
||||
|
||||
/**
|
||||
* Specifies whether JetBrains Runtime custom window decorations should be used
|
||||
* when creating {@code JFrame} or {@code JDialog}.
|
||||
* Requires that the application runs in a
|
||||
* <a href="https://github.com/JetBrains/JetBrainsRuntime/wiki">JetBrains Runtime</a>
|
||||
* (based on OpenJDK).
|
||||
* <p>
|
||||
* Setting this to {@code false} disables using JetBrains Runtime custom window decorations.
|
||||
* Then FlatLaf native window decorations are used.
|
||||
* <p>
|
||||
* (requires Window 10/11)
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> {@code false} (since v2; was {@code true} in v1)
|
||||
*/
|
||||
String USE_JETBRAINS_CUSTOM_DECORATIONS = "flatlaf.useJetBrainsCustomDecorations";
|
||||
|
||||
/**
|
||||
* Specifies whether the menu bar is embedded into the window title pane
|
||||
* if window decorations are enabled.
|
||||
* <p>
|
||||
* Setting this to {@code true} forces embedding.<br>
|
||||
* Setting this to {@code false} disables embedding.
|
||||
* <p>
|
||||
* This system property has higher priority than client property
|
||||
* {@link FlatClientProperties#MENU_BAR_EMBEDDED} and
|
||||
* UI default {@code TitlePane.menuBarEmbedded}.
|
||||
* <p>
|
||||
* (requires Window 10/11)
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> none
|
||||
*/
|
||||
String MENUBAR_EMBEDDED = "flatlaf.menuBarEmbedded";
|
||||
|
||||
/**
|
||||
* Specifies whether animations are enabled.
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> {@code true}
|
||||
*/
|
||||
String ANIMATION = "flatlaf.animation";
|
||||
|
||||
/**
|
||||
* Specifies whether vertical text position is corrected when UI is scaled on HiDPI screens.
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> {@code true}
|
||||
*/
|
||||
String USE_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection";
|
||||
|
||||
/**
|
||||
* Specifies a directory in which the native FlatLaf library have been extracted.
|
||||
* The path can be absolute or relative to current application working directory.
|
||||
* This can be used to avoid extraction of the native libraries to the temporary directory at runtime.
|
||||
*
|
||||
* @since 2
|
||||
*/
|
||||
String NATIVE_LIBRARY_PATH = "flatlaf.nativeLibraryPath";
|
||||
|
||||
/**
|
||||
* Checks whether a system property is set and returns {@code true} if its value
|
||||
* is {@code "true"} (case-insensitive), otherwise it returns {@code false}.
|
||||
* If the system property is not set, {@code defaultValue} is returned.
|
||||
*/
|
||||
static boolean getBoolean( String key, boolean defaultValue ) {
|
||||
String value = System.getProperty( key );
|
||||
return (value != null) ? Boolean.parseBoolean( value ) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a system property is set and returns {@code Boolean.TRUE} if its value
|
||||
* is {@code "true"} (case-insensitive) or returns {@code Boolean.FALSE} if its value
|
||||
* is {@code "false"} (case-insensitive). Otherwise {@code defaultValue} is returned.
|
||||
*/
|
||||
static Boolean getBooleanStrict( String key, Boolean defaultValue ) {
|
||||
String value = System.getProperty( key );
|
||||
if( "true".equalsIgnoreCase( value ) )
|
||||
return Boolean.TRUE;
|
||||
if( "false".equalsIgnoreCase( value ) )
|
||||
return Boolean.FALSE;
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,683 @@
|
||||
/*
|
||||
* Copyright 2019 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.plaf.ColorUIResource;
|
||||
import com.formdev.flatlaf.json.Json;
|
||||
import com.formdev.flatlaf.json.ParseException;
|
||||
import com.formdev.flatlaf.util.ColorFunctions;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
|
||||
/**
|
||||
* This class supports loading IntelliJ .theme.json files and using them as a Laf.
|
||||
*
|
||||
* .theme.json files are used by Theme plugins for IntelliJ IDEA and other
|
||||
* JetBrains IDEs that are based on IntelliJ platform.
|
||||
*
|
||||
* Here you can find IntelliJ Theme plugins:
|
||||
* https://plugins.jetbrains.com/search?tags=Theme
|
||||
*
|
||||
* The IntelliJ .theme.json file are documented here:
|
||||
* http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class IntelliJTheme
|
||||
{
|
||||
public final String name;
|
||||
public final boolean dark;
|
||||
public final String author;
|
||||
|
||||
private final boolean isMaterialUILite;
|
||||
|
||||
private final Map<String, String> colors;
|
||||
private final Map<String, Object> ui;
|
||||
private final Map<String, Object> icons;
|
||||
|
||||
private Map<String, ColorUIResource> namedColors = Collections.emptyMap();
|
||||
|
||||
/**
|
||||
* Loads a IntelliJ .theme.json file from the given input stream,
|
||||
* creates a Laf instance for it and sets it up.
|
||||
*
|
||||
* The input stream is automatically closed.
|
||||
* Using a buffered input stream is not necessary.
|
||||
*/
|
||||
public static boolean setup( InputStream in ) {
|
||||
try {
|
||||
return FlatLaf.setup( createLaf( in ) );
|
||||
} catch( Exception ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load IntelliJ theme", ex );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #setup(InputStream)} instead; this method will be removed in a future version
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean install( InputStream in ) {
|
||||
return setup( in );
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a IntelliJ .theme.json file from the given input stream and
|
||||
* creates a Laf instance for it.
|
||||
*
|
||||
* The input stream is automatically closed.
|
||||
* Using a buffered input stream is not necessary.
|
||||
*/
|
||||
public static FlatLaf createLaf( InputStream in )
|
||||
throws IOException
|
||||
{
|
||||
return createLaf( new IntelliJTheme( in ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Laf instance for the given IntelliJ theme.
|
||||
*/
|
||||
public static FlatLaf createLaf( IntelliJTheme theme ) {
|
||||
return new ThemeLaf( theme );
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a IntelliJ .theme.json file from the given input stream.
|
||||
*
|
||||
* The input stream is automatically closed.
|
||||
* Using a buffered input stream is not necessary.
|
||||
*/
|
||||
@SuppressWarnings( "unchecked" )
|
||||
public IntelliJTheme( InputStream in )
|
||||
throws IOException
|
||||
{
|
||||
Map<String, Object> json;
|
||||
try( Reader reader = new InputStreamReader( in, StandardCharsets.UTF_8 ) ) {
|
||||
json = (Map<String, Object>) Json.parse( reader );
|
||||
} catch( ParseException ex ) {
|
||||
throw new IOException( ex.getMessage(), ex );
|
||||
}
|
||||
|
||||
name = (String) json.get( "name" );
|
||||
dark = Boolean.parseBoolean( (String) json.get( "dark" ) );
|
||||
author = (String) json.get( "author" );
|
||||
|
||||
isMaterialUILite = author.equals( "Mallowigi" );
|
||||
|
||||
colors = (Map<String, String>) json.get( "colors" );
|
||||
ui = (Map<String, Object>) json.get( "ui" );
|
||||
icons = (Map<String, Object>) json.get( "icons" );
|
||||
}
|
||||
|
||||
private void applyProperties( UIDefaults defaults ) {
|
||||
if( ui == null )
|
||||
return;
|
||||
|
||||
defaults.put( "Component.isIntelliJTheme", true );
|
||||
|
||||
// enable button shadows
|
||||
defaults.put( "Button.paintShadow", true );
|
||||
defaults.put( "Button.shadowWidth", dark ? 2 : 1 );
|
||||
|
||||
Map<Object, Object> themeSpecificDefaults = removeThemeSpecificDefaults( defaults );
|
||||
|
||||
loadNamedColors( defaults );
|
||||
|
||||
// convert Json "ui" structure to UI defaults
|
||||
ArrayList<Object> defaultsKeysCache = new ArrayList<>();
|
||||
Set<String> uiKeys = new HashSet<>();
|
||||
for( Map.Entry<String, Object> e : ui.entrySet() )
|
||||
apply( e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
|
||||
|
||||
applyColorPalette( defaults );
|
||||
applyCheckBoxColors( defaults );
|
||||
|
||||
// copy values
|
||||
for( Map.Entry<String, String> e : uiKeyCopying.entrySet() )
|
||||
defaults.put( e.getKey(), defaults.get( e.getValue() ) );
|
||||
|
||||
// IDEA does not paint button background if disabled, but FlatLaf does
|
||||
Object panelBackground = defaults.get( "Panel.background" );
|
||||
defaults.put( "Button.disabledBackground", panelBackground );
|
||||
defaults.put( "ToggleButton.disabledBackground", panelBackground );
|
||||
|
||||
// fix Button borders
|
||||
copyIfNotSet( defaults, "Button.focusedBorderColor", "Component.focusedBorderColor", uiKeys );
|
||||
defaults.put( "Button.hoverBorderColor", defaults.get( "Button.focusedBorderColor" ) );
|
||||
defaults.put( "HelpButton.hoverBorderColor", defaults.get( "Button.focusedBorderColor" ) );
|
||||
|
||||
// IDEA uses a SVG icon for the help button, but paints the background with Button.startBackground and Button.endBackground
|
||||
Object helpButtonBackground = defaults.get( "Button.startBackground" );
|
||||
Object helpButtonBorderColor = defaults.get( "Button.startBorderColor" );
|
||||
if( helpButtonBackground == null )
|
||||
helpButtonBackground = defaults.get( "Button.background" );
|
||||
if( helpButtonBorderColor == null )
|
||||
helpButtonBorderColor = defaults.get( "Button.borderColor" );
|
||||
defaults.put( "HelpButton.background", helpButtonBackground );
|
||||
defaults.put( "HelpButton.borderColor", helpButtonBorderColor );
|
||||
defaults.put( "HelpButton.disabledBackground", panelBackground );
|
||||
defaults.put( "HelpButton.disabledBorderColor", defaults.get( "Button.disabledBorderColor" ) );
|
||||
defaults.put( "HelpButton.focusedBorderColor", defaults.get( "Button.focusedBorderColor" ) );
|
||||
defaults.put( "HelpButton.focusedBackground", defaults.get( "Button.focusedBackground" ) );
|
||||
|
||||
// IDEA uses TextField.background for editable ComboBox and Spinner
|
||||
defaults.put( "ComboBox.editableBackground", defaults.get( "TextField.background" ) );
|
||||
defaults.put( "Spinner.background", defaults.get( "TextField.background" ) );
|
||||
|
||||
// Spinner arrow button always has same colors as ComboBox arrow button
|
||||
defaults.put( "Spinner.buttonBackground", defaults.get( "ComboBox.buttonEditableBackground" ) );
|
||||
defaults.put( "Spinner.buttonArrowColor", defaults.get( "ComboBox.buttonArrowColor" ) );
|
||||
defaults.put( "Spinner.buttonDisabledArrowColor", defaults.get( "ComboBox.buttonDisabledArrowColor" ) );
|
||||
|
||||
// some themes specify colors for TextField.background, but forget to specify it for other components
|
||||
// (probably because those components are not used in IntelliJ)
|
||||
if( uiKeys.contains( "TextField.background" ) ) {
|
||||
Object textFieldBackground = defaults.get( "TextField.background" );
|
||||
if( !uiKeys.contains( "FormattedTextField.background" ) )
|
||||
defaults.put( "FormattedTextField.background", textFieldBackground );
|
||||
if( !uiKeys.contains( "PasswordField.background" ) )
|
||||
defaults.put( "PasswordField.background", textFieldBackground );
|
||||
if( !uiKeys.contains( "EditorPane.background" ) )
|
||||
defaults.put( "EditorPane.background", textFieldBackground );
|
||||
if( !uiKeys.contains( "TextArea.background" ) )
|
||||
defaults.put( "TextArea.background", textFieldBackground );
|
||||
if( !uiKeys.contains( "TextPane.background" ) )
|
||||
defaults.put( "TextPane.background", textFieldBackground );
|
||||
if( !uiKeys.contains( "Spinner.background" ) )
|
||||
defaults.put( "Spinner.background", textFieldBackground );
|
||||
}
|
||||
|
||||
// fix ToggleButton
|
||||
if( !uiKeys.contains( "ToggleButton.startBackground" ) && !uiKeys.contains( "*.startBackground" ) )
|
||||
defaults.put( "ToggleButton.startBackground", defaults.get( "Button.startBackground" ) );
|
||||
if( !uiKeys.contains( "ToggleButton.endBackground" ) && !uiKeys.contains( "*.endBackground" ) )
|
||||
defaults.put( "ToggleButton.endBackground", defaults.get( "Button.endBackground" ) );
|
||||
if( !uiKeys.contains( "ToggleButton.foreground" ) && uiKeys.contains( "Button.foreground" ) )
|
||||
defaults.put( "ToggleButton.foreground", defaults.get( "Button.foreground" ) );
|
||||
|
||||
// fix DesktopPane background (use Panel.background and make it 5% darker/lighter)
|
||||
Color desktopBackgroundBase = defaults.getColor( "Panel.background" );
|
||||
Color desktopBackground = ColorFunctions.applyFunctions( desktopBackgroundBase,
|
||||
new ColorFunctions.HSLIncreaseDecrease( 2, dark, 5, false, true ) );
|
||||
defaults.put( "Desktop.background", new ColorUIResource( desktopBackground ) );
|
||||
|
||||
// fix List and Table background colors in Material UI Lite themes
|
||||
if( isMaterialUILite ) {
|
||||
defaults.put( "List.background", defaults.get( "Tree.background" ) );
|
||||
defaults.put( "Table.background", defaults.get( "Tree.background" ) );
|
||||
}
|
||||
|
||||
// limit tree row height
|
||||
int rowHeight = defaults.getInt( "Tree.rowHeight" );
|
||||
if( rowHeight > 22 )
|
||||
defaults.put( "Tree.rowHeight", 22 );
|
||||
|
||||
// apply theme specific UI defaults at the end to allow overwriting
|
||||
defaults.putAll( themeSpecificDefaults );
|
||||
}
|
||||
|
||||
private Map<Object, Object> removeThemeSpecificDefaults( UIDefaults defaults ) {
|
||||
// search for theme specific UI defaults keys
|
||||
ArrayList<String> themeSpecificKeys = new ArrayList<>();
|
||||
for( Object key : defaults.keySet() ) {
|
||||
if( key instanceof String && ((String)key).startsWith( "[" ) && !((String)key).startsWith( "[style]" ) )
|
||||
themeSpecificKeys.add( (String) key );
|
||||
}
|
||||
|
||||
// remove theme specific UI defaults and remember only those for current theme
|
||||
Map<Object, Object> themeSpecificDefaults = new HashMap<>();
|
||||
String currentThemePrefix = '[' + name.replace( ' ', '_' ) + ']';
|
||||
String currentThemeAndAuthorPrefix = '[' + name.replace( ' ', '_' ) + "---" + author.replace( ' ', '_' ) + ']';
|
||||
String currentAuthorPrefix = "[author-" + author.replace( ' ', '_' ) + ']';
|
||||
String allThemesPrefix = "[*]";
|
||||
String[] prefixes = { currentThemePrefix, currentThemeAndAuthorPrefix, currentAuthorPrefix, allThemesPrefix };
|
||||
for( String key : themeSpecificKeys ) {
|
||||
Object value = defaults.remove( key );
|
||||
for( String prefix : prefixes ) {
|
||||
if( key.startsWith( prefix ) ) {
|
||||
themeSpecificDefaults.put( key.substring( prefix.length() ), value );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return themeSpecificDefaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html#defining-named-colors
|
||||
*/
|
||||
private void loadNamedColors( UIDefaults defaults ) {
|
||||
if( colors == null )
|
||||
return;
|
||||
|
||||
namedColors = new HashMap<>();
|
||||
|
||||
for( Map.Entry<String, String> e : colors.entrySet() ) {
|
||||
String value = e.getValue();
|
||||
ColorUIResource color = UIDefaultsLoader.parseColor( value );
|
||||
if( color != null ) {
|
||||
String key = e.getKey();
|
||||
namedColors.put( key, color );
|
||||
defaults.put( "ColorPalette." + key, color );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html#custom-ui-control-colors
|
||||
*/
|
||||
@SuppressWarnings( "unchecked" )
|
||||
private void apply( String key, Object value, UIDefaults defaults, ArrayList<Object> defaultsKeysCache, Set<String> uiKeys ) {
|
||||
if( value instanceof Map ) {
|
||||
for( Map.Entry<String, Object> e : ((Map<String, Object>)value).entrySet() )
|
||||
apply( key + '.' + e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
|
||||
} else {
|
||||
if( "".equals( value ) )
|
||||
return; // ignore empty value
|
||||
|
||||
uiKeys.add( key );
|
||||
|
||||
// fix ComboBox size and Spinner border in all Material UI Lite themes
|
||||
if( isMaterialUILite && (key.equals( "ComboBox.padding" ) || key.equals( "Spinner.border" )) )
|
||||
return; // ignore
|
||||
|
||||
// map keys
|
||||
key = uiKeyMapping.getOrDefault( key, key );
|
||||
if( key.isEmpty() )
|
||||
return; // ignore key
|
||||
|
||||
String valueStr = value.toString();
|
||||
|
||||
// map named colors
|
||||
Object uiValue = namedColors.get( valueStr );
|
||||
|
||||
// parse value
|
||||
if( uiValue == null ) {
|
||||
// fix errors (missing '#' for colors)
|
||||
if( !valueStr.startsWith( "#" ) && (key.endsWith( "ground" ) || key.endsWith( "Color" )) )
|
||||
valueStr = fixColorIfValid( "#" + valueStr, valueStr );
|
||||
else if( valueStr.startsWith( "##" ) )
|
||||
valueStr = fixColorIfValid( valueStr.substring( 1 ), valueStr );
|
||||
else if( key.endsWith( ".border" ) || key.endsWith( "Border" ) ) {
|
||||
List<String> parts = StringUtils.split( valueStr, ',' );
|
||||
if( parts.size() == 5 && !parts.get( 4 ).startsWith( "#" ) ) {
|
||||
parts.set( 4, "#" + parts.get( 4 ) );
|
||||
valueStr = String.join( ",", parts );
|
||||
}
|
||||
}
|
||||
|
||||
// parse value
|
||||
try {
|
||||
uiValue = UIDefaultsLoader.parseValue( key, valueStr, null );
|
||||
} catch( RuntimeException ex ) {
|
||||
UIDefaultsLoader.logParseError( key, valueStr, ex, false );
|
||||
return; // ignore invalid value
|
||||
}
|
||||
}
|
||||
|
||||
if( key.startsWith( "*." ) ) {
|
||||
// wildcard
|
||||
String tail = key.substring( 1 );
|
||||
|
||||
// because we can not iterate over the UI defaults keys while
|
||||
// modifying UI defaults in the same loop, we have to copy the keys
|
||||
if( defaultsKeysCache.size() != defaults.size() ) {
|
||||
defaultsKeysCache.clear();
|
||||
Enumeration<Object> e = defaults.keys();
|
||||
while( e.hasMoreElements() )
|
||||
defaultsKeysCache.add( e.nextElement() );
|
||||
}
|
||||
|
||||
// replace all values in UI defaults that match the wildcard key
|
||||
for( Object k : defaultsKeysCache ) {
|
||||
if( k.equals( "Desktop.background" ) ||
|
||||
k.equals( "DesktopIcon.background" ) )
|
||||
continue;
|
||||
|
||||
if( k instanceof String ) {
|
||||
// support replacing of mapped keys
|
||||
// (e.g. set ComboBox.buttonEditableBackground to *.background
|
||||
// because it is mapped from ComboBox.ArrowButton.background)
|
||||
String km = uiKeyInverseMapping.getOrDefault( k, (String) k );
|
||||
if( km.endsWith( tail ) && !((String)k).startsWith( "CheckBox.icon." ) )
|
||||
defaults.put( k, uiValue );
|
||||
}
|
||||
}
|
||||
} else
|
||||
defaults.put( key, uiValue );
|
||||
}
|
||||
}
|
||||
|
||||
private String fixColorIfValid( String newColorStr, String colorStr ) {
|
||||
try {
|
||||
// check whether it is valid
|
||||
UIDefaultsLoader.parseColorRGBA( newColorStr );
|
||||
|
||||
return newColorStr;
|
||||
} catch( IllegalArgumentException ex ) {
|
||||
return colorStr;
|
||||
}
|
||||
}
|
||||
|
||||
private void applyColorPalette( UIDefaults defaults ) {
|
||||
if( icons == null )
|
||||
return;
|
||||
|
||||
Object palette = icons.get( "ColorPalette" );
|
||||
if( !(palette instanceof Map) )
|
||||
return;
|
||||
|
||||
@SuppressWarnings( "unchecked" )
|
||||
Map<String, Object> colorPalette = (Map<String, Object>) palette;
|
||||
for( Map.Entry<String, Object> e : colorPalette.entrySet() ) {
|
||||
String key = e.getKey();
|
||||
Object value = e.getValue();
|
||||
if( key.startsWith( "Checkbox." ) || !(value instanceof String) )
|
||||
continue;
|
||||
|
||||
if( dark )
|
||||
key = StringUtils.removeTrailing( key, ".Dark" );
|
||||
|
||||
ColorUIResource color = toColor( (String) value );
|
||||
if( color != null )
|
||||
defaults.put( key, color );
|
||||
}
|
||||
}
|
||||
|
||||
private ColorUIResource toColor( String value ) {
|
||||
// map named colors
|
||||
ColorUIResource color = namedColors.get( value );
|
||||
|
||||
// parse color
|
||||
return (color != null) ? color : UIDefaultsLoader.parseColor( value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Because IDEA uses SVGs for check boxes and radio buttons, the colors for
|
||||
* this two components are specified in "icons > ColorPalette".
|
||||
* FlatLaf uses vector icons and expects colors for the two components in UI defaults.
|
||||
*/
|
||||
private void applyCheckBoxColors( UIDefaults defaults ) {
|
||||
if( icons == null )
|
||||
return;
|
||||
|
||||
Object palette = icons.get( "ColorPalette" );
|
||||
if( !(palette instanceof Map) )
|
||||
return;
|
||||
|
||||
boolean checkboxModified = false;
|
||||
@SuppressWarnings( "unchecked" )
|
||||
Map<String, Object> colorPalette = (Map<String, Object>) palette;
|
||||
for( Map.Entry<String, Object> e : colorPalette.entrySet() ) {
|
||||
String key = e.getKey();
|
||||
Object value = e.getValue();
|
||||
if( !key.startsWith( "Checkbox." ) || !(value instanceof String) )
|
||||
continue;
|
||||
|
||||
if( key.equals( "Checkbox.Background.Default" ) ||
|
||||
key.equals( "Checkbox.Foreground.Selected" ) )
|
||||
{
|
||||
// This two keys do not work correctly in IDEA because they
|
||||
// map SVG color "#ffffff" to another color, but checkBox.svg and
|
||||
// radio.svg (in package com.intellij.ide.ui.laf.icons.intellij)
|
||||
// use "#fff". So use white to get same appearance as in IDEA.
|
||||
value = "#ffffff";
|
||||
}
|
||||
|
||||
String key2 = checkboxDuplicateColors.get( key );
|
||||
|
||||
if( dark )
|
||||
key = StringUtils.removeTrailing( key, ".Dark" );
|
||||
|
||||
String newKey = checkboxKeyMapping.get( key );
|
||||
if( newKey != null ) {
|
||||
String checkBoxIconPrefix = "CheckBox.icon.";
|
||||
if( !dark && newKey.startsWith( checkBoxIconPrefix ) )
|
||||
newKey = "CheckBox.icon[filled].".concat( newKey.substring( checkBoxIconPrefix.length() ) );
|
||||
|
||||
ColorUIResource color = toColor( (String) value );
|
||||
if( color != null ) {
|
||||
defaults.put( newKey, color );
|
||||
|
||||
if( key2 != null ) {
|
||||
// When IDEA replaces colors in SVGs it uses color values and not the keys
|
||||
// from com.intellij.ide.ui.UITheme.colorPalette, but there are some keys that
|
||||
// have same color value:
|
||||
// - Checkbox.Background.Default.Dark has same color as Checkbox.Background.Selected.Dark
|
||||
// - Checkbox.Border.Default.Dark has same color as Checkbox.Border.Selected.Dark
|
||||
// - Checkbox.Focus.Thin.Default.Dark has same color as Checkbox.Focus.Thin.Selected.Dark
|
||||
//
|
||||
// So if only e.g. Checkbox.Background.Default.Dark is specified in .theme.json,
|
||||
// then this color is also used for Checkbox.Background.Selected.Dark.
|
||||
//
|
||||
// If Checkbox.Background.Default.Dark and Checkbox.Background.Selected.Dark
|
||||
// are specified in .theme.json, then the later specified is used for both.
|
||||
if( dark )
|
||||
key2 = StringUtils.removeTrailing( key2, ".Dark" );
|
||||
|
||||
String newKey2 = checkboxKeyMapping.get( key2 );
|
||||
if( newKey2 != null )
|
||||
defaults.put( newKey2, color );
|
||||
}
|
||||
}
|
||||
|
||||
checkboxModified = true;
|
||||
}
|
||||
}
|
||||
|
||||
// update hover, pressed and focused colors
|
||||
if( checkboxModified ) {
|
||||
// for non-filled checkbox/radiobutton used in dark themes
|
||||
defaults.remove( "CheckBox.icon.focusWidth" );
|
||||
defaults.put( "CheckBox.icon.hoverBorderColor", defaults.get( "CheckBox.icon.focusedBorderColor" ) );
|
||||
|
||||
// for filled checkbox/radiobutton used in light themes
|
||||
defaults.remove( "CheckBox.icon[filled].focusWidth" );
|
||||
defaults.put( "CheckBox.icon[filled].hoverBorderColor", defaults.get( "CheckBox.icon[filled].focusedBorderColor" ) );
|
||||
defaults.put( "CheckBox.icon[filled].focusedSelectedBackground", defaults.get( "CheckBox.icon[filled].selectedBackground" ) );
|
||||
|
||||
if( dark ) {
|
||||
// IDEA Darcula checkBoxFocused.svg, checkBoxSelectedFocused.svg,
|
||||
// radioFocused.svg and radioSelectedFocused.svg
|
||||
// use opacity=".65" for the border
|
||||
// --> add alpha to focused border colors
|
||||
String[] focusedBorderColorKeys = new String[] {
|
||||
"CheckBox.icon.focusedBorderColor",
|
||||
"CheckBox.icon.focusedSelectedBorderColor",
|
||||
"CheckBox.icon[filled].focusedBorderColor",
|
||||
"CheckBox.icon[filled].focusedSelectedBorderColor",
|
||||
};
|
||||
for( String key : focusedBorderColorKeys ) {
|
||||
Color color = defaults.getColor( key );
|
||||
if( color != null ) {
|
||||
defaults.put( key, new ColorUIResource( new Color(
|
||||
(color.getRGB() & 0xffffff) | 0xa6000000, true ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copyIfNotSet( UIDefaults defaults, String destKey, String srcKey, Set<String> uiKeys ) {
|
||||
if( !uiKeys.contains( destKey ) )
|
||||
defaults.put( destKey, defaults.get( srcKey ) );
|
||||
}
|
||||
|
||||
/** Rename UI default keys (key --> value). */
|
||||
private static Map<String, String> uiKeyMapping = new HashMap<>();
|
||||
/** Copy UI default keys (value --> key). */
|
||||
private static Map<String, String> uiKeyCopying = new HashMap<>();
|
||||
private static Map<String, String> uiKeyInverseMapping = new HashMap<>();
|
||||
private static Map<String, String> checkboxKeyMapping = new HashMap<>();
|
||||
private static Map<String, String> checkboxDuplicateColors = new HashMap<>();
|
||||
|
||||
static {
|
||||
// ComboBox
|
||||
uiKeyMapping.put( "ComboBox.background", "" ); // ignore
|
||||
uiKeyMapping.put( "ComboBox.nonEditableBackground", "ComboBox.background" );
|
||||
uiKeyMapping.put( "ComboBox.ArrowButton.background", "ComboBox.buttonEditableBackground" );
|
||||
uiKeyMapping.put( "ComboBox.ArrowButton.disabledIconColor", "ComboBox.buttonDisabledArrowColor" );
|
||||
uiKeyMapping.put( "ComboBox.ArrowButton.iconColor", "ComboBox.buttonArrowColor" );
|
||||
uiKeyMapping.put( "ComboBox.ArrowButton.nonEditableBackground", "ComboBox.buttonBackground" );
|
||||
uiKeyCopying.put( "ComboBox.buttonSeparatorColor", "Component.borderColor" );
|
||||
uiKeyCopying.put( "ComboBox.buttonDisabledSeparatorColor", "Component.disabledBorderColor" );
|
||||
|
||||
// Component
|
||||
uiKeyMapping.put( "Component.inactiveErrorFocusColor", "Component.error.borderColor" );
|
||||
uiKeyMapping.put( "Component.errorFocusColor", "Component.error.focusedBorderColor" );
|
||||
uiKeyMapping.put( "Component.inactiveWarningFocusColor", "Component.warning.borderColor" );
|
||||
uiKeyMapping.put( "Component.warningFocusColor", "Component.warning.focusedBorderColor" );
|
||||
|
||||
// Link
|
||||
uiKeyMapping.put( "Link.activeForeground", "Component.linkColor" );
|
||||
|
||||
// Menu
|
||||
uiKeyMapping.put( "Menu.border", "Menu.margin" );
|
||||
uiKeyMapping.put( "MenuItem.border", "MenuItem.margin" );
|
||||
uiKeyCopying.put( "CheckBoxMenuItem.margin", "MenuItem.margin" );
|
||||
uiKeyCopying.put( "RadioButtonMenuItem.margin", "MenuItem.margin" );
|
||||
uiKeyMapping.put( "PopupMenu.border", "PopupMenu.borderInsets" );
|
||||
uiKeyCopying.put( "MenuItem.underlineSelectionColor", "TabbedPane.underlineColor" );
|
||||
|
||||
// IDEA uses List.selectionBackground also for menu selection
|
||||
uiKeyCopying.put( "Menu.selectionBackground", "List.selectionBackground" );
|
||||
uiKeyCopying.put( "MenuItem.selectionBackground", "List.selectionBackground" );
|
||||
uiKeyCopying.put( "CheckBoxMenuItem.selectionBackground", "List.selectionBackground" );
|
||||
uiKeyCopying.put( "RadioButtonMenuItem.selectionBackground", "List.selectionBackground" );
|
||||
|
||||
// ProgressBar
|
||||
uiKeyMapping.put( "ProgressBar.background", "" ); // ignore
|
||||
uiKeyMapping.put( "ProgressBar.foreground", "" ); // ignore
|
||||
uiKeyMapping.put( "ProgressBar.trackColor", "ProgressBar.background" );
|
||||
uiKeyMapping.put( "ProgressBar.progressColor", "ProgressBar.foreground" );
|
||||
uiKeyCopying.put( "ProgressBar.selectionForeground", "ProgressBar.background" );
|
||||
uiKeyCopying.put( "ProgressBar.selectionBackground", "ProgressBar.foreground" );
|
||||
|
||||
// ScrollBar
|
||||
uiKeyMapping.put( "ScrollBar.trackColor", "ScrollBar.track" );
|
||||
uiKeyMapping.put( "ScrollBar.thumbColor", "ScrollBar.thumb" );
|
||||
|
||||
// Separator
|
||||
uiKeyMapping.put( "Separator.separatorColor", "Separator.foreground" );
|
||||
|
||||
// Slider
|
||||
uiKeyMapping.put( "Slider.trackWidth", "" ); // ignore (used in Material Theme UI Lite)
|
||||
uiKeyCopying.put( "Slider.trackValueColor", "ProgressBar.foreground" );
|
||||
uiKeyCopying.put( "Slider.thumbColor", "ProgressBar.foreground" );
|
||||
uiKeyCopying.put( "Slider.trackColor", "ProgressBar.background" );
|
||||
|
||||
// Spinner
|
||||
uiKeyCopying.put( "Spinner.buttonSeparatorColor", "Component.borderColor" );
|
||||
uiKeyCopying.put( "Spinner.buttonDisabledSeparatorColor", "Component.disabledBorderColor" );
|
||||
|
||||
// TitlePane
|
||||
uiKeyCopying.put( "TitlePane.inactiveBackground", "TitlePane.background" );
|
||||
uiKeyMapping.put( "TitlePane.infoForeground", "TitlePane.foreground" );
|
||||
uiKeyMapping.put( "TitlePane.inactiveInfoForeground", "TitlePane.inactiveForeground" );
|
||||
|
||||
for( Map.Entry<String, String> e : uiKeyMapping.entrySet() )
|
||||
uiKeyInverseMapping.put( e.getValue(), e.getKey() );
|
||||
|
||||
uiKeyCopying.put( "ToggleButton.tab.underlineColor", "TabbedPane.underlineColor" );
|
||||
uiKeyCopying.put( "ToggleButton.tab.disabledUnderlineColor", "TabbedPane.disabledUnderlineColor" );
|
||||
uiKeyCopying.put( "ToggleButton.tab.selectedBackground", "TabbedPane.selectedBackground" );
|
||||
uiKeyCopying.put( "ToggleButton.tab.hoverBackground", "TabbedPane.hoverColor" );
|
||||
uiKeyCopying.put( "ToggleButton.tab.focusBackground", "TabbedPane.focusColor" );
|
||||
|
||||
checkboxKeyMapping.put( "Checkbox.Background.Default", "CheckBox.icon.background" );
|
||||
checkboxKeyMapping.put( "Checkbox.Background.Disabled", "CheckBox.icon.disabledBackground" );
|
||||
checkboxKeyMapping.put( "Checkbox.Border.Default", "CheckBox.icon.borderColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Border.Disabled", "CheckBox.icon.disabledBorderColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Focus.Thin.Default", "CheckBox.icon.focusedBorderColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Focus.Wide", "CheckBox.icon.focusColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Foreground.Disabled", "CheckBox.icon.disabledCheckmarkColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Background.Selected", "CheckBox.icon.selectedBackground" );
|
||||
checkboxKeyMapping.put( "Checkbox.Border.Selected", "CheckBox.icon.selectedBorderColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Foreground.Selected", "CheckBox.icon.checkmarkColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Focus.Thin.Selected", "CheckBox.icon.focusedSelectedBorderColor" );
|
||||
|
||||
checkboxDuplicateColors.put( "Checkbox.Background.Default.Dark", "Checkbox.Background.Selected.Dark" );
|
||||
checkboxDuplicateColors.put( "Checkbox.Border.Default.Dark", "Checkbox.Border.Selected.Dark" );
|
||||
checkboxDuplicateColors.put( "Checkbox.Focus.Thin.Default.Dark", "Checkbox.Focus.Thin.Selected.Dark" );
|
||||
@SuppressWarnings( "unchecked" )
|
||||
Map.Entry<String, String>[] entries = checkboxDuplicateColors.entrySet().toArray( new Map.Entry[checkboxDuplicateColors.size()] );
|
||||
for( Map.Entry<String, String> e : entries )
|
||||
checkboxDuplicateColors.put( e.getValue(), e.getKey() );
|
||||
}
|
||||
|
||||
//---- class ThemeLaf -----------------------------------------------------
|
||||
|
||||
public static class ThemeLaf
|
||||
extends FlatLaf
|
||||
{
|
||||
private final IntelliJTheme theme;
|
||||
|
||||
public ThemeLaf( IntelliJTheme theme ) {
|
||||
this.theme = theme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return theme.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDark() {
|
||||
return theme.dark;
|
||||
}
|
||||
|
||||
public IntelliJTheme getTheme() {
|
||||
return theme;
|
||||
}
|
||||
|
||||
@Override
|
||||
void applyAdditionalDefaults( UIDefaults defaults ) {
|
||||
theme.applyProperties( defaults );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArrayList<Class<?>> getLafClassesForDefaultsLoading() {
|
||||
ArrayList<Class<?>> lafClasses = new ArrayList<>();
|
||||
lafClasses.add( FlatLaf.class );
|
||||
lafClasses.add( theme.dark ? FlatDarkLaf.class : FlatLightLaf.class );
|
||||
lafClasses.add( theme.dark ? FlatDarculaLaf.class : FlatIntelliJLaf.class );
|
||||
lafClasses.add( ThemeLaf.class );
|
||||
return lafClasses;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright 2019 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import javax.swing.text.StyleContext;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
class LinuxFontPolicy
|
||||
{
|
||||
static Font getFont() {
|
||||
return SystemInfo.isKDE ? getKDEFont() : getGnomeFont();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default font for Gnome.
|
||||
*/
|
||||
private static Font getGnomeFont() {
|
||||
// see class com.sun.java.swing.plaf.gtk.PangoFonts background information
|
||||
|
||||
Object fontName = Toolkit.getDefaultToolkit().getDesktopProperty( "gnome.Gtk/FontName" );
|
||||
if( !(fontName instanceof String) )
|
||||
fontName = "sans 10";
|
||||
|
||||
String family = "";
|
||||
int style = Font.PLAIN;
|
||||
double dsize = 10;
|
||||
|
||||
// parse pango font description
|
||||
// see https://developer.gnome.org/pango/1.46/pango-Fonts.html#pango-font-description-from-string
|
||||
StringTokenizer st = new StringTokenizer( (String) fontName );
|
||||
while( st.hasMoreTokens() ) {
|
||||
String word = st.nextToken();
|
||||
|
||||
// remove trailing ',' (e.g. in "Ubuntu Condensed, 11" or "Ubuntu Condensed, Bold 11")
|
||||
if( word.endsWith( "," ) )
|
||||
word = word.substring( 0, word.length() - 1 ).trim();
|
||||
|
||||
String lword = word.toLowerCase();
|
||||
if( lword.equals( "italic" ) || lword.equals( "oblique" ) )
|
||||
style |= Font.ITALIC;
|
||||
else if( lword.equals( "bold" ) )
|
||||
style |= Font.BOLD;
|
||||
else if( Character.isDigit( word.charAt( 0 ) ) ) {
|
||||
try {
|
||||
dsize = Double.parseDouble( word );
|
||||
} catch( NumberFormatException ex ) {
|
||||
// ignore
|
||||
}
|
||||
} else {
|
||||
// remove '-' from "Semi-Bold", "Extra-Light", etc
|
||||
if( lword.startsWith( "semi-" ) || lword.startsWith( "demi-" ) )
|
||||
word = word.substring( 0, 4 ) + word.substring( 5 );
|
||||
else if( lword.startsWith( "extra-" ) || lword.startsWith( "ultra-" ) )
|
||||
word = word.substring( 0, 5 ) + word.substring( 6 );
|
||||
|
||||
family = family.isEmpty() ? word : (family + ' ' + word);
|
||||
}
|
||||
}
|
||||
|
||||
// Ubuntu font is rendered poorly (except if running in JetBrains VM)
|
||||
// --> use Liberation Sans font
|
||||
if( family.startsWith( "Ubuntu" ) &&
|
||||
!SystemInfo.isJetBrainsJVM &&
|
||||
!FlatSystemProperties.getBoolean( FlatSystemProperties.USE_UBUNTU_FONT, false ) )
|
||||
family = "Liberation Sans";
|
||||
|
||||
// scale font size
|
||||
dsize *= getGnomeFontScale();
|
||||
int size = (int) (dsize + 0.5);
|
||||
if( size < 1 )
|
||||
size = 1;
|
||||
|
||||
// handle logical font names
|
||||
String logicalFamily = mapFcName( family.toLowerCase() );
|
||||
if( logicalFamily != null )
|
||||
family = logicalFamily;
|
||||
|
||||
return createFontEx( family, style, size, dsize );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a font for the given family, style and size.
|
||||
* If the font family does not match any font on the system,
|
||||
* then the last word (usually a font weight) from the family name is removed and tried again.
|
||||
* E.g. family 'URW Bookman Light' is not found, but 'URW Bookman' is found.
|
||||
* If still not found, then font of family 'Dialog' is returned.
|
||||
*/
|
||||
private static Font createFontEx( String family, int style, int size, double dsize ) {
|
||||
for(;;) {
|
||||
Font font = createFont( family, style, size, dsize );
|
||||
|
||||
if( Font.DIALOG.equals( family ) )
|
||||
return font;
|
||||
|
||||
// if the font family does not match any font on the system, "Dialog" family is returned
|
||||
if( !Font.DIALOG.equals( font.getFamily() ) ) {
|
||||
// check for font problems
|
||||
// - font height much larger than expected (e.g. font Inter; Oracle Java 8)
|
||||
// - character width is zero (e.g. font Cantarell; Fedora; Oracle Java 8)
|
||||
FontMetrics fm = StyleContext.getDefaultStyleContext().getFontMetrics( font );
|
||||
if( fm.getHeight() > size * 2 || fm.stringWidth( "a" ) == 0 )
|
||||
return createFont( Font.DIALOG, style, size, dsize );
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
// find last word in family
|
||||
int index = family.lastIndexOf( ' ' );
|
||||
if( index < 0 )
|
||||
return createFont( Font.DIALOG, style, size, dsize );
|
||||
|
||||
// check whether last work contains some font weight (e.g. Ultra-Bold or Heavy)
|
||||
String lastWord = family.substring( index + 1 ).toLowerCase();
|
||||
if( lastWord.contains( "bold" ) || lastWord.contains( "heavy" ) || lastWord.contains( "black" ) )
|
||||
style |= Font.BOLD;
|
||||
|
||||
// remove last word from family and try again
|
||||
family = family.substring( 0, index );
|
||||
}
|
||||
}
|
||||
|
||||
private static Font createFont( String family, int style, int size, double dsize ) {
|
||||
Font font = FlatLaf.createCompositeFont( family, style, size );
|
||||
|
||||
// set font size in floating points
|
||||
font = font.deriveFont( style, (float) dsize );
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
private static double getGnomeFontScale() {
|
||||
// do not scale font here if JRE scales
|
||||
if( isSystemScaling() )
|
||||
return 96. / 72.;
|
||||
|
||||
// see class com.sun.java.swing.plaf.gtk.PangoFonts background information
|
||||
|
||||
Object value = Toolkit.getDefaultToolkit().getDesktopProperty( "gnome.Xft/DPI" );
|
||||
if( value instanceof Integer ) {
|
||||
int dpi = ((Integer)value).intValue() / 1024;
|
||||
if( dpi == -1 )
|
||||
dpi = 96;
|
||||
if( dpi < 50 )
|
||||
dpi = 50;
|
||||
return dpi / 72.0;
|
||||
} else {
|
||||
return GraphicsEnvironment.getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice().getDefaultConfiguration()
|
||||
.getNormalizingTransform().getScaleY();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* map GTK/fontconfig names to equivalent JDK logical font name
|
||||
*/
|
||||
private static String mapFcName( String name ) {
|
||||
switch( name ) {
|
||||
case "sans": return "sansserif";
|
||||
case "sans-serif": return "sansserif";
|
||||
case "serif": return "serif";
|
||||
case "monospace": return "monospaced";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default font for KDE for KDE configuration files.
|
||||
*
|
||||
* The Swing fonts are not updated when the user changes system font size
|
||||
* (System Settings > Fonts > Force Font DPI). A application restart is necessary.
|
||||
* This is the same behavior as in native KDE applications.
|
||||
*
|
||||
* The "display scale factor" (kdeglobals: [KScreen] > ScaleFactor) is not used
|
||||
* KDE also does not use it to calculate font size. Only forceFontDPI is used by KDE.
|
||||
* If user changes "display scale factor" (System Settings > Display and Monitors >
|
||||
* Displays > Scale Display), the forceFontDPI is also changed to reflect the scale factor.
|
||||
*/
|
||||
private static Font getKDEFont() {
|
||||
List<String> kdeglobals = readConfig( "kdeglobals" );
|
||||
List<String> kcmfonts = readConfig( "kcmfonts" );
|
||||
|
||||
String generalFont = getConfigEntry( kdeglobals, "General", "font" );
|
||||
String forceFontDPI = getConfigEntry( kcmfonts, "General", "forceFontDPI" );
|
||||
|
||||
String family = "sansserif";
|
||||
int style = Font.PLAIN;
|
||||
int size = 10;
|
||||
|
||||
if( generalFont != null ) {
|
||||
List<String> strs = StringUtils.split( generalFont, ',' );
|
||||
try {
|
||||
family = strs.get( 0 );
|
||||
size = Integer.parseInt( strs.get( 1 ) );
|
||||
if( "75".equals( strs.get( 4 ) ) )
|
||||
style |= Font.BOLD;
|
||||
if( "1".equals( strs.get( 5 ) ) )
|
||||
style |= Font.ITALIC;
|
||||
} catch( RuntimeException ex ) {
|
||||
LoggingFacade.INSTANCE.logConfig( "FlatLaf: Failed to parse 'font=" + generalFont + "'.", ex );
|
||||
}
|
||||
}
|
||||
|
||||
// font dpi
|
||||
int dpi = 96;
|
||||
if( forceFontDPI != null && !isSystemScaling() ) {
|
||||
try {
|
||||
dpi = Integer.parseInt( forceFontDPI );
|
||||
if( dpi <= 0 )
|
||||
dpi = 96;
|
||||
if( dpi < 50 )
|
||||
dpi = 50;
|
||||
} catch( NumberFormatException ex ) {
|
||||
LoggingFacade.INSTANCE.logConfig( "FlatLaf: Failed to parse 'forceFontDPI=" + forceFontDPI + "'.", ex );
|
||||
}
|
||||
}
|
||||
|
||||
// scale font size
|
||||
double fontScale = dpi / 72.0;
|
||||
double dsize = size * fontScale;
|
||||
size = (int) (dsize + 0.5);
|
||||
if( size < 1 )
|
||||
size = 1;
|
||||
|
||||
return createFont( family, style, size, dsize );
|
||||
}
|
||||
|
||||
private static List<String> readConfig( String filename ) {
|
||||
File userHome = new File( System.getProperty( "user.home" ) );
|
||||
|
||||
// search for config file
|
||||
String[] configDirs = {
|
||||
".config", // KDE 5
|
||||
".kde4/share/config", // KDE 4
|
||||
".kde/share/config"// KDE 3
|
||||
};
|
||||
File file = null;
|
||||
for( String configDir : configDirs ) {
|
||||
file = new File( userHome, configDir + "/" + filename );
|
||||
if( file.isFile() )
|
||||
break;
|
||||
}
|
||||
if( !file.isFile() )
|
||||
return Collections.emptyList();
|
||||
|
||||
// read config file
|
||||
ArrayList<String> lines = new ArrayList<>( 200 );
|
||||
try( BufferedReader reader = new BufferedReader( new FileReader( file ) ) ) {
|
||||
String line = null;
|
||||
while( (line = reader.readLine()) != null )
|
||||
lines.add( line );
|
||||
} catch( IOException ex ) {
|
||||
LoggingFacade.INSTANCE.logConfig( "FlatLaf: Failed to read '" + filename + "'.", ex );
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
private static String getConfigEntry( List<String> config, String group, String key ) {
|
||||
int groupLength = group.length();
|
||||
int keyLength = key.length();
|
||||
boolean inGroup = false;
|
||||
for( String line : config ) {
|
||||
if( !inGroup ) {
|
||||
if( line.length() >= groupLength + 2 &&
|
||||
line.charAt( 0 ) == '[' &&
|
||||
line.charAt( groupLength + 1 ) == ']' &&
|
||||
line.indexOf( group ) == 1 )
|
||||
{
|
||||
inGroup = true;
|
||||
}
|
||||
} else {
|
||||
if( line.startsWith( "[" ) )
|
||||
return null;
|
||||
|
||||
if( line.length() >= keyLength + 2 &&
|
||||
line.charAt( keyLength ) == '=' &&
|
||||
line.startsWith( key ) )
|
||||
{
|
||||
return line.substring( keyLength + 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the JRE scales, which is the case if:
|
||||
* - environment variable GDK_SCALE is set and running on Java 9 or later
|
||||
* - running on JetBrains Runtime 11 or later and scaling is enabled in system Settings
|
||||
*/
|
||||
private static boolean isSystemScaling() {
|
||||
if( GraphicsEnvironment.isHeadless() )
|
||||
return true;
|
||||
|
||||
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice().getDefaultConfiguration();
|
||||
return UIScale.getSystemScaleFactor( gc ) > 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.KeyEventPostProcessor;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.lang.ref.WeakReference;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.MenuElement;
|
||||
import javax.swing.MenuSelectionManager;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
* Show/hide mnemonics.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
class MnemonicHandler
|
||||
implements KeyEventPostProcessor, ChangeListener
|
||||
{
|
||||
private static boolean showMnemonics;
|
||||
private static WeakReference<Window> lastShowMnemonicWindow;
|
||||
private static WindowListener windowListener;
|
||||
|
||||
static boolean isShowMnemonics() {
|
||||
return showMnemonics || !UIManager.getBoolean( "Component.hideMnemonics" );
|
||||
}
|
||||
|
||||
void install() {
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor( this );
|
||||
MenuSelectionManager.defaultManager().addChangeListener( this );
|
||||
}
|
||||
|
||||
void uninstall() {
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventPostProcessor( this );
|
||||
MenuSelectionManager.defaultManager().removeChangeListener( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postProcessKeyEvent( KeyEvent e ) {
|
||||
int keyCode = e.getKeyCode();
|
||||
if( SystemInfo.isMacOS ) {
|
||||
// Ctrl+Alt keys must be pressed on Mac
|
||||
if( keyCode == KeyEvent.VK_CONTROL || keyCode == KeyEvent.VK_ALT )
|
||||
showMnemonics( shouldShowMnemonics( e ) && e.isControlDown() && e.isAltDown(), e.getComponent() );
|
||||
} else {
|
||||
// Alt key must be pressed on Windows and Linux
|
||||
if( SystemInfo.isWindows )
|
||||
return processKeyEventOnWindows( e );
|
||||
|
||||
if( keyCode == KeyEvent.VK_ALT )
|
||||
showMnemonics( shouldShowMnemonics( e ), e.getComponent() );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean shouldShowMnemonics( KeyEvent e ) {
|
||||
return e.getID() == KeyEvent.KEY_PRESSED ||
|
||||
MenuSelectionManager.defaultManager().getSelectedPath().length > 0;
|
||||
}
|
||||
|
||||
private static int altPressedEventCount;
|
||||
private static boolean selectMenuOnAltReleased;
|
||||
|
||||
/**
|
||||
* Special Alt key behavior on Windows.
|
||||
*
|
||||
* Press-and-release Alt key selects first menu (if available) and moves focus
|
||||
* temporary to menu bar. If menu bar has focus (some menu is selected),
|
||||
* pressing Alt key unselects menu and moves focus back to permanent focus owner.
|
||||
*/
|
||||
private boolean processKeyEventOnWindows( KeyEvent e ) {
|
||||
if( e.getKeyCode() != KeyEvent.VK_ALT ) {
|
||||
selectMenuOnAltReleased = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( e.getID() == KeyEvent.KEY_PRESSED ) {
|
||||
altPressedEventCount++;
|
||||
|
||||
if( altPressedEventCount == 1 && !e.isConsumed() ) {
|
||||
MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager();
|
||||
selectMenuOnAltReleased = (menuSelectionManager.getSelectedPath().length == 0);
|
||||
|
||||
// if menu is selected when Alt key is pressed then clear menu selection
|
||||
if( !selectMenuOnAltReleased )
|
||||
menuSelectionManager.clearSelectedPath();
|
||||
}
|
||||
|
||||
// show mnemonics
|
||||
showMnemonics( shouldShowMnemonics( e ), e.getComponent() );
|
||||
|
||||
// avoid that the system menu of the window gets focus
|
||||
e.consume();
|
||||
return true;
|
||||
|
||||
} else if( e.getID() == KeyEvent.KEY_RELEASED ) {
|
||||
altPressedEventCount = 0;
|
||||
|
||||
boolean mnemonicsShown = false;
|
||||
if( selectMenuOnAltReleased && !e.isConsumed() ) {
|
||||
MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager();
|
||||
if( menuSelectionManager.getSelectedPath().length == 0 ) {
|
||||
// get menu bar and first menu
|
||||
Component c = e.getComponent();
|
||||
JRootPane rootPane = SwingUtilities.getRootPane( c );
|
||||
JMenuBar menuBar = (rootPane != null) ? rootPane.getJMenuBar() : null;
|
||||
if( menuBar == null ) {
|
||||
// get menu bar from frame/dialog because there
|
||||
// may be multiple nested root panes in a frame/dialog
|
||||
// (e.g. each internal frame has its own root pane)
|
||||
Window window = SwingUtilities.getWindowAncestor( c );
|
||||
if( window instanceof JFrame )
|
||||
menuBar = ((JFrame)window).getJMenuBar();
|
||||
else if( window instanceof JDialog )
|
||||
menuBar = ((JDialog)window).getJMenuBar();
|
||||
}
|
||||
JMenu firstMenu = (menuBar != null) ? menuBar.getMenu( 0 ) : null;
|
||||
|
||||
// select first menu and show mnemonics
|
||||
if( firstMenu != null ) {
|
||||
menuSelectionManager.setSelectedPath( new MenuElement[] { menuBar, firstMenu } );
|
||||
showMnemonics( true, c );
|
||||
mnemonicsShown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
selectMenuOnAltReleased = false;
|
||||
|
||||
// hide mnemonics
|
||||
if( !mnemonicsShown )
|
||||
showMnemonics( shouldShowMnemonics( e ), e.getComponent() );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e ) {
|
||||
MenuElement[] selectedPath = MenuSelectionManager.defaultManager().getSelectedPath();
|
||||
if( selectedPath.length == 0 && altPressedEventCount == 0 ) {
|
||||
// hide mnemonics when menu selection was canceled
|
||||
showMnemonics( false, null );
|
||||
}
|
||||
}
|
||||
|
||||
static void showMnemonics( boolean show, Component c ) {
|
||||
if( show == showMnemonics )
|
||||
return;
|
||||
|
||||
showMnemonics = show;
|
||||
|
||||
// check whether it is necessary to repaint
|
||||
if( !UIManager.getBoolean( "Component.hideMnemonics" ) )
|
||||
return;
|
||||
|
||||
if( show ) {
|
||||
// get root pane
|
||||
JRootPane rootPane = SwingUtilities.getRootPane( c );
|
||||
if( rootPane == null )
|
||||
return;
|
||||
|
||||
// get window
|
||||
Window window = SwingUtilities.getWindowAncestor( rootPane );
|
||||
if( window == null )
|
||||
return;
|
||||
|
||||
// repaint components with mnemonics in focused window
|
||||
repaintMnemonics( window );
|
||||
|
||||
// hide mnemonics if window is deactivated (e.g. Alt+Tab to another window)
|
||||
windowListener = new WindowAdapter() {
|
||||
@Override
|
||||
public void windowDeactivated( WindowEvent e ) {
|
||||
altPressedEventCount = 0;
|
||||
selectMenuOnAltReleased = false;
|
||||
|
||||
// use invokeLater() to avoid that the listener is removed
|
||||
// while the listener queue is iterated to fire this event
|
||||
EventQueue.invokeLater( () -> {
|
||||
showMnemonics( false, null );
|
||||
} );
|
||||
}
|
||||
};
|
||||
window.addWindowListener( windowListener );
|
||||
|
||||
lastShowMnemonicWindow = new WeakReference<>( window );
|
||||
} else if( lastShowMnemonicWindow != null ) {
|
||||
Window window = lastShowMnemonicWindow.get();
|
||||
if( window != null ) {
|
||||
repaintMnemonics( window );
|
||||
|
||||
if( windowListener != null ) {
|
||||
window.removeWindowListener( windowListener );
|
||||
windowListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
lastShowMnemonicWindow = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void repaintMnemonics( Container container ) {
|
||||
for( Component c : container.getComponents() ) {
|
||||
if( !c.isVisible() )
|
||||
continue;
|
||||
|
||||
if( hasMnemonic( c ) )
|
||||
c.repaint();
|
||||
|
||||
if( c instanceof Container )
|
||||
repaintMnemonics( (Container) c );
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasMnemonic( Component c ) {
|
||||
if( c instanceof JLabel && ((JLabel)c).getDisplayedMnemonicIndex() >= 0 )
|
||||
return true;
|
||||
|
||||
if( c instanceof AbstractButton && ((AbstractButton)c).getDisplayedMnemonicIndex() >= 0 )
|
||||
return true;
|
||||
|
||||
if( c instanceof JTabbedPane ) {
|
||||
JTabbedPane tabPane = (JTabbedPane) c;
|
||||
int tabCount = tabPane.getTabCount();
|
||||
for( int i = 0; i < tabCount; i++ ) {
|
||||
if( tabPane.getDisplayedMnemonicIndexAt( i ) >= 0 )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
1339
flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java
Normal file
1339
flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -39,7 +39,7 @@ public abstract class FlatAbstractIcon
|
||||
{
|
||||
protected final int width;
|
||||
protected final int height;
|
||||
protected final Color color;
|
||||
protected Color color;
|
||||
|
||||
public FlatAbstractIcon( int width, int height, Color color ) {
|
||||
this.width = width;
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import com.formdev.flatlaf.util.AnimatedIcon;
|
||||
|
||||
/**
|
||||
* Base class for animated icons that scales width and height, creates and initializes
|
||||
* a scaled graphics context for icon painting.
|
||||
* <p>
|
||||
* Subclasses do not need to scale icon painting.
|
||||
* <p>
|
||||
* This class does not store any state information (needed for animation) in its instance.
|
||||
* Instead a client property is set on the painted component.
|
||||
* This makes it possible to use a share icon instance for multiple components.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public abstract class FlatAnimatedIcon
|
||||
extends FlatAbstractIcon
|
||||
implements AnimatedIcon
|
||||
{
|
||||
public FlatAnimatedIcon( int width, int height, Color color ) {
|
||||
super( width, height, color );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon( Component c, Graphics g, int x, int y ) {
|
||||
super.paintIcon( c, g, x, y );
|
||||
AnimatedIcon.AnimationSupport.saveIconLocation( this, c, x, y );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
AnimatedIcon.AnimationSupport.paintIcon( this, c, g, 0, 0 );
|
||||
}
|
||||
}
|
||||
@@ -16,15 +16,22 @@
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.TableHeaderUI;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import com.formdev.flatlaf.ui.FlatTableHeaderUI;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "ascendingSort" icon for {@link javax.swing.table.JTableHeader}.
|
||||
*
|
||||
* @uiDefault Component.arrowType String chevron (default) or triangle
|
||||
* @uiDefault Table.sortIconColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
@@ -32,7 +39,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
public class FlatAscendingSortIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
protected final Color sortIconColor = UIManager.getColor( "Table.sortIconColor" );
|
||||
protected boolean chevron = FlatUIUtils.isChevron( UIManager.getString( "Component.arrowType" ) );
|
||||
protected Color sortIconColor = UIManager.getColor( "Table.sortIconColor" );
|
||||
|
||||
public FlatAscendingSortIcon() {
|
||||
super( 10, 5, null );
|
||||
@@ -40,7 +48,36 @@ public class FlatAscendingSortIcon
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
boolean chevron = this.chevron;
|
||||
Color sortIconColor = this.sortIconColor;
|
||||
|
||||
// Because this icons are always shared for all table headers,
|
||||
// get icon specific style from FlatTableHeaderUI.
|
||||
JTableHeader tableHeader = (JTableHeader) SwingUtilities.getAncestorOfClass( JTableHeader.class, c );
|
||||
if( tableHeader != null ) {
|
||||
TableHeaderUI ui = tableHeader.getUI();
|
||||
if( ui instanceof FlatTableHeaderUI ) {
|
||||
FlatTableHeaderUI fui = (FlatTableHeaderUI) ui;
|
||||
if( fui.arrowType != null )
|
||||
chevron = FlatUIUtils.isChevron( fui.arrowType );
|
||||
if( fui.sortIconColor != null )
|
||||
sortIconColor = fui.sortIconColor;
|
||||
}
|
||||
}
|
||||
|
||||
g.setColor( sortIconColor );
|
||||
g.fill( FlatUIUtils.createPath( 0.5,5, 9.5,5, 5,0 ) );
|
||||
paintArrow( c, g, chevron );
|
||||
}
|
||||
|
||||
protected void paintArrow( Component c, Graphics2D g, boolean chevron ) {
|
||||
if( chevron ) {
|
||||
// chevron arrow
|
||||
Path2D path = FlatUIUtils.createPath( false, 1,4, 5,0, 9,4 );
|
||||
g.setStroke( new BasicStroke( 1f ) );
|
||||
g.draw( path );
|
||||
} else {
|
||||
// triangle arrow
|
||||
g.fill( FlatUIUtils.createPath( 0.5,5, 5,0, 9.5,5 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "caps lock" icon for {@link javax.swing.JPasswordField}.
|
||||
*
|
||||
* @uiDefault PasswordField.capsLockIconColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatCapsLockIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatCapsLockIcon() {
|
||||
super( 16, 16, UIManager.getColor( "PasswordField.capsLockIconColor" ) );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Object applyStyleProperty( String key, Object value ) {
|
||||
Object oldValue;
|
||||
switch( key ) {
|
||||
case "capsLockIconColor": oldValue = color; color = (Color) value; return oldValue;
|
||||
default: throw new UnknownStyleException( key );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
/*
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<rect width="16" height="16" fill="#6E6E6E" rx="3"/>
|
||||
<rect width="6" height="2" x="5" y="11.5" fill="#FFF"/>
|
||||
<path fill="#FFF" d="M2,8 L8,2 L14,8 L11,8 L11,10 L5,10 L5,8 L2,8 Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new RoundRectangle2D.Float( 0, 0, 16, 16, 6, 6 ), false );
|
||||
path.append( new Rectangle2D.Float( 5, 11.5f, 6, 2 ), false );
|
||||
path.append( FlatUIUtils.createPath( 2,8, 8,2, 14,8, 11,8, 11,10, 5,10, 5,8 ), false );
|
||||
g.fill( path );
|
||||
}
|
||||
}
|
||||
@@ -16,65 +16,145 @@
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.util.Map;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* Icon for {@link javax.swing.JCheckBox}.
|
||||
*
|
||||
* Note: If Component.focusWidth is greater than zero, then the outline focus border
|
||||
* <p>
|
||||
* <strong>Note</strong>:
|
||||
* If Component.focusWidth is greater than zero, then the outer focus border
|
||||
* is painted outside of the icon bounds. Make sure that the checkbox
|
||||
* has margins, which are equal or greater than focusWidth.
|
||||
*
|
||||
* @uiDefault CheckBox.icon.style String optional; "outlined"/null (default) or "filled"
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.borderWidth int
|
||||
* @uiDefault Component.focusColor Color
|
||||
* @uiDefault CheckBox.icon.focusWidth int or float optional; defaults to Component.focusWidth
|
||||
* @uiDefault CheckBox.icon.borderWidth int or float optional; defaults to Component.borderWidth
|
||||
* @uiDefault CheckBox.icon.selectedBorderWidth int or float optional; defaults to CheckBox.icon.borderWidth
|
||||
* @uiDefault CheckBox.icon.disabledSelectedBorderWidth int or float optional; defaults to CheckBox.icon.selectedBorderWidth
|
||||
* @uiDefault CheckBox.arc int
|
||||
*
|
||||
* @uiDefault CheckBox.icon.focusColor Color optional; defaults to Component.focusColor
|
||||
* @uiDefault CheckBox.icon.borderColor Color
|
||||
* @uiDefault CheckBox.icon.disabledBorderColor Color
|
||||
* @uiDefault CheckBox.icon.selectedBorderColor Color
|
||||
* @uiDefault CheckBox.icon.focusedBorderColor Color
|
||||
* @uiDefault CheckBox.icon.hoverBorderColor Color optional
|
||||
* @uiDefault CheckBox.icon.selectedFocusedBorderColor Color optional
|
||||
* @uiDefault CheckBox.icon.background Color
|
||||
* @uiDefault CheckBox.icon.disabledBackground Color
|
||||
* @uiDefault CheckBox.icon.focusedBackground Color optional
|
||||
* @uiDefault CheckBox.icon.hoverBackground Color optional
|
||||
* @uiDefault CheckBox.icon.pressedBackground Color optional
|
||||
* @uiDefault CheckBox.icon.selectedBorderColor Color
|
||||
* @uiDefault CheckBox.icon.selectedBackground Color
|
||||
* @uiDefault CheckBox.icon.selectedHoverBackground Color optional
|
||||
* @uiDefault CheckBox.icon.selectedPressedBackground Color optional
|
||||
* @uiDefault CheckBox.icon.checkmarkColor Color
|
||||
*
|
||||
* @uiDefault CheckBox.icon.disabledBorderColor Color
|
||||
* @uiDefault CheckBox.icon.disabledBackground Color
|
||||
* @uiDefault CheckBox.icon.disabledSelectedBorderColor Color optional; CheckBox.icon.disabledBorderColor is used if not specified
|
||||
* @uiDefault CheckBox.icon.disabledSelectedBackground Color optional; CheckBox.icon.disabledBackground is used if not specified
|
||||
* @uiDefault CheckBox.icon.disabledCheckmarkColor Color
|
||||
*
|
||||
* @uiDefault CheckBox.icon.focusedBorderColor Color optional
|
||||
* @uiDefault CheckBox.icon.focusedBackground Color optional
|
||||
* @uiDefault CheckBox.icon.focusedSelectedBorderColor Color optional; CheckBox.icon.focusedBorderColor is used if not specified
|
||||
* @uiDefault CheckBox.icon.focusedSelectedBackground Color optional; CheckBox.icon.focusedBackground is used if not specified
|
||||
* @uiDefault CheckBox.icon.focusedCheckmarkColor Color optional; CheckBox.icon.checkmarkColor is used if not specified
|
||||
*
|
||||
* @uiDefault CheckBox.icon.hoverBorderColor Color optional
|
||||
* @uiDefault CheckBox.icon.hoverBackground Color optional
|
||||
* @uiDefault CheckBox.icon.hoverSelectedBorderColor Color optional; CheckBox.icon.hoverBorderColor is used if not specified
|
||||
* @uiDefault CheckBox.icon.hoverSelectedBackground Color optional; CheckBox.icon.hoverBackground is used if not specified
|
||||
* @uiDefault CheckBox.icon.hoverCheckmarkColor Color optional; CheckBox.icon.checkmarkColor is used if not specified
|
||||
*
|
||||
* @uiDefault CheckBox.icon.pressedBorderColor Color optional
|
||||
* @uiDefault CheckBox.icon.pressedBackground Color optional
|
||||
* @uiDefault CheckBox.icon.pressedSelectedBorderColor Color optional; CheckBox.icon.pressedBorderColor is used if not specified
|
||||
* @uiDefault CheckBox.icon.pressedSelectedBackground Color optional; CheckBox.icon.pressedBackground is used if not specified
|
||||
* @uiDefault CheckBox.icon.pressedCheckmarkColor Color optional; CheckBox.icon.checkmarkColor is used if not specified
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatCheckBoxIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
protected final int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
protected final Color focusColor = UIManager.getColor( "Component.focusColor" );
|
||||
protected final String style = UIManager.getString( getPropertyPrefix() + "icon.style" );
|
||||
@Styleable protected float focusWidth = getUIFloat( "CheckBox.icon.focusWidth", UIManager.getInt( "Component.focusWidth" ), style );
|
||||
@Styleable protected Color focusColor = FlatUIUtils.getUIColor( "CheckBox.icon.focusColor", UIManager.getColor( "Component.focusColor" ) );
|
||||
/** @since 2 */ @Styleable protected float borderWidth = getUIFloat( "CheckBox.icon.borderWidth", FlatUIUtils.getUIFloat( "Component.borderWidth", 1 ), style );
|
||||
/** @since 2 */ @Styleable protected float selectedBorderWidth = getUIFloat( "CheckBox.icon.selectedBorderWidth", Float.MIN_VALUE, style );
|
||||
/** @since 2 */ @Styleable protected float disabledSelectedBorderWidth = getUIFloat( "CheckBox.icon.disabledSelectedBorderWidth", Float.MIN_VALUE, style );
|
||||
@Styleable protected int arc = FlatUIUtils.getUIInt( "CheckBox.arc", 2 );
|
||||
|
||||
protected final Color borderColor = UIManager.getColor( "CheckBox.icon.borderColor" );
|
||||
protected final Color disabledBorderColor = UIManager.getColor( "CheckBox.icon.disabledBorderColor" );
|
||||
protected final Color selectedBorderColor = UIManager.getColor( "CheckBox.icon.selectedBorderColor" );
|
||||
protected final Color focusedBorderColor = UIManager.getColor( "CheckBox.icon.focusedBorderColor" );
|
||||
protected final Color hoverBorderColor = UIManager.getColor( "CheckBox.icon.hoverBorderColor" );
|
||||
protected final Color selectedFocusedBorderColor = UIManager.getColor( "CheckBox.icon.selectedFocusedBorderColor" );
|
||||
protected final Color background = UIManager.getColor( "CheckBox.icon.background" );
|
||||
protected final Color disabledBackground = UIManager.getColor( "CheckBox.icon.disabledBackground" );
|
||||
protected final Color focusedBackground = UIManager.getColor( "CheckBox.icon.focusedBackground" );
|
||||
protected final Color hoverBackground = UIManager.getColor( "CheckBox.icon.hoverBackground" );
|
||||
protected final Color pressedBackground = UIManager.getColor( "CheckBox.icon.pressedBackground" );
|
||||
protected final Color selectedBackground = UIManager.getColor( "CheckBox.icon.selectedBackground" );
|
||||
protected final Color selectedHoverBackground = UIManager.getColor( "CheckBox.icon.selectedHoverBackground" );
|
||||
protected final Color selectedPressedBackground = UIManager.getColor( "CheckBox.icon.selectedPressedBackground" );
|
||||
protected final Color checkmarkColor = UIManager.getColor( "CheckBox.icon.checkmarkColor" );
|
||||
protected final Color disabledCheckmarkColor = UIManager.getColor( "CheckBox.icon.disabledCheckmarkColor" );
|
||||
// enabled
|
||||
@Styleable protected Color borderColor = getUIColor( "CheckBox.icon.borderColor", style );
|
||||
@Styleable protected Color background = getUIColor( "CheckBox.icon.background", style );
|
||||
@Styleable protected Color selectedBorderColor = getUIColor( "CheckBox.icon.selectedBorderColor", style );
|
||||
@Styleable protected Color selectedBackground = getUIColor( "CheckBox.icon.selectedBackground", style );
|
||||
@Styleable protected Color checkmarkColor = getUIColor( "CheckBox.icon.checkmarkColor", style );
|
||||
|
||||
// disabled
|
||||
@Styleable protected Color disabledBorderColor = getUIColor( "CheckBox.icon.disabledBorderColor", style );
|
||||
@Styleable protected Color disabledBackground = getUIColor( "CheckBox.icon.disabledBackground", style );
|
||||
/** @since 2 */ @Styleable protected Color disabledSelectedBorderColor = getUIColor( "CheckBox.icon.disabledSelectedBorderColor", style );
|
||||
/** @since 2 */ @Styleable protected Color disabledSelectedBackground = getUIColor( "CheckBox.icon.disabledSelectedBackground", style );
|
||||
@Styleable protected Color disabledCheckmarkColor = getUIColor( "CheckBox.icon.disabledCheckmarkColor", style );
|
||||
|
||||
// focused
|
||||
@Styleable protected Color focusedBorderColor = getUIColor( "CheckBox.icon.focusedBorderColor", style );
|
||||
@Styleable protected Color focusedBackground = getUIColor( "CheckBox.icon.focusedBackground", style );
|
||||
/** @since 2 */ @Styleable protected Color focusedSelectedBorderColor = getUIColor( "CheckBox.icon.focusedSelectedBorderColor", style );
|
||||
/** @since 2 */ @Styleable protected Color focusedSelectedBackground = getUIColor( "CheckBox.icon.focusedSelectedBackground", style );
|
||||
/** @since 2 */ @Styleable protected Color focusedCheckmarkColor = getUIColor( "CheckBox.icon.focusedCheckmarkColor", style );
|
||||
|
||||
// hover
|
||||
@Styleable protected Color hoverBorderColor = getUIColor( "CheckBox.icon.hoverBorderColor", style );
|
||||
@Styleable protected Color hoverBackground = getUIColor( "CheckBox.icon.hoverBackground", style );
|
||||
/** @since 2 */ @Styleable protected Color hoverSelectedBorderColor = getUIColor( "CheckBox.icon.hoverSelectedBorderColor", style );
|
||||
/** @since 2 */ @Styleable protected Color hoverSelectedBackground = getUIColor( "CheckBox.icon.hoverSelectedBackground", style );
|
||||
/** @since 2 */ @Styleable protected Color hoverCheckmarkColor = getUIColor( "CheckBox.icon.hoverCheckmarkColor", style );
|
||||
|
||||
// pressed
|
||||
/** @since 2 */ @Styleable protected Color pressedBorderColor = getUIColor( "CheckBox.icon.pressedBorderColor", style );
|
||||
@Styleable protected Color pressedBackground = getUIColor( "CheckBox.icon.pressedBackground", style );
|
||||
/** @since 2 */ @Styleable protected Color pressedSelectedBorderColor = getUIColor( "CheckBox.icon.pressedSelectedBorderColor", style );
|
||||
/** @since 2 */ @Styleable protected Color pressedSelectedBackground = getUIColor( "CheckBox.icon.pressedSelectedBackground", style );
|
||||
/** @since 2 */ @Styleable protected Color pressedCheckmarkColor = getUIColor( "CheckBox.icon.pressedCheckmarkColor", style );
|
||||
|
||||
protected String getPropertyPrefix() {
|
||||
return "CheckBox.";
|
||||
}
|
||||
|
||||
protected static Color getUIColor( String key, String style ) {
|
||||
if( style != null ) {
|
||||
Color color = UIManager.getColor( styleKey( key, style ) );
|
||||
if( color != null )
|
||||
return color;
|
||||
}
|
||||
return UIManager.getColor( key );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
protected static float getUIFloat( String key, float defaultValue, String style ) {
|
||||
if( style != null ) {
|
||||
float value = FlatUIUtils.getUIFloat( styleKey( key, style ), Float.MIN_VALUE );
|
||||
if( value != Float.MIN_VALUE )
|
||||
return value;
|
||||
}
|
||||
return FlatUIUtils.getUIFloat( key, defaultValue );
|
||||
}
|
||||
|
||||
private static String styleKey( String key, String style ) {
|
||||
return key.replace( ".icon.", ".icon[" + style + "]." );
|
||||
}
|
||||
|
||||
static final int ICON_SIZE = 15;
|
||||
|
||||
@@ -82,62 +162,135 @@ public class FlatCheckBoxIcon
|
||||
super( ICON_SIZE, ICON_SIZE, null );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Object applyStyleProperty( String key, Object value ) {
|
||||
return FlatStylingSupport.applyToAnnotatedObject( this, key, value );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Map<String, Class<?>> getStyleableInfos() {
|
||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g2 ) {
|
||||
boolean selected = (c instanceof AbstractButton) ? ((AbstractButton)c).isSelected() : false;
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
boolean indeterminate = isIndeterminate( c );
|
||||
boolean selected = indeterminate || isSelected( c );
|
||||
boolean isFocused = FlatUIUtils.isPermanentFocusOwner( c );
|
||||
float bw = selected
|
||||
? (disabledSelectedBorderWidth != Float.MIN_VALUE && !c.isEnabled()
|
||||
? disabledSelectedBorderWidth
|
||||
: (selectedBorderWidth != Float.MIN_VALUE ? selectedBorderWidth : borderWidth))
|
||||
: borderWidth;
|
||||
|
||||
// paint focused border
|
||||
if( c.hasFocus() && focusWidth > 0 ) {
|
||||
g2.setColor( focusColor );
|
||||
paintFocusBorder( g2 );
|
||||
if( isFocused && focusWidth > 0 && FlatButtonUI.isFocusPainted( c ) ) {
|
||||
g.setColor( getFocusColor( c ) );
|
||||
paintFocusBorder( c, g );
|
||||
}
|
||||
|
||||
// paint border
|
||||
g2.setColor( FlatButtonUI.buttonStateColor( c,
|
||||
selected ? selectedBorderColor : borderColor,
|
||||
disabledBorderColor,
|
||||
selected && selectedFocusedBorderColor != null ? selectedFocusedBorderColor : focusedBorderColor,
|
||||
hoverBorderColor,
|
||||
null ) );
|
||||
paintBorder( g2 );
|
||||
g.setColor( getBorderColor( c, selected ) );
|
||||
paintBorder( c, g, bw );
|
||||
|
||||
// paint background
|
||||
g2.setColor( FlatButtonUI.buttonStateColor( c,
|
||||
selected ? selectedBackground : background,
|
||||
disabledBackground,
|
||||
focusedBackground,
|
||||
selected && selectedHoverBackground != null ? selectedHoverBackground : hoverBackground,
|
||||
selected && selectedPressedBackground != null ? selectedPressedBackground : pressedBackground ) );
|
||||
paintBackground( g2 );
|
||||
Color bg = FlatUIUtils.deriveColor( getBackground( c, selected ),
|
||||
selected ? selectedBackground : background );
|
||||
if( bg.getAlpha() < 255 ) {
|
||||
// fill background with default color before filling with non-opaque background
|
||||
g.setColor( selected ? selectedBackground : background );
|
||||
paintBackground( c, g, bw );
|
||||
}
|
||||
g.setColor( bg );
|
||||
paintBackground( c, g, bw );
|
||||
|
||||
// paint checkmark
|
||||
if( selected ) {
|
||||
g2.setColor( c.isEnabled() ? checkmarkColor : disabledCheckmarkColor );
|
||||
paintCheckmark( g2 );
|
||||
g.setColor( getCheckmarkColor( c ) );
|
||||
if( indeterminate )
|
||||
paintIndeterminate( c, g );
|
||||
else
|
||||
paintCheckmark( c, g );
|
||||
}
|
||||
}
|
||||
|
||||
protected void paintFocusBorder( Graphics2D g2 ) {
|
||||
// the outline focus border is painted outside of the icon
|
||||
int wh = ICON_SIZE - 1 + (focusWidth * 2);
|
||||
g2.fillRoundRect( -focusWidth + 1, -focusWidth, wh, wh, 8, 8 );
|
||||
protected void paintFocusBorder( Component c, Graphics2D g ) {
|
||||
// the outer focus border is painted outside of the icon
|
||||
float wh = ICON_SIZE - 1 + (focusWidth * 2);
|
||||
float arcwh = arc + (focusWidth * 2);
|
||||
g.fill( new RoundRectangle2D.Float( -focusWidth + 1, -focusWidth, wh, wh, arcwh, arcwh ) );
|
||||
}
|
||||
|
||||
protected void paintBorder( Graphics2D g2 ) {
|
||||
g2.fillRoundRect( 1, 0, 14, 14, 4, 4 );
|
||||
protected void paintBorder( Component c, Graphics2D g, float borderWidth ) {
|
||||
if( borderWidth == 0 )
|
||||
return;
|
||||
|
||||
int arcwh = arc;
|
||||
g.fillRoundRect( 1, 0, 14, 14, arcwh, arcwh );
|
||||
}
|
||||
|
||||
protected void paintBackground( Graphics2D g2 ) {
|
||||
g2.fillRoundRect( 2, 1, 12, 12, 3, 3 );
|
||||
protected void paintBackground( Component c, Graphics2D g, float borderWidth ) {
|
||||
float xy = borderWidth;
|
||||
float wh = 14 - (borderWidth * 2);
|
||||
float arcwh = arc - borderWidth;
|
||||
g.fill( new RoundRectangle2D.Float( 1 + xy, xy, wh, wh, arcwh, arcwh ) );
|
||||
}
|
||||
|
||||
protected void paintCheckmark( Graphics2D g2 ) {
|
||||
protected void paintCheckmark( Component c, Graphics2D g ) {
|
||||
Path2D.Float path = new Path2D.Float();
|
||||
path.moveTo( 4.5f, 7.5f );
|
||||
path.lineTo( 6.6f, 10f );
|
||||
path.lineTo( 11.25f, 3.5f );
|
||||
|
||||
g2.setStroke( new BasicStroke( 1.9f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||
g2.draw( path );
|
||||
g.setStroke( new BasicStroke( 1.9f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||
g.draw( path );
|
||||
}
|
||||
|
||||
protected void paintIndeterminate( Component c, Graphics2D g ) {
|
||||
g.fill( new RoundRectangle2D.Float( 3.75f, 5.75f, 8.5f, 2.5f, 2f, 2f ) );
|
||||
}
|
||||
|
||||
protected boolean isIndeterminate( Component c ) {
|
||||
return c instanceof JComponent && clientPropertyEquals( (JComponent) c, SELECTED_STATE, SELECTED_STATE_INDETERMINATE );
|
||||
}
|
||||
|
||||
protected boolean isSelected( Component c ) {
|
||||
return c instanceof AbstractButton && ((AbstractButton)c).isSelected();
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public float getFocusWidth() {
|
||||
return focusWidth;
|
||||
}
|
||||
|
||||
protected Color getFocusColor( Component c ) {
|
||||
return focusColor;
|
||||
}
|
||||
|
||||
protected Color getBorderColor( Component c, boolean selected ) {
|
||||
return FlatButtonUI.buttonStateColor( c,
|
||||
selected ? selectedBorderColor : borderColor,
|
||||
(selected && disabledSelectedBorderColor != null) ? disabledSelectedBorderColor : disabledBorderColor,
|
||||
(selected && focusedSelectedBorderColor != null) ? focusedSelectedBorderColor : focusedBorderColor,
|
||||
(selected && hoverSelectedBorderColor != null) ? hoverSelectedBorderColor : hoverBorderColor,
|
||||
(selected && pressedSelectedBorderColor != null) ? pressedSelectedBorderColor : pressedBorderColor );
|
||||
}
|
||||
|
||||
protected Color getBackground( Component c, boolean selected ) {
|
||||
return FlatButtonUI.buttonStateColor( c,
|
||||
selected ? selectedBackground : background,
|
||||
(selected && disabledSelectedBackground != null) ? disabledSelectedBackground : disabledBackground,
|
||||
(selected && focusedSelectedBackground != null) ? focusedSelectedBackground : focusedBackground,
|
||||
(selected && hoverSelectedBackground != null) ? hoverSelectedBackground : hoverBackground,
|
||||
(selected && pressedSelectedBackground != null) ? pressedSelectedBackground : pressedBackground );
|
||||
}
|
||||
|
||||
protected Color getCheckmarkColor( Component c ) {
|
||||
return FlatButtonUI.buttonStateColor( c,
|
||||
checkmarkColor,
|
||||
disabledCheckmarkColor,
|
||||
focusedCheckmarkColor,
|
||||
hoverCheckmarkColor,
|
||||
pressedCheckmarkColor );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,30 +21,44 @@ import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.util.Map;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
|
||||
/**
|
||||
* Icon for {@link javax.swing.JCheckBoxMenuItem}.
|
||||
*
|
||||
* @uiDefault MenuItemCheckBox.icon.checkmarkColor Color
|
||||
* @uiDefault MenuItemCheckBox.icon.disabledCheckmarkColor Color
|
||||
* @uiDefault Menu.selectionForeground Color
|
||||
* @uiDefault CheckBoxMenuItem.icon.checkmarkColor Color
|
||||
* @uiDefault CheckBoxMenuItem.icon.disabledCheckmarkColor Color
|
||||
* @uiDefault MenuItem.selectionForeground Color
|
||||
* @uiDefault MenuItem.selectionType String
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatCheckBoxMenuItemIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
protected final Color checkmarkColor = UIManager.getColor( "MenuItemCheckBox.icon.checkmarkColor" );
|
||||
protected final Color disabledCheckmarkColor = UIManager.getColor( "MenuItemCheckBox.icon.disabledCheckmarkColor" );
|
||||
protected final Color selectionForeground = UIManager.getColor( "Menu.selectionForeground" );
|
||||
@Styleable protected Color checkmarkColor = UIManager.getColor( "CheckBoxMenuItem.icon.checkmarkColor" );
|
||||
@Styleable protected Color disabledCheckmarkColor = UIManager.getColor( "CheckBoxMenuItem.icon.disabledCheckmarkColor" );
|
||||
@Styleable protected Color selectionForeground = UIManager.getColor( "MenuItem.selectionForeground" );
|
||||
|
||||
public FlatCheckBoxMenuItemIcon() {
|
||||
super( 15, 15, null );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Object applyStyleProperty( String key, Object value ) {
|
||||
return FlatStylingSupport.applyToAnnotatedObject( this, key, value );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Map<String, Class<?>> getStyleableInfos() {
|
||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g2 ) {
|
||||
boolean selected = (c instanceof AbstractButton) && ((AbstractButton)c).isSelected();
|
||||
@@ -66,10 +80,15 @@ public class FlatCheckBoxMenuItemIcon
|
||||
g2.draw( path );
|
||||
}
|
||||
|
||||
private Color getCheckmarkColor( Component c ) {
|
||||
if( c instanceof JMenuItem && ((JMenuItem)c).isArmed() )
|
||||
protected Color getCheckmarkColor( Component c ) {
|
||||
if( c instanceof JMenuItem && ((JMenuItem)c).isArmed() && !isUnderlineSelection() )
|
||||
return selectionForeground;
|
||||
|
||||
return c.isEnabled() ? checkmarkColor : disabledCheckmarkColor;
|
||||
}
|
||||
|
||||
protected boolean isUnderlineSelection() {
|
||||
// not storing value of "MenuItem.selectionType" in class to allow changing at runtime
|
||||
return "underline".equals( UIManager.getString( "MenuItem.selectionType" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2021 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.util.Map;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "clear" icon for search fields.
|
||||
*
|
||||
* @uiDefault SearchField.clearIconColor Color
|
||||
* @uiDefault SearchField.clearIconHoverColor Color
|
||||
* @uiDefault SearchField.clearIconPressedColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
* @since 1.5
|
||||
*/
|
||||
public class FlatClearIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
@Styleable protected Color clearIconColor = UIManager.getColor( "SearchField.clearIconColor" );
|
||||
@Styleable protected Color clearIconHoverColor = UIManager.getColor( "SearchField.clearIconHoverColor" );
|
||||
@Styleable protected Color clearIconPressedColor = UIManager.getColor( "SearchField.clearIconPressedColor" );
|
||||
|
||||
private final boolean ignoreButtonState;
|
||||
|
||||
public FlatClearIcon() {
|
||||
this( false );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public FlatClearIcon( boolean ignoreButtonState ) {
|
||||
super( 16, 16, null );
|
||||
this.ignoreButtonState = ignoreButtonState;
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Object applyStyleProperty( String key, Object value ) {
|
||||
return FlatStylingSupport.applyToAnnotatedObject( this, key, value );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Map<String, Class<?>> getStyleableInfos() {
|
||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
if( !ignoreButtonState && c instanceof AbstractButton ) {
|
||||
ButtonModel model = ((AbstractButton)c).getModel();
|
||||
if( model.isPressed() || model.isRollover() ) {
|
||||
/*
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<path fill="#7F8B91" fill-opacity=".5" fill-rule="evenodd" d="M8,1.75 C11.4517797,1.75 14.25,4.54822031 14.25,8 C14.25,11.4517797 11.4517797,14.25 8,14.25 C4.54822031,14.25 1.75,11.4517797 1.75,8 C1.75,4.54822031 4.54822031,1.75 8,1.75 Z M10.5,4.5 L8,7 L5.5,4.5 L4.5,5.5 L7,8 L4.5,10.5 L5.5,11.5 L8,9 L10.5,11.5 L11.5,10.5 L9,8 L11.5,5.5 L10.5,4.5 Z"/>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
// paint filled circle with cross
|
||||
g.setColor( model.isPressed() ? clearIconPressedColor : clearIconHoverColor );
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Ellipse2D.Float( 1.75f, 1.75f, 12.5f, 12.5f ), false );
|
||||
path.append( FlatUIUtils.createPath( 4.5,5.5, 5.5,4.5, 8,7, 10.5,4.5, 11.5,5.5, 9,8, 11.5,10.5, 10.5,11.5, 8,9, 5.5,11.5, 4.5,10.5, 7,8 ), false );
|
||||
g.fill( path );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<path fill="none" stroke="#7F8B91" stroke-linecap="square" stroke-opacity=".5" d="M5,5 L11,11 M5,11 L11,5"/>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
// paint cross
|
||||
g.setColor( clearIconColor );
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Line2D.Float( 5,5, 11,11 ), false );
|
||||
path.append( new Line2D.Float( 5,11, 11,5 ), false );
|
||||
g.draw( path );
|
||||
}
|
||||
}
|
||||
@@ -16,31 +16,37 @@
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.swing.UIManager;
|
||||
import java.awt.geom.Path2D;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "descendingSort" icon for {@link javax.swing.table.JTableHeader}.
|
||||
*
|
||||
* @uiDefault Component.arrowType String chevron (default) or triangle
|
||||
* @uiDefault Table.sortIconColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatDescendingSortIcon
|
||||
extends FlatAbstractIcon
|
||||
extends FlatAscendingSortIcon
|
||||
{
|
||||
protected final Color sortIconColor = UIManager.getColor( "Table.sortIconColor" );
|
||||
|
||||
public FlatDescendingSortIcon() {
|
||||
super( 10, 5, null );
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
g.setColor( sortIconColor );
|
||||
g.fill( FlatUIUtils.createPath( 0.5,0, 9.5,0, 5,5 ) );
|
||||
protected void paintArrow( Component c, Graphics2D g, boolean chevron ) {
|
||||
if( chevron ) {
|
||||
// chevron arrow
|
||||
Path2D path = FlatUIUtils.createPath( false, 1,0, 5,4, 9,0 );
|
||||
g.setStroke( new BasicStroke( 1f ) );
|
||||
g.draw( path );
|
||||
} else {
|
||||
// triangle arrow
|
||||
g.fill( FlatUIUtils.createPath( 0.5,0, 5,5, 9.5,0 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import javax.swing.UIManager;
|
||||
/**
|
||||
* "details view" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileChooser.icon.detailsViewColor Color
|
||||
* @uiDefault Actions.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -31,7 +31,7 @@ public class FlatFileChooserDetailsViewIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileChooserDetailsViewIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.detailsViewColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "home folder" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileChooser.icon.homeFolderColor Color
|
||||
* @uiDefault Actions.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +32,7 @@ public class FlatFileChooserHomeFolderIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileChooserHomeFolderIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.homeFolderColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,7 +23,7 @@ import javax.swing.UIManager;
|
||||
/**
|
||||
* "list view" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileChooser.icon.listViewColor Color
|
||||
* @uiDefault Actions.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -31,7 +31,7 @@ public class FlatFileChooserListViewIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileChooserListViewIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.listViewColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "new folder" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileChooser.icon.newFolderColor Color
|
||||
* @uiDefault Actions.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +32,7 @@ public class FlatFileChooserNewFolderIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileChooserNewFolderIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.newFolderColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.swing.UIManager;
|
||||
@@ -24,15 +25,18 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "up folder" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileChooser.icon.upFolderColor Color
|
||||
* @uiDefault Actions.Grey Color
|
||||
* @uiDefault Actions.Blue Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatFileChooserUpFolderIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private final Color blueColor = UIManager.getColor( "Actions.Blue" );
|
||||
|
||||
public FlatFileChooserUpFolderIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.upFolderColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,6 +51,8 @@ public class FlatFileChooserUpFolderIcon
|
||||
*/
|
||||
|
||||
g.fill( FlatUIUtils.createPath( 2,3, 5.5,3, 7,5, 9,5, 9,9, 13,9, 13,5, 14,5, 14,13, 2,13 ) );
|
||||
|
||||
g.setColor( blueColor );
|
||||
g.fill( FlatUIUtils.createPath( 12,4, 12,8, 10,8, 10,4, 8,4, 11,1, 14,4, 12,4 ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import javax.swing.UIManager;
|
||||
/**
|
||||
* "computer" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileView.icon.computerColor Color
|
||||
* @uiDefault Objects.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -33,7 +33,7 @@ public class FlatFileViewComputerIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileViewComputerIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileView.icon.computerColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "directory" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileView.icon.directoryColor Color
|
||||
* @uiDefault Objects.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +32,7 @@ public class FlatFileViewDirectoryIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileViewDirectoryIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileView.icon.directoryColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "file" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileView.icon.fileColor Color
|
||||
* @uiDefault Objects.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +32,7 @@ public class FlatFileViewFileIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileViewFileIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileView.icon.fileColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,7 +25,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "floppy drive" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileView.icon.floppyDriveColor Color
|
||||
* @uiDefault Objects.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -33,7 +33,7 @@ public class FlatFileViewFloppyDriveIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileViewFloppyDriveIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileView.icon.floppyDriveColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,7 +25,7 @@ import javax.swing.UIManager;
|
||||
/**
|
||||
* "hard drive" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileView.icon.hardDriveColor Color
|
||||
* @uiDefault Objects.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -33,7 +33,7 @@ public class FlatFileViewHardDriveIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileViewHardDriveIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileView.icon.hardDriveColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,14 +22,20 @@ import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.util.Map;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* Help button icon for {@link javax.swing.JButton}.
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.focusColor Color
|
||||
* @uiDefault HelpButton.innerFocusWidth int or float optional; defaults to Component.innerFocusWidth
|
||||
* @uiDefault HelpButton.borderWidth int optional; default is 1
|
||||
* @uiDefault HelpButton.borderColor Color
|
||||
* @uiDefault HelpButton.disabledBorderColor Color
|
||||
* @uiDefault HelpButton.focusedBorderColor Color
|
||||
@@ -47,27 +53,37 @@ import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
public class FlatHelpButtonIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
protected final int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
protected final Color focusColor = UIManager.getColor( "Component.focusColor" );
|
||||
@Styleable protected int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
@Styleable protected Color focusColor = UIManager.getColor( "Component.focusColor" );
|
||||
@Styleable protected float innerFocusWidth = FlatUIUtils.getUIFloat( "HelpButton.innerFocusWidth", FlatUIUtils.getUIFloat( "Component.innerFocusWidth", 0 ) );
|
||||
@Styleable protected int borderWidth = FlatUIUtils.getUIInt( "HelpButton.borderWidth", 1 );
|
||||
|
||||
protected final Color borderColor = UIManager.getColor( "HelpButton.borderColor" );
|
||||
protected final Color disabledBorderColor = UIManager.getColor( "HelpButton.disabledBorderColor" );
|
||||
protected final Color focusedBorderColor = UIManager.getColor( "HelpButton.focusedBorderColor" );
|
||||
protected final Color hoverBorderColor = UIManager.getColor( "HelpButton.hoverBorderColor" );
|
||||
protected final Color background = UIManager.getColor( "HelpButton.background" );
|
||||
protected final Color disabledBackground = UIManager.getColor( "HelpButton.disabledBackground" );
|
||||
protected final Color focusedBackground = UIManager.getColor( "HelpButton.focusedBackground" );
|
||||
protected final Color hoverBackground = UIManager.getColor( "HelpButton.hoverBackground" );
|
||||
protected final Color pressedBackground = UIManager.getColor( "HelpButton.pressedBackground" );
|
||||
protected final Color questionMarkColor = UIManager.getColor( "HelpButton.questionMarkColor" );
|
||||
protected final Color disabledQuestionMarkColor = UIManager.getColor( "HelpButton.disabledQuestionMarkColor" );
|
||||
|
||||
protected final int iconSize = 22 + (focusWidth * 2);
|
||||
@Styleable protected Color borderColor = UIManager.getColor( "HelpButton.borderColor" );
|
||||
@Styleable protected Color disabledBorderColor = UIManager.getColor( "HelpButton.disabledBorderColor" );
|
||||
@Styleable protected Color focusedBorderColor = UIManager.getColor( "HelpButton.focusedBorderColor" );
|
||||
@Styleable protected Color hoverBorderColor = UIManager.getColor( "HelpButton.hoverBorderColor" );
|
||||
@Styleable protected Color background = UIManager.getColor( "HelpButton.background" );
|
||||
@Styleable protected Color disabledBackground = UIManager.getColor( "HelpButton.disabledBackground" );
|
||||
@Styleable protected Color focusedBackground = UIManager.getColor( "HelpButton.focusedBackground" );
|
||||
@Styleable protected Color hoverBackground = UIManager.getColor( "HelpButton.hoverBackground" );
|
||||
@Styleable protected Color pressedBackground = UIManager.getColor( "HelpButton.pressedBackground" );
|
||||
@Styleable protected Color questionMarkColor = UIManager.getColor( "HelpButton.questionMarkColor" );
|
||||
@Styleable protected Color disabledQuestionMarkColor = UIManager.getColor( "HelpButton.disabledQuestionMarkColor" );
|
||||
|
||||
public FlatHelpButtonIcon() {
|
||||
super( 0, 0, null );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Object applyStyleProperty( String key, Object value ) {
|
||||
return FlatStylingSupport.applyToAnnotatedObject( this, key, value );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Map<String, Class<?>> getStyleableInfos() {
|
||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g2 ) {
|
||||
/*
|
||||
@@ -81,14 +97,20 @@ public class FlatHelpButtonIcon
|
||||
*/
|
||||
|
||||
boolean enabled = c.isEnabled();
|
||||
boolean focused = c.hasFocus();
|
||||
boolean focused = FlatUIUtils.isPermanentFocusOwner( c );
|
||||
|
||||
// paint focused border
|
||||
if( focused ) {
|
||||
float xy = 0.5f;
|
||||
float wh = iconSize() - 1;
|
||||
|
||||
// paint outer focus border
|
||||
if( focused && FlatButtonUI.isFocusPainted( c ) ) {
|
||||
g2.setColor( focusColor );
|
||||
g2.fill( new Ellipse2D.Float( 0.5f, 0.5f, iconSize - 1, iconSize - 1 ) );
|
||||
g2.fill( new Ellipse2D.Float( xy, xy, wh, wh ) );
|
||||
}
|
||||
|
||||
xy += focusWidth;
|
||||
wh -= (focusWidth * 2);
|
||||
|
||||
// paint border
|
||||
g2.setColor( FlatButtonUI.buttonStateColor( c,
|
||||
borderColor,
|
||||
@@ -96,16 +118,28 @@ public class FlatHelpButtonIcon
|
||||
focusedBorderColor,
|
||||
hoverBorderColor,
|
||||
null ) );
|
||||
g2.fill( new Ellipse2D.Float( focusWidth + 0.5f, focusWidth + 0.5f, 21, 21 ) );
|
||||
g2.fill( new Ellipse2D.Float( xy, xy, wh, wh ) );
|
||||
|
||||
xy += borderWidth;
|
||||
wh -= (borderWidth * 2);
|
||||
|
||||
// paint inner focus border
|
||||
if( innerFocusWidth > 0 && focused && FlatButtonUI.isFocusPainted( c ) ) {
|
||||
g2.setColor( focusColor );
|
||||
g2.fill( new Ellipse2D.Float( xy, xy, wh, wh ) );
|
||||
|
||||
xy += innerFocusWidth;
|
||||
wh -= (innerFocusWidth * 2);
|
||||
}
|
||||
|
||||
// paint background
|
||||
g2.setColor( FlatButtonUI.buttonStateColor( c,
|
||||
g2.setColor( FlatUIUtils.deriveColor( FlatButtonUI.buttonStateColor( c,
|
||||
background,
|
||||
disabledBackground,
|
||||
focusedBackground,
|
||||
hoverBackground,
|
||||
pressedBackground ) );
|
||||
g2.fill( new Ellipse2D.Float( focusWidth + 1.5f, focusWidth + 1.5f, 19, 19 ) );
|
||||
pressedBackground ), background ) );
|
||||
g2.fill( new Ellipse2D.Float( xy, xy, wh, wh ) );
|
||||
|
||||
// paint question mark
|
||||
Path2D q = new Path2D.Float();
|
||||
@@ -128,11 +162,15 @@ public class FlatHelpButtonIcon
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return scale( iconSize );
|
||||
return scale( iconSize() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return scale( iconSize );
|
||||
return scale( iconSize() );
|
||||
}
|
||||
|
||||
private int iconSize() {
|
||||
return 22 + (focusWidth * 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2019 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* Base class for internal frame icons.
|
||||
*
|
||||
* @uiDefault InternalFrame.buttonSize Dimension
|
||||
* @uiDefault InternalFrame.buttonHoverBackground Color
|
||||
* @uiDefault InternalFrame.buttonPressedBackground Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public abstract class FlatInternalFrameAbstractIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private final Color hoverBackground;
|
||||
private final Color pressedBackground;
|
||||
|
||||
public FlatInternalFrameAbstractIcon() {
|
||||
this( UIManager.getDimension( "InternalFrame.buttonSize" ),
|
||||
UIManager.getColor( "InternalFrame.buttonHoverBackground" ),
|
||||
UIManager.getColor( "InternalFrame.buttonPressedBackground" ) );
|
||||
}
|
||||
|
||||
public FlatInternalFrameAbstractIcon( Dimension size, Color hoverBackground, Color pressedBackground ) {
|
||||
super( size.width, size.height, null );
|
||||
this.hoverBackground = hoverBackground;
|
||||
this.pressedBackground = pressedBackground;
|
||||
}
|
||||
|
||||
protected void paintBackground( Component c, Graphics2D g ) {
|
||||
Color background = FlatButtonUI.buttonStateColor( c, null, null, null, hoverBackground, pressedBackground );
|
||||
if( background != null ) {
|
||||
g.setColor( FlatUIUtils.deriveColor( background, c.getBackground() ) );
|
||||
g.fillRect( 0, 0, width, height );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2019 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
|
||||
/**
|
||||
* "close" icon for {@link javax.swing.JInternalFrame}.
|
||||
*
|
||||
* @uiDefault InternalFrame.buttonSize Dimension
|
||||
* @uiDefault InternalFrame.closeHoverBackground Color
|
||||
* @uiDefault InternalFrame.closePressedBackground Color
|
||||
* @uiDefault InternalFrame.closeHoverForeground Color
|
||||
* @uiDefault InternalFrame.closePressedForeground Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatInternalFrameCloseIcon
|
||||
extends FlatInternalFrameAbstractIcon
|
||||
{
|
||||
private final Color hoverForeground = UIManager.getColor( "InternalFrame.closeHoverForeground" );
|
||||
private final Color pressedForeground = UIManager.getColor( "InternalFrame.closePressedForeground" );
|
||||
|
||||
public FlatInternalFrameCloseIcon() {
|
||||
super( UIManager.getDimension( "InternalFrame.buttonSize" ),
|
||||
UIManager.getColor( "InternalFrame.closeHoverBackground" ),
|
||||
UIManager.getColor( "InternalFrame.closePressedBackground" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
paintBackground( c, g );
|
||||
|
||||
g.setColor( FlatButtonUI.buttonStateColor( c, c.getForeground(), null, null, hoverForeground, pressedForeground ) );
|
||||
|
||||
float mx = width / 2;
|
||||
float my = height / 2;
|
||||
float r = 3.25f;
|
||||
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Line2D.Float( mx - r, my - r, mx + r, my + r ), false );
|
||||
path.append( new Line2D.Float( mx - r, my + r, mx + r, my - r ), false );
|
||||
g.setStroke( new BasicStroke( 1f ) );
|
||||
g.draw( path );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2019 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
/**
|
||||
* "iconify" icon for {@link javax.swing.JInternalFrame}.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatInternalFrameIconifyIcon
|
||||
extends FlatInternalFrameAbstractIcon
|
||||
{
|
||||
public FlatInternalFrameIconifyIcon() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
paintBackground( c, g );
|
||||
|
||||
g.setColor( c.getForeground() );
|
||||
g.fillRect( (width / 2) - 4, height / 2, 8, 1 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2019 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "maximize" icon for {@link javax.swing.JInternalFrame}.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatInternalFrameMaximizeIcon
|
||||
extends FlatInternalFrameAbstractIcon
|
||||
{
|
||||
public FlatInternalFrameMaximizeIcon() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
paintBackground( c, g );
|
||||
|
||||
g.setColor( c.getForeground() );
|
||||
g.fill( FlatUIUtils.createRectangle( (width / 2) - 4, (height / 2) - 4, 8, 8, 1 ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2019 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "restore" (or "minimize") icon for {@link javax.swing.JInternalFrame}.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatInternalFrameRestoreIcon
|
||||
extends FlatInternalFrameAbstractIcon
|
||||
{
|
||||
public FlatInternalFrameRestoreIcon() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
paintBackground( c, g );
|
||||
|
||||
g.setColor( c.getForeground() );
|
||||
|
||||
int x = (width / 2) - 4;
|
||||
int y = (height / 2) - 4;
|
||||
Path2D r1 = FlatUIUtils.createRectangle( x + 1, y - 1, 8, 8, 1 );
|
||||
Path2D r2 = FlatUIUtils.createRectangle( x - 1, y + 1, 8, 8, 1 );
|
||||
|
||||
Area area = new Area( r1 );
|
||||
area.subtract( new Area( new Rectangle2D.Float( x - 1, y + 1, 8, 8 ) ) );
|
||||
g.fill( area );
|
||||
|
||||
g.fill( r2 );
|
||||
}
|
||||
}
|
||||
@@ -21,53 +21,72 @@ import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.util.Map;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
|
||||
/**
|
||||
* "arrow" icon for {@link javax.swing.JMenu}.
|
||||
*
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault Component.arrowType String chevron (default) or triangle
|
||||
* @uiDefault Menu.icon.arrowColor Color
|
||||
* @uiDefault Menu.icon.disabledArrowColor Color
|
||||
* @uiDefault Menu.selectionForeground Color
|
||||
* @uiDefault MenuItem.selectionType String
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatMenuArrowIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
protected final boolean chevron = "chevron".equals( UIManager.getString( "Component.arrowType" ) );
|
||||
protected final Color arrowColor = UIManager.getColor( "Menu.icon.arrowColor" );
|
||||
protected final Color disabledArrowColor = UIManager.getColor( "Menu.icon.disabledArrowColor" );
|
||||
protected final Color selectionForeground = UIManager.getColor( "Menu.selectionForeground" );
|
||||
@Styleable protected String arrowType = UIManager.getString( "Component.arrowType" );
|
||||
@Styleable protected Color arrowColor = UIManager.getColor( "Menu.icon.arrowColor" );
|
||||
@Styleable protected Color disabledArrowColor = UIManager.getColor( "Menu.icon.disabledArrowColor" );
|
||||
@Styleable protected Color selectionForeground = UIManager.getColor( "Menu.selectionForeground" );
|
||||
|
||||
public FlatMenuArrowIcon() {
|
||||
super( 6, 10, null );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Object applyStyleProperty( String key, Object value ) {
|
||||
return FlatStylingSupport.applyToAnnotatedObject( this, key, value );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Map<String, Class<?>> getStyleableInfos() {
|
||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
if( !c.getComponentOrientation().isLeftToRight() )
|
||||
g.rotate( Math.toRadians( 180 ), width / 2., height / 2. );
|
||||
|
||||
g.setColor( getArrowColor( c ) );
|
||||
if( chevron ) {
|
||||
if( FlatUIUtils.isChevron( arrowType ) ) {
|
||||
// chevron arrow
|
||||
Path2D path = FlatUIUtils.createPath( false, 1,1, 5,5, 1,9 );
|
||||
g.setStroke( new BasicStroke( 1f ) );
|
||||
g.draw( path );
|
||||
} else {
|
||||
// triangle arrow
|
||||
g.fill( FlatUIUtils.createPath( 0,0.5, 0,9.5, 5,5 ) );
|
||||
g.fill( FlatUIUtils.createPath( 0,0.5, 5,5, 0,9.5 ) );
|
||||
}
|
||||
}
|
||||
|
||||
private Color getArrowColor( Component c ) {
|
||||
if( c instanceof JMenu && ((JMenu)c).isSelected() )
|
||||
protected Color getArrowColor( Component c ) {
|
||||
if( c instanceof JMenu && ((JMenu)c).isSelected() && !isUnderlineSelection() )
|
||||
return selectionForeground;
|
||||
|
||||
return c.isEnabled() ? arrowColor : disabledArrowColor;
|
||||
}
|
||||
|
||||
protected boolean isUnderlineSelection() {
|
||||
// not storing value of "MenuItem.selectionType" in class to allow changing at runtime
|
||||
return "underline".equals( UIManager.getString( "MenuItem.selectionType" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,16 @@ import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
/**
|
||||
* "arrow" icon for {@link javax.swing.JMenuItem}.
|
||||
* "arrow" icon for {@link javax.swing.JMenuItem}, {@link javax.swing.JCheckBoxMenuItem}
|
||||
* and {@link javax.swing.JRadioButtonMenuItem}.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatMenuItemArrowIcon
|
||||
extends FlatMenuArrowIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatMenuItemArrowIcon() {
|
||||
super( 6, 10, null );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,11 +22,12 @@ import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* Base class for icons for {@link javax.swing.JOptionPane}.
|
||||
*
|
||||
* @uiDefault OptionPane.icon.foreground Color
|
||||
* @uiDefault OptionPane.icon.foreground Color default is transparent
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -35,8 +36,8 @@ public abstract class FlatOptionPaneAbstractIcon
|
||||
{
|
||||
protected final Color foreground = UIManager.getColor( "OptionPane.icon.foreground" );
|
||||
|
||||
protected FlatOptionPaneAbstractIcon( String colorKey ) {
|
||||
super( 32, 32, UIManager.getColor( colorKey ) );
|
||||
protected FlatOptionPaneAbstractIcon( String colorKey, String defaultColorKey ) {
|
||||
super( 32, 32, FlatUIUtils.getUIColor( colorKey, defaultColorKey ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,8 @@ import java.awt.geom.Rectangle2D;
|
||||
/**
|
||||
* "Error" icon for {@link javax.swing.JOptionPane}.
|
||||
*
|
||||
* @uiDefault OptionPane.icon.errorColor Color
|
||||
* @uiDefault OptionPane.icon.errorColor Color optional; defaults to Actions.Red
|
||||
* @uiDefault Actions.Red Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +33,7 @@ public class FlatOptionPaneErrorIcon
|
||||
extends FlatOptionPaneAbstractIcon
|
||||
{
|
||||
public FlatOptionPaneErrorIcon() {
|
||||
super( "OptionPane.icon.errorColor" );
|
||||
super( "OptionPane.icon.errorColor", "Actions.Red" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -24,7 +24,8 @@ import java.awt.geom.Rectangle2D;
|
||||
/**
|
||||
* "Information" icon for {@link javax.swing.JOptionPane}.
|
||||
*
|
||||
* @uiDefault OptionPane.icon.informationColor Color
|
||||
* @uiDefault OptionPane.icon.informationColor Color optional; defaults to Actions.Blue
|
||||
* @uiDefault Actions.Blue Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +33,7 @@ public class FlatOptionPaneInformationIcon
|
||||
extends FlatOptionPaneAbstractIcon
|
||||
{
|
||||
public FlatOptionPaneInformationIcon() {
|
||||
super( "OptionPane.icon.informationColor" );
|
||||
super( "OptionPane.icon.informationColor", "Actions.Blue" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -24,7 +24,8 @@ import java.awt.geom.Rectangle2D;
|
||||
/**
|
||||
* "Question" icon for {@link javax.swing.JOptionPane}.
|
||||
*
|
||||
* @uiDefault OptionPane.icon.questionColor Color
|
||||
* @uiDefault OptionPane.icon.questionColor Color optional; defaults to Actions.Blue
|
||||
* @uiDefault Actions.Blue Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +33,7 @@ public class FlatOptionPaneQuestionIcon
|
||||
extends FlatOptionPaneAbstractIcon
|
||||
{
|
||||
public FlatOptionPaneQuestionIcon() {
|
||||
super( "OptionPane.icon.questionColor" );
|
||||
super( "OptionPane.icon.questionColor", "Actions.Blue" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -24,7 +24,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "Warning" icon for {@link javax.swing.JOptionPane}.
|
||||
*
|
||||
* @uiDefault OptionPane.icon.warningColor Color
|
||||
* @uiDefault OptionPane.icon.warningColor Color optional; defaults to Actions.Yellow
|
||||
* @uiDefault Actions.Yellow Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +33,7 @@ public class FlatOptionPaneWarningIcon
|
||||
extends FlatOptionPaneAbstractIcon
|
||||
{
|
||||
public FlatOptionPaneWarningIcon() {
|
||||
super( "OptionPane.icon.warningColor" );
|
||||
super( "OptionPane.icon.warningColor", "Actions.Yellow" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -16,46 +16,59 @@
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
|
||||
/**
|
||||
* Icon for {@link javax.swing.JRadioButton}.
|
||||
*
|
||||
* Note: If Component.focusWidth is greater than zero, then the outline focus border
|
||||
* <p>
|
||||
* <strong>Note</strong>:
|
||||
* If Component.focusWidth is greater than zero, then the outer focus border
|
||||
* is painted outside of the icon bounds. Make sure that the radiobutton
|
||||
* has margins, which are equal or greater than focusWidth.
|
||||
*
|
||||
* @uiDefault RadioButton.icon.centerDiameter int
|
||||
* @uiDefault RadioButton.icon.style String optional; "outlined"/null (default) or "filled"
|
||||
* @uiDefault RadioButton.icon.centerDiameter int or float
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatRadioButtonIcon
|
||||
extends FlatCheckBoxIcon
|
||||
{
|
||||
protected final int centerDiameter = FlatUIUtils.getUIInt( "RadioButton.icon.centerDiameter", 8 );
|
||||
@Styleable protected float centerDiameter = getUIFloat( "RadioButton.icon.centerDiameter", 8, style );
|
||||
|
||||
@Override
|
||||
protected void paintFocusBorder( Graphics2D g2 ) {
|
||||
// the outline focus border is painted outside of the icon
|
||||
int wh = ICON_SIZE + (focusWidth * 2);
|
||||
g2.fillOval( -focusWidth, -focusWidth, wh, wh );
|
||||
protected String getPropertyPrefix() {
|
||||
return "RadioButton.";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintBorder( Graphics2D g2 ) {
|
||||
g2.fillOval( 0, 0, 15, 15 );
|
||||
protected void paintFocusBorder( Component c, Graphics2D g ) {
|
||||
// the outer focus border is painted outside of the icon
|
||||
float wh = ICON_SIZE + (focusWidth * 2);
|
||||
g.fill( new Ellipse2D.Float( -focusWidth, -focusWidth, wh, wh ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintBackground( Graphics2D g2 ) {
|
||||
g2.fillOval( 1, 1, 13, 13 );
|
||||
protected void paintBorder( Component c, Graphics2D g, float borderWidth ) {
|
||||
if( borderWidth == 0 )
|
||||
return;
|
||||
|
||||
g.fillOval( 0, 0, 15, 15 );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintCheckmark( Graphics2D g2 ) {
|
||||
protected void paintBackground( Component c, Graphics2D g, float borderWidth ) {
|
||||
float xy = borderWidth;
|
||||
float wh = 15 - (borderWidth * 2);
|
||||
g.fill( new Ellipse2D.Float( xy, xy, wh, wh ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintCheckmark( Component c, Graphics2D g ) {
|
||||
float xy = (ICON_SIZE - centerDiameter) / 2f;
|
||||
g2.fill( new Ellipse2D.Float( xy, xy, centerDiameter, centerDiameter ) );
|
||||
g.fill( new Ellipse2D.Float( xy, xy, centerDiameter, centerDiameter ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2021 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* "eye" icon for {@link javax.swing.JPasswordField}.
|
||||
*
|
||||
* @uiDefault PasswordField.revealIconColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
* @since 2
|
||||
*/
|
||||
public class FlatRevealIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatRevealIcon() {
|
||||
super( 16, 16, UIManager.getColor( "PasswordField.revealIconColor" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Ellipse2D.Float( 5.15f, 6.15f, 5.7f, 5.7f ), false );
|
||||
path.append( new Ellipse2D.Float( 6, 7, 4, 4 ), false );
|
||||
g.fill( path );
|
||||
|
||||
Path2D path2 = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path2.append( new Ellipse2D.Float( 2.15f, 4.15f, 11.7f, 11.7f ), false );
|
||||
path2.append( new Ellipse2D.Float( 3, 5, 10, 10 ), false );
|
||||
Area area = new Area( path2 );
|
||||
area.subtract( new Area( new Rectangle2D.Float( 0, 9.5f, 16, 16 ) ) );
|
||||
g.fill( area );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2021 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.util.Map;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "search" icon for search fields.
|
||||
*
|
||||
* @uiDefault SearchField.searchIconColor Color
|
||||
* @uiDefault SearchField.searchIconHoverColor Color
|
||||
* @uiDefault SearchField.searchIconPressedColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
* @since 1.5
|
||||
*/
|
||||
public class FlatSearchIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
@Styleable protected Color searchIconColor = UIManager.getColor( "SearchField.searchIconColor" );
|
||||
@Styleable protected Color searchIconHoverColor = UIManager.getColor( "SearchField.searchIconHoverColor" );
|
||||
@Styleable protected Color searchIconPressedColor = UIManager.getColor( "SearchField.searchIconPressedColor" );
|
||||
|
||||
private final boolean ignoreButtonState;
|
||||
|
||||
public FlatSearchIcon() {
|
||||
this( false );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public FlatSearchIcon( boolean ignoreButtonState ) {
|
||||
super( 16, 16, null );
|
||||
this.ignoreButtonState = ignoreButtonState;
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Object applyStyleProperty( String key, Object value ) {
|
||||
return FlatStylingSupport.applyToAnnotatedObject( this, key, value );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Map<String, Class<?>> getStyleableInfos() {
|
||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
/*
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<g fill="none" fill-opacity=".9" fill-rule="evenodd">
|
||||
<polygon fill="#7F8B91" points="10.813 9.75 14 12.938 12.938 14 9.75 10.813"/>
|
||||
<path fill="#7F8B91" d="M7,2 C9.76142375,2 12,4.23857625 12,7 C12,9.76142375 9.76142375,12 7,12 C4.23857625,12 2,9.76142375 2,7 C2,4.23857625 4.23857625,2 7,2 Z M7,3 C4.790861,3 3,4.790861 3,7 C3,9.209139 4.790861,11 7,11 C9.209139,11 11,9.209139 11,7 C11,4.790861 9.209139,3 7,3 Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
g.setColor( ignoreButtonState
|
||||
? searchIconColor
|
||||
: FlatButtonUI.buttonStateColor( c, searchIconColor, searchIconColor,
|
||||
null, searchIconHoverColor, searchIconPressedColor ) );
|
||||
|
||||
// paint magnifier
|
||||
Area area = new Area( new Ellipse2D.Float( 2, 2, 10, 10 ) );
|
||||
area.subtract( new Area( new Ellipse2D.Float( 3, 3, 8, 8 ) ) );
|
||||
area.add( new Area( FlatUIUtils.createPath( 10.813,9.75, 14,12.938, 12.938,14, 9.75,10.813 ) ) );
|
||||
g.fill( area );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2021 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "search with history" icon for search fields.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
* @since 1.5
|
||||
*/
|
||||
public class FlatSearchWithHistoryIcon
|
||||
extends FlatSearchIcon
|
||||
{
|
||||
public FlatSearchWithHistoryIcon() {
|
||||
this( false );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public FlatSearchWithHistoryIcon( boolean ignoreButtonState ) {
|
||||
super( ignoreButtonState );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
/*
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<g fill="none" fill-opacity=".9" fill-rule="evenodd">
|
||||
<polygon fill="#7F8B91" points="8.813 9.75 12 12.938 10.938 14 7.75 10.813"/>
|
||||
<path fill="#7F8B91" d="M5,2 C7.76142375,2 10,4.23857625 10,7 C10,9.76142375 7.76142375,12 5,12 C2.23857625,12 0,9.76142375 0,7 C0,4.23857625 2.23857625,2 5,2 Z M5,3 C2.790861,3 1,4.790861 1,7 C1,9.209139 2.790861,11 5,11 C7.209139,11 9,9.209139 9,7 C9,4.790861 7.209139,3 5,3 Z"/>
|
||||
<polygon fill="#7F8B91" points="11 7 16 7 13.5 10"/>
|
||||
</g>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
// paint magnifier
|
||||
g.translate( -2, 0 );
|
||||
super.paintIcon( c, g );
|
||||
g.translate( 2, 0 );
|
||||
|
||||
// paint history arrow
|
||||
g.fill( FlatUIUtils.createPath( 11,7, 16,7, 13.5,10 ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.util.Map;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "close" icon for closable tabs in {@link javax.swing.JTabbedPane}.
|
||||
*
|
||||
* @uiDefault TabbedPane.closeSize Dimension
|
||||
* @uiDefault TabbedPane.closeArc int
|
||||
* @uiDefault TabbedPane.closeCrossPlainSize float
|
||||
* @uiDefault TabbedPane.closeCrossFilledSize float
|
||||
* @uiDefault TabbedPane.closeCrossLineWidth float
|
||||
* @uiDefault TabbedPane.closeBackground Color
|
||||
* @uiDefault TabbedPane.closeForeground Color
|
||||
* @uiDefault TabbedPane.closeHoverBackground Color
|
||||
* @uiDefault TabbedPane.closeHoverForeground Color
|
||||
* @uiDefault TabbedPane.closePressedBackground Color
|
||||
* @uiDefault TabbedPane.closePressedForeground Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatTabbedPaneCloseIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
@Styleable protected Dimension closeSize = UIManager.getDimension( "TabbedPane.closeSize" );
|
||||
@Styleable protected int closeArc = UIManager.getInt( "TabbedPane.closeArc" );
|
||||
@Styleable protected float closeCrossPlainSize = FlatUIUtils.getUIFloat( "TabbedPane.closeCrossPlainSize", 7.5f );
|
||||
@Styleable protected float closeCrossFilledSize = FlatUIUtils.getUIFloat( "TabbedPane.closeCrossFilledSize", closeCrossPlainSize );
|
||||
@Styleable protected float closeCrossLineWidth = FlatUIUtils.getUIFloat( "TabbedPane.closeCrossLineWidth", 1f );
|
||||
@Styleable protected Color closeBackground = UIManager.getColor( "TabbedPane.closeBackground" );
|
||||
@Styleable protected Color closeForeground = UIManager.getColor( "TabbedPane.closeForeground" );
|
||||
@Styleable protected Color closeHoverBackground = UIManager.getColor( "TabbedPane.closeHoverBackground" );
|
||||
@Styleable protected Color closeHoverForeground = UIManager.getColor( "TabbedPane.closeHoverForeground" );
|
||||
@Styleable protected Color closePressedBackground = UIManager.getColor( "TabbedPane.closePressedBackground" );
|
||||
@Styleable protected Color closePressedForeground = UIManager.getColor( "TabbedPane.closePressedForeground" );
|
||||
|
||||
public FlatTabbedPaneCloseIcon() {
|
||||
super( 16, 16, null );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Object applyStyleProperty( String key, Object value ) {
|
||||
return FlatStylingSupport.applyToAnnotatedObject( this, key, value );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public Map<String, Class<?>> getStyleableInfos() {
|
||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
// paint background
|
||||
Color bg = FlatButtonUI.buttonStateColor( c, closeBackground, null, null, closeHoverBackground, closePressedBackground );
|
||||
if( bg != null ) {
|
||||
g.setColor( FlatUIUtils.deriveColor( bg, c.getBackground() ) );
|
||||
g.fillRoundRect( (width - closeSize.width) / 2, (height - closeSize.height) / 2,
|
||||
closeSize.width, closeSize.height, closeArc, closeArc );
|
||||
}
|
||||
|
||||
// set cross color
|
||||
Color fg = FlatButtonUI.buttonStateColor( c, closeForeground, null, null, closeHoverForeground, closePressedForeground );
|
||||
g.setColor( FlatUIUtils.deriveColor( fg, c.getForeground() ) );
|
||||
|
||||
float mx = width / 2;
|
||||
float my = height / 2;
|
||||
float r = ((bg != null) ? closeCrossFilledSize : closeCrossPlainSize) / 2;
|
||||
|
||||
// paint cross
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Line2D.Float( mx - r, my - r, mx + r, my + r ), false );
|
||||
path.append( new Line2D.Float( mx - r, my + r, mx + r, my - r ), false );
|
||||
g.setStroke( new BasicStroke( closeCrossLineWidth ) );
|
||||
g.draw( path );
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,8 @@ public class FlatTreeClosedIcon
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
FlatTreeCollapsedIcon.setStyleColorFromTreeUI( c, g, ui -> ui.iconClosedColor );
|
||||
|
||||
/*
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<polygon fill="#6E6E6E" fill-rule="evenodd" points="1 2 6 2 8 4 15 4 15 13 1 13"/>
|
||||
|
||||
@@ -19,13 +19,18 @@ package com.formdev.flatlaf.icons;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.TreeUI;
|
||||
import com.formdev.flatlaf.ui.FlatTreeUI;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "collapsed" icon for {@link javax.swing.JTree}.
|
||||
*
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault Component.arrowType String chevron (default) or triangle
|
||||
* @uiDefault Tree.icon.collapsedColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
@@ -41,13 +46,17 @@ public class FlatTreeCollapsedIcon
|
||||
|
||||
FlatTreeCollapsedIcon( Color color ) {
|
||||
super( 11, 11, color );
|
||||
chevron = "chevron".equals( UIManager.getString( "Component.arrowType" ) );
|
||||
chevron = FlatUIUtils.isChevron( UIManager.getString( "Component.arrowType" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
setStyleColorFromTreeUI( c, g );
|
||||
rotate( c, g );
|
||||
|
||||
String arrowType = getStyleFromTreeUI( c, ui -> ui.iconArrowType );
|
||||
boolean chevron = (arrowType != null) ? FlatUIUtils.isChevron( arrowType ) : this.chevron;
|
||||
|
||||
if( chevron ) {
|
||||
// chevron arrow
|
||||
g.fill( FlatUIUtils.createPath( 3,1, 3,2.5, 6,5.5, 3,8.5, 3,10, 4.5,10, 9,5.5, 4.5,1 ) );
|
||||
@@ -57,8 +66,34 @@ public class FlatTreeCollapsedIcon
|
||||
}
|
||||
}
|
||||
|
||||
void setStyleColorFromTreeUI( Component c, Graphics2D g ) {
|
||||
setStyleColorFromTreeUI( c, g, ui -> ui.iconCollapsedColor );
|
||||
}
|
||||
|
||||
void rotate( Component c, Graphics2D g ) {
|
||||
if( !c.getComponentOrientation().isLeftToRight() )
|
||||
g.rotate( Math.toRadians( 180 ), width / 2., height / 2. );
|
||||
}
|
||||
|
||||
/**
|
||||
* Because this icons are always shared for all trees,
|
||||
* get icon specific style from FlatTreeUI.
|
||||
*/
|
||||
static <T> T getStyleFromTreeUI( Component c, Function<FlatTreeUI, T> f ) {
|
||||
JTree tree = (c instanceof JTree)
|
||||
? (JTree) c
|
||||
: (JTree) SwingUtilities.getAncestorOfClass( JTree.class, c );
|
||||
if( tree != null ) {
|
||||
TreeUI ui = tree.getUI();
|
||||
if( ui instanceof FlatTreeUI )
|
||||
return f.apply( (FlatTreeUI) ui );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static void setStyleColorFromTreeUI( Component c, Graphics2D g, Function<FlatTreeUI, Color> f ) {
|
||||
Color color = getStyleFromTreeUI( c, f );
|
||||
if( color != null )
|
||||
g.setColor( color );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,11 @@ public class FlatTreeExpandedIcon
|
||||
super( UIManager.getColor( "Tree.icon.expandedColor" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
void setStyleColorFromTreeUI( Component c, Graphics2D g ) {
|
||||
setStyleColorFromTreeUI( c, g, ui -> ui.iconExpandedColor );
|
||||
}
|
||||
|
||||
@Override
|
||||
void rotate( Component c, Graphics2D g ) {
|
||||
g.rotate( Math.toRadians( 90 ), width / 2., height / 2. );
|
||||
|
||||
@@ -37,6 +37,8 @@ public class FlatTreeLeafIcon
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
FlatTreeCollapsedIcon.setStyleColorFromTreeUI( c, g, ui -> ui.iconLeafColor );
|
||||
|
||||
/*
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
|
||||
@@ -37,6 +37,8 @@ public class FlatTreeOpenIcon
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
FlatTreeCollapsedIcon.setStyleColorFromTreeUI( c, g, ui -> ui.iconOpenColor );
|
||||
|
||||
/*
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||
|
||||
/**
|
||||
* Base class for window icons.
|
||||
*
|
||||
* @uiDefault TitlePane.buttonSize Dimension
|
||||
* @uiDefault TitlePane.buttonHoverBackground Color
|
||||
* @uiDefault TitlePane.buttonPressedBackground Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public abstract class FlatWindowAbstractIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private final Color hoverBackground;
|
||||
private final Color pressedBackground;
|
||||
|
||||
public FlatWindowAbstractIcon() {
|
||||
this( UIManager.getDimension( "TitlePane.buttonSize" ),
|
||||
UIManager.getColor( "TitlePane.buttonHoverBackground" ),
|
||||
UIManager.getColor( "TitlePane.buttonPressedBackground" ) );
|
||||
}
|
||||
|
||||
public FlatWindowAbstractIcon( Dimension size, Color hoverBackground, Color pressedBackground ) {
|
||||
super( size.width, size.height, null );
|
||||
this.hoverBackground = hoverBackground;
|
||||
this.pressedBackground = pressedBackground;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
paintBackground( c, g );
|
||||
|
||||
g.setColor( getForeground( c ) );
|
||||
HiDPIUtils.paintAtScale1x( g, 0, 0, width, height, this::paintIconAt1x );
|
||||
}
|
||||
|
||||
protected abstract void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor );
|
||||
|
||||
protected void paintBackground( Component c, Graphics2D g ) {
|
||||
Color background = FlatButtonUI.buttonStateColor( c, null, null, null, hoverBackground, pressedBackground );
|
||||
if( background != null ) {
|
||||
// disable antialiasing for background rectangle painting to avoid blury edges when scaled (e.g. at 125% or 175%)
|
||||
Object oldHint = g.getRenderingHint( RenderingHints.KEY_ANTIALIASING );
|
||||
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
|
||||
|
||||
g.setColor( FlatUIUtils.deriveColor( background, c.getBackground() ) );
|
||||
g.fillRect( 0, 0, width, height );
|
||||
|
||||
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, oldHint );
|
||||
}
|
||||
}
|
||||
|
||||
protected Color getForeground( Component c ) {
|
||||
return c.getForeground();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
* "close" icon for windows (frames and dialogs).
|
||||
*
|
||||
* @uiDefault TitlePane.closeHoverBackground Color
|
||||
* @uiDefault TitlePane.closePressedBackground Color
|
||||
* @uiDefault TitlePane.closeHoverForeground Color
|
||||
* @uiDefault TitlePane.closePressedForeground Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatWindowCloseIcon
|
||||
extends FlatWindowAbstractIcon
|
||||
{
|
||||
private final Color hoverForeground = UIManager.getColor( "TitlePane.closeHoverForeground" );
|
||||
private final Color pressedForeground = UIManager.getColor( "TitlePane.closePressedForeground" );
|
||||
|
||||
public FlatWindowCloseIcon() {
|
||||
super( UIManager.getDimension( "TitlePane.buttonSize" ),
|
||||
UIManager.getColor( "TitlePane.closeHoverBackground" ),
|
||||
UIManager.getColor( "TitlePane.closePressedBackground" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
int iwh = (int) (10 * scaleFactor);
|
||||
int ix = x + ((width - iwh) / 2);
|
||||
int iy = y + ((height - iwh) / 2);
|
||||
int ix2 = ix + iwh - 1;
|
||||
int iy2 = iy + iwh - 1;
|
||||
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
|
||||
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Line2D.Float( ix, iy, ix2, iy2 ), false );
|
||||
path.append( new Line2D.Float( ix, iy2, ix2, iy ), false );
|
||||
g.setStroke( new BasicStroke( thickness ) );
|
||||
g.draw( path );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getForeground( Component c ) {
|
||||
return FlatButtonUI.buttonStateColor( c, c.getForeground(), null, null, hoverForeground, pressedForeground );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
/**
|
||||
* "iconify" icon for windows (frames and dialogs).
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatWindowIconifyIcon
|
||||
extends FlatWindowAbstractIcon
|
||||
{
|
||||
public FlatWindowIconifyIcon() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
int iw = (int) (10 * scaleFactor);
|
||||
int ih = (int) scaleFactor;
|
||||
int ix = x + ((width - iw) / 2);
|
||||
int iy = y + ((height - ih) / 2);
|
||||
|
||||
g.fillRect( ix, iy, iw, ih );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
* "maximize" icon for windows (frames and dialogs).
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatWindowMaximizeIcon
|
||||
extends FlatWindowAbstractIcon
|
||||
{
|
||||
public FlatWindowMaximizeIcon() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
int iwh = (int) (10 * scaleFactor);
|
||||
int ix = x + ((width - iwh) / 2);
|
||||
int iy = y + ((height - iwh) / 2);
|
||||
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
|
||||
int arc = Math.max( (int) (1.5 * scaleFactor), 2 );
|
||||
|
||||
g.fill( SystemInfo.isWindows_11_orLater
|
||||
? FlatUIUtils.createRoundRectangle( ix, iy, iwh, iwh, thickness, arc, arc, arc, arc )
|
||||
: FlatUIUtils.createRectangle( ix, iy, iwh, iwh, thickness ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
* "restore" icon for windows (frames and dialogs).
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatWindowRestoreIcon
|
||||
extends FlatWindowAbstractIcon
|
||||
{
|
||||
public FlatWindowRestoreIcon() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
int iwh = (int) (10 * scaleFactor);
|
||||
int ix = x + ((width - iwh) / 2);
|
||||
int iy = y + ((height - iwh) / 2);
|
||||
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
|
||||
int arc = Math.max( (int) (1.5 * scaleFactor), 2 );
|
||||
int arcOuter = (int) (arc + (1.5 * scaleFactor));
|
||||
|
||||
int rwh = (int) (8 * scaleFactor);
|
||||
int ro2 = iwh - rwh;
|
||||
|
||||
// upper-right rectangle
|
||||
Path2D r1 = SystemInfo.isWindows_11_orLater
|
||||
? FlatUIUtils.createRoundRectangle( ix + ro2, iy, rwh, rwh, thickness, arc, arcOuter, arc, arc )
|
||||
: FlatUIUtils.createRectangle( ix + ro2, iy, rwh, rwh, thickness );
|
||||
|
||||
// lower-left rectangle
|
||||
Path2D r2 = SystemInfo.isWindows_11_orLater
|
||||
? FlatUIUtils.createRoundRectangle( ix, iy + ro2, rwh, rwh, thickness, arc, arc, arc, arc )
|
||||
: FlatUIUtils.createRectangle( ix, iy + ro2, rwh, rwh, thickness );
|
||||
|
||||
// paint upper-right rectangle
|
||||
Area area = new Area( r1 );
|
||||
if( SystemInfo.isWindows_11_orLater ) {
|
||||
area.subtract( new Area( new Rectangle2D.Float( ix, (float) (iy + scaleFactor), rwh, rwh ) ) );
|
||||
area.subtract( new Area( new Rectangle2D.Float( (float) (ix + scaleFactor), iy + ro2, rwh, rwh ) ) );
|
||||
} else
|
||||
area.subtract( new Area( new Rectangle2D.Float( ix, iy + ro2, rwh, rwh ) ) );
|
||||
g.fill( area );
|
||||
|
||||
// paint lower-left rectangle
|
||||
g.fill( r2 );
|
||||
}
|
||||
}
|
||||
100
flatlaf-core/src/main/java/com/formdev/flatlaf/json/Json.java
Normal file
100
flatlaf-core/src/main/java/com/formdev/flatlaf/json/Json.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2019 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class Json
|
||||
{
|
||||
public static Object parse( Reader reader )
|
||||
throws IOException, ParseException
|
||||
{
|
||||
DefaultHandler handler = new DefaultHandler();
|
||||
new JsonParser( handler ).parse( reader );
|
||||
return handler.getValue();
|
||||
}
|
||||
|
||||
//---- class DefaultHandler -----------------------------------------------
|
||||
|
||||
static class DefaultHandler
|
||||
extends JsonHandler<List<Object>, Map<String, Object>>
|
||||
{
|
||||
private Object value;
|
||||
|
||||
@Override
|
||||
public List<Object> startArray() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> startObject() {
|
||||
return new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endNull() {
|
||||
value = "null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endBoolean( boolean bool ) {
|
||||
value = bool ? "true" : "false";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endString( String string ) {
|
||||
value = string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endNumber( String string ) {
|
||||
value = string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endArray( List<Object> array ) {
|
||||
value = array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endObject( Map<String, Object> object ) {
|
||||
value = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endArrayValue( List<Object> array ) {
|
||||
array.add( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endObjectValue( Map<String, Object> object, String name ) {
|
||||
object.put( name, value );
|
||||
}
|
||||
|
||||
Object getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 EclipseSource.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
// from https://github.com/ralfstx/minimal-json
|
||||
|
||||
package com.formdev.flatlaf.json;
|
||||
|
||||
|
||||
/**
|
||||
* A handler for parser events. Instances of this class can be given to a {@link JsonParser}. The
|
||||
* parser will then call the methods of the given handler while reading the input.
|
||||
* <p>
|
||||
* The default implementations of these methods do nothing. Subclasses may override only those
|
||||
* methods they are interested in. They can use <code>getLocation()</code> to access the current
|
||||
* character position of the parser at any point. The <code>start*</code> methods will be called
|
||||
* while the location points to the first character of the parsed element. The <code>end*</code>
|
||||
* methods will be called while the location points to the character position that directly follows
|
||||
* the last character of the parsed element. Example:
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* ["lorem ipsum"]
|
||||
* ^ ^
|
||||
* startString endString
|
||||
* </pre>
|
||||
* <p>
|
||||
* Subclasses that build an object representation of the parsed JSON can return arbitrary handler
|
||||
* objects for JSON arrays and JSON objects in {@link #startArray()} and {@link #startObject()}.
|
||||
* These handler objects will then be provided in all subsequent parser events for this particular
|
||||
* array or object. They can be used to keep track the elements of a JSON array or object.
|
||||
* </p>
|
||||
*
|
||||
* @param <A>
|
||||
* The type of handlers used for JSON arrays
|
||||
* @param <O>
|
||||
* The type of handlers used for JSON objects
|
||||
* @see JsonParser
|
||||
*/
|
||||
abstract class JsonHandler<A, O> {
|
||||
|
||||
JsonParser parser;
|
||||
|
||||
/**
|
||||
* Returns the current parser location.
|
||||
*
|
||||
* @return the current parser location
|
||||
*/
|
||||
protected Location getLocation() {
|
||||
return parser.getLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of a <code>null</code> literal in the JSON input. This method will be
|
||||
* called when reading the first character of the literal.
|
||||
*/
|
||||
public void startNull() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of a <code>null</code> literal in the JSON input. This method will be called
|
||||
* after reading the last character of the literal.
|
||||
*/
|
||||
public void endNull() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of a boolean literal (<code>true</code> or <code>false</code>) in the
|
||||
* JSON input. This method will be called when reading the first character of the literal.
|
||||
*/
|
||||
public void startBoolean() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of a boolean literal (<code>true</code> or <code>false</code>) in the JSON
|
||||
* input. This method will be called after reading the last character of the literal.
|
||||
*
|
||||
* @param value
|
||||
* the parsed boolean value
|
||||
*/
|
||||
public void endBoolean(boolean value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of a string in the JSON input. This method will be called when reading
|
||||
* the opening double quote character (<code>'"'</code>).
|
||||
*/
|
||||
public void startString() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of a string in the JSON input. This method will be called after reading the
|
||||
* closing double quote character (<code>'"'</code>).
|
||||
*
|
||||
* @param string
|
||||
* the parsed string
|
||||
*/
|
||||
public void endString(String string) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of a number in the JSON input. This method will be called when reading
|
||||
* the first character of the number.
|
||||
*/
|
||||
public void startNumber() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of a number in the JSON input. This method will be called after reading the
|
||||
* last character of the number.
|
||||
*
|
||||
* @param string
|
||||
* the parsed number string
|
||||
*/
|
||||
public void endNumber(String string) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of an array in the JSON input. This method will be called when reading
|
||||
* the opening square bracket character (<code>'['</code>).
|
||||
* <p>
|
||||
* This method may return an object to handle subsequent parser events for this array. This array
|
||||
* handler will then be provided in all calls to {@link #startArrayValue(Object)
|
||||
* startArrayValue()}, {@link #endArrayValue(Object) endArrayValue()}, and
|
||||
* {@link #endArray(Object) endArray()} for this array.
|
||||
* </p>
|
||||
*
|
||||
* @return a handler for this array, or <code>null</code> if not needed
|
||||
*/
|
||||
public A startArray() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of an array in the JSON input. This method will be called after reading the
|
||||
* closing square bracket character (<code>']'</code>).
|
||||
*
|
||||
* @param array
|
||||
* the array handler returned from {@link #startArray()}, or <code>null</code> if not
|
||||
* provided
|
||||
*/
|
||||
public void endArray(A array) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of an array element in the JSON input. This method will be called when
|
||||
* reading the first character of the element, just before the call to the <code>start</code>
|
||||
* method for the specific element type ({@link #startString()}, {@link #startNumber()}, etc.).
|
||||
*
|
||||
* @param array
|
||||
* the array handler returned from {@link #startArray()}, or <code>null</code> if not
|
||||
* provided
|
||||
*/
|
||||
public void startArrayValue(A array) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of an array element in the JSON input. This method will be called after
|
||||
* reading the last character of the element value, just after the <code>end</code> method for the
|
||||
* specific element type (like {@link #endString(String) endString()}, {@link #endNumber(String)
|
||||
* endNumber()}, etc.).
|
||||
*
|
||||
* @param array
|
||||
* the array handler returned from {@link #startArray()}, or <code>null</code> if not
|
||||
* provided
|
||||
*/
|
||||
public void endArrayValue(A array) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of an object in the JSON input. This method will be called when reading
|
||||
* the opening curly bracket character (<code>'{'</code>).
|
||||
* <p>
|
||||
* This method may return an object to handle subsequent parser events for this object. This
|
||||
* object handler will be provided in all calls to {@link #startObjectName(Object)
|
||||
* startObjectName()}, {@link #endObjectName(Object, String) endObjectName()},
|
||||
* {@link #startObjectValue(Object, String) startObjectValue()},
|
||||
* {@link #endObjectValue(Object, String) endObjectValue()}, and {@link #endObject(Object)
|
||||
* endObject()} for this object.
|
||||
* </p>
|
||||
*
|
||||
* @return a handler for this object, or <code>null</code> if not needed
|
||||
*/
|
||||
public O startObject() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of an object in the JSON input. This method will be called after reading the
|
||||
* closing curly bracket character (<code>'}'</code>).
|
||||
*
|
||||
* @param object
|
||||
* the object handler returned from {@link #startObject()}, or null if not provided
|
||||
*/
|
||||
public void endObject(O object) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of the name of an object member in the JSON input. This method will be
|
||||
* called when reading the opening quote character ('"') of the member name.
|
||||
*
|
||||
* @param object
|
||||
* the object handler returned from {@link #startObject()}, or <code>null</code> if not
|
||||
* provided
|
||||
*/
|
||||
public void startObjectName(O object) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of an object member name in the JSON input. This method will be called after
|
||||
* reading the closing quote character (<code>'"'</code>) of the member name.
|
||||
*
|
||||
* @param object
|
||||
* the object handler returned from {@link #startObject()}, or null if not provided
|
||||
* @param name
|
||||
* the parsed member name
|
||||
*/
|
||||
public void endObjectName(O object, String name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of the name of an object member in the JSON input. This method will be
|
||||
* called when reading the opening quote character ('"') of the member name.
|
||||
*
|
||||
* @param object
|
||||
* the object handler returned from {@link #startObject()}, or <code>null</code> if not
|
||||
* provided
|
||||
* @param name
|
||||
* the member name
|
||||
*/
|
||||
public void startObjectValue(O object, String name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of an object member value in the JSON input. This method will be called after
|
||||
* reading the last character of the member value, just after the <code>end</code> method for the
|
||||
* specific member type (like {@link #endString(String) endString()}, {@link #endNumber(String)
|
||||
* endNumber()}, etc.).
|
||||
*
|
||||
* @param object
|
||||
* the object handler returned from {@link #startObject()}, or null if not provided
|
||||
* @param name
|
||||
* the parsed member name
|
||||
*/
|
||||
public void endObjectValue(O object, String name) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,514 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013, 2016 EclipseSource.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
// from https://github.com/ralfstx/minimal-json
|
||||
|
||||
package com.formdev.flatlaf.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
|
||||
/**
|
||||
* A streaming parser for JSON text. The parser reports all events to a given handler.
|
||||
*/
|
||||
class JsonParser {
|
||||
|
||||
private static final int MAX_NESTING_LEVEL = 1000;
|
||||
private static final int MIN_BUFFER_SIZE = 10;
|
||||
private static final int DEFAULT_BUFFER_SIZE = 1024;
|
||||
|
||||
private final JsonHandler<Object, Object> handler;
|
||||
private Reader reader;
|
||||
private char[] buffer;
|
||||
private int bufferOffset;
|
||||
private int index;
|
||||
private int fill;
|
||||
private int line;
|
||||
private int lineOffset;
|
||||
private int current;
|
||||
private StringBuilder captureBuffer;
|
||||
private int captureStart;
|
||||
private int nestingLevel;
|
||||
|
||||
/*
|
||||
* | bufferOffset
|
||||
* v
|
||||
* [a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t] < input
|
||||
* [l|m|n|o|p|q|r|s|t|?|?] < buffer
|
||||
* ^ ^
|
||||
* | index fill
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a new JsonParser with the given handler. The parser will report all parser events to
|
||||
* this handler.
|
||||
*
|
||||
* @param handler
|
||||
* the handler to process parser events
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public JsonParser(JsonHandler<?, ?> handler) {
|
||||
if (handler == null) {
|
||||
throw new NullPointerException("handler is null");
|
||||
}
|
||||
this.handler = (JsonHandler<Object, Object>)handler;
|
||||
handler.parser = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given input string. The input must contain a valid JSON value, optionally padded
|
||||
* with whitespace.
|
||||
*
|
||||
* @param string
|
||||
* the input string, must be valid JSON
|
||||
* @throws ParseException
|
||||
* if the input is not valid JSON
|
||||
*/
|
||||
public void parse(String string) {
|
||||
if (string == null) {
|
||||
throw new NullPointerException("string is null");
|
||||
}
|
||||
int bufferSize = Math.max(MIN_BUFFER_SIZE, Math.min(DEFAULT_BUFFER_SIZE, string.length()));
|
||||
try {
|
||||
parse(new StringReader(string), bufferSize);
|
||||
} catch (IOException exception) {
|
||||
// StringReader does not throw IOException
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the entire input from the given reader and parses it as JSON. The input must contain a
|
||||
* valid JSON value, optionally padded with whitespace.
|
||||
* <p>
|
||||
* Characters are read in chunks into a default-sized input buffer. Hence, wrapping a reader in an
|
||||
* additional <code>BufferedReader</code> likely won't improve reading performance.
|
||||
* </p>
|
||||
*
|
||||
* @param reader
|
||||
* the reader to read the input from
|
||||
* @throws IOException
|
||||
* if an I/O error occurs in the reader
|
||||
* @throws ParseException
|
||||
* if the input is not valid JSON
|
||||
*/
|
||||
public void parse(Reader reader) throws IOException {
|
||||
parse(reader, DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the entire input from the given reader and parses it as JSON. The input must contain a
|
||||
* valid JSON value, optionally padded with whitespace.
|
||||
* <p>
|
||||
* Characters are read in chunks into an input buffer of the given size. Hence, wrapping a reader
|
||||
* in an additional <code>BufferedReader</code> likely won't improve reading performance.
|
||||
* </p>
|
||||
*
|
||||
* @param reader
|
||||
* the reader to read the input from
|
||||
* @param buffersize
|
||||
* the size of the input buffer in chars
|
||||
* @throws IOException
|
||||
* if an I/O error occurs in the reader
|
||||
* @throws ParseException
|
||||
* if the input is not valid JSON
|
||||
*/
|
||||
public void parse(Reader reader, int buffersize) throws IOException {
|
||||
if (reader == null) {
|
||||
throw new NullPointerException("reader is null");
|
||||
}
|
||||
if (buffersize <= 0) {
|
||||
throw new IllegalArgumentException("buffersize is zero or negative");
|
||||
}
|
||||
this.reader = reader;
|
||||
buffer = new char[buffersize];
|
||||
bufferOffset = 0;
|
||||
index = 0;
|
||||
fill = 0;
|
||||
line = 1;
|
||||
lineOffset = 0;
|
||||
current = 0;
|
||||
captureStart = -1;
|
||||
read();
|
||||
skipWhiteSpace();
|
||||
readValue();
|
||||
skipWhiteSpace();
|
||||
if (!isEndOfText()) {
|
||||
throw error("Unexpected character");
|
||||
}
|
||||
}
|
||||
|
||||
private void readValue() throws IOException {
|
||||
switch (current) {
|
||||
case 'n':
|
||||
readNull();
|
||||
break;
|
||||
case 't':
|
||||
readTrue();
|
||||
break;
|
||||
case 'f':
|
||||
readFalse();
|
||||
break;
|
||||
case '"':
|
||||
readString();
|
||||
break;
|
||||
case '[':
|
||||
readArray();
|
||||
break;
|
||||
case '{':
|
||||
readObject();
|
||||
break;
|
||||
case '-':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
readNumber();
|
||||
break;
|
||||
default:
|
||||
throw expected("value");
|
||||
}
|
||||
}
|
||||
|
||||
private void readArray() throws IOException {
|
||||
Object array = handler.startArray();
|
||||
read();
|
||||
if (++nestingLevel > MAX_NESTING_LEVEL) {
|
||||
throw error("Nesting too deep");
|
||||
}
|
||||
skipWhiteSpace();
|
||||
if (readChar(']')) {
|
||||
nestingLevel--;
|
||||
handler.endArray(array);
|
||||
return;
|
||||
}
|
||||
do {
|
||||
skipWhiteSpace();
|
||||
handler.startArrayValue(array);
|
||||
readValue();
|
||||
handler.endArrayValue(array);
|
||||
skipWhiteSpace();
|
||||
} while (readChar(','));
|
||||
if (!readChar(']')) {
|
||||
throw expected("',' or ']'");
|
||||
}
|
||||
nestingLevel--;
|
||||
handler.endArray(array);
|
||||
}
|
||||
|
||||
private void readObject() throws IOException {
|
||||
Object object = handler.startObject();
|
||||
read();
|
||||
if (++nestingLevel > MAX_NESTING_LEVEL) {
|
||||
throw error("Nesting too deep");
|
||||
}
|
||||
skipWhiteSpace();
|
||||
if (readChar('}')) {
|
||||
nestingLevel--;
|
||||
handler.endObject(object);
|
||||
return;
|
||||
}
|
||||
do {
|
||||
skipWhiteSpace();
|
||||
handler.startObjectName(object);
|
||||
String name = readName();
|
||||
handler.endObjectName(object, name);
|
||||
skipWhiteSpace();
|
||||
if (!readChar(':')) {
|
||||
throw expected("':'");
|
||||
}
|
||||
skipWhiteSpace();
|
||||
handler.startObjectValue(object, name);
|
||||
readValue();
|
||||
handler.endObjectValue(object, name);
|
||||
skipWhiteSpace();
|
||||
} while (readChar(','));
|
||||
if (!readChar('}')) {
|
||||
throw expected("',' or '}'");
|
||||
}
|
||||
nestingLevel--;
|
||||
handler.endObject(object);
|
||||
}
|
||||
|
||||
private String readName() throws IOException {
|
||||
if (current != '"') {
|
||||
throw expected("name");
|
||||
}
|
||||
return readStringInternal();
|
||||
}
|
||||
|
||||
private void readNull() throws IOException {
|
||||
handler.startNull();
|
||||
read();
|
||||
readRequiredChar('u');
|
||||
readRequiredChar('l');
|
||||
readRequiredChar('l');
|
||||
handler.endNull();
|
||||
}
|
||||
|
||||
private void readTrue() throws IOException {
|
||||
handler.startBoolean();
|
||||
read();
|
||||
readRequiredChar('r');
|
||||
readRequiredChar('u');
|
||||
readRequiredChar('e');
|
||||
handler.endBoolean(true);
|
||||
}
|
||||
|
||||
private void readFalse() throws IOException {
|
||||
handler.startBoolean();
|
||||
read();
|
||||
readRequiredChar('a');
|
||||
readRequiredChar('l');
|
||||
readRequiredChar('s');
|
||||
readRequiredChar('e');
|
||||
handler.endBoolean(false);
|
||||
}
|
||||
|
||||
private void readRequiredChar(char ch) throws IOException {
|
||||
if (!readChar(ch)) {
|
||||
throw expected("'" + ch + "'");
|
||||
}
|
||||
}
|
||||
|
||||
private void readString() throws IOException {
|
||||
handler.startString();
|
||||
handler.endString(readStringInternal());
|
||||
}
|
||||
|
||||
private String readStringInternal() throws IOException {
|
||||
read();
|
||||
startCapture();
|
||||
while (current != '"') {
|
||||
if (current == '\\') {
|
||||
pauseCapture();
|
||||
readEscape();
|
||||
startCapture();
|
||||
} else if (current < 0x20) {
|
||||
throw expected("valid string character");
|
||||
} else {
|
||||
read();
|
||||
}
|
||||
}
|
||||
String string = endCapture();
|
||||
read();
|
||||
return string;
|
||||
}
|
||||
|
||||
private void readEscape() throws IOException {
|
||||
read();
|
||||
switch (current) {
|
||||
case '"':
|
||||
case '/':
|
||||
case '\\':
|
||||
captureBuffer.append((char)current);
|
||||
break;
|
||||
case 'b':
|
||||
captureBuffer.append('\b');
|
||||
break;
|
||||
case 'f':
|
||||
captureBuffer.append('\f');
|
||||
break;
|
||||
case 'n':
|
||||
captureBuffer.append('\n');
|
||||
break;
|
||||
case 'r':
|
||||
captureBuffer.append('\r');
|
||||
break;
|
||||
case 't':
|
||||
captureBuffer.append('\t');
|
||||
break;
|
||||
case 'u':
|
||||
char[] hexChars = new char[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
read();
|
||||
if (!isHexDigit()) {
|
||||
throw expected("hexadecimal digit");
|
||||
}
|
||||
hexChars[i] = (char)current;
|
||||
}
|
||||
captureBuffer.append((char)Integer.parseInt(new String(hexChars), 16));
|
||||
break;
|
||||
default:
|
||||
throw expected("valid escape sequence");
|
||||
}
|
||||
read();
|
||||
}
|
||||
|
||||
private void readNumber() throws IOException {
|
||||
handler.startNumber();
|
||||
startCapture();
|
||||
readChar('-');
|
||||
int firstDigit = current;
|
||||
if (!readDigit()) {
|
||||
throw expected("digit");
|
||||
}
|
||||
if (firstDigit != '0') {
|
||||
while (readDigit()) {
|
||||
}
|
||||
}
|
||||
readFraction();
|
||||
readExponent();
|
||||
handler.endNumber(endCapture());
|
||||
}
|
||||
|
||||
private boolean readFraction() throws IOException {
|
||||
if (!readChar('.')) {
|
||||
return false;
|
||||
}
|
||||
if (!readDigit()) {
|
||||
throw expected("digit");
|
||||
}
|
||||
while (readDigit()) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean readExponent() throws IOException {
|
||||
if (!readChar('e') && !readChar('E')) {
|
||||
return false;
|
||||
}
|
||||
if (!readChar('+')) {
|
||||
readChar('-');
|
||||
}
|
||||
if (!readDigit()) {
|
||||
throw expected("digit");
|
||||
}
|
||||
while (readDigit()) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean readChar(char ch) throws IOException {
|
||||
if (current != ch) {
|
||||
return false;
|
||||
}
|
||||
read();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean readDigit() throws IOException {
|
||||
if (!isDigit()) {
|
||||
return false;
|
||||
}
|
||||
read();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void skipWhiteSpace() throws IOException {
|
||||
while (isWhiteSpace()) {
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
private void read() throws IOException {
|
||||
if (index == fill) {
|
||||
if (captureStart != -1) {
|
||||
captureBuffer.append(buffer, captureStart, fill - captureStart);
|
||||
captureStart = 0;
|
||||
}
|
||||
bufferOffset += fill;
|
||||
fill = reader.read(buffer, 0, buffer.length);
|
||||
index = 0;
|
||||
if (fill == -1) {
|
||||
current = -1;
|
||||
index++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (current == '\n') {
|
||||
line++;
|
||||
lineOffset = bufferOffset + index;
|
||||
}
|
||||
current = buffer[index++];
|
||||
}
|
||||
|
||||
private void startCapture() {
|
||||
if (captureBuffer == null) {
|
||||
captureBuffer = new StringBuilder();
|
||||
}
|
||||
captureStart = index - 1;
|
||||
}
|
||||
|
||||
private void pauseCapture() {
|
||||
int end = current == -1 ? index : index - 1;
|
||||
captureBuffer.append(buffer, captureStart, end - captureStart);
|
||||
captureStart = -1;
|
||||
}
|
||||
|
||||
private String endCapture() {
|
||||
int start = captureStart;
|
||||
int end = index - 1;
|
||||
captureStart = -1;
|
||||
if (captureBuffer.length() > 0) {
|
||||
captureBuffer.append(buffer, start, end - start);
|
||||
String captured = captureBuffer.toString();
|
||||
captureBuffer.setLength(0);
|
||||
return captured;
|
||||
}
|
||||
return new String(buffer, start, end - start);
|
||||
}
|
||||
|
||||
Location getLocation() {
|
||||
int offset = bufferOffset + index - 1;
|
||||
int column = offset - lineOffset + 1;
|
||||
return new Location(offset, line, column);
|
||||
}
|
||||
|
||||
private ParseException expected(String expected) {
|
||||
if (isEndOfText()) {
|
||||
return error("Unexpected end of input");
|
||||
}
|
||||
return error("Expected " + expected);
|
||||
}
|
||||
|
||||
private ParseException error(String message) {
|
||||
return new ParseException(message, getLocation());
|
||||
}
|
||||
|
||||
private boolean isWhiteSpace() {
|
||||
return current == ' ' || current == '\t' || current == '\n' || current == '\r';
|
||||
}
|
||||
|
||||
private boolean isDigit() {
|
||||
return current >= '0' && current <= '9';
|
||||
}
|
||||
|
||||
private boolean isHexDigit() {
|
||||
return current >= '0' && current <= '9'
|
||||
|| current >= 'a' && current <= 'f'
|
||||
|| current >= 'A' && current <= 'F';
|
||||
}
|
||||
|
||||
private boolean isEndOfText() {
|
||||
return current == -1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 EclipseSource.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
// from https://github.com/ralfstx/minimal-json
|
||||
|
||||
package com.formdev.flatlaf.json;
|
||||
|
||||
|
||||
/**
|
||||
* An immutable object that represents a location in the parsed text.
|
||||
*/
|
||||
public class Location {
|
||||
|
||||
/**
|
||||
* The absolute character index, starting at 0.
|
||||
*/
|
||||
public final int offset;
|
||||
|
||||
/**
|
||||
* The line number, starting at 1.
|
||||
*/
|
||||
public final int line;
|
||||
|
||||
/**
|
||||
* The column number, starting at 1.
|
||||
*/
|
||||
public final int column;
|
||||
|
||||
Location(int offset, int line, int column) {
|
||||
this.offset = offset;
|
||||
this.column = column;
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return line + ":" + column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Location other = (Location)obj;
|
||||
return offset == other.offset && column == other.column && line == other.line;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013, 2016 EclipseSource.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
// from https://github.com/ralfstx/minimal-json
|
||||
|
||||
package com.formdev.flatlaf.json;
|
||||
|
||||
/**
|
||||
* An unchecked exception to indicate that an input does not qualify as valid JSON.
|
||||
*/
|
||||
public class ParseException extends RuntimeException {
|
||||
|
||||
private final Location location;
|
||||
|
||||
ParseException(String message, Location location) {
|
||||
super(message + " at " + location);
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location at which the error occurred.
|
||||
*
|
||||
* @return the error location
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute character index at which the error occurred. The offset of the first
|
||||
* character of a document is 0.
|
||||
*
|
||||
* @return the character offset at which the error occurred, will be >= 0
|
||||
* @deprecated Use {@link #getLocation()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public int getOffset() {
|
||||
return location.offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the line number in which the error occurred. The number of the first line is 1.
|
||||
*
|
||||
* @return the line in which the error occurred, will be >= 1
|
||||
* @deprecated Use {@link #getLocation()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public int getLine() {
|
||||
return location.line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the column number at which the error occurred, i.e. the number of the character in its
|
||||
* line. The number of the first character of a line is 1.
|
||||
*
|
||||
* @return the column in which the error occurred, will be >= 1
|
||||
* @deprecated Use {@link #getLocation()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public int getColumn() {
|
||||
return location.column;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2021 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.resources;
|
||||
|
||||
/**
|
||||
* The only purpose of this file is to add a .class file to this package to make it non-empty.
|
||||
* Otherwise the compiler outputs a warning because this package is opend in module-info.java.
|
||||
* Also when using --patch-module (e.g. from an IDE), an error would occur for empty packages.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
interface EmptyPackage
|
||||
{
|
||||
}
|
||||
@@ -17,15 +17,14 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicArrowButton;
|
||||
|
||||
@@ -38,32 +37,36 @@ public class FlatArrowButton
|
||||
extends BasicArrowButton
|
||||
implements UIResource
|
||||
{
|
||||
private final boolean chevron;
|
||||
private final Color foreground;
|
||||
private final Color disabledForeground;
|
||||
private final Color hoverForeground;
|
||||
private final Color hoverBackground;
|
||||
public static final int DEFAULT_ARROW_WIDTH = 8;
|
||||
|
||||
private int xOffset = 0;
|
||||
private int yOffset = 0;
|
||||
protected boolean chevron;
|
||||
protected Color foreground;
|
||||
protected Color disabledForeground;
|
||||
protected Color hoverForeground;
|
||||
protected Color hoverBackground;
|
||||
protected Color pressedForeground;
|
||||
protected Color pressedBackground;
|
||||
|
||||
private int arrowWidth = DEFAULT_ARROW_WIDTH;
|
||||
private float xOffset = 0;
|
||||
private float yOffset = 0;
|
||||
|
||||
private boolean hover;
|
||||
private boolean pressed;
|
||||
|
||||
public FlatArrowButton( int direction, String type, Color foreground, Color disabledForeground,
|
||||
Color hoverForeground, Color hoverBackground )
|
||||
Color hoverForeground, Color hoverBackground, Color pressedForeground, Color pressedBackground )
|
||||
{
|
||||
super( direction, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE );
|
||||
|
||||
this.chevron = "chevron".equals( type );
|
||||
this.foreground = foreground;
|
||||
this.disabledForeground = disabledForeground;
|
||||
this.hoverForeground = hoverForeground;
|
||||
this.hoverBackground = hoverBackground;
|
||||
updateStyle( type, foreground, disabledForeground, hoverForeground, hoverBackground,
|
||||
pressedForeground, pressedBackground );
|
||||
|
||||
setOpaque( false );
|
||||
setBorder( null );
|
||||
|
||||
if( hoverForeground != null || hoverBackground != null ) {
|
||||
if( hoverForeground != null || hoverBackground != null ||
|
||||
pressedForeground != null || pressedBackground != null )
|
||||
{
|
||||
addMouseListener( new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered( MouseEvent e ) {
|
||||
@@ -76,30 +79,90 @@ public class FlatArrowButton
|
||||
hover = false;
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed( MouseEvent e ) {
|
||||
pressed = true;
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased( MouseEvent e ) {
|
||||
pressed = false;
|
||||
repaint();
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public void updateStyle( String type, Color foreground, Color disabledForeground,
|
||||
Color hoverForeground, Color hoverBackground, Color pressedForeground, Color pressedBackground )
|
||||
{
|
||||
this.chevron = FlatUIUtils.isChevron( type );
|
||||
this.foreground = foreground;
|
||||
this.disabledForeground = disabledForeground;
|
||||
this.hoverForeground = hoverForeground;
|
||||
this.hoverBackground = hoverBackground;
|
||||
this.pressedForeground = pressedForeground;
|
||||
this.pressedBackground = pressedBackground;
|
||||
}
|
||||
|
||||
public int getArrowWidth() {
|
||||
return arrowWidth;
|
||||
}
|
||||
|
||||
public void setArrowWidth( int arrowWidth ) {
|
||||
this.arrowWidth = arrowWidth;
|
||||
}
|
||||
|
||||
protected boolean isHover() {
|
||||
return hover;
|
||||
}
|
||||
|
||||
public int getXOffset() {
|
||||
protected boolean isPressed() {
|
||||
return pressed;
|
||||
}
|
||||
|
||||
public float getXOffset() {
|
||||
return xOffset;
|
||||
}
|
||||
|
||||
public void setXOffset( int xOffset ) {
|
||||
public void setXOffset( float xOffset ) {
|
||||
this.xOffset = xOffset;
|
||||
}
|
||||
|
||||
public int getYOffset() {
|
||||
public float getYOffset() {
|
||||
return yOffset;
|
||||
}
|
||||
|
||||
public void setYOffset( int yOffset ) {
|
||||
public void setYOffset( float yOffset ) {
|
||||
this.yOffset = yOffset;
|
||||
}
|
||||
|
||||
protected Color deriveBackground( Color background ) {
|
||||
return background;
|
||||
}
|
||||
|
||||
protected Color deriveForeground( Color foreground ) {
|
||||
return FlatUIUtils.deriveColor( foreground, this.foreground );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color used to paint the arrow.
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
protected Color getArrowColor() {
|
||||
return isEnabled()
|
||||
? (pressedForeground != null && isPressed()
|
||||
? pressedForeground
|
||||
: (hoverForeground != null && isHover()
|
||||
? hoverForeground
|
||||
: foreground))
|
||||
: disabledForeground;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return scale( super.getPreferredSize() );
|
||||
@@ -112,58 +175,42 @@ public class FlatArrowButton
|
||||
|
||||
@Override
|
||||
public void paint( Graphics g ) {
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
FlatUIUtils.setRenderingHints( g2 );
|
||||
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
boolean enabled = isEnabled();
|
||||
// paint hover or pressed background
|
||||
if( isEnabled() ) {
|
||||
Color background = (pressedBackground != null && isPressed())
|
||||
? pressedBackground
|
||||
: (hoverBackground != null && isHover()
|
||||
? hoverBackground
|
||||
: null);
|
||||
|
||||
// paint hover background
|
||||
if( enabled && isHover() && hoverBackground != null ) {
|
||||
g.setColor( hoverBackground );
|
||||
g.fillRect( 0, 0, width, height );
|
||||
if( background != null ) {
|
||||
g.setColor( deriveBackground( background ) );
|
||||
paintBackground( (Graphics2D) g );
|
||||
}
|
||||
}
|
||||
|
||||
int direction = getDirection();
|
||||
boolean vert = (direction == NORTH || direction == SOUTH);
|
||||
|
||||
int w = scale( chevron ? 8 : 9 );
|
||||
int h = scale( chevron ? 4 : 5 );
|
||||
int rw = vert ? w : h;
|
||||
int rh = vert ? h : w;
|
||||
int x = Math.round( (width - rw) / 2f + scale( (float) xOffset ) );
|
||||
int y = Math.round( (height - rh) / 2f + scale( (float) yOffset ) );
|
||||
|
||||
// optimization for small chevron arrows (e.g. OneTouchButtons in SplitPane)
|
||||
if( x + rw >= width && x > 0 )
|
||||
x--;
|
||||
if( y + rh >= height && y > 0 )
|
||||
y--;
|
||||
|
||||
// paint arrow
|
||||
g.setColor( enabled
|
||||
? (isHover() && hoverForeground != null ? hoverForeground : foreground)
|
||||
: disabledForeground );
|
||||
g.translate( x, y );
|
||||
Shape arrowShape = createArrowShape( direction, chevron, w, h );
|
||||
if( chevron ) {
|
||||
g2.setStroke( new BasicStroke( scale( 1f ) ) );
|
||||
g2.draw( arrowShape );
|
||||
} else {
|
||||
// triangle
|
||||
g2.fill( arrowShape );
|
||||
}
|
||||
g.translate( -x, -y );
|
||||
g.setColor( deriveForeground( getArrowColor() ) );
|
||||
paintArrow( (Graphics2D) g );
|
||||
|
||||
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||
}
|
||||
|
||||
public static Shape createArrowShape( int direction, boolean chevron, int w, int h ) {
|
||||
switch( direction ) {
|
||||
case NORTH: return FlatUIUtils.createPath( !chevron, 0,h, (w / 2f),0, w,h );
|
||||
case SOUTH: return FlatUIUtils.createPath( !chevron, 0,0, (w / 2f),h, w,0 );
|
||||
case WEST: return FlatUIUtils.createPath( !chevron, h,0, 0,(w / 2f), h,w );
|
||||
case EAST: return FlatUIUtils.createPath( !chevron, 0,0, h,(w / 2f), 0,w );
|
||||
default: return new Path2D.Float();
|
||||
}
|
||||
protected void paintBackground( Graphics2D g ) {
|
||||
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||
}
|
||||
|
||||
protected void paintArrow( Graphics2D g ) {
|
||||
boolean vert = (direction == NORTH || direction == SOUTH);
|
||||
int x = 0;
|
||||
|
||||
// move arrow for round borders
|
||||
Container parent = getParent();
|
||||
if( vert && parent instanceof JComponent && FlatUIUtils.hasRoundBorder( (JComponent) parent ) )
|
||||
x -= scale( parent.getComponentOrientation().isLeftToRight() ? 1 : -1 );
|
||||
|
||||
FlatUIUtils.paintArrow( g, x, 0, getWidth(), getHeight(), getDirection(), chevron, arrowWidth, xOffset, yOffset );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,49 +22,84 @@ import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Paint;
|
||||
import java.util.Map;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.basic.BasicBorders;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableBorder;
|
||||
import com.formdev.flatlaf.util.DerivedColor;
|
||||
|
||||
/**
|
||||
* Border for various components (e.g. {@link javax.swing.JTextField}).
|
||||
*
|
||||
* <p>
|
||||
* There is empty space around the component border, if Component.focusWidth is greater than zero,
|
||||
* which is used to paint focus border.
|
||||
*
|
||||
* Because there is empty space (if focus border is not painted),
|
||||
* which is used to paint outer focus border.
|
||||
* <p>
|
||||
* Because there is empty space (if outer focus border is not painted),
|
||||
* UI delegates that use this border (or subclasses) must invoke
|
||||
* {@link FlatUIUtils#paintParentBackground} to paint the empty space correctly.
|
||||
* {@link FlatUIUtils#paintParentBackground} to fill the empty space correctly.
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.innerFocusWidth int
|
||||
* @uiDefault Component.focusColor Color
|
||||
* @uiDefault Component.borderColor Color
|
||||
* @uiDefault Component.disabledBorderColor Color
|
||||
* @uiDefault Component.focusedBorderColor Color
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.innerFocusWidth int or float
|
||||
* @uiDefault Component.innerOutlineWidth int or float
|
||||
* @uiDefault Component.borderWidth int or float
|
||||
*
|
||||
* @uiDefault Component.focusColor Color
|
||||
* @uiDefault Component.borderColor Color
|
||||
* @uiDefault Component.disabledBorderColor Color
|
||||
* @uiDefault Component.focusedBorderColor Color
|
||||
*
|
||||
* @uiDefault Component.error.borderColor Color
|
||||
* @uiDefault Component.error.focusedBorderColor Color
|
||||
* @uiDefault Component.warning.borderColor Color
|
||||
* @uiDefault Component.warning.focusedBorderColor Color
|
||||
* @uiDefault Component.custom.borderColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatBorder
|
||||
extends BasicBorders.MarginBorder
|
||||
implements StyleableBorder
|
||||
{
|
||||
protected final int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
protected final int innerFocusWidth = UIManager.getInt( "Component.innerFocusWidth" );
|
||||
protected final Color focusColor = UIManager.getColor( "Component.focusColor" );
|
||||
protected final Color borderColor = UIManager.getColor( "Component.borderColor" );
|
||||
protected final Color disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
||||
protected final Color focusedBorderColor = UIManager.getColor( "Component.focusedBorderColor" );
|
||||
@Styleable protected int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
@Styleable protected float innerFocusWidth = FlatUIUtils.getUIFloat( "Component.innerFocusWidth", 0 );
|
||||
@Styleable protected float innerOutlineWidth = FlatUIUtils.getUIFloat( "Component.innerOutlineWidth", 0 );
|
||||
/** @since 2 */ @Styleable protected float borderWidth = FlatUIUtils.getUIFloat( "Component.borderWidth", 1 );
|
||||
|
||||
@Styleable protected Color focusColor = UIManager.getColor( "Component.focusColor" );
|
||||
@Styleable protected Color borderColor = UIManager.getColor( "Component.borderColor" );
|
||||
@Styleable protected Color disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
||||
@Styleable protected Color focusedBorderColor = UIManager.getColor( "Component.focusedBorderColor" );
|
||||
|
||||
@Styleable(dot=true) protected Color errorBorderColor = UIManager.getColor( "Component.error.borderColor" );
|
||||
@Styleable(dot=true) protected Color errorFocusedBorderColor = UIManager.getColor( "Component.error.focusedBorderColor" );
|
||||
@Styleable(dot=true) protected Color warningBorderColor = UIManager.getColor( "Component.warning.borderColor" );
|
||||
@Styleable(dot=true) protected Color warningFocusedBorderColor = UIManager.getColor( "Component.warning.focusedBorderColor" );
|
||||
@Styleable(dot=true) protected Color customBorderColor = UIManager.getColor( "Component.custom.borderColor" );
|
||||
|
||||
// only used via styling (not in UI defaults, but has likewise client properties)
|
||||
/** @since 2 */ @Styleable protected String outline;
|
||||
/** @since 2 */ @Styleable protected Color outlineColor;
|
||||
/** @since 2 */ @Styleable protected Color outlineFocusedColor;
|
||||
|
||||
/** @since 2 */
|
||||
@Override
|
||||
public Object applyStyleProperty( String key, Object value ) {
|
||||
return FlatStylingSupport.applyToAnnotatedObject( this, key, value );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
@Override
|
||||
public Map<String, Class<?>> getStyleableInfos() {
|
||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
@@ -72,91 +107,175 @@ public class FlatBorder
|
||||
try {
|
||||
FlatUIUtils.setRenderingHints( g2 );
|
||||
|
||||
float focusWidth = getFocusWidth();
|
||||
float borderWidth = getBorderWidth( c );
|
||||
float arc = getArc();
|
||||
float focusWidth = scale( (float) getFocusWidth( c ) );
|
||||
float focusInnerWidth = 0;
|
||||
float borderWidth = scale( getBorderWidth( c ) );
|
||||
float arc = scale( (float) getArc( c ) );
|
||||
Color outlineColor = getOutlineColor( c );
|
||||
Color focusColor = null;
|
||||
|
||||
if( isFocused( c ) ) {
|
||||
g2.setColor( getFocusColor( c ) );
|
||||
FlatUIUtils.paintOutlineBorder( g2, x, y, width, height, focusWidth,
|
||||
getLineWidth() + scale( (float) innerFocusWidth ), arc );
|
||||
// paint outer border
|
||||
if( outlineColor != null || isFocused( c ) ) {
|
||||
float innerWidth = !isCellEditor( c ) && !(c instanceof JScrollPane)
|
||||
? (outlineColor != null ? innerOutlineWidth : getInnerFocusWidth( c ))
|
||||
: 0;
|
||||
|
||||
if( focusWidth > 0 || innerWidth > 0 ) {
|
||||
focusColor = (outlineColor != null) ? outlineColor : getFocusColor( c );
|
||||
focusInnerWidth = borderWidth + scale( innerWidth );
|
||||
}
|
||||
}
|
||||
|
||||
g2.setPaint( getBorderColor( c ) );
|
||||
FlatUIUtils.drawRoundRectangle( g2, x, y, width, height, focusWidth, borderWidth, arc );
|
||||
// paint border
|
||||
Paint borderColor = (outlineColor != null) ? outlineColor : getBorderColor( c );
|
||||
FlatUIUtils.paintOutlinedComponent( g2, x, y, width, height,
|
||||
focusWidth, 1, focusInnerWidth, borderWidth, arc,
|
||||
focusColor, borderColor, null );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the outline color of the component border specified in client property
|
||||
* {@link FlatClientProperties#OUTLINE}.
|
||||
*/
|
||||
protected Color getOutlineColor( Component c ) {
|
||||
if( !(c instanceof JComponent) )
|
||||
return null;
|
||||
|
||||
Object outline = ((JComponent)c).getClientProperty( FlatClientProperties.OUTLINE );
|
||||
if( outline == null )
|
||||
outline = this.outline;
|
||||
if( outline == null ) {
|
||||
if( outlineColor != null && outlineFocusedColor != null )
|
||||
outline = new Color[] { outlineFocusedColor, outlineColor };
|
||||
else if( outlineColor != null )
|
||||
outline = outlineColor;
|
||||
else if( outlineFocusedColor != null )
|
||||
outline = outlineFocusedColor;
|
||||
}
|
||||
|
||||
if( outline instanceof String ) {
|
||||
switch( (String) outline ) {
|
||||
case FlatClientProperties.OUTLINE_ERROR:
|
||||
return isFocused( c ) ? errorFocusedBorderColor : errorBorderColor;
|
||||
|
||||
case FlatClientProperties.OUTLINE_WARNING:
|
||||
return isFocused( c ) ? warningFocusedBorderColor : warningBorderColor;
|
||||
}
|
||||
} else if( outline instanceof Color ) {
|
||||
Color color = (Color) outline;
|
||||
// use color functions to compute color for unfocused state
|
||||
if( !isFocused( c ) && customBorderColor instanceof DerivedColor )
|
||||
color = ((DerivedColor)customBorderColor).derive( color );
|
||||
return color;
|
||||
} else if( outline instanceof Color[] && ((Color[])outline).length >= 2 )
|
||||
return ((Color[])outline)[isFocused( c ) ? 0 : 1];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Color getFocusColor( Component c ) {
|
||||
return focusColor;
|
||||
}
|
||||
|
||||
protected Paint getBorderColor( Component c ) {
|
||||
boolean enabled = c.isEnabled() && (!(c instanceof JTextComponent) || ((JTextComponent)c).isEditable());
|
||||
return enabled
|
||||
return isEnabled( c )
|
||||
? (isFocused( c ) ? focusedBorderColor : borderColor)
|
||||
: disabledBorderColor;
|
||||
}
|
||||
|
||||
protected boolean isFocused( Component c ) {
|
||||
protected boolean isEnabled( Component c ) {
|
||||
if( c instanceof JScrollPane ) {
|
||||
// check whether view component is disabled
|
||||
JViewport viewport = ((JScrollPane)c).getViewport();
|
||||
Component view = (viewport != null) ? viewport.getView() : null;
|
||||
if( view != null ) {
|
||||
if( view.hasFocus() )
|
||||
return true;
|
||||
if( view != null && !isEnabled( view ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( (view instanceof JTable && ((JTable)view).isEditing()) ||
|
||||
(view instanceof JTree && ((JTree)view).isEditing()) )
|
||||
{
|
||||
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
|
||||
if( focusOwner != null )
|
||||
return SwingUtilities.isDescendingFrom( focusOwner, view );
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if( c instanceof JComboBox && ((JComboBox<?>)c).isEditable() ) {
|
||||
Component editorComponent = ((JComboBox<?>)c).getEditor().getEditorComponent();
|
||||
return (editorComponent != null) ? editorComponent.hasFocus() : false;
|
||||
} else if( c instanceof JSpinner ) {
|
||||
JComponent editor = ((JSpinner)c).getEditor();
|
||||
if( editor instanceof JSpinner.DefaultEditor ) {
|
||||
JTextField textField = ((JSpinner.DefaultEditor)editor).getTextField();
|
||||
if( textField != null )
|
||||
return textField.hasFocus();
|
||||
}
|
||||
return false;
|
||||
} else
|
||||
return c.hasFocus();
|
||||
return c.isEnabled();
|
||||
}
|
||||
|
||||
protected boolean isFocused( Component c ) {
|
||||
if( c instanceof JScrollPane )
|
||||
return FlatScrollPaneUI.isPermanentFocusOwner( (JScrollPane) c );
|
||||
else if( c instanceof JComboBox )
|
||||
return FlatComboBoxUI.isPermanentFocusOwner( (JComboBox<?>) c );
|
||||
else if( c instanceof JSpinner )
|
||||
return FlatSpinnerUI.isPermanentFocusOwner( (JSpinner) c );
|
||||
else
|
||||
return FlatUIUtils.isPermanentFocusOwner( c );
|
||||
}
|
||||
|
||||
protected boolean isCellEditor( Component c ) {
|
||||
return FlatUIUtils.isCellEditor( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||
float ow = getFocusWidth() + getLineWidth();
|
||||
float focusWidth = scale( (float) getFocusWidth( c ) );
|
||||
int ow = Math.round( focusWidth + scale( (float) getLineWidth( c ) ) );
|
||||
|
||||
insets = super.getBorderInsets( c, insets );
|
||||
insets.top = Math.round( scale( (float) insets.top ) + ow );
|
||||
insets.left = Math.round( scale( (float) insets.left ) + ow );
|
||||
insets.bottom = Math.round( scale( (float) insets.bottom ) + ow );
|
||||
insets.right = Math.round( scale( (float) insets.right ) + ow );
|
||||
|
||||
insets.top = scale( insets.top ) + ow;
|
||||
insets.left = scale( insets.left ) + ow;
|
||||
insets.bottom = scale( insets.bottom ) + ow;
|
||||
insets.right = scale( insets.right ) + ow;
|
||||
|
||||
if( isCellEditor( c ) ) {
|
||||
// remove top and bottom insets if used as cell editor
|
||||
insets.top = insets.bottom = 0;
|
||||
|
||||
// remove right/left insets to avoid that text is truncated (e.g. in file chooser)
|
||||
if( c.getComponentOrientation().isLeftToRight() )
|
||||
insets.right = 0;
|
||||
else
|
||||
insets.left = 0;
|
||||
}
|
||||
|
||||
return insets;
|
||||
}
|
||||
|
||||
protected float getFocusWidth() {
|
||||
return scale( (float) focusWidth );
|
||||
/**
|
||||
* Returns the (unscaled) thickness of the outer focus border.
|
||||
*/
|
||||
protected int getFocusWidth( Component c ) {
|
||||
if( isCellEditor( c ) )
|
||||
return 0;
|
||||
|
||||
return focusWidth;
|
||||
}
|
||||
|
||||
protected float getLineWidth() {
|
||||
return scale( 1f );
|
||||
/**
|
||||
* Returns the (unscaled) thickness of the inner focus border.
|
||||
*/
|
||||
protected float getInnerFocusWidth( Component c ) {
|
||||
return innerFocusWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the (unscaled) line thickness used to compute the border insets.
|
||||
* This may be different to {@link #getBorderWidth}.
|
||||
*/
|
||||
protected int getLineWidth( Component c ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the (unscaled) line thickness used to paint the border.
|
||||
* This may be different to {@link #getLineWidth}.
|
||||
*/
|
||||
protected float getBorderWidth( Component c ) {
|
||||
return getLineWidth();
|
||||
return borderWidth;
|
||||
}
|
||||
|
||||
protected float getArc() {
|
||||
/**
|
||||
* Returns the (unscaled) arc diameter of the border.
|
||||
*/
|
||||
protected int getArc( Component c ) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,86 +16,186 @@
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Paint;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Border for {@link javax.swing.JButton}.
|
||||
*
|
||||
* @uiDefault Button.arc int
|
||||
* @uiDefault Button.innerFocusWidth int or float optional; defaults to Component.innerFocusWidth
|
||||
* @uiDefault Button.borderWidth int or float optional; defaults to Component.borderWidth
|
||||
*
|
||||
* @uiDefault Button.borderColor Color
|
||||
* @uiDefault Button.startBorderColor Color optional; if set, a gradient paint is used and Button.borderColor is ignored
|
||||
* @uiDefault Button.endBorderColor Color optional; if set, a gradient paint is used
|
||||
* @uiDefault Button.disabledBorderColor Color
|
||||
* @uiDefault Button.focusedBorderColor Color
|
||||
* @uiDefault Button.hoverBorderColor Color optional
|
||||
*
|
||||
* @uiDefault Button.default.borderWidth int or float
|
||||
* @uiDefault Button.default.borderColor Color
|
||||
* @uiDefault Button.default.hoverBorderColor Color optional
|
||||
* @uiDefault Button.default.startBorderColor Color optional; if set, a gradient paint is used and Button.default.borderColor is ignored
|
||||
* @uiDefault Button.default.endBorderColor Color optional; if set, a gradient paint is used
|
||||
* @uiDefault Button.default.focusedBorderColor Color
|
||||
* @uiDefault Button.default.focusColor Color
|
||||
* @uiDefault Button.default.borderWidth int
|
||||
* @uiDefault Button.arc int
|
||||
* @uiDefault Button.default.hoverBorderColor Color optional
|
||||
*
|
||||
* @uiDefault Button.toolbar.focusWidth int or float optional; default is 1.5
|
||||
* @uiDefault Button.toolbar.focusColor Color optional; defaults to Component.focusColor
|
||||
* @uiDefault Button.toolbar.margin Insets
|
||||
* @uiDefault Button.toolbar.spacingInsets Insets
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatButtonBorder
|
||||
extends FlatBorder
|
||||
{
|
||||
protected final Color borderColor = UIManager.getColor( "Button.borderColor" );
|
||||
protected final Color disabledBorderColor = UIManager.getColor( "Button.disabledBorderColor" );
|
||||
protected final Color focusedBorderColor = UIManager.getColor( "Button.focusedBorderColor" );
|
||||
protected final Color hoverBorderColor = UIManager.getColor( "Button.hoverBorderColor" );
|
||||
protected final Color defaultBorderColor = UIManager.getColor( "Button.default.borderColor" );
|
||||
protected final Color defaultHoverBorderColor = UIManager.getColor( "Button.default.hoverBorderColor" );
|
||||
protected final Color defaultFocusedBorderColor = UIManager.getColor( "Button.default.focusedBorderColor" );
|
||||
protected final Color defaultFocusColor = UIManager.getColor( "Button.default.focusColor" );
|
||||
protected final int defaultBorderWidth = UIManager.getInt( "Button.default.borderWidth" );
|
||||
protected final int arc = UIManager.getInt( "Button.arc" );
|
||||
@Styleable protected int arc = UIManager.getInt( "Button.arc" );
|
||||
|
||||
protected Color endBorderColor = UIManager.getColor( "Button.endBorderColor" );
|
||||
@Styleable protected Color hoverBorderColor = UIManager.getColor( "Button.hoverBorderColor" );
|
||||
|
||||
@Styleable(dot=true) protected float defaultBorderWidth = FlatUIUtils.getUIFloat( "Button.default.borderWidth", 1 );
|
||||
@Styleable(dot=true) protected Color defaultBorderColor = FlatUIUtils.getUIColor( "Button.default.startBorderColor", "Button.default.borderColor" );
|
||||
protected Color defaultEndBorderColor = UIManager.getColor( "Button.default.endBorderColor" );
|
||||
@Styleable(dot=true) protected Color defaultFocusedBorderColor = UIManager.getColor( "Button.default.focusedBorderColor" );
|
||||
@Styleable(dot=true) protected Color defaultFocusColor = UIManager.getColor( "Button.default.focusColor" );
|
||||
@Styleable(dot=true) protected Color defaultHoverBorderColor = UIManager.getColor( "Button.default.hoverBorderColor" );
|
||||
|
||||
/** @since 1.4 */ @Styleable(dot=true) protected float toolbarFocusWidth = FlatUIUtils.getUIFloat( "Button.toolbar.focusWidth", 1.5f );
|
||||
/** @since 1.4 */ @Styleable(dot=true) protected Color toolbarFocusColor = UIManager.getColor( "Button.toolbar.focusColor" );
|
||||
@Styleable(dot=true) protected Insets toolbarMargin = UIManager.getInsets( "Button.toolbar.margin" );
|
||||
@Styleable(dot=true) protected Insets toolbarSpacingInsets = UIManager.getInsets( "Button.toolbar.spacingInsets" );
|
||||
|
||||
public FlatButtonBorder() {
|
||||
innerFocusWidth = FlatUIUtils.getUIFloat( "Button.innerFocusWidth", innerFocusWidth );
|
||||
borderWidth = FlatUIUtils.getUIFloat( "Button.borderWidth", borderWidth );
|
||||
|
||||
borderColor = FlatUIUtils.getUIColor( "Button.startBorderColor", "Button.borderColor" );
|
||||
disabledBorderColor = UIManager.getColor( "Button.disabledBorderColor" );
|
||||
focusedBorderColor = UIManager.getColor( "Button.focusedBorderColor" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
if( FlatButtonUI.isContentAreaFilled( c ) && !FlatButtonUI.isHelpButton( c ) )
|
||||
super.paintBorder( c, g, x, y, width, height );
|
||||
if( FlatButtonUI.isContentAreaFilled( c ) &&
|
||||
!FlatButtonUI.isToolBarButton( c ) &&
|
||||
(!FlatButtonUI.isBorderlessButton( c ) || FlatUIUtils.isPermanentFocusOwner( c )) &&
|
||||
!FlatButtonUI.isHelpButton( c ) &&
|
||||
!FlatToggleButtonUI.isTabButton( c ) )
|
||||
super.paintBorder( c, g, x, y, width, height );
|
||||
else if( FlatButtonUI.isToolBarButton( c ) && isFocused( c ) )
|
||||
paintToolBarFocus( c, g, x, y, width, height );
|
||||
}
|
||||
|
||||
/** @since 1.4 */
|
||||
protected void paintToolBarFocus( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
try {
|
||||
FlatUIUtils.setRenderingHints( g2 );
|
||||
|
||||
float focusWidth = UIScale.scale( toolbarFocusWidth );
|
||||
float arc = UIScale.scale( (float) getArc( c ) );
|
||||
Color outlineColor = getOutlineColor( c );
|
||||
|
||||
Insets spacing = UIScale.scale( toolbarSpacingInsets );
|
||||
x += spacing.left;
|
||||
y += spacing.top;
|
||||
width -= spacing.left + spacing.right;
|
||||
height -= spacing.top + spacing.bottom;
|
||||
|
||||
Color color = (outlineColor != null) ? outlineColor : getFocusColor( c );
|
||||
// not using focus border painting of paintOutlinedComponent() here
|
||||
// because its round edges look too "thick"
|
||||
FlatUIUtils.paintOutlinedComponent( g2, x, y, width, height, 0, 0, 0, focusWidth, arc, null, color, null );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getFocusColor( Component c ) {
|
||||
return FlatButtonUI.isDefaultButton( c ) ? defaultFocusColor : super.getFocusColor( c );
|
||||
return (toolbarFocusColor != null && FlatButtonUI.isToolBarButton( c ))
|
||||
? toolbarFocusColor
|
||||
: (FlatButtonUI.isDefaultButton( c ) ? defaultFocusColor : super.getFocusColor( c ));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isFocused( Component c ) {
|
||||
return FlatButtonUI.isFocusPainted( c ) && super.isFocused( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Paint getBorderColor( Component c ) {
|
||||
boolean def = FlatButtonUI.isDefaultButton( c );
|
||||
return FlatButtonUI.buttonStateColor( c,
|
||||
Paint color = FlatButtonUI.buttonStateColor( c,
|
||||
def ? defaultBorderColor : borderColor,
|
||||
disabledBorderColor,
|
||||
def ? defaultFocusedBorderColor : focusedBorderColor,
|
||||
def ? defaultHoverBorderColor : hoverBorderColor,
|
||||
null );
|
||||
|
||||
// change to gradient paint if start/end colors are specified
|
||||
Color startBg = def ? defaultBorderColor : borderColor;
|
||||
Color endBg = def ? defaultEndBorderColor : endBorderColor;
|
||||
if( color == startBg && endBg != null && !startBg.equals( endBg ) )
|
||||
color = new GradientPaint( 0, 0, startBg, 0, c.getHeight(), endBg );
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||
insets = super.getBorderInsets( c, insets );
|
||||
if( FlatButtonUI.isToolBarButton( c ) ) {
|
||||
// In toolbars, use button margin only if explicitly set.
|
||||
// Otherwise use toolbar margin specified in UI defaults.
|
||||
Insets margin = (c instanceof AbstractButton)
|
||||
? ((AbstractButton)c).getMargin()
|
||||
: null;
|
||||
|
||||
// use smaller left and right insets for icon-only buttons (so that they are square)
|
||||
if( FlatButtonUI.isIconOnlyButton( c ) && ((JButton)c).getMargin() instanceof UIResource )
|
||||
insets.left = insets.right = Math.min( insets.top, insets.bottom );
|
||||
FlatUIUtils.setInsets( insets, UIScale.scale( FlatUIUtils.addInsets( toolbarSpacingInsets,
|
||||
(margin != null && !(margin instanceof UIResource)) ? margin : toolbarMargin ) ) );
|
||||
} else {
|
||||
insets = super.getBorderInsets( c, insets );
|
||||
|
||||
// use smaller left and right insets for icon-only or single-character buttons (so that they are square)
|
||||
if( FlatButtonUI.isIconOnlyOrSingleCharacterButton( c ) && ((AbstractButton)c).getMargin() instanceof UIResource )
|
||||
insets.left = insets.right = Math.min( insets.top, insets.bottom );
|
||||
}
|
||||
|
||||
return insets;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getBorderWidth( Component c ) {
|
||||
return FlatButtonUI.isDefaultButton( c ) ? scale( (float) defaultBorderWidth ) : super.getBorderWidth( c );
|
||||
protected int getFocusWidth( Component c ) {
|
||||
return FlatToggleButtonUI.isTabButton( c ) ? 0 : super.getFocusWidth( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getArc() {
|
||||
return scale( (float) arc );
|
||||
protected float getBorderWidth( Component c ) {
|
||||
return FlatButtonUI.isDefaultButton( c ) ? defaultBorderWidth : borderWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getArc( Component c ) {
|
||||
if( isCellEditor( c ) )
|
||||
return 0;
|
||||
|
||||
switch( FlatButtonUI.getButtonType( c ) ) {
|
||||
case FlatButtonUI.TYPE_SQUARE: return 0;
|
||||
case FlatButtonUI.TYPE_ROUND_RECT: return Short.MAX_VALUE;
|
||||
default: return arc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,80 +23,154 @@ import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.ButtonUI;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicButtonListener;
|
||||
import javax.swing.plaf.basic.BasicButtonUI;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.icons.FlatHelpButtonIcon;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JButton}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicButtonUI -->
|
||||
*
|
||||
* @uiDefault Button.font Font
|
||||
* @uiDefault Button.background Color
|
||||
* @uiDefault Button.foreground Color
|
||||
* @uiDefault Button.border Border
|
||||
* @uiDefault Button.margin Insets
|
||||
* @uiDefault Button.rollover boolean
|
||||
*
|
||||
* <!-- FlatButtonUI -->
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Button.arc int
|
||||
* @uiDefault Button.minimumWidth int
|
||||
* @uiDefault Button.iconTextGap int
|
||||
* @uiDefault Button.startBackground Color optional; if set, a gradient paint is used and Button.background is ignored
|
||||
* @uiDefault Button.endBackground Color optional; if set, a gradient paint is used
|
||||
* @uiDefault Button.focusedBackground Color optional
|
||||
* @uiDefault Button.hoverBackground Color optional
|
||||
* @uiDefault Button.pressedBackground Color optional
|
||||
* @uiDefault Button.selectedBackground Color
|
||||
* @uiDefault Button.selectedForeground Color
|
||||
* @uiDefault Button.disabledBackground Color optional
|
||||
* @uiDefault Button.disabledText Color
|
||||
* @uiDefault Button.disabledSelectedBackground Color
|
||||
* @uiDefault Button.default.background Color
|
||||
* @uiDefault Button.default.startBackground Color optional; if set, a gradient paint is used and Button.default.background is ignored
|
||||
* @uiDefault Button.default.endBackground Color optional; if set, a gradient paint is used
|
||||
* @uiDefault Button.default.foreground Color
|
||||
* @uiDefault Button.default.focusedBackground Color optional
|
||||
* @uiDefault Button.default.hoverBackground Color optional
|
||||
* @uiDefault Button.default.pressedBackground Color optional
|
||||
* @uiDefault Button.default.boldText boolean
|
||||
* @uiDefault Button.paintShadow boolean default is false
|
||||
* @uiDefault Button.shadowWidth int default is 2
|
||||
* @uiDefault Button.shadowColor Color optional
|
||||
* @uiDefault Button.default.shadowColor Color optional
|
||||
* @uiDefault Button.toolbar.spacingInsets Insets
|
||||
* @uiDefault Button.toolbar.hoverBackground Color
|
||||
* @uiDefault Button.toolbar.pressedBackground Color
|
||||
* @uiDefault Button.toolbar.selectedBackground Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatButtonUI
|
||||
extends BasicButtonUI
|
||||
implements StyleableUI
|
||||
{
|
||||
protected int focusWidth;
|
||||
protected int arc;
|
||||
protected int minimumWidth;
|
||||
@Styleable protected int minimumWidth;
|
||||
protected int iconTextGap;
|
||||
|
||||
protected Color focusedBackground;
|
||||
protected Color hoverBackground;
|
||||
protected Color pressedBackground;
|
||||
protected Color disabledText;
|
||||
protected Color background;
|
||||
protected Color foreground;
|
||||
|
||||
protected Color defaultBackground;
|
||||
protected Color defaultForeground;
|
||||
protected Color defaultFocusedBackground;
|
||||
protected Color defaultHoverBackground;
|
||||
protected Color defaultPressedBackground;
|
||||
protected boolean defaultBoldText;
|
||||
protected Color startBackground;
|
||||
protected Color endBackground;
|
||||
@Styleable protected Color focusedBackground;
|
||||
@Styleable protected Color hoverBackground;
|
||||
@Styleable protected Color pressedBackground;
|
||||
@Styleable protected Color selectedBackground;
|
||||
@Styleable protected Color selectedForeground;
|
||||
@Styleable protected Color disabledBackground;
|
||||
@Styleable protected Color disabledText;
|
||||
@Styleable protected Color disabledSelectedBackground;
|
||||
|
||||
protected Color toolbarHoverBackground;
|
||||
protected Color toolbarPressedBackground;
|
||||
@Styleable(dot=true) protected Color defaultBackground;
|
||||
protected Color defaultEndBackground;
|
||||
@Styleable(dot=true) protected Color defaultForeground;
|
||||
@Styleable(dot=true) protected Color defaultFocusedBackground;
|
||||
@Styleable(dot=true) protected Color defaultHoverBackground;
|
||||
@Styleable(dot=true) protected Color defaultPressedBackground;
|
||||
@Styleable(dot=true) protected boolean defaultBoldText;
|
||||
|
||||
@Styleable protected boolean paintShadow;
|
||||
@Styleable protected int shadowWidth;
|
||||
@Styleable protected Color shadowColor;
|
||||
@Styleable(dot=true) protected Color defaultShadowColor;
|
||||
|
||||
@Styleable(dot=true) protected Color toolbarHoverBackground;
|
||||
@Styleable(dot=true) protected Color toolbarPressedBackground;
|
||||
@Styleable(dot=true) protected Color toolbarSelectedBackground;
|
||||
|
||||
// only used via styling (not in UI defaults, but has likewise client properties)
|
||||
/** @since 2 */ @Styleable protected String buttonType;
|
||||
/** @since 2 */ @Styleable protected boolean squareSize;
|
||||
/** @since 2 */ @Styleable protected int minimumHeight;
|
||||
|
||||
private Icon helpButtonIcon;
|
||||
private Insets defaultMargin;
|
||||
|
||||
private final boolean shared;
|
||||
private boolean helpButtonIconShared = true;
|
||||
private boolean defaults_initialized = false;
|
||||
|
||||
private static ComponentUI instance;
|
||||
private Map<String, Object> oldStyleValues;
|
||||
private AtomicBoolean borderShared;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
if( instance == null )
|
||||
instance = new FlatButtonUI();
|
||||
return instance;
|
||||
return FlatUIUtils.canUseSharedUI( c )
|
||||
? FlatUIUtils.createSharedUI( FlatButtonUI.class, () -> new FlatButtonUI( true ) )
|
||||
: new FlatButtonUI( false );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
protected FlatButtonUI( boolean shared ) {
|
||||
this.shared = shared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
installStyle( (AbstractButton) c );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,99 +180,316 @@ public class FlatButtonUI
|
||||
if( !defaults_initialized ) {
|
||||
String prefix = getPropertyPrefix();
|
||||
|
||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
arc = UIManager.getInt( prefix + "arc" );
|
||||
minimumWidth = UIManager.getInt( prefix + "minimumWidth" );
|
||||
iconTextGap = FlatUIUtils.getUIInt( prefix + "iconTextGap", 4 );
|
||||
|
||||
background = UIManager.getColor( prefix + "background" );
|
||||
foreground = UIManager.getColor( prefix + "foreground" );
|
||||
|
||||
startBackground = UIManager.getColor( prefix + "startBackground" );
|
||||
endBackground = UIManager.getColor( prefix + "endBackground" );
|
||||
focusedBackground = UIManager.getColor( prefix + "focusedBackground" );
|
||||
hoverBackground = UIManager.getColor( prefix + "hoverBackground" );
|
||||
pressedBackground = UIManager.getColor( prefix + "pressedBackground" );
|
||||
selectedBackground = UIManager.getColor( prefix + "selectedBackground" );
|
||||
selectedForeground = UIManager.getColor( prefix + "selectedForeground" );
|
||||
disabledBackground = UIManager.getColor( prefix + "disabledBackground" );
|
||||
disabledText = UIManager.getColor( prefix + "disabledText" );
|
||||
disabledSelectedBackground = UIManager.getColor( prefix + "disabledSelectedBackground" );
|
||||
|
||||
defaultBackground = UIManager.getColor( "Button.default.background" );
|
||||
defaultBackground = FlatUIUtils.getUIColor( "Button.default.startBackground", "Button.default.background" );
|
||||
defaultEndBackground = UIManager.getColor( "Button.default.endBackground" );
|
||||
defaultForeground = UIManager.getColor( "Button.default.foreground" );
|
||||
defaultFocusedBackground = UIManager.getColor( "Button.default.focusedBackground" );
|
||||
defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" );
|
||||
defaultPressedBackground = UIManager.getColor( "Button.default.pressedBackground" );
|
||||
defaultBoldText = UIManager.getBoolean( "Button.default.boldText" );
|
||||
|
||||
paintShadow = UIManager.getBoolean( "Button.paintShadow" );
|
||||
shadowWidth = FlatUIUtils.getUIInt( "Button.shadowWidth", 2 );
|
||||
shadowColor = UIManager.getColor( "Button.shadowColor" );
|
||||
defaultShadowColor = UIManager.getColor( "Button.default.shadowColor" );
|
||||
|
||||
toolbarHoverBackground = UIManager.getColor( prefix + "toolbar.hoverBackground" );
|
||||
toolbarPressedBackground = UIManager.getColor( prefix + "toolbar.pressedBackground" );
|
||||
toolbarSelectedBackground = UIManager.getColor( prefix + "toolbar.selectedBackground" );
|
||||
|
||||
helpButtonIcon = UIManager.getIcon( "HelpButton.icon" );
|
||||
defaultMargin = UIManager.getInsets( prefix + "margin" );
|
||||
|
||||
helpButtonIconShared = true;
|
||||
defaults_initialized = true;
|
||||
}
|
||||
|
||||
if( startBackground != null ) {
|
||||
Color bg = b.getBackground();
|
||||
if( bg == null || bg instanceof UIResource )
|
||||
b.setBackground( startBackground );
|
||||
}
|
||||
|
||||
LookAndFeel.installProperty( b, "opaque", false );
|
||||
LookAndFeel.installProperty( b, "iconTextGap", scale( iconTextGap ) );
|
||||
|
||||
MigLayoutVisualPadding.install( b, focusWidth );
|
||||
MigLayoutVisualPadding.install( b );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallDefaults( AbstractButton b ) {
|
||||
super.uninstallDefaults( b );
|
||||
|
||||
oldStyleValues = null;
|
||||
borderShared = null;
|
||||
|
||||
MigLayoutVisualPadding.uninstall( b );
|
||||
defaults_initialized = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BasicButtonListener createButtonListener( AbstractButton b ) {
|
||||
return new FlatButtonListener( b );
|
||||
}
|
||||
|
||||
protected void propertyChange( AbstractButton b, PropertyChangeEvent e ) {
|
||||
switch( e.getPropertyName() ) {
|
||||
case SQUARE_SIZE:
|
||||
case MINIMUM_WIDTH:
|
||||
case MINIMUM_HEIGHT:
|
||||
b.revalidate();
|
||||
break;
|
||||
|
||||
case BUTTON_TYPE:
|
||||
b.revalidate();
|
||||
b.repaint();
|
||||
break;
|
||||
|
||||
case STYLE:
|
||||
case STYLE_CLASS:
|
||||
if( shared && FlatStylingSupport.hasStyleProperty( b ) ) {
|
||||
// unshare component UI if necessary
|
||||
// updateUI() invokes installStyle() from installUI()
|
||||
b.updateUI();
|
||||
} else
|
||||
installStyle( b );
|
||||
b.revalidate();
|
||||
b.repaint();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
protected void installStyle( AbstractButton b ) {
|
||||
try {
|
||||
applyStyle( b, FlatStylingSupport.getResolvedStyle( b, getStyleType() ) );
|
||||
} catch( RuntimeException ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
String getStyleType() {
|
||||
return "Button";
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
protected void applyStyle( AbstractButton b, Object style ) {
|
||||
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style,
|
||||
(key, value) -> applyStyleProperty( b, key, value ) );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
protected Object applyStyleProperty( AbstractButton b, String key, Object value ) {
|
||||
if( key.startsWith( "help." ) ) {
|
||||
if( !(helpButtonIcon instanceof FlatHelpButtonIcon) )
|
||||
return new UnknownStyleException( key );
|
||||
|
||||
if( helpButtonIconShared ) {
|
||||
helpButtonIcon = FlatStylingSupport.cloneIcon( helpButtonIcon );
|
||||
helpButtonIconShared = false;
|
||||
}
|
||||
|
||||
key = key.substring( "help.".length() );
|
||||
return ((FlatHelpButtonIcon)helpButtonIcon).applyStyleProperty( key, value );
|
||||
}
|
||||
|
||||
if( borderShared == null )
|
||||
borderShared = new AtomicBoolean( true );
|
||||
return FlatStylingSupport.applyToAnnotatedObjectOrBorder( this, key, value, b, borderShared );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
@Override
|
||||
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||
Map<String, Class<?>> infos = FlatStylingSupport.getAnnotatedStyleableInfos( this, c.getBorder() );
|
||||
if( helpButtonIcon instanceof FlatHelpButtonIcon )
|
||||
FlatStylingSupport.putAllPrefixKey( infos, "help.", ((FlatHelpButtonIcon)helpButtonIcon).getStyleableInfos() );
|
||||
return infos;
|
||||
}
|
||||
|
||||
static boolean isContentAreaFilled( Component c ) {
|
||||
return !(c instanceof AbstractButton) || ((AbstractButton)c).isContentAreaFilled();
|
||||
}
|
||||
|
||||
public static boolean isFocusPainted( Component c ) {
|
||||
return !(c instanceof AbstractButton) || ((AbstractButton)c).isFocusPainted();
|
||||
}
|
||||
|
||||
static boolean isDefaultButton( Component c ) {
|
||||
return c instanceof JButton && ((JButton)c).isDefaultButton();
|
||||
}
|
||||
|
||||
static boolean isIconOnlyButton( Component c ) {
|
||||
String text;
|
||||
return c instanceof JButton &&
|
||||
((JButton)c).getIcon() != null &&
|
||||
((text = ((JButton)c).getText()) == null || text.isEmpty());
|
||||
/**
|
||||
* Returns true if the button has an icon but no text,
|
||||
* or it it does not have an icon and the text is either "..." or one character.
|
||||
*/
|
||||
static boolean isIconOnlyOrSingleCharacterButton( Component c ) {
|
||||
if( !(c instanceof JButton) && !(c instanceof JToggleButton) )
|
||||
return false;
|
||||
|
||||
Icon icon = ((AbstractButton)c).getIcon();
|
||||
String text = ((AbstractButton)c).getText();
|
||||
return (icon != null && (text == null || text.isEmpty())) ||
|
||||
(icon == null && text != null &&
|
||||
("...".equals( text ) ||
|
||||
text.length() == 1 ||
|
||||
(text.length() == 2 && Character.isSurrogatePair( text.charAt( 0 ), text.charAt( 1 ) ))));
|
||||
}
|
||||
|
||||
static final int TYPE_OTHER = -1;
|
||||
static final int TYPE_SQUARE = 0;
|
||||
static final int TYPE_ROUND_RECT = 1;
|
||||
|
||||
static int getButtonType( Component c ) {
|
||||
if( !(c instanceof AbstractButton) )
|
||||
return TYPE_OTHER;
|
||||
|
||||
String value = getButtonTypeStr( (AbstractButton) c );
|
||||
if( value == null )
|
||||
return TYPE_OTHER;
|
||||
|
||||
switch( value ) {
|
||||
case BUTTON_TYPE_SQUARE: return TYPE_SQUARE;
|
||||
case BUTTON_TYPE_ROUND_RECT: return TYPE_ROUND_RECT;
|
||||
default: return TYPE_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isHelpButton( Component c ) {
|
||||
return c instanceof JButton && clientPropertyEquals( (JButton) c, BUTTON_TYPE, BUTTON_TYPE_HELP );
|
||||
return c instanceof JButton && BUTTON_TYPE_HELP.equals( getButtonTypeStr( (JButton) c ) );
|
||||
}
|
||||
|
||||
static boolean isToolBarButton( JComponent c ) {
|
||||
return c.getParent() instanceof JToolBar;
|
||||
static boolean isToolBarButton( Component c ) {
|
||||
return c.getParent() instanceof JToolBar ||
|
||||
(c instanceof AbstractButton && BUTTON_TYPE_TOOLBAR_BUTTON.equals( getButtonTypeStr( (AbstractButton) c ) ));
|
||||
}
|
||||
|
||||
static boolean isBorderlessButton( Component c ) {
|
||||
return c instanceof AbstractButton && BUTTON_TYPE_BORDERLESS.equals( getButtonTypeStr( (AbstractButton) c ) );
|
||||
}
|
||||
|
||||
static String getButtonTypeStr( AbstractButton c ) {
|
||||
// get from client property
|
||||
Object value = c.getClientProperty( BUTTON_TYPE );
|
||||
if( value instanceof String )
|
||||
return (String) value;
|
||||
|
||||
// get from styling property
|
||||
ButtonUI ui = c.getUI();
|
||||
return (ui instanceof FlatButtonUI) ? ((FlatButtonUI)ui).buttonType : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update( Graphics g, JComponent c ) {
|
||||
if( isHelpButton( c ) ) {
|
||||
// fill background if opaque to avoid garbage if user sets opaque to true
|
||||
if( c.isOpaque() )
|
||||
FlatUIUtils.paintParentBackground( g, c );
|
||||
|
||||
if( isHelpButton( c ) ) {
|
||||
helpButtonIcon.paintIcon( c, g, 0, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
if( c.isOpaque() && isContentAreaFilled( c ) ) {
|
||||
FlatUIUtils.paintParentBackground( g, c );
|
||||
|
||||
Color background = getBackground( c );
|
||||
if( background != null ) {
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
try {
|
||||
FlatUIUtils.setRenderingHints( g2 );
|
||||
|
||||
Border border = c.getBorder();
|
||||
float focusWidth = (border instanceof FlatBorder) ? scale( (float) this.focusWidth ) : 0;
|
||||
float arc = (border instanceof FlatButtonBorder || isToolBarButton( c )) ? scale( (float) this.arc ) : 0;
|
||||
|
||||
g2.setColor( background );
|
||||
FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
if( isContentAreaFilled( c ) )
|
||||
paintBackground( g, c );
|
||||
|
||||
paint( g, c );
|
||||
}
|
||||
|
||||
protected void paintBackground( Graphics g, JComponent c ) {
|
||||
Color background = getBackground( c );
|
||||
if( background == null )
|
||||
return;
|
||||
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
try {
|
||||
FlatUIUtils.setRenderingHints( g2 );
|
||||
|
||||
boolean def = isDefaultButton( c );
|
||||
boolean isToolBarButton = isToolBarButton( c );
|
||||
float focusWidth = isToolBarButton ? 0 : FlatUIUtils.getBorderFocusWidth( c );
|
||||
float arc = FlatUIUtils.getBorderArc( c );
|
||||
float textFieldArc = 0;
|
||||
|
||||
// if toolbar button is in leading/trailing component of a text field,
|
||||
// increase toolbar button arc to match text field arc (if necessary)
|
||||
if( isToolBarButton &&
|
||||
FlatClientProperties.clientProperty( c, STYLE_CLASS, "", String.class ).contains( "inTextField" ) )
|
||||
{
|
||||
JTextField textField = (JTextField) SwingUtilities.getAncestorOfClass( JTextField.class, c );
|
||||
if( textField != null )
|
||||
textFieldArc = FlatUIUtils.getBorderArc( textField );
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int width = c.getWidth();
|
||||
int height = c.getHeight();
|
||||
|
||||
if( isToolBarButton && c.getBorder() instanceof FlatButtonBorder ) {
|
||||
Insets spacing = UIScale.scale( ((FlatButtonBorder)c.getBorder()).toolbarSpacingInsets );
|
||||
x += spacing.left;
|
||||
y += spacing.top;
|
||||
width -= spacing.left + spacing.right;
|
||||
height -= spacing.top + spacing.bottom;
|
||||
|
||||
// reduce text field arc
|
||||
textFieldArc -= spacing.top + spacing.bottom;
|
||||
}
|
||||
|
||||
// increase toolbar button arc to match text field arc (if necessary)
|
||||
if( arc < textFieldArc )
|
||||
arc = textFieldArc;
|
||||
|
||||
// paint shadow
|
||||
Color shadowColor = def ? defaultShadowColor : this.shadowColor;
|
||||
if( paintShadow &&
|
||||
shadowColor != null && shadowWidth > 0 && focusWidth > 0 && c.isEnabled() &&
|
||||
!isToolBarButton && !isBorderlessButton( c ) &&
|
||||
!(isFocusPainted( c ) && FlatUIUtils.isPermanentFocusOwner( c )) )
|
||||
{
|
||||
g2.setColor( shadowColor );
|
||||
g2.fill( new RoundRectangle2D.Float( focusWidth, focusWidth + UIScale.scale( (float) shadowWidth ),
|
||||
width - focusWidth * 2, height - focusWidth * 2, arc, arc ) );
|
||||
}
|
||||
|
||||
// paint background
|
||||
Color startBg = def ? defaultBackground : startBackground;
|
||||
Color endBg = def ? defaultEndBackground : endBackground;
|
||||
if( background == startBg && endBg != null && !startBg.equals( endBg ) )
|
||||
g2.setPaint( new GradientPaint( 0, 0, startBg, 0, height, endBg ) );
|
||||
else
|
||||
g2.setColor( FlatUIUtils.deriveColor( background, getBackgroundBase( c, def ) ) );
|
||||
|
||||
FlatUIUtils.paintComponentBackground( g2, x, y, width, height, focusWidth, arc );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint( Graphics g, JComponent c ) {
|
||||
super.paint( FlatLabelUI.createGraphicsHTMLTextYCorrection( g, c ), c );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text ) {
|
||||
if( isHelpButton( b ) )
|
||||
@@ -215,10 +506,10 @@ public class FlatButtonUI
|
||||
}
|
||||
}
|
||||
|
||||
paintText( g, b, textRect, text, b.isEnabled() ? getForeground( b ) : disabledText );
|
||||
paintText( g, b, textRect, text, getForeground( b ) );
|
||||
}
|
||||
|
||||
static void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text, Color foreground ) {
|
||||
public static void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text, Color foreground ) {
|
||||
FontMetrics fm = b.getFontMetrics( b.getFont() );
|
||||
int mnemonicIndex = FlatLaf.isShowMnemonics() ? b.getDisplayedMnemonicIndex() : -1;
|
||||
|
||||
@@ -228,53 +519,93 @@ public class FlatButtonUI
|
||||
}
|
||||
|
||||
protected Color getBackground( JComponent c ) {
|
||||
if( !c.isEnabled() )
|
||||
return null;
|
||||
boolean toolBarButton = isToolBarButton( c ) || isBorderlessButton( c );
|
||||
|
||||
// selected state
|
||||
if( ((AbstractButton)c).isSelected() ) {
|
||||
// in toolbar use same background colors for disabled and enabled because
|
||||
// we assume that toolbar icon is shown disabled
|
||||
return buttonStateColor( c,
|
||||
toolBarButton ? toolbarSelectedBackground : selectedBackground,
|
||||
toolBarButton ? toolbarSelectedBackground : disabledSelectedBackground,
|
||||
null,
|
||||
null,
|
||||
toolBarButton ? toolbarPressedBackground : pressedBackground );
|
||||
}
|
||||
|
||||
// toolbar button
|
||||
if( isToolBarButton( c ) ) {
|
||||
ButtonModel model = ((AbstractButton)c).getModel();
|
||||
if( model.isPressed() )
|
||||
return toolbarPressedBackground;
|
||||
if( model.isRollover() )
|
||||
return toolbarHoverBackground;
|
||||
|
||||
// use background of toolbar
|
||||
return c.getParent().getBackground();
|
||||
if( toolBarButton ) {
|
||||
Color bg = c.getBackground();
|
||||
return buttonStateColor( c,
|
||||
isCustomBackground( bg ) ? bg : null,
|
||||
null,
|
||||
null,
|
||||
toolbarHoverBackground,
|
||||
toolbarPressedBackground );
|
||||
}
|
||||
|
||||
boolean def = isDefaultButton( c );
|
||||
return buttonStateColor( c,
|
||||
def ? defaultBackground : c.getBackground(),
|
||||
null,
|
||||
def ? defaultFocusedBackground : focusedBackground,
|
||||
getBackgroundBase( c, def ),
|
||||
disabledBackground,
|
||||
isCustomBackground( c.getBackground() ) ? null : (def ? defaultFocusedBackground : focusedBackground),
|
||||
def ? defaultHoverBackground : hoverBackground,
|
||||
def ? defaultPressedBackground : pressedBackground );
|
||||
}
|
||||
|
||||
protected Color getBackgroundBase( JComponent c, boolean def ) {
|
||||
// use component background if explicitly set
|
||||
Color bg = c.getBackground();
|
||||
if( isCustomBackground( bg ) )
|
||||
return bg;
|
||||
|
||||
return def ? defaultBackground : bg;
|
||||
}
|
||||
|
||||
protected boolean isCustomBackground( Color bg ) {
|
||||
return bg != background && (startBackground == null || bg != startBackground);
|
||||
}
|
||||
|
||||
public static Color buttonStateColor( Component c, Color enabledColor, Color disabledColor,
|
||||
Color focusedColor, Color hoverColor, Color pressedColor )
|
||||
{
|
||||
AbstractButton b = (c instanceof AbstractButton) ? (AbstractButton) c : null;
|
||||
|
||||
if( !c.isEnabled() )
|
||||
return disabledColor;
|
||||
|
||||
if( pressedColor != null && b != null && b.getModel().isPressed() )
|
||||
return pressedColor;
|
||||
if( c instanceof AbstractButton ) {
|
||||
ButtonModel model = ((AbstractButton)c).getModel();
|
||||
|
||||
if( hoverColor != null && b != null && b.getModel().isRollover() )
|
||||
return hoverColor;
|
||||
if( pressedColor != null && model.isPressed() )
|
||||
return pressedColor;
|
||||
|
||||
if( focusedColor != null && c.hasFocus() )
|
||||
if( hoverColor != null && model.isRollover() )
|
||||
return hoverColor;
|
||||
}
|
||||
|
||||
if( focusedColor != null && isFocusPainted( c ) && FlatUIUtils.isPermanentFocusOwner( c ) )
|
||||
return focusedColor;
|
||||
|
||||
return enabledColor;
|
||||
}
|
||||
|
||||
protected Color getForeground( JComponent c ) {
|
||||
if( !c.isEnabled() )
|
||||
return disabledText;
|
||||
|
||||
if( ((AbstractButton)c).isSelected() && !(isToolBarButton( c ) || isBorderlessButton( c )) )
|
||||
return selectedForeground;
|
||||
|
||||
// use component foreground if explicitly set
|
||||
Color fg = c.getForeground();
|
||||
if( isCustomForeground( fg ) )
|
||||
return fg;
|
||||
|
||||
boolean def = isDefaultButton( c );
|
||||
return def ? defaultForeground : c.getForeground();
|
||||
return def ? defaultForeground : fg;
|
||||
}
|
||||
|
||||
protected boolean isCustomForeground( Color fg ) {
|
||||
return fg != foreground;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -283,11 +614,50 @@ public class FlatButtonUI
|
||||
return new Dimension( helpButtonIcon.getIconWidth(), helpButtonIcon.getIconHeight() );
|
||||
|
||||
Dimension prefSize = super.getPreferredSize( c );
|
||||
if( prefSize == null )
|
||||
return null;
|
||||
|
||||
// apply minimum width, if not in toolbar and not a icon-only button
|
||||
if( !isToolBarButton( c ) && !isIconOnlyButton( c ) )
|
||||
prefSize.width = Math.max( prefSize.width, scale( minimumWidth + (focusWidth * 2) ) );
|
||||
// make square or apply minimum width/height
|
||||
boolean isIconOnlyOrSingleCharacter = isIconOnlyOrSingleCharacterButton( c );
|
||||
if( clientPropertyBoolean( c, SQUARE_SIZE, squareSize ) ) {
|
||||
// make button square (increase width or height so that they are equal)
|
||||
prefSize.width = prefSize.height = Math.max( prefSize.width, prefSize.height );
|
||||
} else if( isIconOnlyOrSingleCharacter && ((AbstractButton)c).getIcon() == null ) {
|
||||
// make single-character-no-icon button square (increase width)
|
||||
prefSize.width = Math.max( prefSize.width, prefSize.height );
|
||||
} else if( !isIconOnlyOrSingleCharacter && !isToolBarButton( c ) &&
|
||||
c.getBorder() instanceof FlatButtonBorder && hasDefaultMargins( c ) )
|
||||
{
|
||||
// apply minimum width/height
|
||||
int fw = Math.round( FlatUIUtils.getBorderFocusWidth( c ) * 2 );
|
||||
prefSize.width = Math.max( prefSize.width, scale( FlatUIUtils.minimumWidth( c, minimumWidth ) ) + fw );
|
||||
prefSize.height = Math.max( prefSize.height, scale( FlatUIUtils.minimumHeight( c, minimumHeight ) ) + fw );
|
||||
}
|
||||
|
||||
return prefSize;
|
||||
}
|
||||
|
||||
private boolean hasDefaultMargins( JComponent c ) {
|
||||
Insets margin = ((AbstractButton)c).getMargin();
|
||||
return margin instanceof UIResource && Objects.equals( margin, defaultMargin );
|
||||
}
|
||||
|
||||
//---- class FlatButtonListener -------------------------------------------
|
||||
|
||||
protected class FlatButtonListener
|
||||
extends BasicButtonListener
|
||||
{
|
||||
private final AbstractButton b;
|
||||
|
||||
protected FlatButtonListener( AbstractButton b ) {
|
||||
super( b );
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
super.propertyChange( e );
|
||||
FlatButtonUI.this.propertyChange( b, e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
292
flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCaret.java
Normal file
292
flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCaret.java
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.ActionMap;
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.DefaultCaret;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import javax.swing.text.Utilities;
|
||||
|
||||
/**
|
||||
* Caret that can select all text on focus gained.
|
||||
* Also fixes Swing's double-click-and-drag behavior so that dragging after
|
||||
* a double-click extends selection by whole words.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatCaret
|
||||
extends DefaultCaret
|
||||
implements UIResource
|
||||
{
|
||||
private static final String KEY_CARET_INFO = "FlatLaf.internal.caretInfo";
|
||||
|
||||
private final String selectAllOnFocusPolicy;
|
||||
private final boolean selectAllOnMouseClick;
|
||||
|
||||
private boolean inInstall;
|
||||
private boolean wasFocused;
|
||||
private boolean wasTemporaryLost;
|
||||
private boolean isMousePressed;
|
||||
private boolean isWordSelection;
|
||||
private boolean isLineSelection;
|
||||
private int dragSelectionStart;
|
||||
private int dragSelectionEnd;
|
||||
|
||||
public FlatCaret( String selectAllOnFocusPolicy, boolean selectAllOnMouseClick ) {
|
||||
this.selectAllOnFocusPolicy = selectAllOnFocusPolicy;
|
||||
this.selectAllOnMouseClick = selectAllOnMouseClick;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void install( JTextComponent c ) {
|
||||
// get caret info if switched theme
|
||||
long[] ci = (long[]) c.getClientProperty( KEY_CARET_INFO );
|
||||
if( ci != null ) {
|
||||
c.putClientProperty( KEY_CARET_INFO, null );
|
||||
|
||||
// if caret info is too old assume that switched from FlatLaf
|
||||
// to another Laf and back to FlatLaf
|
||||
if( System.currentTimeMillis() - 500 > ci[3] )
|
||||
ci = null;
|
||||
}
|
||||
if( ci != null ) {
|
||||
// when switching theme, it is necessary to set blink rate before
|
||||
// invoking super.install() otherwise the caret does not blink
|
||||
setBlinkRate( (int) ci[2] );
|
||||
}
|
||||
|
||||
inInstall = true;
|
||||
try {
|
||||
super.install( c );
|
||||
} finally {
|
||||
inInstall = false;
|
||||
}
|
||||
|
||||
if( ci != null ) {
|
||||
// restore selection
|
||||
select( (int) ci[1], (int) ci[0] );
|
||||
|
||||
// if text component is focused, then caret and selection are visible,
|
||||
// but when switching theme, the component does not yet have
|
||||
// an highlighter and the selection is not painted
|
||||
// --> make selection temporary invisible later, then the caret
|
||||
// adds selection highlights to the text component highlighter
|
||||
if( isSelectionVisible() ) {
|
||||
EventQueue.invokeLater( () -> {
|
||||
if( getComponent() == null )
|
||||
return; // was deinstalled
|
||||
|
||||
if( isSelectionVisible() ) {
|
||||
setSelectionVisible( false );
|
||||
setSelectionVisible( true );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deinstall( JTextComponent c ) {
|
||||
// remember dot and mark (the selection) when switching theme
|
||||
c.putClientProperty( KEY_CARET_INFO, new long[] {
|
||||
getDot(),
|
||||
getMark(),
|
||||
getBlinkRate(),
|
||||
System.currentTimeMillis(),
|
||||
} );
|
||||
|
||||
super.deinstall( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void adjustVisibility( Rectangle nloc ) {
|
||||
JTextComponent c = getComponent();
|
||||
if( c != null && c.getUI() instanceof FlatTextFieldUI ) {
|
||||
// need to fix x location because JTextField.scrollRectToVisible() uses insets.left
|
||||
// (as BasicTextUI.getVisibleEditorRect() does),
|
||||
// but FlatTextFieldUI.getVisibleEditorRect() may add some padding
|
||||
Rectangle r = ((FlatTextFieldUI)c.getUI()).getVisibleEditorRect();
|
||||
if( r != null )
|
||||
nloc.x -= r.x - c.getInsets().left;
|
||||
}
|
||||
super.adjustVisibility( nloc );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusGained( FocusEvent e ) {
|
||||
if( !inInstall && !wasTemporaryLost && (!isMousePressed || selectAllOnMouseClick) )
|
||||
selectAllOnFocusGained();
|
||||
wasTemporaryLost = false;
|
||||
wasFocused = true;
|
||||
|
||||
super.focusGained( e );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost( FocusEvent e ) {
|
||||
wasTemporaryLost = e.isTemporary();
|
||||
super.focusLost( e );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed( MouseEvent e ) {
|
||||
isMousePressed = true;
|
||||
super.mousePressed( e );
|
||||
|
||||
JTextComponent c = getComponent();
|
||||
|
||||
// left double-click starts word selection
|
||||
isWordSelection = e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton( e ) && !e.isConsumed();
|
||||
|
||||
// left triple-click starts line selection
|
||||
isLineSelection = e.getClickCount() == 3 && SwingUtilities.isLeftMouseButton( e ) && (!e.isConsumed() || c.getDragEnabled());
|
||||
|
||||
// select line
|
||||
// (this is also done in DefaultCaret.mouseClicked(), but this event is
|
||||
// sent when the mouse is released, which is too late for triple-click-and-drag)
|
||||
if( isLineSelection ) {
|
||||
ActionMap actionMap = c.getActionMap();
|
||||
Action selectLineAction = (actionMap != null)
|
||||
? actionMap.get( DefaultEditorKit.selectLineAction )
|
||||
: null;
|
||||
if( selectLineAction != null ) {
|
||||
selectLineAction.actionPerformed( new ActionEvent( c,
|
||||
ActionEvent.ACTION_PERFORMED, null, e.getWhen(), e.getModifiers() ) );
|
||||
}
|
||||
}
|
||||
|
||||
// remember selection where word/line selection starts to keep it always selected while dragging
|
||||
if( isWordSelection || isLineSelection ) {
|
||||
int mark = getMark();
|
||||
int dot = getDot();
|
||||
dragSelectionStart = Math.min( dot, mark );
|
||||
dragSelectionEnd = Math.max( dot, mark );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased( MouseEvent e ) {
|
||||
isMousePressed = false;
|
||||
isWordSelection = false;
|
||||
isLineSelection = false;
|
||||
super.mouseReleased( e );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged( MouseEvent e ) {
|
||||
if( (isWordSelection || isLineSelection) &&
|
||||
!e.isConsumed() && SwingUtilities.isLeftMouseButton( e ) )
|
||||
{
|
||||
// fix Swing's double/triple-click-and-drag behavior so that dragging after
|
||||
// a double/triple-click extends selection by whole words/lines
|
||||
JTextComponent c = getComponent();
|
||||
int pos = c.viewToModel( e.getPoint() );
|
||||
if( pos < 0 )
|
||||
return;
|
||||
|
||||
try {
|
||||
if( pos > dragSelectionEnd )
|
||||
select( dragSelectionStart, isWordSelection ? Utilities.getWordEnd( c, pos ) : Utilities.getRowEnd( c, pos ) );
|
||||
else if( pos < dragSelectionStart )
|
||||
select( dragSelectionEnd, isWordSelection ? Utilities.getWordStart( c, pos ) : Utilities.getRowStart( c, pos ) );
|
||||
else
|
||||
select( dragSelectionStart, dragSelectionEnd );
|
||||
} catch( BadLocationException ex ) {
|
||||
UIManager.getLookAndFeel().provideErrorFeedback( c );
|
||||
}
|
||||
} else
|
||||
super.mouseDragged( e );
|
||||
}
|
||||
|
||||
protected void selectAllOnFocusGained() {
|
||||
JTextComponent c = getComponent();
|
||||
Document doc = c.getDocument();
|
||||
if( doc == null || !c.isEnabled() || !c.isEditable() || FlatUIUtils.isCellEditor( c ) )
|
||||
return;
|
||||
|
||||
Object selectAllOnFocusPolicy = c.getClientProperty( SELECT_ALL_ON_FOCUS_POLICY );
|
||||
if( selectAllOnFocusPolicy == null )
|
||||
selectAllOnFocusPolicy = this.selectAllOnFocusPolicy;
|
||||
|
||||
if( SELECT_ALL_ON_FOCUS_POLICY_NEVER.equals( selectAllOnFocusPolicy ) )
|
||||
return;
|
||||
|
||||
if( !SELECT_ALL_ON_FOCUS_POLICY_ALWAYS.equals( selectAllOnFocusPolicy ) ) {
|
||||
// policy is "once" (or null or unknown)
|
||||
|
||||
// was already focused?
|
||||
if( wasFocused )
|
||||
return;
|
||||
|
||||
// check whether selection was modified before gaining focus
|
||||
int dot = getDot();
|
||||
int mark = getMark();
|
||||
if( dot != mark || dot != doc.getLength() )
|
||||
return;
|
||||
}
|
||||
|
||||
// select all
|
||||
if( c instanceof JFormattedTextField ) {
|
||||
EventQueue.invokeLater( () -> {
|
||||
if( getComponent() == null )
|
||||
return; // was deinstalled
|
||||
|
||||
select( 0, doc.getLength() );
|
||||
} );
|
||||
} else {
|
||||
select( 0, doc.getLength() );
|
||||
}
|
||||
}
|
||||
|
||||
private void select( int mark, int dot ) {
|
||||
if( mark != getMark() )
|
||||
setDot( mark );
|
||||
if( dot != getDot() )
|
||||
moveDot( dot );
|
||||
}
|
||||
|
||||
/** @since 1.4 */
|
||||
public void scrollCaretToVisible() {
|
||||
JTextComponent c = getComponent();
|
||||
if( c == null || c.getUI() == null )
|
||||
return;
|
||||
|
||||
try {
|
||||
Rectangle loc = c.getUI().modelToView( c, getDot(), getDotBias() );
|
||||
if( loc != null ) {
|
||||
adjustVisibility( loc );
|
||||
damage( loc );
|
||||
}
|
||||
} catch( BadLocationException ex ) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,42 +16,142 @@
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Map;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JCheckBoxMenuItem}.
|
||||
*
|
||||
* <!-- BasicCheckBoxMenuItemUI -->
|
||||
*
|
||||
* @uiDefault CheckBoxMenuItem.font Font
|
||||
* @uiDefault CheckBoxMenuItem.background Color
|
||||
* @uiDefault CheckBoxMenuItem.foreground Color
|
||||
* @uiDefault CheckBoxMenuItem.disabledForeground Color
|
||||
* @uiDefault CheckBoxMenuItem.selectionBackground Color
|
||||
* @uiDefault CheckBoxMenuItem.selectionForeground Color
|
||||
* @uiDefault CheckBoxMenuItem.acceleratorForeground Color
|
||||
* @uiDefault CheckBoxMenuItem.acceleratorSelectionForeground Color
|
||||
* @uiDefault MenuItem.acceleratorFont Font defaults to MenuItem.font
|
||||
* @uiDefault MenuItem.acceleratorDelimiter String
|
||||
* @uiDefault CheckBoxMenuItem.border Border
|
||||
* @uiDefault CheckBoxMenuItem.borderPainted boolean
|
||||
* @uiDefault CheckBoxMenuItem.margin Insets
|
||||
* @uiDefault CheckBoxMenuItem.arrowIcon Icon
|
||||
* @uiDefault CheckBoxMenuItem.checkIcon Icon
|
||||
* @uiDefault CheckBoxMenuItem.opaque boolean
|
||||
*
|
||||
* <!-- FlatCheckBoxMenuItemUI -->
|
||||
*
|
||||
* @uiDefault MenuItem.iconTextGap int
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatCheckBoxMenuItemUI
|
||||
extends BasicCheckBoxMenuItemUI
|
||||
implements StyleableUI
|
||||
{
|
||||
private FlatMenuItemRenderer renderer;
|
||||
private Map<String, Object> oldStyleValues;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatCheckBoxMenuItemUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
installStyle();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
|
||||
// scale
|
||||
defaultTextIconGap = scale( defaultTextIconGap );
|
||||
LookAndFeel.installProperty( menuItem, "iconTextGap", FlatUIUtils.getUIInt( "MenuItem.iconTextGap", 4 ) );
|
||||
|
||||
renderer = createRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
super.uninstallDefaults();
|
||||
|
||||
FlatMenuItemRenderer.clearClientProperties( menuItem.getParent() );
|
||||
renderer = null;
|
||||
oldStyleValues = null;
|
||||
}
|
||||
|
||||
protected FlatMenuItemRenderer createRenderer() {
|
||||
return new FlatMenuItemRenderer( menuItem, checkIcon, arrowIcon, acceleratorFont, acceleratorDelimiter );
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale defaultTextIconGap again if iconTextGap property has changed.
|
||||
*/
|
||||
@Override
|
||||
protected PropertyChangeListener createPropertyChangeListener( JComponent c ) {
|
||||
PropertyChangeListener superListener = super.createPropertyChangeListener( c );
|
||||
return e -> {
|
||||
superListener.propertyChange( e );
|
||||
if( e.getPropertyName() == "iconTextGap" )
|
||||
defaultTextIconGap = scale( defaultTextIconGap );
|
||||
};
|
||||
return FlatStylingSupport.createPropertyChangeListener( c, this::installStyle, super.createPropertyChangeListener( c ) );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
protected void installStyle() {
|
||||
try {
|
||||
applyStyle( FlatStylingSupport.getResolvedStyle( menuItem, "CheckBoxMenuItem" ) );
|
||||
} catch( RuntimeException ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
protected void applyStyle( Object style ) {
|
||||
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
protected Object applyStyleProperty( String key, Object value ) {
|
||||
try {
|
||||
return renderer.applyStyleProperty( key, value );
|
||||
} catch ( UnknownStyleException ex ) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
Object oldValue;
|
||||
switch( key ) {
|
||||
// BasicMenuItemUI
|
||||
case "selectionBackground": oldValue = selectionBackground; selectionBackground = (Color) value; return oldValue;
|
||||
case "selectionForeground": oldValue = selectionForeground; selectionForeground = (Color) value; return oldValue;
|
||||
case "disabledForeground": oldValue = disabledForeground; disabledForeground = (Color) value; return oldValue;
|
||||
case "acceleratorForeground": oldValue = acceleratorForeground; acceleratorForeground = (Color) value; return oldValue;
|
||||
case "acceleratorSelectionForeground": oldValue = acceleratorSelectionForeground; acceleratorSelectionForeground = (Color) value; return oldValue;
|
||||
}
|
||||
|
||||
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, menuItem, key, value );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
@Override
|
||||
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||
return FlatMenuItemUI.getStyleableInfos( renderer );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dimension getPreferredMenuItemSize( JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap ) {
|
||||
return renderer.getPreferredMenuItemSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint( Graphics g, JComponent c ) {
|
||||
renderer.paintMenuItem( g, selectionBackground, selectionForeground, disabledForeground,
|
||||
acceleratorForeground, acceleratorSelectionForeground );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,21 +22,45 @@ import javax.swing.plaf.ComponentUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JCheckBox}.
|
||||
*
|
||||
* <!-- BasicRadioButtonUI -->
|
||||
*
|
||||
* @uiDefault CheckBox.font Font
|
||||
* @uiDefault CheckBox.background Color
|
||||
* @uiDefault CheckBox.foreground Color
|
||||
* @uiDefault CheckBox.border Border
|
||||
* @uiDefault CheckBox.margin Insets
|
||||
* @uiDefault CheckBox.rollover boolean
|
||||
* @uiDefault CheckBox.icon Icon
|
||||
*
|
||||
* <!-- FlatRadioButtonUI -->
|
||||
*
|
||||
* @uiDefault CheckBox.iconTextGap int
|
||||
* @uiDefault CheckBox.disabledText Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatCheckBoxUI
|
||||
extends FlatRadioButtonUI
|
||||
{
|
||||
private static ComponentUI instance;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
if( instance == null )
|
||||
instance = new FlatCheckBoxUI();
|
||||
return instance;
|
||||
return FlatUIUtils.canUseSharedUI( c )
|
||||
? FlatUIUtils.createSharedUI( FlatCheckBoxUI.class, () -> new FlatCheckBoxUI( true ) )
|
||||
: new FlatCheckBoxUI( false );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
protected FlatCheckBoxUI( boolean shared ) {
|
||||
super( shared );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPropertyPrefix() {
|
||||
return "CheckBox.";
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
@Override
|
||||
String getStyleType() {
|
||||
return "CheckBox";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,16 +16,18 @@
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicColorChooserUI;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JColorChooser}.
|
||||
*
|
||||
* <!-- BasicColorChooserUI -->
|
||||
*
|
||||
* @uiDefault ColorChooser.font Font
|
||||
* @uiDefault ColorChooser.background Color
|
||||
* @uiDefault ColorChooser.foreground Color
|
||||
* @uiDefault ColorChooser.showPreviewPanelText boolean
|
||||
* @uiDefault ColorChooser.swatchesSwatchSize Dimension
|
||||
* @uiDefault ColorChooser.swatchesRecentSwatchSize Dimension
|
||||
@@ -38,21 +40,4 @@ public class FlatColorChooserUI
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatColorChooserUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
if( UIScale.getUserScaleFactor() != 1f ) {
|
||||
// temporary scale swatch sizes
|
||||
Dimension swatchSize = UIManager.getDimension( "ColorChooser.swatchesSwatchSize" );
|
||||
Dimension swatchSize2 = UIManager.getDimension( "ColorChooser.swatchesRecentSwatchSize" );
|
||||
UIManager.put( "ColorChooser.swatchesSwatchSize", UIScale.scale( swatchSize ) );
|
||||
UIManager.put( "ColorChooser.swatchesRecentSwatchSize", UIScale.scale( swatchSize2 ) );
|
||||
|
||||
super.installUI( c );
|
||||
|
||||
UIManager.put( "ColorChooser.swatchesSwatchSize", null );
|
||||
UIManager.put( "ColorChooser.swatchesRecentSwatchSize", null );
|
||||
} else
|
||||
super.installUI( c );
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyVetoException;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDesktopPane;
|
||||
import javax.swing.event.MouseInputAdapter;
|
||||
import javax.swing.event.MouseInputListener;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JLayeredPane;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.JToolTip;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicDesktopIconUI;
|
||||
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JInternalFrame.JDesktopIcon}.
|
||||
*
|
||||
* <!-- BasicDesktopIconUI -->
|
||||
*
|
||||
* @uiDefault DesktopIcon.border Border
|
||||
*
|
||||
* <!-- FlatDesktopIconUI -->
|
||||
*
|
||||
* @uiDefault DesktopIcon.background Color
|
||||
* @uiDefault DesktopIcon.foreground Color
|
||||
* @uiDefault DesktopIcon.iconSize Dimension
|
||||
* @uiDefault DesktopIcon.closeSize Dimension
|
||||
* @uiDefault DesktopIcon.closeIcon Icon
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatDesktopIconUI
|
||||
extends BasicDesktopIconUI
|
||||
{
|
||||
private Dimension iconSize;
|
||||
private Dimension closeSize;
|
||||
|
||||
private JLabel dockIcon;
|
||||
private JButton closeButton;
|
||||
private JToolTip titleTip;
|
||||
private ActionListener closeListener;
|
||||
private MouseInputListener mouseInputListener;
|
||||
private PropertyChangeListener ancestorListener;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatDesktopIconUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
// update dock icon preview if already iconified
|
||||
if( c.isDisplayable() )
|
||||
updateDockIconPreviewLater();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallUI( JComponent c ) {
|
||||
super.uninstallUI( c );
|
||||
|
||||
dockIcon = null;
|
||||
closeButton = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installComponents() {
|
||||
dockIcon = new JLabel();
|
||||
dockIcon.setHorizontalAlignment( SwingConstants.CENTER );
|
||||
|
||||
closeButton = new JButton();
|
||||
closeButton.setIcon( UIManager.getIcon( "DesktopIcon.closeIcon" ) );
|
||||
closeButton.setFocusable( false );
|
||||
closeButton.setBorder( BorderFactory.createEmptyBorder() );
|
||||
closeButton.setOpaque( true );
|
||||
closeButton.setBackground( FlatUIUtils.nonUIResource( desktopIcon.getBackground() ) );
|
||||
closeButton.setForeground( FlatUIUtils.nonUIResource( desktopIcon.getForeground() ) );
|
||||
closeButton.setVisible( false );
|
||||
|
||||
desktopIcon.setLayout( new FlatDesktopIconLayout() );
|
||||
desktopIcon.add( closeButton );
|
||||
desktopIcon.add( dockIcon );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallComponents() {
|
||||
hideTitleTip();
|
||||
|
||||
desktopIcon.remove( dockIcon );
|
||||
desktopIcon.remove( closeButton );
|
||||
desktopIcon.setLayout( null );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
|
||||
LookAndFeel.installColors( desktopIcon, "DesktopIcon.background", "DesktopIcon.foreground" );
|
||||
|
||||
iconSize = UIManager.getDimension( "DesktopIcon.iconSize" );
|
||||
closeSize = UIManager.getDimension( "DesktopIcon.closeSize" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
|
||||
closeListener = e -> {
|
||||
if( frame.isClosable() )
|
||||
frame.doDefaultCloseAction();
|
||||
};
|
||||
closeButton.addActionListener( closeListener );
|
||||
closeButton.addMouseListener( mouseInputListener );
|
||||
|
||||
ancestorListener = e -> {
|
||||
if( e.getNewValue() != null ) {
|
||||
// update dock icon preview if desktopIcon is added to desktop (internal frame was iconified)
|
||||
updateDockIconPreviewLater();
|
||||
} else {
|
||||
// remove preview icon to release memory
|
||||
dockIcon.setIcon( null );
|
||||
}
|
||||
};
|
||||
desktopIcon.addPropertyChangeListener( "ancestor", ancestorListener );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
|
||||
closeButton.removeActionListener( closeListener );
|
||||
closeButton.removeMouseListener( mouseInputListener );
|
||||
closeListener = null;
|
||||
mouseInputListener = null;
|
||||
|
||||
desktopIcon.removePropertyChangeListener( "ancestor", ancestorListener );
|
||||
ancestorListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MouseInputListener createMouseInputListener() {
|
||||
mouseInputListener = new MouseInputAdapter() {
|
||||
@Override
|
||||
public void mouseReleased( MouseEvent e ) {
|
||||
if( frame.isIcon() && desktopIcon.contains( e.getX(), e.getY() ) ) {
|
||||
hideTitleTip();
|
||||
closeButton.setVisible( false );
|
||||
|
||||
try {
|
||||
frame.setIcon( false );
|
||||
} catch( PropertyVetoException ex ) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered( MouseEvent e ) {
|
||||
showTitleTip();
|
||||
if( frame.isClosable() )
|
||||
closeButton.setVisible( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited( MouseEvent e ) {
|
||||
hideTitleTip();
|
||||
closeButton.setVisible( false );
|
||||
}
|
||||
};
|
||||
return mouseInputListener;
|
||||
}
|
||||
|
||||
private void showTitleTip() {
|
||||
JRootPane rootPane = SwingUtilities.getRootPane( desktopIcon );
|
||||
if( rootPane == null )
|
||||
return;
|
||||
|
||||
if( titleTip == null ) {
|
||||
titleTip = new JToolTip();
|
||||
rootPane.getLayeredPane().add( titleTip, JLayeredPane.POPUP_LAYER );
|
||||
}
|
||||
titleTip.setTipText( frame.getTitle() );
|
||||
titleTip.setSize( titleTip.getPreferredSize() );
|
||||
|
||||
int tx = (desktopIcon.getWidth() - titleTip.getWidth()) / 2;
|
||||
int ty = -(titleTip.getHeight() + UIScale.scale( 4 ));
|
||||
Point pt = SwingUtilities.convertPoint( desktopIcon, tx, ty, titleTip.getParent() );
|
||||
if( pt.x + titleTip.getWidth() > rootPane.getWidth() )
|
||||
pt.x = rootPane.getWidth() - titleTip.getWidth();
|
||||
if( pt.x < 0 )
|
||||
pt.x = 0;
|
||||
titleTip.setLocation( pt );
|
||||
titleTip.repaint();
|
||||
}
|
||||
|
||||
private void hideTitleTip() {
|
||||
if( titleTip == null )
|
||||
return;
|
||||
|
||||
titleTip.setVisible( false );
|
||||
titleTip.getParent().remove( titleTip );
|
||||
titleTip = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize( JComponent c ) {
|
||||
return UIScale.scale( iconSize );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize( JComponent c ) {
|
||||
return getPreferredSize( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMaximumSize( JComponent c ) {
|
||||
return getPreferredSize( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update( Graphics g, JComponent c ) {
|
||||
if( c.isOpaque() ) {
|
||||
// fill background with color derived from desktop pane
|
||||
Color background = c.getBackground();
|
||||
JDesktopPane desktopPane = desktopIcon.getDesktopPane();
|
||||
g.setColor( (desktopPane != null)
|
||||
? FlatUIUtils.deriveColor( background, desktopPane.getBackground() )
|
||||
: background );
|
||||
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
||||
}
|
||||
|
||||
paint( g, c );
|
||||
}
|
||||
|
||||
private void updateDockIconPreviewLater() {
|
||||
// use invoke later to make sure that components are updated when switching LaF
|
||||
EventQueue.invokeLater( () -> {
|
||||
if( dockIcon != null )
|
||||
updateDockIconPreview();
|
||||
} );
|
||||
}
|
||||
|
||||
protected void updateDockIconPreview() {
|
||||
// make sure that frame is not selected
|
||||
if( frame.isSelected() ) {
|
||||
try {
|
||||
frame.setSelected( false );
|
||||
} catch( PropertyVetoException ex ) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
// layout internal frame title pane, which was recreated when switching Laf
|
||||
// (directly invoke doLayout() because frame.validate() does not work here
|
||||
// because frame is not displayable)
|
||||
if( !frame.isValid() )
|
||||
frame.doLayout();
|
||||
for( Component c : frame.getComponents() ) {
|
||||
if( !c.isValid() )
|
||||
c.doLayout();
|
||||
}
|
||||
|
||||
// paint internal frame to buffered image
|
||||
int frameWidth = Math.max( frame.getWidth(), 1 );
|
||||
int frameHeight = Math.max( frame.getHeight(), 1 );
|
||||
BufferedImage frameImage = new BufferedImage( frameWidth, frameHeight, BufferedImage.TYPE_INT_ARGB );
|
||||
Graphics2D g = frameImage.createGraphics();
|
||||
try {
|
||||
frame.paint( g );
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
// compute preview size (keep ratio; also works with non-square preview)
|
||||
Insets insets = desktopIcon.getInsets();
|
||||
int previewWidth = UIScale.scale( iconSize.width ) - insets.left - insets.right;
|
||||
int previewHeight = UIScale.scale( iconSize.height ) - insets.top - insets.bottom;
|
||||
float frameRatio = ((float) frameHeight / (float) frameWidth);
|
||||
if( ((float) previewWidth / (float) frameWidth) > ((float) previewHeight / (float) frameHeight) )
|
||||
previewWidth = Math.round( previewHeight / frameRatio );
|
||||
else
|
||||
previewHeight = Math.round( previewWidth * frameRatio );
|
||||
|
||||
// scale preview
|
||||
Image previewImage = frameImage.getScaledInstance( previewWidth, previewHeight, Image.SCALE_SMOOTH );
|
||||
if( MultiResolutionImageSupport.isAvailable() ) {
|
||||
// On HiDPI screens, create preview images for 1x, 2x and current scale factor.
|
||||
// The icon then chooses the best resolution for painting, which is usually
|
||||
// the one for the current scale factor. But if changing scale factor or
|
||||
// moving window to another screen with different scale factor, then another
|
||||
// resolution may be used because the preview icon is not updated.
|
||||
Image previewImage2x = frameImage.getScaledInstance( previewWidth * 2, previewHeight * 2, Image.SCALE_SMOOTH );
|
||||
double scaleFactor = UIScale.getSystemScaleFactor( desktopIcon.getGraphicsConfiguration() );
|
||||
if( scaleFactor != 1 && scaleFactor != 2 ) {
|
||||
Image previewImageCurrent = frameImage.getScaledInstance(
|
||||
(int) Math.round( previewWidth * scaleFactor ),
|
||||
(int) Math.round( previewHeight * scaleFactor ),
|
||||
Image.SCALE_SMOOTH );
|
||||
|
||||
// the images must be ordered by resolution
|
||||
previewImage = (scaleFactor < 2)
|
||||
? MultiResolutionImageSupport.create( 0, previewImage, previewImageCurrent, previewImage2x )
|
||||
: MultiResolutionImageSupport.create( 0, previewImage, previewImage2x, previewImageCurrent );
|
||||
} else
|
||||
previewImage = MultiResolutionImageSupport.create( 0, previewImage, previewImage2x );
|
||||
}
|
||||
dockIcon.setIcon( new ImageIcon( previewImage ) );
|
||||
}
|
||||
|
||||
//---- class DockIcon -----------------------------------------------------
|
||||
|
||||
private class FlatDesktopIconLayout
|
||||
implements LayoutManager
|
||||
{
|
||||
@Override public void addLayoutComponent( String name, Component comp ) {}
|
||||
@Override public void removeLayoutComponent( Component comp ) {}
|
||||
|
||||
@Override
|
||||
public Dimension preferredLayoutSize( Container parent ) {
|
||||
return dockIcon.getPreferredSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension minimumLayoutSize( Container parent ) {
|
||||
return dockIcon.getMinimumSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutContainer( Container parent ) {
|
||||
Insets insets = parent.getInsets();
|
||||
|
||||
// dock icon
|
||||
dockIcon.setBounds( insets.left, insets.top,
|
||||
parent.getWidth() - insets.left - insets.right,
|
||||
parent.getHeight() - insets.top - insets.bottom );
|
||||
|
||||
// close button in upper right corner
|
||||
Dimension cSize = UIScale.scale( closeSize );
|
||||
closeButton.setBounds( parent.getWidth() - cSize.width, 0, cSize.width, cSize.height );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ContainerEvent;
|
||||
import java.awt.event.ContainerListener;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JInternalFrame.JDesktopIcon;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicDesktopPaneUI;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JDesktopPane}.
|
||||
*
|
||||
* <!-- BasicDesktopPaneUI -->
|
||||
*
|
||||
* @uiDefault Desktop.background Color
|
||||
* @uiDefault Desktop.minOnScreenInsets Insets
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatDesktopPaneUI
|
||||
extends BasicDesktopPaneUI
|
||||
{
|
||||
private LayoutDockListener layoutDockListener;
|
||||
private boolean layoutDockPending;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatDesktopPaneUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
layoutDockLaterOnce();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
|
||||
layoutDockListener = new LayoutDockListener();
|
||||
desktop.addContainerListener( layoutDockListener );
|
||||
desktop.addComponentListener( layoutDockListener );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
|
||||
desktop.removeContainerListener( layoutDockListener );
|
||||
desktop.removeComponentListener( layoutDockListener );
|
||||
layoutDockListener = null;
|
||||
}
|
||||
|
||||
private void layoutDockLaterOnce() {
|
||||
if( layoutDockPending )
|
||||
return;
|
||||
layoutDockPending = true;
|
||||
|
||||
EventQueue.invokeLater( () -> {
|
||||
layoutDockPending = false;
|
||||
if( desktop != null )
|
||||
layoutDock();
|
||||
} );
|
||||
}
|
||||
|
||||
protected void layoutDock() {
|
||||
Dimension desktopSize = desktop.getSize();
|
||||
int x = 0;
|
||||
int y = desktopSize.height;
|
||||
int rowHeight = 0;
|
||||
|
||||
for( Component c : desktop.getComponents() ) {
|
||||
if( !(c instanceof JDesktopIcon) )
|
||||
continue;
|
||||
|
||||
JDesktopIcon icon = (JDesktopIcon) c;
|
||||
Dimension iconSize = icon.getPreferredSize();
|
||||
|
||||
if( x + iconSize.width > desktopSize.width ) {
|
||||
// new row
|
||||
x = 0;
|
||||
y -= rowHeight;
|
||||
rowHeight = 0;
|
||||
}
|
||||
|
||||
icon.setLocation( x, y - iconSize.height );
|
||||
|
||||
x += iconSize.width;
|
||||
rowHeight = Math.max( iconSize.height, rowHeight );
|
||||
}
|
||||
}
|
||||
|
||||
//---- class LayoutDockListener -------------------------------------------
|
||||
|
||||
private class LayoutDockListener
|
||||
extends ComponentAdapter
|
||||
implements ContainerListener
|
||||
{
|
||||
@Override
|
||||
public void componentAdded( ContainerEvent e ) {
|
||||
layoutDockLaterOnce();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentRemoved( ContainerEvent e ) {
|
||||
layoutDockLaterOnce();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentResized( ComponentEvent e ) {
|
||||
layoutDockLaterOnce();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.RadialGradientPaint;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Map;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableBorder;
|
||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Paints a drop shadow border around the component.
|
||||
* Supports 1-sided, 2-side, 3-sided or 4-sided drop shadows.
|
||||
* <p>
|
||||
* The shadow insets allow specifying drop shadow thickness for each side.
|
||||
* A zero or negative value hides the drop shadow on that side.
|
||||
* A negative value can be used to indent the drop shadow on corners.
|
||||
* E.g. -4 on left indents drop shadow at top-left and bottom-left corners by 4 pixels.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatDropShadowBorder
|
||||
extends FlatEmptyBorder
|
||||
implements StyleableBorder
|
||||
{
|
||||
@Styleable protected Color shadowColor;
|
||||
@Styleable protected Insets shadowInsets;
|
||||
@Styleable protected float shadowOpacity;
|
||||
|
||||
private int shadowSize;
|
||||
private Image shadowImage;
|
||||
private Color lastShadowColor;
|
||||
private float lastShadowOpacity;
|
||||
private int lastShadowSize;
|
||||
private double lastSystemScaleFactor;
|
||||
private float lastUserScaleFactor;
|
||||
|
||||
public FlatDropShadowBorder() {
|
||||
this( null );
|
||||
}
|
||||
|
||||
public FlatDropShadowBorder( Color shadowColor ) {
|
||||
this( shadowColor, 4, 0.5f );
|
||||
}
|
||||
|
||||
public FlatDropShadowBorder( Color shadowColor, int shadowSize, float shadowOpacity ) {
|
||||
this( shadowColor, new Insets( -shadowSize, -shadowSize, shadowSize, shadowSize ), shadowOpacity );
|
||||
}
|
||||
|
||||
public FlatDropShadowBorder( Color shadowColor, Insets shadowInsets, float shadowOpacity ) {
|
||||
super( nonNegativeInsets( shadowInsets ) );
|
||||
|
||||
this.shadowColor = shadowColor;
|
||||
this.shadowInsets = shadowInsets;
|
||||
this.shadowOpacity = shadowOpacity;
|
||||
|
||||
shadowSize = maxInset( shadowInsets );
|
||||
}
|
||||
|
||||
private static Insets nonNegativeInsets( Insets shadowInsets ) {
|
||||
return new Insets( Math.max( shadowInsets.top, 0 ), Math.max( shadowInsets.left, 0 ),
|
||||
Math.max( shadowInsets.bottom, 0 ), Math.max( shadowInsets.right, 0 ) );
|
||||
}
|
||||
|
||||
private int maxInset( Insets shadowInsets ) {
|
||||
return Math.max(
|
||||
Math.max( shadowInsets.left, shadowInsets.right ),
|
||||
Math.max( shadowInsets.top, shadowInsets.bottom ) );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
@Override
|
||||
public Object applyStyleProperty( String key, Object value ) {
|
||||
Object oldValue = FlatStylingSupport.applyToAnnotatedObject( this, key, value );
|
||||
if( key.equals( "shadowInsets" ) ) {
|
||||
applyStyleProperty( nonNegativeInsets( shadowInsets ) );
|
||||
shadowSize = maxInset( shadowInsets );
|
||||
}
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
@Override
|
||||
public Map<String, Class<?>> getStyleableInfos() {
|
||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
if( shadowSize <= 0 )
|
||||
return;
|
||||
|
||||
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
|
||||
}
|
||||
|
||||
private void paintImpl( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
Color shadowColor = (this.shadowColor != null) ? this.shadowColor : g.getColor();
|
||||
int shadowSize = scale( this.shadowSize, scaleFactor );
|
||||
|
||||
// create and cache shadow image
|
||||
float userScaleFactor = UIScale.getUserScaleFactor();
|
||||
if( shadowImage == null ||
|
||||
!shadowColor.equals( lastShadowColor ) ||
|
||||
lastShadowOpacity != shadowOpacity ||
|
||||
lastShadowSize != shadowSize ||
|
||||
lastSystemScaleFactor != scaleFactor ||
|
||||
lastUserScaleFactor != userScaleFactor )
|
||||
{
|
||||
shadowImage = createShadowImage( shadowColor, shadowSize, shadowOpacity,
|
||||
(float) (scaleFactor * userScaleFactor) );
|
||||
lastShadowColor = shadowColor;
|
||||
lastShadowOpacity = shadowOpacity;
|
||||
lastShadowSize = shadowSize;
|
||||
lastSystemScaleFactor = scaleFactor;
|
||||
lastUserScaleFactor = userScaleFactor;
|
||||
}
|
||||
|
||||
/*debug
|
||||
int m = shadowImage.getWidth( null );
|
||||
Color oldColor = g.getColor();
|
||||
g.setColor( Color.lightGray );
|
||||
g.drawRect( x - m - 1, y - m - 1, m + 1, m + 1 );
|
||||
g.setColor( Color.white );
|
||||
g.fillRect( x - m, y - m, m, m );
|
||||
g.drawImage( shadowImage, x - m, y - m, null );
|
||||
g.setColor( oldColor );
|
||||
debug*/
|
||||
|
||||
int left = scale( shadowInsets.left, scaleFactor );
|
||||
int right = scale( shadowInsets.right, scaleFactor );
|
||||
int top = scale( shadowInsets.top, scaleFactor );
|
||||
int bottom = scale( shadowInsets.bottom, scaleFactor );
|
||||
|
||||
// shadow outer coordinates
|
||||
int x1o = x - Math.min( left, 0 );
|
||||
int y1o = y - Math.min( top, 0 );
|
||||
int x2o = x + width + Math.min( right, 0 );
|
||||
int y2o = y + height + Math.min( bottom, 0 );
|
||||
|
||||
// shadow inner coordinates
|
||||
int x1i = x1o + shadowSize;
|
||||
int y1i = y1o + shadowSize;
|
||||
int x2i = x2o - shadowSize;
|
||||
int y2i = y2o - shadowSize;
|
||||
|
||||
int wh = (shadowSize * 2) - 1;
|
||||
int center = shadowSize - 1;
|
||||
|
||||
// left-top edge
|
||||
if( left > 0 || top > 0 ) {
|
||||
g.drawImage( shadowImage, x1o, y1o, x1i, y1i,
|
||||
0, 0, center, center, null );
|
||||
}
|
||||
|
||||
// top shadow
|
||||
if( top > 0 ) {
|
||||
g.drawImage( shadowImage, x1i, y1o, x2i, y1i,
|
||||
center, 0, center + 1, center, null );
|
||||
}
|
||||
|
||||
// right-top edge
|
||||
if( right > 0 || top > 0 ) {
|
||||
g.drawImage( shadowImage, x2i, y1o, x2o, y1i,
|
||||
center, 0, wh, center, null );
|
||||
}
|
||||
|
||||
// left shadow
|
||||
if( left > 0 ) {
|
||||
g.drawImage( shadowImage, x1o, y1i, x1i, y2i,
|
||||
0, center, center, center + 1, null );
|
||||
}
|
||||
|
||||
// right shadow
|
||||
if( right > 0 ) {
|
||||
g.drawImage( shadowImage, x2i, y1i, x2o, y2i,
|
||||
center, center, wh, center + 1, null );
|
||||
}
|
||||
|
||||
// left-bottom edge
|
||||
if( left > 0 || bottom > 0 ) {
|
||||
g.drawImage( shadowImage, x1o, y2i, x1i, y2o,
|
||||
0, center, center, wh, null );
|
||||
}
|
||||
|
||||
// bottom shadow
|
||||
if( bottom > 0 ) {
|
||||
g.drawImage( shadowImage, x1i, y2i, x2i, y2o,
|
||||
center, center, center + 1, wh, null );
|
||||
}
|
||||
|
||||
// right-bottom edge
|
||||
if( right > 0 || bottom > 0 ) {
|
||||
g.drawImage( shadowImage, x2i, y2i, x2o, y2o,
|
||||
center, center, wh, wh, null );
|
||||
}
|
||||
}
|
||||
|
||||
private int scale( int value, double scaleFactor ) {
|
||||
return (int) Math.ceil( UIScale.scale( value ) * scaleFactor );
|
||||
}
|
||||
|
||||
private static BufferedImage createShadowImage( Color shadowColor, int shadowSize,
|
||||
float shadowOpacity, float scaleFactor )
|
||||
{
|
||||
int shadowRGB = shadowColor.getRGB() & 0xffffff;
|
||||
int shadowAlpha = (int) (255 * shadowOpacity);
|
||||
Color startColor = new Color( shadowRGB | ((shadowAlpha & 0xff) << 24), true );
|
||||
Color midColor = new Color( shadowRGB | (((shadowAlpha / 2) & 0xff) << 24), true );
|
||||
Color endColor = new Color( shadowRGB, true );
|
||||
|
||||
/*debug
|
||||
startColor = Color.red;
|
||||
midColor = Color.green;
|
||||
endColor = Color.blue;
|
||||
debug*/
|
||||
|
||||
int wh = (shadowSize * 2) - 1;
|
||||
int center = shadowSize - 1;
|
||||
|
||||
RadialGradientPaint p = new RadialGradientPaint( center, center,
|
||||
shadowSize - (0.75f * scaleFactor),
|
||||
new float[] { 0, 0.35f, 1 },
|
||||
new Color[] { startColor, midColor, endColor } );
|
||||
|
||||
BufferedImage image = new BufferedImage( wh, wh, BufferedImage.TYPE_INT_ARGB );
|
||||
|
||||
Graphics2D g = image.createGraphics();
|
||||
try {
|
||||
g.setPaint( p );
|
||||
g.fillRect( 0, 0, wh, wh );
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
@@ -17,53 +17,240 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.util.Map;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicEditorPaneUI;
|
||||
import javax.swing.text.Caret;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JEditorPane}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicEditorPaneUI -->
|
||||
*
|
||||
* @uiDefault EditorPane.font Font
|
||||
* @uiDefault EditorPane.background Color
|
||||
* @uiDefault EditorPane.foreground Color also used if not editable
|
||||
* @uiDefault EditorPane.caretForeground Color
|
||||
* @uiDefault EditorPane.selectionBackground Color
|
||||
* @uiDefault EditorPane.selectionForeground Color
|
||||
* @uiDefault EditorPane.disabledBackground Color used if not enabled
|
||||
* @uiDefault EditorPane.inactiveBackground Color used if not editable
|
||||
* @uiDefault EditorPane.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||
* @uiDefault EditorPane.border Border
|
||||
* @uiDefault EditorPane.margin Insets
|
||||
* @uiDefault EditorPane.caretBlinkRate int default is 500 milliseconds
|
||||
*
|
||||
* <!-- FlatEditorPaneUI -->
|
||||
*
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
* @uiDefault EditorPane.focusedBackground Color optional
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatEditorPaneUI
|
||||
extends BasicEditorPaneUI
|
||||
implements StyleableUI
|
||||
{
|
||||
protected int minimumWidth;
|
||||
@Styleable protected int minimumWidth;
|
||||
protected boolean isIntelliJTheme;
|
||||
private Color background;
|
||||
@Styleable protected Color disabledBackground;
|
||||
@Styleable protected Color inactiveBackground;
|
||||
@Styleable protected Color focusedBackground;
|
||||
|
||||
private Color oldDisabledBackground;
|
||||
private Color oldInactiveBackground;
|
||||
|
||||
private Insets defaultMargin;
|
||||
|
||||
private Object oldHonorDisplayProperties;
|
||||
private FocusListener focusListener;
|
||||
private Map<String, Object> oldStyleValues;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatEditorPaneUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
installStyle();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
|
||||
String prefix = getPropertyPrefix();
|
||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||
background = UIManager.getColor( prefix + ".background" );
|
||||
disabledBackground = UIManager.getColor( prefix + ".disabledBackground" );
|
||||
inactiveBackground = UIManager.getColor( prefix + ".inactiveBackground" );
|
||||
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
|
||||
|
||||
defaultMargin = UIManager.getInsets( prefix + ".margin" );
|
||||
|
||||
// use component font and foreground for HTML text
|
||||
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
|
||||
getComponent().putClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES, true );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
super.uninstallDefaults();
|
||||
|
||||
background = null;
|
||||
disabledBackground = null;
|
||||
inactiveBackground = null;
|
||||
focusedBackground = null;
|
||||
|
||||
oldDisabledBackground = null;
|
||||
oldInactiveBackground = null;
|
||||
|
||||
oldStyleValues = null;
|
||||
|
||||
getComponent().putClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES, oldHonorDisplayProperties );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
|
||||
// necessary to update focus background
|
||||
focusListener = new FlatUIUtils.RepaintFocusListener( getComponent(), c -> focusedBackground != null );
|
||||
getComponent().addFocusListener( focusListener );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
|
||||
getComponent().removeFocusListener( focusListener );
|
||||
focusListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Caret createCaret() {
|
||||
return new FlatCaret( null, false );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void propertyChange( PropertyChangeEvent e ) {
|
||||
// invoke updateBackground() before super.propertyChange()
|
||||
String propertyName = e.getPropertyName();
|
||||
if( "editable".equals( propertyName ) || "enabled".equals( propertyName ) )
|
||||
updateBackground();
|
||||
|
||||
super.propertyChange( e );
|
||||
propertyChange( getComponent(), e, this::installStyle );
|
||||
}
|
||||
|
||||
static void propertyChange( JTextComponent c, PropertyChangeEvent e, Runnable installStyle ) {
|
||||
switch( e.getPropertyName() ) {
|
||||
case FlatClientProperties.MINIMUM_WIDTH:
|
||||
c.revalidate();
|
||||
break;
|
||||
|
||||
case FlatClientProperties.STYLE:
|
||||
case FlatClientProperties.STYLE_CLASS:
|
||||
installStyle.run();
|
||||
c.revalidate();
|
||||
c.repaint();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
protected void installStyle() {
|
||||
try {
|
||||
applyStyle( FlatStylingSupport.getResolvedStyle( getComponent(), "EditorPane" ) );
|
||||
} catch( RuntimeException ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
protected void applyStyle( Object style ) {
|
||||
oldDisabledBackground = disabledBackground;
|
||||
oldInactiveBackground = inactiveBackground;
|
||||
|
||||
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
|
||||
|
||||
updateBackground();
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
protected Object applyStyleProperty( String key, Object value ) {
|
||||
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, getComponent(), key, value );
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
@Override
|
||||
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||
}
|
||||
|
||||
private void updateBackground() {
|
||||
FlatTextFieldUI.updateBackground( getComponent(), background,
|
||||
disabledBackground, inactiveBackground,
|
||||
oldDisabledBackground, oldInactiveBackground );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize( JComponent c ) {
|
||||
return applyMinimumWidth( super.getPreferredSize( c ) );
|
||||
return applyMinimumWidth( c, super.getPreferredSize( c ), minimumWidth, defaultMargin );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize( JComponent c ) {
|
||||
return applyMinimumWidth( super.getMinimumSize( c ) );
|
||||
return applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth, defaultMargin );
|
||||
}
|
||||
|
||||
private Dimension applyMinimumWidth( Dimension size ) {
|
||||
static Dimension applyMinimumWidth( JComponent c, Dimension size, int minimumWidth, Insets defaultMargin ) {
|
||||
// do not apply minimum width if JTextComponent.margin is set
|
||||
if( !FlatTextFieldUI.hasDefaultMargins( c, defaultMargin ) )
|
||||
return size;
|
||||
|
||||
// Assume that text area is in a scroll pane (that displays the border)
|
||||
// and subtract 1px border line width.
|
||||
// Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding
|
||||
// issues. E.g. at scale factor 1.5 the first returns 4, but the second 3.
|
||||
minimumWidth = FlatUIUtils.minimumWidth( c, minimumWidth );
|
||||
size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) );
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintSafely( Graphics g ) {
|
||||
super.paintSafely( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintBackground( Graphics g ) {
|
||||
paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground );
|
||||
}
|
||||
|
||||
static void paintBackground( Graphics g, JTextComponent c, boolean isIntelliJTheme, Color focusedBackground ) {
|
||||
g.setColor( FlatTextFieldUI.getBackground( c, isIntelliJTheme, focusedBackground ) );
|
||||
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user