mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-09 16:25:10 +03:00
Compare commits
1999 Commits
0.16
...
fonts/robo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09c7f15364 | ||
|
|
b879b393ad | ||
|
|
e4503c2a54 | ||
|
|
7e2d02b997 | ||
|
|
d286550572 | ||
|
|
4e44e25d30 | ||
|
|
9fef2f9d05 | ||
|
|
04f1f5921d | ||
|
|
f9ecffb850 | ||
|
|
c9b5274ccf | ||
|
|
d209d47b9e | ||
|
|
21baaf810c | ||
|
|
95b4366270 | ||
|
|
c3adadfe2f | ||
|
|
adf7753617 | ||
|
|
d491847754 | ||
|
|
6afc747790 | ||
|
|
ff46935448 | ||
|
|
78c2f98f1f | ||
|
|
91be9aa2fe | ||
|
|
13e5da584f | ||
|
|
1762e0b7a6 | ||
|
|
05240abfe0 | ||
|
|
b515e8be04 | ||
|
|
24bc7fb0b5 | ||
|
|
0d2e1e6d18 | ||
|
|
f23c523baf | ||
|
|
76fee29f5b | ||
|
|
ec77746a43 | ||
|
|
92cd6f8f34 | ||
|
|
e7d2b5cbb6 | ||
|
|
4d175da3a0 | ||
|
|
5f047ddda9 | ||
|
|
ccca6fe88e | ||
|
|
a1f18e1ec9 | ||
|
|
afdaf7a0a5 | ||
|
|
62f0ef19f4 | ||
|
|
b736502c27 | ||
|
|
2be2dae3d6 | ||
|
|
aefe104ca4 | ||
|
|
3e6bce9cec | ||
|
|
a6394cac38 | ||
|
|
1e09ddfc93 | ||
|
|
664f5c98e9 | ||
|
|
c7bfd2ea82 | ||
|
|
9ce7ddd088 | ||
|
|
cca8d427d2 | ||
|
|
aa9263a2e7 | ||
|
|
5eaebde437 | ||
|
|
7f15f557a5 | ||
|
|
b459715cb5 | ||
|
|
bfede219d0 | ||
|
|
ef21efecf5 | ||
|
|
2bfbc9dc12 | ||
|
|
c3a1b45546 | ||
|
|
b72508f920 | ||
|
|
22bb80218d | ||
|
|
873a7e8572 | ||
|
|
0c5016fe89 | ||
|
|
607b084697 | ||
|
|
9d8ffec276 | ||
|
|
15f08e9b7c | ||
|
|
08aa6b1894 | ||
|
|
06b02c4f7c | ||
|
|
b56acd271f | ||
|
|
b24e2db59e | ||
|
|
f215356629 | ||
|
|
069a7c809c | ||
|
|
883b4d735a | ||
|
|
9f39b269bb | ||
|
|
36c405c708 | ||
|
|
bc7c68ebe4 | ||
|
|
6c502ad4c5 | ||
|
|
100aa0b621 | ||
|
|
8e42b19934 | ||
|
|
1a456d5d68 | ||
|
|
e83c26a76a | ||
|
|
6e7c2a616b | ||
|
|
0699454df8 | ||
|
|
92c110548a | ||
|
|
ca88023560 | ||
|
|
12fc2299ec | ||
|
|
2089c77b84 | ||
|
|
4f5a3e8d8b | ||
|
|
95522846ac | ||
|
|
614ac956de | ||
|
|
c228362c01 | ||
|
|
f6c5db07f2 | ||
|
|
78e7839213 | ||
|
|
f7be12df67 | ||
|
|
a1d1e221ae | ||
|
|
0a4dc54fb9 | ||
|
|
b8c7801365 | ||
|
|
a7099c039f | ||
|
|
a4d2d347e3 | ||
|
|
829c537fd3 | ||
|
|
28437f99cf | ||
|
|
c1402d85e1 | ||
|
|
32e071ab89 | ||
|
|
01125e030e | ||
|
|
b43278439a | ||
|
|
7a445aabd7 | ||
|
|
86a4f306c6 | ||
|
|
0e523f1193 | ||
|
|
9041a16b22 | ||
|
|
596ff3382d | ||
|
|
cbd80252ed | ||
|
|
bcd7a7e3dd | ||
|
|
9c98f1a553 | ||
|
|
c3d214aa23 | ||
|
|
d301f6e104 | ||
|
|
eb9fa585f7 | ||
|
|
16c6ffb032 | ||
|
|
7858e42e37 | ||
|
|
30132aa6b0 | ||
|
|
bf4d4cc2c5 | ||
|
|
9f0554c883 | ||
|
|
218ea6ce47 | ||
|
|
0baae7da8b | ||
|
|
fb4576fc1b | ||
|
|
16f3f9e6ff | ||
|
|
fee7cf6265 | ||
|
|
2dd75c4a64 | ||
|
|
d2f46cd0b5 | ||
|
|
10914083e6 | ||
|
|
5d167da55e | ||
|
|
b381e20e57 | ||
|
|
380dae1017 | ||
|
|
fb15cdc546 | ||
|
|
a525fe29db | ||
|
|
475cc9a9a5 | ||
|
|
264d6fbd6d | ||
|
|
2826cf379b | ||
|
|
d28745df29 | ||
|
|
94f9e4a1be | ||
|
|
ec547e1d65 | ||
|
|
61d4eb649b | ||
|
|
52ad15e375 | ||
|
|
ff00a6c0f0 | ||
|
|
9b1ebd658d | ||
|
|
f842530537 | ||
|
|
63077bbb19 | ||
|
|
4dad337377 | ||
|
|
10a965d765 | ||
|
|
3e9c9c9066 | ||
|
|
8b5a738e65 | ||
|
|
2c041dce3a | ||
|
|
ef151c68f4 | ||
|
|
52feaac92a | ||
|
|
cddbb3d7d4 | ||
|
|
42764550e6 | ||
|
|
6ee737b314 | ||
|
|
f460ef7685 | ||
|
|
9977bcb468 | ||
|
|
7437d984c7 | ||
|
|
5cd0b2403c | ||
|
|
a372da22f3 | ||
|
|
8b10d3ba5a | ||
|
|
a8b15c6a12 | ||
|
|
23bac7e5fd | ||
|
|
b82ee2ef61 | ||
|
|
b7761f4b71 | ||
|
|
f9a4f9771c | ||
|
|
d2acb2c98a | ||
|
|
bf0685cee2 | ||
|
|
d60bd5df14 | ||
|
|
73b6ca3762 | ||
|
|
8262793751 | ||
|
|
5ec7848fb0 | ||
|
|
450fc123ff | ||
|
|
3802c64be3 | ||
|
|
7bf1b26812 | ||
|
|
6c18431a30 | ||
|
|
a49d20249f | ||
|
|
ad384acd57 | ||
|
|
69851b7f3a | ||
|
|
92b53bf0df | ||
|
|
93e0496fd2 | ||
|
|
5151951f46 | ||
|
|
58dbccec2d | ||
|
|
90de14d013 | ||
|
|
f1792e46c6 | ||
|
|
84e9c36280 | ||
|
|
2ef6a2c3c9 | ||
|
|
5f961618bf | ||
|
|
37c375e2fa | ||
|
|
1758c175ed | ||
|
|
96f2a02cfa | ||
|
|
96d4bda6c8 | ||
|
|
02cf6050a1 | ||
|
|
38cf32a2e9 | ||
|
|
2ae7589d14 | ||
|
|
bcb2e1f0a1 | ||
|
|
14932d3f07 | ||
|
|
c3b9dc397d | ||
|
|
58b653f55d | ||
|
|
1dcdc42dde | ||
|
|
58a0a16985 | ||
|
|
a117243f14 | ||
|
|
22411060be | ||
|
|
045263ae58 | ||
|
|
024b6daaf6 | ||
|
|
bd5512c121 | ||
|
|
9afce83a02 | ||
|
|
07a8bd9486 | ||
|
|
bcdc0a8fce | ||
|
|
b295809432 | ||
|
|
52763ab932 | ||
|
|
99666265c9 | ||
|
|
af3e280d74 | ||
|
|
b57e4c0565 | ||
|
|
aca9931560 | ||
|
|
d09e166e4a | ||
|
|
68a7a60ff2 | ||
|
|
f21261914b | ||
|
|
7b11339fdc | ||
|
|
081fd43d98 | ||
|
|
ef2eedfc7c | ||
|
|
0dba9265be | ||
|
|
301aae9b8e | ||
|
|
c63f4e9662 | ||
|
|
47508dc6ac | ||
|
|
3a8879608a | ||
|
|
b221889549 | ||
|
|
c00d99b85f | ||
|
|
0bf87b753d | ||
|
|
53f2730064 | ||
|
|
d487c3b005 | ||
|
|
fef6ae7ff7 | ||
|
|
f6b42754de | ||
|
|
2ae9bb381d | ||
|
|
53bde84710 | ||
|
|
d006ac27ff | ||
|
|
c478d28b71 | ||
|
|
99f7b9ad84 | ||
|
|
ab58101ce3 | ||
|
|
d8f3682dc0 | ||
|
|
1fec7ba553 | ||
|
|
418f55f34e | ||
|
|
05d795b2ae | ||
|
|
a365b750d9 | ||
|
|
0aecfb565f | ||
|
|
0cf4edd9e5 | ||
|
|
dd7b7c6aef | ||
|
|
0bd677c46b | ||
|
|
1a131d5206 | ||
|
|
016e515ae2 | ||
|
|
456ceb3c58 | ||
|
|
2169be1b45 | ||
|
|
49eb0b0201 | ||
|
|
2e222bcdea | ||
|
|
c7fa475128 | ||
|
|
4174b065f3 | ||
|
|
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 |
228
.editorconfig
228
.editorconfig
@@ -6,3 +6,231 @@ insert_final_newline = true
|
|||||||
charset = latin1
|
charset = latin1
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
indent_size = 4
|
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
|
||||||
|
|||||||
6
.gitattributes
vendored
6
.gitattributes
vendored
@@ -15,8 +15,14 @@
|
|||||||
# BINARY FILES:
|
# BINARY FILES:
|
||||||
# Disable line ending normalize on checkin.
|
# Disable line ending normalize on checkin.
|
||||||
|
|
||||||
|
*.dll binary
|
||||||
|
*.dylib binary
|
||||||
*.gif binary
|
*.gif binary
|
||||||
*.jar binary
|
*.jar binary
|
||||||
|
*.lib binary
|
||||||
|
*.otf binary
|
||||||
*.png binary
|
*.png binary
|
||||||
*.sketch binary
|
*.sketch binary
|
||||||
|
*.so binary
|
||||||
|
*.ttf binary
|
||||||
*.zip 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}"
|
||||||
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
custom: https://www.formdev.com/flatlaf/sponsor/
|
||||||
142
.github/workflows/ci.yml
vendored
Normal file
142
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
|
||||||
|
# https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
|
||||||
|
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '*'
|
||||||
|
tags:
|
||||||
|
- '[0-9]*'
|
||||||
|
|
||||||
|
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
|
||||||
|
toolchain: [""]
|
||||||
|
include:
|
||||||
|
- java: 17
|
||||||
|
toolchain: 19 # latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- uses: gradle/wrapper-validation-action@v1
|
||||||
|
if: matrix.java == '8'
|
||||||
|
|
||||||
|
- name: Setup Java ${{ matrix.java }}
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
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 -Dtoolchain=${{ matrix.toolchain }}
|
||||||
|
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
if: matrix.java == '11'
|
||||||
|
with:
|
||||||
|
name: FlatLaf-build-artifacts
|
||||||
|
path: |
|
||||||
|
flatlaf-*/build/libs
|
||||||
|
flatlaf-*/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@v3
|
||||||
|
|
||||||
|
- name: Setup Java 11
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
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 -PskipFonts -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@v3
|
||||||
|
|
||||||
|
- name: Setup Java 11
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
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 -PskipFonts -Prelease
|
||||||
|
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"
|
||||||
59
.github/workflows/fonts.yml
vendored
Normal file
59
.github/workflows/fonts.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
|
||||||
|
# https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
|
||||||
|
|
||||||
|
name: Fonts
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '*'
|
||||||
|
tags:
|
||||||
|
- 'fonts/*-[0-9]*'
|
||||||
|
paths:
|
||||||
|
- 'flatlaf-fonts/**'
|
||||||
|
- '.github/workflows/fonts.yml'
|
||||||
|
- 'gradle/wrapper/gradle-wrapper.properties'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Fonts:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
font:
|
||||||
|
- inter
|
||||||
|
- jetbrains-mono
|
||||||
|
- roboto
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: |
|
||||||
|
github.event_name == 'push' &&
|
||||||
|
github.repository == 'JFormDesigner/FlatLaf'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup Java 11
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
java-version: 11
|
||||||
|
distribution: adopt # pre-installed on ubuntu-latest
|
||||||
|
cache: gradle
|
||||||
|
|
||||||
|
- name: Build with Gradle
|
||||||
|
run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:build
|
||||||
|
if: startsWith( github.ref, format( 'refs/tags/fonts/{0}-', matrix.font ) ) != true
|
||||||
|
|
||||||
|
- name: Publish snapshot to oss.sonatype.org
|
||||||
|
run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:publish -Dorg.gradle.internal.publish.checksums.insecure=true
|
||||||
|
env:
|
||||||
|
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||||
|
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
||||||
|
if: github.ref == 'refs/heads/main' || startsWith( github.ref, 'refs/heads/develop-' )
|
||||||
|
|
||||||
|
- name: Release a new stable version to Maven Central
|
||||||
|
run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:build :flatlaf-fonts-${{ matrix.font }}:publish -Prelease
|
||||||
|
env:
|
||||||
|
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||||
|
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
||||||
|
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||||
|
SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}
|
||||||
|
if: startsWith( github.ref, format( 'refs/tags/fonts/{0}-', matrix.font ) )
|
||||||
50
.github/workflows/natives.yml
vendored
Normal file
50
.github/workflows/natives.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
|
||||||
|
# https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
|
||||||
|
|
||||||
|
name: Native Libraries
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '*'
|
||||||
|
tags:
|
||||||
|
- '[0-9]*'
|
||||||
|
paths:
|
||||||
|
- 'flatlaf-natives/**'
|
||||||
|
- '.github/workflows/natives.yml'
|
||||||
|
- 'gradle/wrapper/gradle-wrapper.properties'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Natives:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- windows
|
||||||
|
- ubuntu
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- uses: gradle/wrapper-validation-action@v1
|
||||||
|
|
||||||
|
- name: Setup Java 11
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
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 build-natives --no-daemon
|
||||||
|
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: FlatLaf-natives-build-artifacts-${{ matrix.os }}
|
||||||
|
path: |
|
||||||
|
flatlaf-core/src/main/resources/com/formdev/flatlaf/natives
|
||||||
|
flatlaf-natives/flatlaf-natives-*/build
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -9,3 +9,7 @@ out/
|
|||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
*.iws
|
*.iws
|
||||||
|
*.xcuserstate
|
||||||
|
*.xcworkspacedata
|
||||||
|
.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
|
|
||||||
1564
CHANGELOG.md
1564
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
218
README.md
218
README.md
@@ -11,11 +11,31 @@ scales on **HiDPI** displays and runs on Java 8 or newer.
|
|||||||
The look is heavily inspired by **Darcula** and **IntelliJ** themes from
|
The look is heavily inspired by **Darcula** and **IntelliJ** themes from
|
||||||
IntelliJ IDEA 2019.2+ and uses almost 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)):
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
Sponsors
|
||||||
|
--------
|
||||||
|
|
||||||
|
<a href="https://www.ej-technologies.com/"><img src="https://www.formdev.com/flatlaf/sponsor/ej-technologies.png" width="200" alt="ej-technologies" title="ej-technologies - Java APM, Java Profiler, Java Installer Builder"></a>
|
||||||
|
|
||||||
|
<a href="https://www.dbvis.com/"><img src="https://www.formdev.com/flatlaf/sponsor/dbvisualizer.svg" width="200" alt="DbVisualizer" title="DbVisualizer - SQL Client and Editor"></a>
|
||||||
|
|
||||||
|
<a href="https://www.dscsag.com/"><img src="https://www.formdev.com/flatlaf/sponsor/DSC.png" height="48" alt="DSC Software AG" title="DSC Software AG - Your Companion for Integrative PLM"></a>
|
||||||
|
|
||||||
|
[Become a Sponsor](https://www.formdev.com/flatlaf/sponsor/)
|
||||||
|
|
||||||
Demo
|
Demo
|
||||||
----
|
----
|
||||||
|
|
||||||
@@ -28,28 +48,212 @@ Requires Java 8 or newer.
|
|||||||
Download
|
Download
|
||||||
--------
|
--------
|
||||||
|
|
||||||
FlatLaf binaries are available on **JCenter** and **Maven Central**.
|
FlatLaf binaries are available on **Maven Central**.
|
||||||
|
|
||||||
If you use Maven or Gradle, add a dependency with following coordinates to your
|
If you use Maven or Gradle, add a dependency with following coordinates to your
|
||||||
build script:
|
build script:
|
||||||
|
|
||||||
groupId: com.formdev
|
groupId: com.formdev
|
||||||
artifactId: flatlaf
|
artifactId: flatlaf
|
||||||
version: 0.16
|
version: (see button below)
|
||||||
|
|
||||||
Otherwise download `flatlaf-<version>.jar` here:
|
Otherwise download `flatlaf-<version>.jar` here:
|
||||||
|
|
||||||
[](https://bintray.com/jformdesigner/flatlaf/flatlaf/_latestVersion)
|
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf)
|
||||||
|
|
||||||
|
|
||||||
|
### Snapshots
|
||||||
|
|
||||||
|
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
|
Addons
|
||||||
------
|
------
|
||||||
|
|
||||||
- [SwingX](flatlaf-swingx)
|
- [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
|
||||||
|
- [Fonts](flatlaf-fonts) - some font families bundled in easy-to-use and
|
||||||
|
redistributable JARs
|
||||||
|
|
||||||
|
|
||||||
|
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
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
For more information and documentation visit
|
For more information and documentation visit
|
||||||
[FlatLaf Home](https://www.formdev.com/flatlaf/)
|
[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
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
- 
|
||||||
|
[JProfiler](https://www.ej-technologies.com/products/jprofiler/overview.html)
|
||||||
|
12 (**commercial**) - the award-winning all-in-one Java profiler
|
||||||
|
-  [JFormDesigner](https://www.formdev.com/) 8
|
||||||
|
(**commercial**) - Java/Swing GUI Designer
|
||||||
|
-  [Jeyla Studio](https://www.jeylastudio.com/) - Salon
|
||||||
|
Software
|
||||||
|
-  [Fanurio](https://www.fanuriotimetracking.com/) 3.3.2
|
||||||
|
(**commercial**) - time tracking and billing for freelancers and teams
|
||||||
|
-  [Antares](https://www.antarescircuit.io/) - a free,
|
||||||
|
powerful platform for designing, simulating and explaining digital circuits
|
||||||
|
- 
|
||||||
|
[Logisim-evolution](https://github.com/logisim-evolution/logisim-evolution)
|
||||||
|
3.6 - Digital logic design tool and simulator
|
||||||
|
-  [Cinecred](https://loadingbyte.com/cinecred/) - create
|
||||||
|
beautiful film credit sequences
|
||||||
|
-  [tinyMediaManager](https://www.tinymediamanager.org/)
|
||||||
|
v4 (**commercial**) - a media management tool
|
||||||
|
-  [Weasis](https://nroduit.github.io/) - medical DICOM
|
||||||
|
viewer used in healthcare by hospitals, health networks, etc
|
||||||
|
- 
|
||||||
|
[Makelangelo Software](https://github.com/MarginallyClever/Makelangelo-software)
|
||||||
|
7.3.0 - for plotters, especially the wall-hanging polargraph
|
||||||
|
-  [Ultorg](https://www.ultorg.com/) (**commercial**) - a
|
||||||
|
visual query system for relational databases
|
||||||
|
- [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 not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
@@ -14,11 +14,16 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
version = "0.16"
|
val releaseVersion = "3.0"
|
||||||
|
val developmentVersion = "3.1-SNAPSHOT"
|
||||||
|
|
||||||
|
version = if( rootProject.hasProperty( "release" ) ) releaseVersion else developmentVersion
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
|
version = rootProject.version
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,4 +37,48 @@ println( "----------------------------------------------------------------------
|
|||||||
println( "FlatLaf Version: ${version}" )
|
println( "FlatLaf Version: ${version}" )
|
||||||
println( "Gradle ${gradle.gradleVersion} at ${gradle.gradleHomeDir}" )
|
println( "Gradle ${gradle.gradleVersion} at ${gradle.gradleHomeDir}" )
|
||||||
println( "Java ${System.getProperty( "java.version" )}" )
|
println( "Java ${System.getProperty( "java.version" )}" )
|
||||||
|
val toolchainJavaVersion = System.getProperty( "toolchain" )
|
||||||
|
if( !toolchainJavaVersion.isNullOrEmpty() )
|
||||||
|
println( "Java toolchain ${toolchainJavaVersion}" )
|
||||||
println()
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
46
buildSrc/src/main/kotlin/flatlaf-cpp-library.gradle.kts
Normal file
46
buildSrc/src/main/kotlin/flatlaf-cpp-library.gradle.kts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 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 {
|
||||||
|
`cpp-library`
|
||||||
|
}
|
||||||
|
|
||||||
|
library {
|
||||||
|
// disable debuggable for release builds to make shared libraries smaller
|
||||||
|
binaries.configureEach( CppSharedLibrary::class ) {
|
||||||
|
with( compileTask.get() ) {
|
||||||
|
if( name.contains( "Release" ) )
|
||||||
|
isDebuggable = false
|
||||||
|
}
|
||||||
|
with( linkTask.get() ) {
|
||||||
|
if( name.contains( "Release" ) )
|
||||||
|
debuggable.set( false )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
withType<CppCompile>().configureEach {
|
||||||
|
doFirst {
|
||||||
|
println( "Used Tool Chain:" )
|
||||||
|
println( " - ${toolChain.get()}" )
|
||||||
|
println( "Available Tool Chains:" )
|
||||||
|
toolChains.forEach {
|
||||||
|
println( " - $it" )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
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 )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
buildSrc/src/main/kotlin/flatlaf-jni-headers.gradle.kts
Normal file
36
buildSrc/src/main/kotlin/flatlaf-jni-headers.gradle.kts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 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 JniHeadersExtension {
|
||||||
|
var headers: List<String> = emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
val extension = project.extensions.create<JniHeadersExtension>( "flatlafJniHeaders" )
|
||||||
|
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
register<Copy>( "jni-headers" ) {
|
||||||
|
// depend on :flatlaf-core:compileJava because it generates the JNI headers
|
||||||
|
dependsOn( ":flatlaf-core:compileJava" )
|
||||||
|
|
||||||
|
from( project( ":flatlaf-core" ).buildDir.resolve( "generated/jni-headers" ) )
|
||||||
|
into( "src/main/headers" )
|
||||||
|
include( extension.headers )
|
||||||
|
filter<org.apache.tools.ant.filters.FixCrLfFilter>(
|
||||||
|
"eol" to org.apache.tools.ant.filters.FixCrLfFilter.CrLf.newInstance( "lf" )
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
69
buildSrc/src/main/kotlin/flatlaf-module-info.gradle.kts
Normal file
69
buildSrc/src/main/kotlin/flatlaf-module-info.gradle.kts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* 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 {
|
||||||
|
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( rootProject.hasProperty( "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 { rootProject.hasProperty( "release" ) }
|
||||||
|
}
|
||||||
26
buildSrc/src/main/kotlin/flatlaf-toolchain.gradle.kts
Normal file
26
buildSrc/src/main/kotlin/flatlaf-toolchain.gradle.kts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 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
|
||||||
|
}
|
||||||
|
|
||||||
|
val toolchainJavaVersion = System.getProperty( "toolchain" )
|
||||||
|
if( !toolchainJavaVersion.isNullOrEmpty() ) {
|
||||||
|
java.toolchain {
|
||||||
|
languageVersion.set( JavaLanguageVersion.of( toolchainJavaVersion ) )
|
||||||
|
}
|
||||||
|
}
|
||||||
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 not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
@@ -14,150 +14,113 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
version = rootProject.version
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
`java-library`
|
`java-library`
|
||||||
`maven-publish`
|
`flatlaf-toolchain`
|
||||||
id( "com.jfrog.bintray" ) version "1.8.4"
|
`flatlaf-module-info`
|
||||||
|
`flatlaf-java9`
|
||||||
|
`flatlaf-publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
val sigtest = configurations.create( "sigtest" )
|
||||||
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" ) )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation( "com.miglayout:miglayout-swing:5.2" )
|
testImplementation( "org.junit.jupiter:junit-jupiter-api:5.7.2" )
|
||||||
testImplementation( "com.jgoodies:jgoodies-forms:1.9.0" )
|
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.7" )
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
withSourcesJar()
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
withJavadocJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
compileJava {
|
||||||
named<JavaCompile>( "compileModuleInfoJava" ) {
|
// generate JNI headers
|
||||||
sourceCompatibility = "9"
|
options.headerOutputDirectory.set( buildDir.resolve( "generated/jni-headers" ) )
|
||||||
targetCompatibility = "9"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
archiveBaseName.set( "flatlaf" )
|
archiveBaseName.set( "flatlaf" )
|
||||||
|
|
||||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
doLast {
|
||||||
manifest.attributes(
|
ReorderJarEntries.reorderJarEntries( outputs.files.singleFile );
|
||||||
"Multi-Release" to "true"
|
|
||||||
)
|
|
||||||
|
|
||||||
into( "META-INF/versions/9" ) {
|
|
||||||
from( sourceSets["module-info"].output )
|
|
||||||
include( "module-info.class" )
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
javadoc {
|
named<Jar>( "sourcesJar" ) {
|
||||||
options {
|
|
||||||
this as StandardJavadocDocletOptions
|
|
||||||
tags = listOf( "uiDefault", "clientProperty" )
|
|
||||||
}
|
|
||||||
isFailOnError = false
|
|
||||||
}
|
|
||||||
|
|
||||||
register( "sourcesJar", Jar::class ) {
|
|
||||||
archiveBaseName.set( "flatlaf" )
|
archiveBaseName.set( "flatlaf" )
|
||||||
archiveClassifier.set( "sources" )
|
|
||||||
|
|
||||||
from( sourceSets.main.get().allJava )
|
|
||||||
}
|
}
|
||||||
|
|
||||||
register( "javadocJar", Jar::class ) {
|
named<Jar>( "javadocJar" ) {
|
||||||
archiveBaseName.set( "flatlaf" )
|
archiveBaseName.set( "flatlaf" )
|
||||||
archiveClassifier.set( "javadoc" )
|
|
||||||
|
|
||||||
from( javadoc )
|
|
||||||
}
|
}
|
||||||
|
|
||||||
register( "testJar", Jar::class ) {
|
check {
|
||||||
archiveBaseName.set( "flatlaf-test" )
|
dependsOn( "sigtestCheck" )
|
||||||
from( sourceSets.test.get().output )
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
||||||
|
|
||||||
|
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 )
|
||||||
|
jvmArgs( listOf( "--add-opens", "java.desktop/javax.swing.plaf.basic=ALL-UNNAMED" ) )
|
||||||
|
}
|
||||||
|
|
||||||
|
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.themes,com.formdev.flatlaf.util",
|
||||||
|
"version" to version,
|
||||||
|
"release" to "1.8", // Java version
|
||||||
|
"failonerror" to "true" )
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
register( "sigtestCheck" ) {
|
||||||
create( "testArtifacts" )
|
group = "verification"
|
||||||
|
dependsOn( "jar" )
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
ant.withGroovyBuilder {
|
||||||
|
"taskdef"(
|
||||||
|
"name" to "sigtest",
|
||||||
|
"classname" to "org.netbeans.apitest.Sigtest",
|
||||||
|
"classpath" to sigtest.asPath )
|
||||||
|
|
||||||
|
"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" )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
artifacts {
|
flatlafPublish {
|
||||||
add( "testArtifacts", tasks.getByPath( "testJar" ) )
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
create<MavenPublication>( "maven" ) {
|
|
||||||
artifactId = "flatlaf"
|
artifactId = "flatlaf"
|
||||||
groupId = "com.formdev"
|
name = "FlatLaf"
|
||||||
|
description = "Flat Look and Feel"
|
||||||
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" )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
developers {
|
|
||||||
developer {
|
|
||||||
name.set( "Karl Tauber" )
|
|
||||||
organization.set( "FormDev Software GmbH" )
|
|
||||||
organizationUrl.set( "https://www.formdev.com/" )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scm {
|
|
||||||
url.set( "https://github.com/JFormDesigner/FlatLaf" )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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"
|
|
||||||
setLicenses( "Apache-2.0" )
|
|
||||||
vcsUrl = "https://github.com/JFormDesigner/FlatLaf"
|
|
||||||
|
|
||||||
with( version ) {
|
|
||||||
name = project.version.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
publish = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
1135
flatlaf-core/flatlaf-core-sigtest.txt
Normal file
1135
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,25 +16,56 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf;
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Flat LaF that has a dark color scheme and looks like Darcula LaF.
|
* 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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatDarculaLaf
|
public class FlatDarculaLaf
|
||||||
extends FlatDarkLaf
|
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)}.
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
|
*/
|
||||||
|
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() {
|
public static boolean install() {
|
||||||
return install( new FlatDarculaLaf() );
|
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
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "Flat Darcula";
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return "Flat Darcula Look and Feel";
|
return "FlatLaf Darcula Look and Feel";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,25 +16,60 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf;
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Flat LaF that has a dark color scheme.
|
* 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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatDarkLaf
|
public class FlatDarkLaf
|
||||||
extends FlatLaf
|
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)}.
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
|
*/
|
||||||
|
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() {
|
public static boolean install() {
|
||||||
return install( new FlatDarkLaf() );
|
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
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "Flat Dark";
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return "Flat Dark Look and Feel";
|
return "FlatLaf Dark Look and Feel";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDark() {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,17 +17,19 @@
|
|||||||
package com.formdev.flatlaf;
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import javax.swing.LookAndFeel;
|
||||||
|
import javax.swing.UIDefaults;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Addon for FlatLaf UI defaults.
|
* Addon for FlatLaf UI defaults.
|
||||||
*
|
*
|
||||||
* Allows loading of additional .properties files from addon JARs.
|
* Allows loading of additional .properties files from addon JARs.
|
||||||
* {@link java.util.ServiceLoader} is used to load extensions of this class 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
|
* If you extend this class in an addon JAR, you also have to add a text file named
|
||||||
* {@code META-INF/services/com.formdev.flatlaf.FlatDefaultsAddon}
|
* {@code META-INF/services/com.formdev.flatlaf.FlatDefaultsAddon}
|
||||||
* to the addon JAR. The file must contain a single line with the class name.
|
* to the addon JAR. The file must contain a single line with the class name.
|
||||||
*
|
* <p>
|
||||||
* See 'flatlaf-swingx' addon for an example
|
* See 'flatlaf-swingx' addon for an example
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -37,6 +39,33 @@ public abstract class FlatDefaultsAddon
|
|||||||
/**
|
/**
|
||||||
* Finds an addon .properties file for the given LaF class and returns
|
* Finds an addon .properties file for the given LaF class and returns
|
||||||
* it as input stream. Or {@code null} if not found.
|
* 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 abstract InputStream getDefaults( Class<?> lafClass );
|
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 to 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 an 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,25 +16,56 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf;
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Flat LaF that has a light color scheme and looks like IntelliJ LaF.
|
* 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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatIntelliJLaf
|
public class FlatIntelliJLaf
|
||||||
extends FlatLightLaf
|
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)}.
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
|
*/
|
||||||
|
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() {
|
public static boolean install() {
|
||||||
return install( new FlatIntelliJLaf() );
|
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
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "Flat IntelliJ";
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
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,25 +16,60 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf;
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Flat LaF that has a light color scheme.
|
* 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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatLightLaf
|
public class FlatLightLaf
|
||||||
extends FlatLaf
|
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)}.
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
|
*/
|
||||||
|
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() {
|
public static boolean install() {
|
||||||
return install( new FlatLightLaf() );
|
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
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "Flat Light";
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
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,199 @@
|
|||||||
|
/*
|
||||||
|
* 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.SwingUtilities;
|
||||||
|
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 than 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 whether FlatLaf updates the UI when the system font changes.
|
||||||
|
* If {@code true}, {@link SwingUtilities#updateComponentTreeUI(java.awt.Component)}
|
||||||
|
* gets invoked for all windows if the system font has changed.
|
||||||
|
* This is the similar to when switching to another look and feel (theme).
|
||||||
|
* Applications that do not work correctly when switching look and feel,
|
||||||
|
* should disable this option to avoid corrupted UI.
|
||||||
|
* <p>
|
||||||
|
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||||
|
* <strong>Default</strong> {@code true}
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
String UPDATE_UI_ON_SYSTEM_FONT_CHANGE = "flatlaf.updateUIOnSystemFontChange";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies a directory in which the native FlatLaf libraries 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.
|
||||||
|
* <p>
|
||||||
|
* If the value is {@code "system"}, then {@link System#loadLibrary(String)} is
|
||||||
|
* used to load the native library.
|
||||||
|
* Searches for the native library in classloader of caller
|
||||||
|
* (using {@link ClassLoader#findLibrary(String)}) and in paths specified
|
||||||
|
* in system properties {@code sun.boot.library.path} and {@code java.library.path}.
|
||||||
|
* (supported since FlatLaf 2.6)
|
||||||
|
* <p>
|
||||||
|
* If the native library can not loaded from the given path (or via {@link System#loadLibrary(String)}),
|
||||||
|
* then the embedded native library is extracted to the temporary directory and loaded from there.
|
||||||
|
*
|
||||||
|
* @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,725 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
|
*/
|
||||||
|
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() ) {
|
||||||
|
Object value = defaults.get( e.getValue() );
|
||||||
|
if( value != null )
|
||||||
|
defaults.put( e.getKey(), value );
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 an 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
|
||||||
|
for( Map.Entry<Object, Object> e : themeSpecificDefaults.entrySet() ) {
|
||||||
|
Object key = e.getKey();
|
||||||
|
Object value = e.getValue();
|
||||||
|
|
||||||
|
// append styles to existing styles
|
||||||
|
if( key instanceof String && ((String)key).startsWith( "[style]" ) ) {
|
||||||
|
Object oldValue = defaults.get( key );
|
||||||
|
if( oldValue != null )
|
||||||
|
value = oldValue + "; " + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults.put( key, value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = 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 ) {
|
||||||
|
Map<String, Object> map = (Map<String, Object>)value;
|
||||||
|
if( map.containsKey( "os.default" ) || map.containsKey( "os.windows" ) || map.containsKey( "os.mac" ) || map.containsKey( "os.linux" ) ) {
|
||||||
|
String osKey = SystemInfo.isWindows ? "os.windows"
|
||||||
|
: SystemInfo.isMacOS ? "os.mac"
|
||||||
|
: SystemInfo.isLinux ? "os.linux" : null;
|
||||||
|
if( osKey != null && map.containsKey( osKey ) )
|
||||||
|
apply( key, map.get( osKey ), defaults, defaultsKeysCache, uiKeys );
|
||||||
|
else if( map.containsKey( "os.default" ) )
|
||||||
|
apply( key, map.get( "os.default" ), defaults, defaultsKeysCache, uiKeys );
|
||||||
|
} else {
|
||||||
|
for( Map.Entry<String, Object> e : map.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 : parseColor( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
private ColorUIResource parseColor( String value ) {
|
||||||
|
try {
|
||||||
|
return UIDefaultsLoader.parseColor( value );
|
||||||
|
} catch( IllegalArgumentException ex ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 = {
|
||||||
|
"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 final Map<String, String> uiKeyMapping = new HashMap<>();
|
||||||
|
/** Copy UI default keys (value --> key). */
|
||||||
|
private static final Map<String, String> uiKeyCopying = new HashMap<>();
|
||||||
|
private static final Map<String, String> uiKeyInverseMapping = new HashMap<>();
|
||||||
|
private static final Map<String, String> checkboxKeyMapping = new HashMap<>();
|
||||||
|
private static final 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" );
|
||||||
|
|
||||||
|
// TabbedPane
|
||||||
|
uiKeyCopying.put( "TabbedPane.selectedBackground", "DefaultTabs.underlinedTabBackground" );
|
||||||
|
uiKeyCopying.put( "TabbedPane.selectedForeground", "DefaultTabs.underlinedTabForeground" );
|
||||||
|
uiKeyCopying.put( "TabbedPane.inactiveUnderlineColor", "DefaultTabs.inactiveUnderlineColor" );
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,8 @@
|
|||||||
package com.formdev.flatlaf;
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
|
import java.awt.GraphicsConfiguration;
|
||||||
import java.awt.GraphicsEnvironment;
|
import java.awt.GraphicsEnvironment;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
@@ -28,7 +30,10 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import javax.swing.text.StyleContext;
|
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.SystemInfo;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -36,7 +41,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
class LinuxFontPolicy
|
class LinuxFontPolicy
|
||||||
{
|
{
|
||||||
static Font getFont() {
|
static Font getFont() {
|
||||||
return SystemInfo.IS_KDE ? getKDEFont() : getGnomeFont();
|
return SystemInfo.isKDE ? getKDEFont() : getGnomeFont();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,29 +56,50 @@ class LinuxFontPolicy
|
|||||||
|
|
||||||
String family = "";
|
String family = "";
|
||||||
int style = Font.PLAIN;
|
int style = Font.PLAIN;
|
||||||
int size = 10;
|
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 );
|
StringTokenizer st = new StringTokenizer( (String) fontName );
|
||||||
while( st.hasMoreTokens() ) {
|
while( st.hasMoreTokens() ) {
|
||||||
String word = st.nextToken();
|
String word = st.nextToken();
|
||||||
|
|
||||||
if( word.equalsIgnoreCase( "italic" ) )
|
// 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;
|
style |= Font.ITALIC;
|
||||||
else if( word.equalsIgnoreCase( "bold" ) )
|
else if( lword.equals( "bold" ) )
|
||||||
style |= Font.BOLD;
|
style |= Font.BOLD;
|
||||||
else if( Character.isDigit( word.charAt( 0 ) ) ) {
|
else if( Character.isDigit( word.charAt( 0 ) ) ) {
|
||||||
try {
|
try {
|
||||||
size = Integer.parseInt( word );
|
dsize = Double.parseDouble( word );
|
||||||
} catch( NumberFormatException ex ) {
|
} catch( NumberFormatException ex ) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
} else
|
} 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);
|
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
|
// scale font size
|
||||||
double dsize = size * getGnomeFontScale();
|
dsize *= getGnomeFontScale();
|
||||||
size = (int) (dsize + 0.5);
|
int size = (int) (dsize + 0.5);
|
||||||
if( size < 1 )
|
if( size < 1 )
|
||||||
size = 1;
|
size = 1;
|
||||||
|
|
||||||
@@ -82,13 +108,52 @@ class LinuxFontPolicy
|
|||||||
if( logicalFamily != null )
|
if( logicalFamily != null )
|
||||||
family = logicalFamily;
|
family = logicalFamily;
|
||||||
|
|
||||||
return createFont( family, style, size, dsize );
|
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 ) {
|
private static Font createFont( String family, int style, int size, double dsize ) {
|
||||||
// using StyleContext.getFont() here because it uses
|
Font font = FlatLaf.createCompositeFont( family, style, size );
|
||||||
// sun.font.FontUtilities.getCompositeFontUIResource()
|
|
||||||
Font font = new StyleContext().getFont( family, style, size );
|
|
||||||
|
|
||||||
// set font size in floating points
|
// set font size in floating points
|
||||||
font = font.deriveFont( style, (float) dsize );
|
font = font.deriveFont( style, (float) dsize );
|
||||||
@@ -97,11 +162,15 @@ class LinuxFontPolicy
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static double getGnomeFontScale() {
|
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
|
// see class com.sun.java.swing.plaf.gtk.PangoFonts background information
|
||||||
|
|
||||||
Object value = Toolkit.getDefaultToolkit().getDesktopProperty( "gnome.Xft/DPI" );
|
Object value = Toolkit.getDefaultToolkit().getDesktopProperty( "gnome.Xft/DPI" );
|
||||||
if( value instanceof Integer ) {
|
if( value instanceof Integer ) {
|
||||||
int dpi = ((Integer)value).intValue() / 1024;
|
int dpi = (Integer) value / 1024;
|
||||||
if( dpi == -1 )
|
if( dpi == -1 )
|
||||||
dpi = 96;
|
dpi = 96;
|
||||||
if( dpi < 50 )
|
if( dpi < 50 )
|
||||||
@@ -128,7 +197,7 @@ class LinuxFontPolicy
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the default font for KDE for KDE configuration files.
|
* Gets the default font for KDE from KDE configuration files.
|
||||||
*
|
*
|
||||||
* The Swing fonts are not updated when the user changes system font size
|
* The Swing fonts are not updated when the user changes system font size
|
||||||
* (System Settings > Fonts > Force Font DPI). A application restart is necessary.
|
* (System Settings > Fonts > Force Font DPI). A application restart is necessary.
|
||||||
@@ -151,7 +220,7 @@ class LinuxFontPolicy
|
|||||||
int size = 10;
|
int size = 10;
|
||||||
|
|
||||||
if( generalFont != null ) {
|
if( generalFont != null ) {
|
||||||
List<String> strs = FlatLaf.split( generalFont, ',' );
|
List<String> strs = StringUtils.split( generalFont, ',' );
|
||||||
try {
|
try {
|
||||||
family = strs.get( 0 );
|
family = strs.get( 0 );
|
||||||
size = Integer.parseInt( strs.get( 1 ) );
|
size = Integer.parseInt( strs.get( 1 ) );
|
||||||
@@ -160,13 +229,13 @@ class LinuxFontPolicy
|
|||||||
if( "1".equals( strs.get( 5 ) ) )
|
if( "1".equals( strs.get( 5 ) ) )
|
||||||
style |= Font.ITALIC;
|
style |= Font.ITALIC;
|
||||||
} catch( RuntimeException ex ) {
|
} catch( RuntimeException ex ) {
|
||||||
ex.printStackTrace();
|
LoggingFacade.INSTANCE.logConfig( "FlatLaf: Failed to parse 'font=" + generalFont + "'.", ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// font dpi
|
// font dpi
|
||||||
int dpi = 96;
|
int dpi = 96;
|
||||||
if( forceFontDPI != null ) {
|
if( forceFontDPI != null && !isSystemScaling() ) {
|
||||||
try {
|
try {
|
||||||
dpi = Integer.parseInt( forceFontDPI );
|
dpi = Integer.parseInt( forceFontDPI );
|
||||||
if( dpi <= 0 )
|
if( dpi <= 0 )
|
||||||
@@ -174,7 +243,7 @@ class LinuxFontPolicy
|
|||||||
if( dpi < 50 )
|
if( dpi < 50 )
|
||||||
dpi = 50;
|
dpi = 50;
|
||||||
} catch( NumberFormatException ex ) {
|
} catch( NumberFormatException ex ) {
|
||||||
ex.printStackTrace();
|
LoggingFacade.INSTANCE.logConfig( "FlatLaf: Failed to parse 'forceFontDPI=" + forceFontDPI + "'.", ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,11 +278,11 @@ class LinuxFontPolicy
|
|||||||
// read config file
|
// read config file
|
||||||
ArrayList<String> lines = new ArrayList<>( 200 );
|
ArrayList<String> lines = new ArrayList<>( 200 );
|
||||||
try( BufferedReader reader = new BufferedReader( new FileReader( file ) ) ) {
|
try( BufferedReader reader = new BufferedReader( new FileReader( file ) ) ) {
|
||||||
String line = null;
|
String line;
|
||||||
while( (line = reader.readLine()) != null )
|
while( (line = reader.readLine()) != null )
|
||||||
lines.add( line );
|
lines.add( line );
|
||||||
} catch( IOException ex ) {
|
} catch( IOException ex ) {
|
||||||
ex.printStackTrace();
|
LoggingFacade.INSTANCE.logConfig( "FlatLaf: Failed to read '" + filename + "'.", ex );
|
||||||
}
|
}
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
@@ -245,4 +314,18 @@ class LinuxFontPolicy
|
|||||||
}
|
}
|
||||||
return null;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,336 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 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.AWTEvent;
|
||||||
|
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.MouseInfo;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.PointerInfo;
|
||||||
|
import java.awt.Polygon;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JLayeredPane;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
|
import javax.swing.MenuElement;
|
||||||
|
import javax.swing.MenuSelectionManager;
|
||||||
|
import javax.swing.RootPaneContainer;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.event.ChangeListener;
|
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Improves usability of submenus by using a
|
||||||
|
* <a href="https://height.app/blog/guide-to-build-context-menus#safe-triangle">safe triangle</a>
|
||||||
|
* to avoid that the submenu closes while the user moves the mouse to it.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
class SubMenuUsabilityHelper
|
||||||
|
implements ChangeListener
|
||||||
|
{
|
||||||
|
private static final String KEY_USE_SAFE_TRIANGLE = "Menu.useSafeTriangle";
|
||||||
|
private static final String KEY_SHOW_SAFE_TRIANGLE = "FlatLaf.debug.menu.showSafeTriangle";
|
||||||
|
|
||||||
|
// Using a static field to ensure that there is only one instance in the system.
|
||||||
|
// Multiple instances would freeze the application.
|
||||||
|
// https://github.com/apache/netbeans/issues/4231#issuecomment-1179616607
|
||||||
|
private static SubMenuUsabilityHelper instance;
|
||||||
|
|
||||||
|
private SubMenuEventQueue subMenuEventQueue;
|
||||||
|
private SafeTrianglePainter safeTrianglePainter;
|
||||||
|
private boolean changePending;
|
||||||
|
|
||||||
|
// mouse location in screen coordinates
|
||||||
|
private int mouseX;
|
||||||
|
private int mouseY;
|
||||||
|
|
||||||
|
// target popup bounds in screen coordinates
|
||||||
|
private int targetX;
|
||||||
|
private int targetTopY;
|
||||||
|
private int targetBottomY;
|
||||||
|
|
||||||
|
private Rectangle invokerBounds;
|
||||||
|
|
||||||
|
static synchronized boolean install() {
|
||||||
|
if( instance != null )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
instance = new SubMenuUsabilityHelper();
|
||||||
|
MenuSelectionManager.defaultManager().addChangeListener( instance );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static synchronized void uninstall() {
|
||||||
|
if( instance == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
MenuSelectionManager.defaultManager().removeChangeListener( instance );
|
||||||
|
instance.uninstallEventQueue();
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateChanged( ChangeEvent e ) {
|
||||||
|
if( !FlatUIUtils.getUIBoolean( KEY_USE_SAFE_TRIANGLE, true ))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// handle menu selection change later, but only once in case of temporary changes
|
||||||
|
// e.g. moving mouse from one menu item to another one, fires two events:
|
||||||
|
// 1. old menu item is removed from menu selection
|
||||||
|
// 2. new menu item is added to menu selection
|
||||||
|
synchronized( this ) {
|
||||||
|
if( changePending )
|
||||||
|
return;
|
||||||
|
changePending = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventQueue.invokeLater( () -> {
|
||||||
|
synchronized( this ) {
|
||||||
|
changePending = false;
|
||||||
|
}
|
||||||
|
menuSelectionChanged();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void menuSelectionChanged() {
|
||||||
|
MenuElement[] path = MenuSelectionManager.defaultManager().getSelectedPath();
|
||||||
|
|
||||||
|
/*debug
|
||||||
|
System.out.println( "--- " + path.length );
|
||||||
|
for( int i = 0; i < path.length; i++ )
|
||||||
|
System.out.println( " " + i + ": " + path[i].getClass().getName() );
|
||||||
|
debug*/
|
||||||
|
|
||||||
|
// find submenu in menu selection
|
||||||
|
int subMenuIndex = findSubMenu( path );
|
||||||
|
|
||||||
|
// uninstall if there is no submenu in selection
|
||||||
|
if( subMenuIndex < 0 || subMenuIndex != path.length - 1 ) {
|
||||||
|
uninstallEventQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get current mouse location
|
||||||
|
PointerInfo pointerInfo = MouseInfo.getPointerInfo();
|
||||||
|
Point mouseLocation = (pointerInfo != null) ? pointerInfo.getLocation() : new Point();
|
||||||
|
mouseX = mouseLocation.x;
|
||||||
|
mouseY = mouseLocation.y;
|
||||||
|
|
||||||
|
// check whether popup is showing, which is e.g. not the case if it is empty
|
||||||
|
JPopupMenu popup = (JPopupMenu) path[subMenuIndex];
|
||||||
|
if( !popup.isShowing() ) {
|
||||||
|
uninstallEventQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get invoker screen bounds
|
||||||
|
Component invoker = popup.getInvoker();
|
||||||
|
invokerBounds = (invoker != null)
|
||||||
|
? new Rectangle( invoker.getLocationOnScreen(), invoker.getSize() )
|
||||||
|
: null;
|
||||||
|
|
||||||
|
// check whether mouse location is within invoker
|
||||||
|
if( invokerBounds != null && !invokerBounds.contains( mouseX, mouseY ) ) {
|
||||||
|
uninstallEventQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute top/bottom target locations
|
||||||
|
Point popupLocation = popup.getLocationOnScreen();
|
||||||
|
Dimension popupSize = popup.getSize();
|
||||||
|
targetX = (mouseX < popupLocation.x + (popupSize.width / 2))
|
||||||
|
? popupLocation.x
|
||||||
|
: popupLocation.x + popupSize.width;
|
||||||
|
targetTopY = popupLocation.y;
|
||||||
|
targetBottomY = popupLocation.y + popupSize.height;
|
||||||
|
|
||||||
|
// install own event queue to supress mouse events when mouse is moved within safe triangle
|
||||||
|
if( subMenuEventQueue == null )
|
||||||
|
subMenuEventQueue = new SubMenuEventQueue();
|
||||||
|
|
||||||
|
// create safe triangle painter
|
||||||
|
if( safeTrianglePainter == null && UIManager.getBoolean( KEY_SHOW_SAFE_TRIANGLE ) )
|
||||||
|
safeTrianglePainter = new SafeTrianglePainter( popup );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uninstallEventQueue() {
|
||||||
|
if( subMenuEventQueue != null ) {
|
||||||
|
subMenuEventQueue.uninstall();
|
||||||
|
subMenuEventQueue = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( safeTrianglePainter != null ) {
|
||||||
|
safeTrianglePainter.uninstall();
|
||||||
|
safeTrianglePainter = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int findSubMenu( MenuElement[] path ) {
|
||||||
|
for( int i = path.length - 1; i >= 1; i-- ) {
|
||||||
|
if( path[i] instanceof JPopupMenu &&
|
||||||
|
path[i - 1] instanceof JMenu &&
|
||||||
|
!((JMenu)path[i - 1]).isTopLevelMenu() )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Polygon createSafeTriangle() {
|
||||||
|
return new Polygon(
|
||||||
|
new int[] { mouseX, targetX, targetX },
|
||||||
|
new int[] { mouseY, targetTopY, targetBottomY },
|
||||||
|
3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class SubMenuEventQueue --------------------------------------------
|
||||||
|
|
||||||
|
private class SubMenuEventQueue
|
||||||
|
extends EventQueue
|
||||||
|
{
|
||||||
|
private Timer mouseUpdateTimer;
|
||||||
|
private Timer timeoutTimer;
|
||||||
|
|
||||||
|
private int newMouseX;
|
||||||
|
private int newMouseY;
|
||||||
|
private AWTEvent lastMouseEvent;
|
||||||
|
|
||||||
|
SubMenuEventQueue() {
|
||||||
|
// timer used to slightly delay update of mouse location used for safe triangle
|
||||||
|
mouseUpdateTimer = new Timer( 50, e -> {
|
||||||
|
mouseX = newMouseX;
|
||||||
|
mouseY = newMouseY;
|
||||||
|
|
||||||
|
if( safeTrianglePainter != null )
|
||||||
|
safeTrianglePainter.repaint();
|
||||||
|
} );
|
||||||
|
mouseUpdateTimer.setRepeats( false );
|
||||||
|
|
||||||
|
// timer used to timeout safe triangle when mouse stops moving
|
||||||
|
timeoutTimer = new Timer( 200, e -> {
|
||||||
|
if( invokerBounds != null && !invokerBounds.contains( newMouseX, newMouseY ) ) {
|
||||||
|
// post last mouse event, which selects menu item at mouse location
|
||||||
|
if( lastMouseEvent != null ) {
|
||||||
|
postEvent( lastMouseEvent );
|
||||||
|
lastMouseEvent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstallEventQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
timeoutTimer.setRepeats( false );
|
||||||
|
|
||||||
|
Toolkit.getDefaultToolkit().getSystemEventQueue().push( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void uninstall() {
|
||||||
|
mouseUpdateTimer.stop();
|
||||||
|
mouseUpdateTimer = null;
|
||||||
|
|
||||||
|
timeoutTimer.stop();
|
||||||
|
timeoutTimer = null;
|
||||||
|
|
||||||
|
lastMouseEvent = null;
|
||||||
|
|
||||||
|
super.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void dispatchEvent( AWTEvent e ) {
|
||||||
|
int id = e.getID();
|
||||||
|
|
||||||
|
if( e instanceof MouseEvent &&
|
||||||
|
(id == MouseEvent.MOUSE_MOVED || id == MouseEvent.MOUSE_DRAGGED) )
|
||||||
|
{
|
||||||
|
newMouseX = ((MouseEvent)e).getXOnScreen();
|
||||||
|
newMouseY = ((MouseEvent)e).getYOnScreen();
|
||||||
|
|
||||||
|
if( safeTrianglePainter != null )
|
||||||
|
safeTrianglePainter.repaint();
|
||||||
|
|
||||||
|
mouseUpdateTimer.stop();
|
||||||
|
timeoutTimer.stop();
|
||||||
|
|
||||||
|
// check whether mouse moved within safe triangle
|
||||||
|
if( createSafeTriangle().contains( newMouseX, newMouseY ) ) {
|
||||||
|
// update mouse location delayed (this changes the safe triangle)
|
||||||
|
mouseUpdateTimer.start();
|
||||||
|
|
||||||
|
timeoutTimer.start();
|
||||||
|
|
||||||
|
// remember last mouse event, which will be posted if the mouse stops moving
|
||||||
|
lastMouseEvent = e;
|
||||||
|
|
||||||
|
// ignore mouse event
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update mouse location immediately (this changes the safe triangle)
|
||||||
|
mouseX = newMouseX;
|
||||||
|
mouseY = newMouseY;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.dispatchEvent( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class SafeTrianglePainter ------------------------------------------
|
||||||
|
|
||||||
|
private class SafeTrianglePainter
|
||||||
|
extends JComponent
|
||||||
|
{
|
||||||
|
SafeTrianglePainter( JPopupMenu popup ) {
|
||||||
|
Window window = SwingUtilities.windowForComponent( popup.getInvoker() );
|
||||||
|
if( window instanceof RootPaneContainer ) {
|
||||||
|
JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane();
|
||||||
|
setSize( layeredPane.getSize() );
|
||||||
|
layeredPane.add( this, Integer.valueOf( JLayeredPane.POPUP_LAYER + 1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uninstall() {
|
||||||
|
Container parent = getParent();
|
||||||
|
if( parent != null ) {
|
||||||
|
parent.remove( this );
|
||||||
|
parent.repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent( Graphics g ) {
|
||||||
|
Point locationOnScreen = getLocationOnScreen();
|
||||||
|
g.translate( -locationOnScreen.x, -locationOnScreen.y );
|
||||||
|
|
||||||
|
g.setColor( Color.red );
|
||||||
|
((Graphics2D)g).draw( createSafeTriangle() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1422
flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java
Normal file
1422
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 width;
|
||||||
protected final int height;
|
protected final int height;
|
||||||
protected final Color color;
|
protected Color color;
|
||||||
|
|
||||||
public FlatAbstractIcon( int width, int height, Color color ) {
|
public FlatAbstractIcon( int width, int height, Color color ) {
|
||||||
this.width = width;
|
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 scale 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;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
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;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "ascendingSort" icon for {@link javax.swing.table.JTableHeader}.
|
* "ascendingSort" icon for {@link javax.swing.table.JTableHeader}.
|
||||||
*
|
*
|
||||||
|
* @uiDefault Component.arrowType String chevron (default) or triangle
|
||||||
* @uiDefault Table.sortIconColor Color
|
* @uiDefault Table.sortIconColor Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -32,7 +39,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
public class FlatAscendingSortIcon
|
public class FlatAscendingSortIcon
|
||||||
extends FlatAbstractIcon
|
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() {
|
public FlatAscendingSortIcon() {
|
||||||
super( 10, 5, null );
|
super( 10, 5, null );
|
||||||
@@ -40,7 +48,36 @@ public class FlatAscendingSortIcon
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
|
boolean chevron = this.chevron;
|
||||||
|
Color sortIconColor = this.sortIconColor;
|
||||||
|
|
||||||
|
// Because this icon is 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.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,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.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Area;
|
||||||
|
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
|
||||||
|
{
|
||||||
|
private Path2D path;
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
switch( key ) {
|
||||||
|
case "capsLockIconColor": return color;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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="5" height="2" x="5.5" y="11.5" stroke="#FFF" stroke-linejoin="round"/>
|
||||||
|
<path stroke="#FFF" stroke-linejoin="round" d="M2.5,7.5 L8,2 L13.5,7.5 L10.5,7.5 L10.5,9.5 L5.5,9.5 L5.5,7.5 L2.5,7.5 Z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
*/
|
||||||
|
|
||||||
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
|
BasicStroke stroke = new BasicStroke( 1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND );
|
||||||
|
|
||||||
|
if( path == null ) {
|
||||||
|
path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
|
path.append( new RoundRectangle2D.Float( 0, 0, 16, 16, 6, 6 ), false );
|
||||||
|
path.append( new Area( stroke.createStrokedShape( new Rectangle2D.Float( 5.5f, 11.5f, 5, 2 ) ) ), false );
|
||||||
|
path.append( new Area( stroke.createStrokedShape( FlatUIUtils.createPath(
|
||||||
|
2.5,7.5, 8,2, 13.5,7.5, 10.5,7.5, 10.5,9.5, 5.5,9.5, 5.5,7.5, 2.5,7.5 ) ) ), false );
|
||||||
|
}
|
||||||
|
g.fill( path );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,65 +16,145 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||||
import java.awt.BasicStroke;
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
|
import java.awt.geom.RoundRectangle2D;
|
||||||
|
import java.util.Map;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
|
import javax.swing.JComponent;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
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}.
|
* Icon for {@link javax.swing.JCheckBox}.
|
||||||
*
|
* <p>
|
||||||
* Note: If Component.focusWidth is greater than zero, then the outline focus border
|
* <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
|
* is painted outside of the icon bounds. Make sure that the checkbox
|
||||||
* has margins, which are equal or greater than focusWidth.
|
* 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.focusWidth int
|
||||||
|
* @uiDefault Component.borderWidth int
|
||||||
* @uiDefault Component.focusColor Color
|
* @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.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.background Color
|
||||||
* @uiDefault CheckBox.icon.disabledBackground Color
|
* @uiDefault CheckBox.icon.selectedBorderColor Color
|
||||||
* @uiDefault CheckBox.icon.focusedBackground Color optional
|
|
||||||
* @uiDefault CheckBox.icon.hoverBackground Color optional
|
|
||||||
* @uiDefault CheckBox.icon.pressedBackground Color optional
|
|
||||||
* @uiDefault CheckBox.icon.selectedBackground 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.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.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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatCheckBoxIcon
|
public class FlatCheckBoxIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
protected final int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
protected final String style = UIManager.getString( getPropertyPrefix() + "icon.style" );
|
||||||
protected final Color focusColor = UIManager.getColor( "Component.focusColor" );
|
@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" );
|
// enabled
|
||||||
protected final Color disabledBorderColor = UIManager.getColor( "CheckBox.icon.disabledBorderColor" );
|
@Styleable protected Color borderColor = getUIColor( "CheckBox.icon.borderColor", style );
|
||||||
protected final Color selectedBorderColor = UIManager.getColor( "CheckBox.icon.selectedBorderColor" );
|
@Styleable protected Color background = getUIColor( "CheckBox.icon.background", style );
|
||||||
protected final Color focusedBorderColor = UIManager.getColor( "CheckBox.icon.focusedBorderColor" );
|
@Styleable protected Color selectedBorderColor = getUIColor( "CheckBox.icon.selectedBorderColor", style );
|
||||||
protected final Color hoverBorderColor = UIManager.getColor( "CheckBox.icon.hoverBorderColor" );
|
@Styleable protected Color selectedBackground = getUIColor( "CheckBox.icon.selectedBackground", style );
|
||||||
protected final Color selectedFocusedBorderColor = UIManager.getColor( "CheckBox.icon.selectedFocusedBorderColor" );
|
@Styleable protected Color checkmarkColor = getUIColor( "CheckBox.icon.checkmarkColor", style );
|
||||||
protected final Color background = UIManager.getColor( "CheckBox.icon.background" );
|
|
||||||
protected final Color disabledBackground = UIManager.getColor( "CheckBox.icon.disabledBackground" );
|
// disabled
|
||||||
protected final Color focusedBackground = UIManager.getColor( "CheckBox.icon.focusedBackground" );
|
@Styleable protected Color disabledBorderColor = getUIColor( "CheckBox.icon.disabledBorderColor", style );
|
||||||
protected final Color hoverBackground = UIManager.getColor( "CheckBox.icon.hoverBackground" );
|
@Styleable protected Color disabledBackground = getUIColor( "CheckBox.icon.disabledBackground", style );
|
||||||
protected final Color pressedBackground = UIManager.getColor( "CheckBox.icon.pressedBackground" );
|
/** @since 2 */ @Styleable protected Color disabledSelectedBorderColor = getUIColor( "CheckBox.icon.disabledSelectedBorderColor", style );
|
||||||
protected final Color selectedBackground = UIManager.getColor( "CheckBox.icon.selectedBackground" );
|
/** @since 2 */ @Styleable protected Color disabledSelectedBackground = getUIColor( "CheckBox.icon.disabledSelectedBackground", style );
|
||||||
protected final Color selectedHoverBackground = UIManager.getColor( "CheckBox.icon.selectedHoverBackground" );
|
@Styleable protected Color disabledCheckmarkColor = getUIColor( "CheckBox.icon.disabledCheckmarkColor", style );
|
||||||
protected final Color selectedPressedBackground = UIManager.getColor( "CheckBox.icon.selectedPressedBackground" );
|
|
||||||
protected final Color checkmarkColor = UIManager.getColor( "CheckBox.icon.checkmarkColor" );
|
// focused
|
||||||
protected final Color disabledCheckmarkColor = UIManager.getColor( "CheckBox.icon.disabledCheckmarkColor" );
|
@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;
|
static final int ICON_SIZE = 15;
|
||||||
|
|
||||||
@@ -82,62 +162,140 @@ public class FlatCheckBoxIcon
|
|||||||
super( ICON_SIZE, ICON_SIZE, null );
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g2 ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
boolean selected = (c instanceof AbstractButton) ? ((AbstractButton)c).isSelected() : false;
|
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
|
// paint focused border
|
||||||
if( c.hasFocus() && focusWidth > 0 ) {
|
if( isFocused && focusWidth > 0 && FlatButtonUI.isFocusPainted( c ) ) {
|
||||||
g2.setColor( focusColor );
|
g.setColor( getFocusColor( c ) );
|
||||||
paintFocusBorder( g2 );
|
paintFocusBorder( c, g );
|
||||||
}
|
}
|
||||||
|
|
||||||
// paint border
|
// paint border
|
||||||
g2.setColor( FlatButtonUI.buttonStateColor( c,
|
g.setColor( getBorderColor( c, selected ) );
|
||||||
selected ? selectedBorderColor : borderColor,
|
paintBorder( c, g, bw );
|
||||||
disabledBorderColor,
|
|
||||||
selected && selectedFocusedBorderColor != null ? selectedFocusedBorderColor : focusedBorderColor,
|
|
||||||
hoverBorderColor,
|
|
||||||
null ) );
|
|
||||||
paintBorder( g2 );
|
|
||||||
|
|
||||||
// paint background
|
// paint background
|
||||||
g2.setColor( FlatButtonUI.buttonStateColor( c,
|
Color bg = FlatUIUtils.deriveColor( getBackground( c, selected ),
|
||||||
selected ? selectedBackground : background,
|
selected ? selectedBackground : background );
|
||||||
disabledBackground,
|
if( bg.getAlpha() < 255 ) {
|
||||||
focusedBackground,
|
// fill background with default color before filling with non-opaque background
|
||||||
selected && selectedHoverBackground != null ? selectedHoverBackground : hoverBackground,
|
g.setColor( selected ? selectedBackground : background );
|
||||||
selected && selectedPressedBackground != null ? selectedPressedBackground : pressedBackground ) );
|
paintBackground( c, g, bw );
|
||||||
paintBackground( g2 );
|
}
|
||||||
|
g.setColor( bg );
|
||||||
|
paintBackground( c, g, bw );
|
||||||
|
|
||||||
// paint checkmark
|
// paint checkmark
|
||||||
if( selected ) {
|
if( selected ) {
|
||||||
g2.setColor( c.isEnabled() ? checkmarkColor : disabledCheckmarkColor );
|
g.setColor( getCheckmarkColor( c ) );
|
||||||
paintCheckmark( g2 );
|
if( indeterminate )
|
||||||
|
paintIndeterminate( c, g );
|
||||||
|
else
|
||||||
|
paintCheckmark( c, g );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void paintFocusBorder( Graphics2D g2 ) {
|
protected void paintFocusBorder( Component c, Graphics2D g ) {
|
||||||
// the outline focus border is painted outside of the icon
|
// the outer focus border is painted outside of the icon
|
||||||
int wh = ICON_SIZE - 1 + (focusWidth * 2);
|
float wh = ICON_SIZE - 1 + (focusWidth * 2);
|
||||||
g2.fillRoundRect( -focusWidth + 1, -focusWidth, wh, wh, 8, 8 );
|
float arcwh = arc + (focusWidth * 2);
|
||||||
|
g.fill( new RoundRectangle2D.Float( -focusWidth + 1, -focusWidth, wh, wh, arcwh, arcwh ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void paintBorder( Graphics2D g2 ) {
|
protected void paintBorder( Component c, Graphics2D g, float borderWidth ) {
|
||||||
g2.fillRoundRect( 1, 0, 14, 14, 4, 4 );
|
if( borderWidth == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
int arcwh = arc;
|
||||||
|
g.fillRoundRect( 1, 0, 14, 14, arcwh, arcwh );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void paintBackground( Graphics2D g2 ) {
|
protected void paintBackground( Component c, Graphics2D g, float borderWidth ) {
|
||||||
g2.fillRoundRect( 2, 1, 12, 12, 3, 3 );
|
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();
|
Path2D.Float path = new Path2D.Float( Path2D.WIND_NON_ZERO, 3 );
|
||||||
path.moveTo( 4.5f, 7.5f );
|
path.moveTo( 4.5f, 7.5f );
|
||||||
path.lineTo( 6.6f, 10f );
|
path.lineTo( 6.6f, 10f );
|
||||||
path.lineTo( 11.25f, 3.5f );
|
path.lineTo( 11.25f, 3.5f );
|
||||||
|
|
||||||
g2.setStroke( new BasicStroke( 1.9f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
g.setStroke( new BasicStroke( 1.9f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
g2.draw( path );
|
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,49 @@ import java.awt.Color;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
|
import java.util.Map;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Icon for {@link javax.swing.JCheckBoxMenuItem}.
|
* Icon for {@link javax.swing.JCheckBoxMenuItem}.
|
||||||
*
|
*
|
||||||
* @uiDefault MenuItemCheckBox.icon.checkmarkColor Color
|
* @uiDefault CheckBoxMenuItem.icon.checkmarkColor Color
|
||||||
* @uiDefault MenuItemCheckBox.icon.disabledCheckmarkColor Color
|
* @uiDefault CheckBoxMenuItem.icon.disabledCheckmarkColor Color
|
||||||
* @uiDefault Menu.selectionForeground Color
|
* @uiDefault MenuItem.selectionForeground Color
|
||||||
|
* @uiDefault MenuItem.selectionType String
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatCheckBoxMenuItemIcon
|
public class FlatCheckBoxMenuItemIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
protected final Color checkmarkColor = UIManager.getColor( "MenuItemCheckBox.icon.checkmarkColor" );
|
@Styleable protected Color checkmarkColor = UIManager.getColor( "CheckBoxMenuItem.icon.checkmarkColor" );
|
||||||
protected final Color disabledCheckmarkColor = UIManager.getColor( "MenuItemCheckBox.icon.disabledCheckmarkColor" );
|
@Styleable protected Color disabledCheckmarkColor = UIManager.getColor( "CheckBoxMenuItem.icon.disabledCheckmarkColor" );
|
||||||
protected final Color selectionForeground = UIManager.getColor( "Menu.selectionForeground" );
|
@Styleable protected Color selectionForeground = UIManager.getColor( "MenuItem.selectionForeground" );
|
||||||
|
|
||||||
public FlatCheckBoxMenuItemIcon() {
|
public FlatCheckBoxMenuItemIcon() {
|
||||||
super( 15, 15, null );
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g2 ) {
|
protected void paintIcon( Component c, Graphics2D g2 ) {
|
||||||
boolean selected = (c instanceof AbstractButton) && ((AbstractButton)c).isSelected();
|
boolean selected = (c instanceof AbstractButton) && ((AbstractButton)c).isSelected();
|
||||||
@@ -57,7 +76,7 @@ public class FlatCheckBoxMenuItemIcon
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void paintCheckmark( Graphics2D g2 ) {
|
protected void paintCheckmark( Graphics2D g2 ) {
|
||||||
Path2D.Float path = new Path2D.Float();
|
Path2D.Float path = new Path2D.Float( Path2D.WIND_NON_ZERO, 3 );
|
||||||
path.moveTo( 4.5f, 7.5f );
|
path.moveTo( 4.5f, 7.5f );
|
||||||
path.lineTo( 6.6f, 10f );
|
path.lineTo( 6.6f, 10f );
|
||||||
path.lineTo( 11.25f, 3.5f );
|
path.lineTo( 11.25f, 3.5f );
|
||||||
@@ -66,10 +85,15 @@ public class FlatCheckBoxMenuItemIcon
|
|||||||
g2.draw( path );
|
g2.draw( path );
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color getCheckmarkColor( Component c ) {
|
protected Color getCheckmarkColor( Component c ) {
|
||||||
if( c instanceof JMenuItem && ((JMenuItem)c).isArmed() )
|
if( c instanceof JMenuItem && ((JMenuItem)c).isArmed() && !isUnderlineSelection() )
|
||||||
return selectionForeground;
|
return selectionForeground;
|
||||||
|
|
||||||
return c.isEnabled() ? checkmarkColor : disabledCheckmarkColor;
|
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,112 @@
|
|||||||
|
/*
|
||||||
|
* 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.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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
|
@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, 4 );
|
||||||
|
path.moveTo( 5, 5 );
|
||||||
|
path.lineTo( 11, 11 );
|
||||||
|
path.moveTo( 5, 11 );
|
||||||
|
path.lineTo( 11, 5 );
|
||||||
|
g.draw( path );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,31 +16,37 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import javax.swing.UIManager;
|
import java.awt.geom.Path2D;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "descendingSort" icon for {@link javax.swing.table.JTableHeader}.
|
* "descendingSort" icon for {@link javax.swing.table.JTableHeader}.
|
||||||
*
|
*
|
||||||
|
* @uiDefault Component.arrowType String chevron (default) or triangle
|
||||||
* @uiDefault Table.sortIconColor Color
|
* @uiDefault Table.sortIconColor Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatDescendingSortIcon
|
public class FlatDescendingSortIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAscendingSortIcon
|
||||||
{
|
{
|
||||||
protected final Color sortIconColor = UIManager.getColor( "Table.sortIconColor" );
|
|
||||||
|
|
||||||
public FlatDescendingSortIcon() {
|
public FlatDescendingSortIcon() {
|
||||||
super( 10, 5, null );
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintArrow( Component c, Graphics2D g, boolean chevron ) {
|
||||||
g.setColor( sortIconColor );
|
if( chevron ) {
|
||||||
g.fill( FlatUIUtils.createPath( 0.5,0, 9.5,0, 5,5 ) );
|
// 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}.
|
* "details view" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileChooser.icon.detailsViewColor Color
|
* @uiDefault Actions.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -31,7 +31,7 @@ public class FlatFileChooserDetailsViewIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileChooserDetailsViewIcon() {
|
public FlatFileChooserDetailsViewIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.detailsViewColor" ) );
|
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -39,21 +39,25 @@ public class FlatFileChooserDetailsViewIcon
|
|||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<rect width="2" height="2" x="2" y="3" fill="#6E6E6E"/>
|
<rect width="2" height="1" x="2" y="3" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="2" height="2" x="2" y="7" fill="#6E6E6E"/>
|
<rect width="2" height="1" x="2" y="6" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="2" height="2" x="2" y="11" fill="#6E6E6E"/>
|
<rect width="2" height="1" x="2" y="9" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="8" height="2" x="6" y="3" fill="#6E6E6E"/>
|
<rect width="2" height="1" x="2" y="12" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="8" height="2" x="6" y="7" fill="#6E6E6E"/>
|
<rect width="8" height="1" x="6" y="3" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="8" height="2" x="6" y="11" fill="#6E6E6E"/>
|
<rect width="8" height="1" x="6" y="6" fill="#6E6E6E" rx=".5"/>
|
||||||
|
<rect width="8" height="1" x="6" y="9" fill="#6E6E6E" rx=".5"/>
|
||||||
|
<rect width="8" height="1" x="6" y="12" fill="#6E6E6E" rx=".5"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fillRect( 2, 3, 2, 2 );
|
g.fillRoundRect( 2, 3, 2, 1, 1, 1 );
|
||||||
g.fillRect( 2, 7, 2, 2 );
|
g.fillRoundRect( 2, 6, 2, 1, 1, 1 );
|
||||||
g.fillRect( 2, 11, 2, 2 );
|
g.fillRoundRect( 2, 9, 2, 1, 1, 1 );
|
||||||
g.fillRect( 6, 3, 8, 2 );
|
g.fillRoundRect( 2, 12, 2, 1, 1, 1 );
|
||||||
g.fillRect( 6, 7, 8, 2 );
|
g.fillRoundRect( 6, 3, 8, 1, 1, 1 );
|
||||||
g.fillRect( 6, 11, 8, 2 );
|
g.fillRoundRect( 6, 6, 8, 1, 1, 1 );
|
||||||
|
g.fillRoundRect( 6, 9, 8, 1, 1, 1 );
|
||||||
|
g.fillRoundRect( 6, 12, 8, 1, 1, 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,15 +16,17 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "home folder" icon for {@link javax.swing.JFileChooser}.
|
* "home folder" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileChooser.icon.homeFolderColor Color
|
* @uiDefault Actions.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,17 +34,29 @@ public class FlatFileChooserHomeFolderIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileChooserHomeFolderIcon() {
|
public FlatFileChooserHomeFolderIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.homeFolderColor" ) );
|
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<polygon fill="#6E6E6E" fill-rule="evenodd" points="2 8 8 2 14 8 12 8 12 13 9 13 9 10 7 10 7 13 4 13 4 8"/>
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<polyline stroke="#6E6E6E" stroke-linejoin="round" points="6.5 13 6.5 9.5 9.5 9.5 9.5 13"/>
|
||||||
|
<path stroke="#6E6E6E" d="M3.5,6.5 L3.5,12.5 C3.5,13.0522847 3.94771525,13.5 4.5,13.5 L11.5,13.5 C12.0522847,13.5 12.5,13.0522847 12.5,12.5 L12.5,6.5 L12.5,6.5"/>
|
||||||
|
<polyline stroke="#6E6E6E" stroke-linecap="round" stroke-linejoin="round" points="1.5 8.5 8 2 14.5 8.5"/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 2,8, 8,2, 14,8, 12,8, 12,13, 9,13, 9,10, 7,10, 7,13, 4,13, 4,8 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
|
|
||||||
|
g.draw( FlatUIUtils.createPath( false, 6.5,13, 6.5,9.5, 9.5,9.5, 9.5,13 ) );
|
||||||
|
g.draw( FlatUIUtils.createPath( false, 3.5,6.5,
|
||||||
|
3.5,12.5, FlatUIUtils.QUAD_TO, 3.5,13.5, 4.5,13.5,
|
||||||
|
11.5,13.5, FlatUIUtils.QUAD_TO, 12.5,13.5, 12.5,12.5,
|
||||||
|
12.5,6.5 ) );
|
||||||
|
g.draw( FlatUIUtils.createPath( false, 1.5,8.5, 8,2, 14.5,8.5 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,14 +16,17 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.RoundRectangle2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "list view" icon for {@link javax.swing.JFileChooser}.
|
* "list view" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileChooser.icon.listViewColor Color
|
* @uiDefault Actions.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -31,7 +34,7 @@ public class FlatFileChooserListViewIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileChooserListViewIcon() {
|
public FlatFileChooserListViewIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.listViewColor" ) );
|
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -39,17 +42,20 @@ public class FlatFileChooserListViewIcon
|
|||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<rect width="4" height="4" x="3" y="3" fill="#6E6E6E"/>
|
<rect width="4" height="4" x="2.5" y="2.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
<rect width="4" height="4" x="3" y="9" fill="#6E6E6E"/>
|
<rect width="4" height="4" x="2.5" y="9.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
<rect width="4" height="4" x="9" y="9" fill="#6E6E6E"/>
|
<rect width="4" height="4" x="9.5" y="9.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
<rect width="4" height="4" x="9" y="3" fill="#6E6E6E"/>
|
<rect width="4" height="4" x="9.5" y="2.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fillRect( 3, 3, 4, 4 );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
g.fillRect( 3, 9, 4, 4 );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
g.fillRect( 9, 9, 4, 4 );
|
|
||||||
g.fillRect( 9, 3, 4, 4 );
|
g.draw( new RoundRectangle2D.Float( 2.5f, 2.5f, 4, 4, 2, 2 ) );
|
||||||
|
g.draw( new RoundRectangle2D.Float( 2.5f, 9.5f, 4, 4, 2, 2 ) );
|
||||||
|
g.draw( new RoundRectangle2D.Float( 9.5f, 9.5f, 4, 4, 2, 2 ) );
|
||||||
|
g.draw( new RoundRectangle2D.Float( 9.5f, 2.5f, 4, 4, 2, 2 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,23 +16,28 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Line2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "new folder" icon for {@link javax.swing.JFileChooser}.
|
* "new folder" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileChooser.icon.newFolderColor Color
|
* @uiDefault Actions.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatFileChooserNewFolderIcon
|
public class FlatFileChooserNewFolderIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private final Color greenColor = UIManager.getColor( "Actions.Green" );
|
||||||
|
|
||||||
public FlatFileChooserNewFolderIcon() {
|
public FlatFileChooserNewFolderIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.newFolderColor" ) );
|
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -40,13 +45,20 @@ public class FlatFileChooserNewFolderIcon
|
|||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<polygon fill="#6E6E6E" points="2 3 5.5 3 7 5 14 5 14 8 11 8 11 10 9 10 9 13 2 13"/>
|
<path stroke="#6E6E6E" d="M13,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L13,4.5 C13.8284271,4.5 14.5,5.17157288 14.5,6 L14.5,12 C14.5,12.8284271 13.8284271,13.5 13,13.5 Z"/>
|
||||||
<path fill="#59A869" d="M14,11 L16,11 L16,13 L14,13 L14,15 L12,15 L12,13 L10,13 L10,11 L12,11 L12,9 L14,9 L14,11 Z"/>
|
<line x1="5.5" x2="10.5" y1="9" y2="9" stroke="#59A869" stroke-linecap="round"/>
|
||||||
|
<line x1="8" x2="8" y1="6.5" y2="11.5" stroke="#59A869" stroke-linecap="round"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 2,3, 5.5,3, 7,5, 14,5, 14,8, 11,8, 11,10, 9,10, 9,13, 2,13 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
g.fill( FlatUIUtils.createPath( 14,11, 16,11, 16,13, 14,13, 14,15, 12,15, 12,13, 10,13, 10,11, 12,11, 12,9, 14,9, 14,11 ) );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
|
|
||||||
|
g.draw( FlatFileViewDirectoryIcon.createFolderPath() );
|
||||||
|
|
||||||
|
g.setColor( greenColor );
|
||||||
|
g.draw( new Line2D.Float( 5.5f, 9, 10.5f, 9 ) );
|
||||||
|
g.draw( new Line2D.Float( 8, 6.5f, 8, 11.5f ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,23 +16,30 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Line2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "up folder" icon for {@link javax.swing.JFileChooser}.
|
* "up folder" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileChooser.icon.upFolderColor Color
|
* @uiDefault Actions.Grey Color
|
||||||
|
* @uiDefault Actions.Blue Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatFileChooserUpFolderIcon
|
public class FlatFileChooserUpFolderIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private final Color blueColor = UIManager.getColor( "Actions.Blue" );
|
||||||
|
|
||||||
public FlatFileChooserUpFolderIcon() {
|
public FlatFileChooserUpFolderIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.upFolderColor" ) );
|
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -40,13 +47,20 @@ public class FlatFileChooserUpFolderIcon
|
|||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<polygon fill="#6E6E6E" points="2 3 5.5 3 7 5 9 5 9 9 13 9 13 5 14 5 14 13 2 13"/>
|
<path stroke="#6E6E6E" d="M13,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L13,4.5 C13.8284271,4.5 14.5,5.17157288 14.5,6 L14.5,12 C14.5,12.8284271 13.8284271,13.5 13,13.5 Z"/>
|
||||||
<path fill="#389FD6" d="M12,4 L12,8 L10,8 L10,4 L8,4 L11,1 L14,4 L12,4 Z"/>
|
<line x1="8" x2="8" y1="6.5" y2="11.5" stroke="#389FD6" stroke-linecap="round"/>
|
||||||
|
<polyline stroke="#389FD6" stroke-linecap="round" stroke-linejoin="round" points="5.5 9 8 6.5 10.5 9"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
g.fill( FlatUIUtils.createPath( 12,4, 12,8, 10,8, 10,4, 8,4, 11,1, 14,4, 12,4 ) );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
|
|
||||||
|
g.draw( FlatFileViewDirectoryIcon.createFolderPath() );
|
||||||
|
|
||||||
|
g.setColor( blueColor );
|
||||||
|
g.draw( new Line2D.Float( 8, 6.5f, 8, 11.5f ) );
|
||||||
|
g.draw( FlatUIUtils.createPath( false, 5.5,9, 8,6.5, 10.5,9 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,16 +16,18 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.RenderingHints;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Line2D;
|
||||||
|
import java.awt.geom.RoundRectangle2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "computer" icon for {@link javax.swing.JFileChooser}.
|
* "computer" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileView.icon.computerColor Color
|
* @uiDefault Objects.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -33,7 +35,7 @@ public class FlatFileViewComputerIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileViewComputerIcon() {
|
public FlatFileViewComputerIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileView.icon.computerColor" ) );
|
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -41,17 +43,18 @@ public class FlatFileViewComputerIcon
|
|||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<path fill="#6E6E6E" d="M2,3 L14,3 L14,11 L2,11 L2,3 Z M4,5 L4,9 L12,9 L12,5 L4,5 Z"/>
|
<rect width="11" height="7" x="2.5" y="3.5" stroke="#6E6E6E" rx="1"/>
|
||||||
<rect width="12" height="2" x="2" y="12" fill="#6E6E6E"/>
|
<line x1="8" x2="8" y1="11" y2="12" stroke="#6E6E6E"/>
|
||||||
|
<line x1="4.5" x2="11.5" y1="12.5" y2="12.5" stroke="#6E6E6E" stroke-linecap="round"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
path.append( new Rectangle2D.Float( 2, 3, 12, 8 ), false );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
path.append( new Rectangle2D.Float( 4, 5, 8, 4 ), false );
|
|
||||||
g.fill( path );
|
|
||||||
|
|
||||||
g.fillRect( 2, 12, 12, 2 );
|
g.draw( new RoundRectangle2D.Float( 2.5f, 3.5f, 11, 7, 2, 2 ) );
|
||||||
|
g.drawLine( 8, 11, 8, 12 );
|
||||||
|
g.draw( new Line2D.Float( 4.5f, 12.5f, 11.5f, 12.5f ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,31 +18,57 @@ package com.formdev.flatlaf.icons;
|
|||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "directory" icon for {@link javax.swing.JFileChooser}.
|
* "directory" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileView.icon.directoryColor Color
|
* @uiDefault Objects.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatFileViewDirectoryIcon
|
public class FlatFileViewDirectoryIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private Path2D path;
|
||||||
|
|
||||||
public FlatFileViewDirectoryIcon() {
|
public FlatFileViewDirectoryIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileView.icon.directoryColor" ) );
|
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<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"/>
|
<path fill="none" stroke="#6E6E6E" d="M13,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L13,4.5 C13.8284271,4.5 14.5,5.17157288 14.5,6 L14.5,12 C14.5,12.8284271 13.8284271,13.5 13,13.5 Z"/>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 1,2, 6,2, 8,4, 15,4, 15,13, 1,13 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
|
|
||||||
|
if( path == null )
|
||||||
|
path = createFolderPath();
|
||||||
|
g.draw( path );
|
||||||
|
}
|
||||||
|
|
||||||
|
static Path2D createFolderPath() {
|
||||||
|
double arc = 1.5;
|
||||||
|
double arc2 = 0.5;
|
||||||
|
return FlatUIUtils.createPath(
|
||||||
|
// bottom-right
|
||||||
|
14.5,13.5-arc, FlatUIUtils.QUAD_TO, 14.5,13.5, 14.5-arc,13.5,
|
||||||
|
// bottom-left
|
||||||
|
1.5+arc,13.5, FlatUIUtils.QUAD_TO, 1.5,13.5, 1.5,13.5-arc,
|
||||||
|
// top-left
|
||||||
|
1.5,2.5+arc, FlatUIUtils.QUAD_TO, 1.5,2.5, 1.5+arc,2.5,
|
||||||
|
// top-mid-left
|
||||||
|
6.5-arc2,2.5, FlatUIUtils.QUAD_TO, 6.5,2.5, 6.5+arc2,2.5+arc2,
|
||||||
|
// top-mid-right
|
||||||
|
8.5,4.5,
|
||||||
|
// top-right
|
||||||
|
14.5-arc,4.5, FlatUIUtils.QUAD_TO, 14.5,4.5, 14.5,4.5+arc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,37 +16,61 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "file" icon for {@link javax.swing.JFileChooser}.
|
* "file" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileView.icon.fileColor Color
|
* @uiDefault Objects.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatFileViewFileIcon
|
public class FlatFileViewFileIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private Path2D path;
|
||||||
|
|
||||||
public FlatFileViewFileIcon() {
|
public FlatFileViewFileIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileView.icon.fileColor" ) );
|
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd" stroke-linejoin="round">
|
||||||
<polygon fill="#6E6E6E" points="8 6 8 1 13 1 13 15 3 15 3 6"/>
|
<path stroke="#6E6E6E" d="M4,1.5 L8.8,1.5 L8.8,1.5 L13.5,6.2 L13.5,13 C13.5,13.8284271 12.8284271,14.5 12,14.5 L4,14.5 C3.17157288,14.5 2.5,13.8284271 2.5,13 L2.5,3 C2.5,2.17157288 3.17157288,1.5 4,1.5 Z"/>
|
||||||
<polygon fill="#6E6E6E" points="3 5 7 5 7 1"/>
|
<path stroke="#6E6E6E" d="M8.5,2 L8.5,5 C8.5,5.82842712 9.17157288,6.5 10,6.5 L13,6.5 L13,6.5"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 8,6, 8,1, 13,1, 13,15, 3,15, 3,6 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
g.fill( FlatUIUtils.createPath( 3,5, 7,5, 7,1 ) );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
|
|
||||||
|
if( path == null ) {
|
||||||
|
double arc = 1.5;
|
||||||
|
path = FlatUIUtils.createPath( false,
|
||||||
|
// top-left
|
||||||
|
2.5,1.5+arc, FlatUIUtils.QUAD_TO, 2.5,1.5, 2.5+arc,1.5,
|
||||||
|
// top-right
|
||||||
|
8.8,1.5, 13.5,6.2,
|
||||||
|
// bottom-right
|
||||||
|
13.5,14.5-arc, FlatUIUtils.QUAD_TO, 13.5,14.5, 13.5-arc,14.5,
|
||||||
|
// bottom-left
|
||||||
|
2.5+arc,14.5, FlatUIUtils.QUAD_TO, 2.5,14.5, 2.5,14.5-arc,
|
||||||
|
FlatUIUtils.CLOSE_PATH,
|
||||||
|
|
||||||
|
FlatUIUtils.MOVE_TO, 8.5,2,
|
||||||
|
8.5,6.5-arc, FlatUIUtils.QUAD_TO, 8.5,6.5, 8.5+arc,6.5,
|
||||||
|
13,6.5 );
|
||||||
|
}
|
||||||
|
g.draw( path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,16 +16,17 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.RenderingHints;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "floppy drive" icon for {@link javax.swing.JFileChooser}.
|
* "floppy drive" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileView.icon.floppyDriveColor Color
|
* @uiDefault Objects.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -33,25 +34,29 @@ public class FlatFileViewFloppyDriveIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileViewFloppyDriveIcon() {
|
public FlatFileViewFloppyDriveIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileView.icon.floppyDriveColor" ) );
|
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd" stroke-linejoin="round">
|
||||||
<path fill="#6E6E6E" d="M11,14 L11,11 L5,11 L5,14 L2,14 L2,2 L14,2 L14,14 L11,14 Z M4,4 L4,8 L12,8 L12,4 L4,4 Z"/>
|
<path stroke="#6E6E6E" d="M3.5,2.5 L11.5,2.5 L11.5,2.5 L13.5,4.5 L13.5,12.5 C13.5,13.0522847 13.0522847,13.5 12.5,13.5 L3.5,13.5 C2.94771525,13.5 2.5,13.0522847 2.5,12.5 L2.5,3.5 C2.5,2.94771525 2.94771525,2.5 3.5,2.5 Z"/>
|
||||||
<rect width="4" height="2" x="6" y="12" fill="#6E6E6E"/>
|
<polyline stroke="#6E6E6E" points="4.5 13 4.5 9.5 11.5 9.5 11.5 13"/>
|
||||||
|
<polyline stroke="#6E6E6E" points="5.5 3 5.5 5.5 10.5 5.5 10.5 3"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
path.append( FlatUIUtils.createPath( 11,14, 11,11, 5,11, 5,14, 2,14, 2,2, 14,2, 14,14, 11,14 ), false );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
path.append( FlatUIUtils.createPath( 4,4, 4,8, 12,8, 12,4, 4,4 ), false );
|
|
||||||
g.fill( path );
|
|
||||||
|
|
||||||
g.fillRect( 6, 12, 4, 2 );
|
g.draw( FlatUIUtils.createPath( 3.5,2.5, 11.5,2.5, 11.5,2.5, 13.5,4.5,
|
||||||
|
13.5,12.5, FlatUIUtils.QUAD_TO, 13.5,13.5, 12.5,13.5,
|
||||||
|
3.5,13.5, FlatUIUtils.QUAD_TO, 2.5,13.5, 2.5,12.5,
|
||||||
|
2.5,3.5, FlatUIUtils.QUAD_TO, 2.5,2.5, 3.5,2.5 ) );
|
||||||
|
g.draw( FlatUIUtils.createPath( false, 4.5,13, 4.5,9.5, 11.5,9.5, 11.5,13 ) );
|
||||||
|
g.draw( FlatUIUtils.createPath( false, 5.5,3, 5.5,5.5, 10.5,5.5, 10.5,3 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,16 +16,18 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.RenderingHints;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
|
import java.awt.geom.RoundRectangle2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "hard drive" icon for {@link javax.swing.JFileChooser}.
|
* "hard drive" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileView.icon.hardDriveColor Color
|
* @uiDefault Objects.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -33,21 +35,26 @@ public class FlatFileViewHardDriveIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileViewHardDriveIcon() {
|
public FlatFileViewHardDriveIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileView.icon.hardDriveColor" ) );
|
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<path fill="#6E6E6E" fill-rule="evenodd" d="M2,6 L14,6 L14,10 L2,10 L2,6 Z M12,8 L12,9 L13,9 L13,8 L12,8 Z M10,8 L10,9 L11,9 L11,8 L10,8 Z"/>
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<rect width="11" height="5" x="2.5" y="5.5" stroke="#6E6E6E" rx="1"/>
|
||||||
|
<circle cx="11.5" cy="8.5" r="1" fill="#6E6E6E"/>
|
||||||
|
<circle cx="9.5" cy="8.5" r="1" fill="#6E6E6E"/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
path.append( new Rectangle2D.Float( 2, 6, 12, 4 ), false );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
path.append( new Rectangle2D.Float( 12, 8, 1, 1 ), false );
|
|
||||||
path.append( new Rectangle2D.Float( 10, 8, 1, 1 ), false );
|
g.draw( new RoundRectangle2D.Float( 2.5f, 5.5f, 11, 5, 2, 2 ) );
|
||||||
g.fill( path );
|
g.fill( new Ellipse2D.Float( 10.8f, 7.8f, 1.4f, 1.4f ) );
|
||||||
|
g.fill( new Ellipse2D.Float( 8.8f, 7.8f, 1.4f, 1.4f ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,19 +17,27 @@
|
|||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.*;
|
import static com.formdev.flatlaf.util.UIScale.*;
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
|
import java.util.Map;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
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}.
|
* Help button icon for {@link javax.swing.JButton}.
|
||||||
*
|
*
|
||||||
* @uiDefault Component.focusWidth int
|
* @uiDefault Component.focusWidth int
|
||||||
* @uiDefault Component.focusColor Color
|
* @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.borderColor Color
|
||||||
* @uiDefault HelpButton.disabledBorderColor Color
|
* @uiDefault HelpButton.disabledBorderColor Color
|
||||||
* @uiDefault HelpButton.focusedBorderColor Color
|
* @uiDefault HelpButton.focusedBorderColor Color
|
||||||
@@ -47,27 +55,42 @@ import com.formdev.flatlaf.ui.FlatButtonUI;
|
|||||||
public class FlatHelpButtonIcon
|
public class FlatHelpButtonIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
protected final int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
@Styleable protected int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||||
protected final Color focusColor = UIManager.getColor( "Component.focusColor" );
|
@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" );
|
@Styleable protected Color borderColor = UIManager.getColor( "HelpButton.borderColor" );
|
||||||
protected final Color disabledBorderColor = UIManager.getColor( "HelpButton.disabledBorderColor" );
|
@Styleable protected Color disabledBorderColor = UIManager.getColor( "HelpButton.disabledBorderColor" );
|
||||||
protected final Color focusedBorderColor = UIManager.getColor( "HelpButton.focusedBorderColor" );
|
@Styleable protected Color focusedBorderColor = UIManager.getColor( "HelpButton.focusedBorderColor" );
|
||||||
protected final Color hoverBorderColor = UIManager.getColor( "HelpButton.hoverBorderColor" );
|
@Styleable protected Color hoverBorderColor = UIManager.getColor( "HelpButton.hoverBorderColor" );
|
||||||
protected final Color background = UIManager.getColor( "HelpButton.background" );
|
@Styleable protected Color background = UIManager.getColor( "HelpButton.background" );
|
||||||
protected final Color disabledBackground = UIManager.getColor( "HelpButton.disabledBackground" );
|
@Styleable protected Color disabledBackground = UIManager.getColor( "HelpButton.disabledBackground" );
|
||||||
protected final Color focusedBackground = UIManager.getColor( "HelpButton.focusedBackground" );
|
@Styleable protected Color focusedBackground = UIManager.getColor( "HelpButton.focusedBackground" );
|
||||||
protected final Color hoverBackground = UIManager.getColor( "HelpButton.hoverBackground" );
|
@Styleable protected Color hoverBackground = UIManager.getColor( "HelpButton.hoverBackground" );
|
||||||
protected final Color pressedBackground = UIManager.getColor( "HelpButton.pressedBackground" );
|
@Styleable protected Color pressedBackground = UIManager.getColor( "HelpButton.pressedBackground" );
|
||||||
protected final Color questionMarkColor = UIManager.getColor( "HelpButton.questionMarkColor" );
|
@Styleable protected Color questionMarkColor = UIManager.getColor( "HelpButton.questionMarkColor" );
|
||||||
protected final Color disabledQuestionMarkColor = UIManager.getColor( "HelpButton.disabledQuestionMarkColor" );
|
@Styleable protected Color disabledQuestionMarkColor = UIManager.getColor( "HelpButton.disabledQuestionMarkColor" );
|
||||||
|
|
||||||
protected final int iconSize = 22 + (focusWidth * 2);
|
|
||||||
|
|
||||||
public FlatHelpButtonIcon() {
|
public FlatHelpButtonIcon() {
|
||||||
super( 0, 0, null );
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g2 ) {
|
protected void paintIcon( Component c, Graphics2D g2 ) {
|
||||||
/*
|
/*
|
||||||
@@ -75,20 +98,27 @@ public class FlatHelpButtonIcon
|
|||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<circle cx="11" cy="11" r="10.5" fill="#6E6E6E"/>
|
<circle cx="11" cy="11" r="10.5" fill="#6E6E6E"/>
|
||||||
<circle cx="11" cy="11" r="9.5" fill="#FFF"/>
|
<circle cx="11" cy="11" r="9.5" fill="#FFF"/>
|
||||||
<path fill="#6E6E6E" d="M10,17 L12,17 L12,15 L10,15 L10,17 Z M11,5 C8.8,5 7,6.8 7,9 L9,9 C9,7.9 9.9,7 11,7 C12.1,7 13,7.9 13,9 C13,11 10,10.75 10,14 L12,14 C12,11.75 15,11.5 15,9 C15,6.8 13.2,5 11,5 Z"/>
|
<path stroke="#6E6E6E" stroke-linecap="round" stroke-width="2" d="M8,8.5 C8.25,7 9.66585007,6 11,6 C12.5,6 14,7 14,8.5 C14,10.5 11,11 11,13"/>
|
||||||
|
<circle cx="11" cy="16" r="1.2" fill="#6E6E6E"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
boolean enabled = c.isEnabled();
|
boolean enabled = c == null || c.isEnabled();
|
||||||
boolean focused = c.hasFocus();
|
boolean focused = c != null && FlatUIUtils.isPermanentFocusOwner( c );
|
||||||
|
|
||||||
// paint focused border
|
float xy = 0.5f;
|
||||||
if( focused ) {
|
float wh = iconSize() - 1;
|
||||||
|
|
||||||
|
// paint outer focus border
|
||||||
|
if( focused && FlatButtonUI.isFocusPainted( c ) ) {
|
||||||
g2.setColor( focusColor );
|
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
|
// paint border
|
||||||
g2.setColor( FlatButtonUI.buttonStateColor( c,
|
g2.setColor( FlatButtonUI.buttonStateColor( c,
|
||||||
borderColor,
|
borderColor,
|
||||||
@@ -96,43 +126,56 @@ public class FlatHelpButtonIcon
|
|||||||
focusedBorderColor,
|
focusedBorderColor,
|
||||||
hoverBorderColor,
|
hoverBorderColor,
|
||||||
null ) );
|
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
|
// paint background
|
||||||
g2.setColor( FlatButtonUI.buttonStateColor( c,
|
g2.setColor( FlatUIUtils.deriveColor( FlatButtonUI.buttonStateColor( c,
|
||||||
background,
|
background,
|
||||||
disabledBackground,
|
disabledBackground,
|
||||||
focusedBackground,
|
focusedBackground,
|
||||||
hoverBackground,
|
hoverBackground,
|
||||||
pressedBackground ) );
|
pressedBackground ), background ) );
|
||||||
g2.fill( new Ellipse2D.Float( focusWidth + 1.5f, focusWidth + 1.5f, 19, 19 ) );
|
g2.fill( new Ellipse2D.Float( xy, xy, wh, wh ) );
|
||||||
|
|
||||||
// paint question mark
|
// paint question mark
|
||||||
Path2D q = new Path2D.Float();
|
Path2D q = new Path2D.Float( Path2D.WIND_NON_ZERO, 10 );
|
||||||
q.moveTo( 11, 5 );
|
q.moveTo( 8,8.5 );
|
||||||
q.curveTo( 8.8,5, 7,6.8, 7,9 );
|
q.curveTo( 8.25,7, 9.66585007,6, 11,6 );
|
||||||
q.lineTo( 9, 9 );
|
q.curveTo( 12.5,6, 14,7, 14,8.5 );
|
||||||
q.curveTo( 9,7.9, 9.9,7, 11,7 );
|
q.curveTo( 14,10.5, 11,11, 11,13 );
|
||||||
q.curveTo( 12.1,7, 13,7.9, 13,9 );
|
|
||||||
q.curveTo( 13,11, 10,10.75, 10,14 );
|
g2.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
q.lineTo( 12, 14 );
|
g2.setStroke( new BasicStroke( 2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
q.curveTo( 12,11.75, 15,11.5, 15,9 );
|
|
||||||
q.curveTo( 15,6.8, 13.2,5, 11,5 );
|
|
||||||
q.closePath();
|
|
||||||
|
|
||||||
g2.translate( focusWidth, focusWidth );
|
g2.translate( focusWidth, focusWidth );
|
||||||
g2.setColor( enabled ? questionMarkColor : disabledQuestionMarkColor );
|
g2.setColor( enabled ? questionMarkColor : disabledQuestionMarkColor );
|
||||||
g2.fill( q );
|
g2.draw( q );
|
||||||
g2.fillRect( 10, 15, 2, 2 );
|
g2.fill( new Ellipse2D.Float( 9.8f, 14.8f, 2.4f, 2.4f ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getIconWidth() {
|
public int getIconWidth() {
|
||||||
return scale( iconSize );
|
return scale( iconSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getIconHeight() {
|
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,68 @@
|
|||||||
|
/*
|
||||||
|
* 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.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, 4 );
|
||||||
|
path.moveTo( mx - r, my - r );
|
||||||
|
path.lineTo( mx + r, my + r );
|
||||||
|
path.moveTo( mx - r, my + r );
|
||||||
|
path.lineTo( mx + r, my - r );
|
||||||
|
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,77 @@ import java.awt.Color;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
|
import java.util.Map;
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "arrow" icon for {@link javax.swing.JMenu}.
|
* "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.arrowColor Color
|
||||||
* @uiDefault Menu.icon.disabledArrowColor Color
|
* @uiDefault Menu.icon.disabledArrowColor Color
|
||||||
* @uiDefault Menu.selectionForeground Color
|
* @uiDefault Menu.selectionForeground Color
|
||||||
|
* @uiDefault MenuItem.selectionType String
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatMenuArrowIcon
|
public class FlatMenuArrowIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
protected final boolean chevron = "chevron".equals( UIManager.getString( "Component.arrowType" ) );
|
@Styleable protected String arrowType = UIManager.getString( "Component.arrowType" );
|
||||||
protected final Color arrowColor = UIManager.getColor( "Menu.icon.arrowColor" );
|
@Styleable protected Color arrowColor = UIManager.getColor( "Menu.icon.arrowColor" );
|
||||||
protected final Color disabledArrowColor = UIManager.getColor( "Menu.icon.disabledArrowColor" );
|
@Styleable protected Color disabledArrowColor = UIManager.getColor( "Menu.icon.disabledArrowColor" );
|
||||||
protected final Color selectionForeground = UIManager.getColor( "Menu.selectionForeground" );
|
@Styleable protected Color selectionForeground = UIManager.getColor( "Menu.selectionForeground" );
|
||||||
|
|
||||||
public FlatMenuArrowIcon() {
|
public FlatMenuArrowIcon() {
|
||||||
super( 6, 10, null );
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
if( !c.getComponentOrientation().isLeftToRight() )
|
if( c != null && !c.getComponentOrientation().isLeftToRight() )
|
||||||
g.rotate( Math.toRadians( 180 ), width / 2., height / 2. );
|
g.rotate( Math.toRadians( 180 ), width / 2., height / 2. );
|
||||||
|
|
||||||
g.setColor( getArrowColor( c ) );
|
g.setColor( getArrowColor( c ) );
|
||||||
if( chevron ) {
|
if( FlatUIUtils.isChevron( arrowType ) ) {
|
||||||
// chevron arrow
|
// chevron arrow
|
||||||
Path2D path = FlatUIUtils.createPath( false, 1,1, 5,5, 1,9 );
|
Path2D path = FlatUIUtils.createPath( false, 1,1, 5,5, 1,9 );
|
||||||
g.setStroke( new BasicStroke( 1f ) );
|
g.setStroke( new BasicStroke( 1f ) );
|
||||||
g.draw( path );
|
g.draw( path );
|
||||||
} else {
|
} else {
|
||||||
// triangle arrow
|
// 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 ) {
|
protected Color getArrowColor( Component c ) {
|
||||||
if( c instanceof JMenu && ((JMenu)c).isSelected() )
|
if( c instanceof JMenu && ((JMenu)c).isSelected() && !isUnderlineSelection() )
|
||||||
return selectionForeground;
|
return selectionForeground;
|
||||||
|
|
||||||
return c.isEnabled() ? arrowColor : disabledArrowColor;
|
return c == null || 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;
|
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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatMenuItemArrowIcon
|
public class FlatMenuItemArrowIcon
|
||||||
extends FlatMenuArrowIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatMenuItemArrowIcon() {
|
public FlatMenuItemArrowIcon() {
|
||||||
|
super( 6, 10, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ import java.awt.Graphics2D;
|
|||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for icons for {@link javax.swing.JOptionPane}.
|
* 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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -35,8 +36,8 @@ public abstract class FlatOptionPaneAbstractIcon
|
|||||||
{
|
{
|
||||||
protected final Color foreground = UIManager.getColor( "OptionPane.icon.foreground" );
|
protected final Color foreground = UIManager.getColor( "OptionPane.icon.foreground" );
|
||||||
|
|
||||||
protected FlatOptionPaneAbstractIcon( String colorKey ) {
|
protected FlatOptionPaneAbstractIcon( String colorKey, String defaultColorKey ) {
|
||||||
super( 32, 32, UIManager.getColor( colorKey ) );
|
super( 32, 32, FlatUIUtils.getUIColor( colorKey, defaultColorKey ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -19,12 +19,13 @@ package com.formdev.flatlaf.icons;
|
|||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.RoundRectangle2D;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Error" icon for {@link javax.swing.JOptionPane}.
|
* "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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,15 +33,15 @@ public class FlatOptionPaneErrorIcon
|
|||||||
extends FlatOptionPaneAbstractIcon
|
extends FlatOptionPaneAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatOptionPaneErrorIcon() {
|
public FlatOptionPaneErrorIcon() {
|
||||||
super( "OptionPane.icon.errorColor" );
|
super( "OptionPane.icon.errorColor", "Actions.Red" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<circle cx="16" cy="16" r="14" fill="#DB5860"/>
|
<circle cx="16" cy="16" r="14" fill="#DB5860"/>
|
||||||
<rect width="4" height="11" x="14" y="7" fill="#FFF"/>
|
<rect width="4" height="12" x="14" y="7" fill="#FFF" rx="2"/>
|
||||||
<rect width="4" height="4" x="14" y="21" fill="#FFF"/>
|
<circle cx="16" cy="23" r="2" fill="#FFF"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
@@ -53,8 +54,8 @@ public class FlatOptionPaneErrorIcon
|
|||||||
@Override
|
@Override
|
||||||
protected Shape createInside() {
|
protected Shape createInside() {
|
||||||
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
inside.append( new Rectangle2D.Float( 14, 7, 4, 11 ), false );
|
inside.append( new RoundRectangle2D.Float( 14, 7, 4, 12, 4, 4 ), false );
|
||||||
inside.append( new Rectangle2D.Float( 14, 21, 4, 4 ), false );
|
inside.append( new Ellipse2D.Float( 14, 21, 4, 4 ), false );
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,12 +19,13 @@ package com.formdev.flatlaf.icons;
|
|||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.RoundRectangle2D;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Information" icon for {@link javax.swing.JOptionPane}.
|
* "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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,15 +33,15 @@ public class FlatOptionPaneInformationIcon
|
|||||||
extends FlatOptionPaneAbstractIcon
|
extends FlatOptionPaneAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatOptionPaneInformationIcon() {
|
public FlatOptionPaneInformationIcon() {
|
||||||
super( "OptionPane.icon.informationColor" );
|
super( "OptionPane.icon.informationColor", "Actions.Blue" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
||||||
<rect width="4" height="11" x="14" y="14" fill="#FFF"/>
|
<rect width="4" height="12" x="14" y="13" fill="#FFF" rx="2"/>
|
||||||
<rect width="4" height="4" x="14" y="7" fill="#FFF"/>
|
<circle cx="16" cy="9" r="2" fill="#FFF"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
@@ -53,8 +54,8 @@ public class FlatOptionPaneInformationIcon
|
|||||||
@Override
|
@Override
|
||||||
protected Shape createInside() {
|
protected Shape createInside() {
|
||||||
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
inside.append( new Rectangle2D.Float( 14, 14, 4, 11 ), false );
|
inside.append( new RoundRectangle2D.Float( 14, 13, 4, 12, 4, 4 ), false );
|
||||||
inside.append( new Rectangle2D.Float( 14, 7, 4, 4 ), false );
|
inside.append( new Ellipse2D.Float( 14, 7, 4, 4 ), false );
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,15 +16,16 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Question" icon for {@link javax.swing.JOptionPane}.
|
* "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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,15 +33,15 @@ public class FlatOptionPaneQuestionIcon
|
|||||||
extends FlatOptionPaneAbstractIcon
|
extends FlatOptionPaneAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatOptionPaneQuestionIcon() {
|
public FlatOptionPaneQuestionIcon() {
|
||||||
super( "OptionPane.icon.questionColor" );
|
super( "OptionPane.icon.questionColor", "Actions.Blue" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
||||||
<rect width="4" height="4" x="14" y="22" fill="#FFF"/>
|
<circle cx="16" cy="24" r="1.7" fill="#FFF"/>
|
||||||
<path fill="#FFF" d="M14,20 C14,20 18,20 18,20 C18,16 23,16 23,12 C23,8 20,6 16,6 C12,6 9,8 9,12 C9,12 13,12 13,12 C13,10 14,9 16,9 C18,9 19,10 19,12 C19,15 14,15 14,20 Z"/>
|
<path stroke="#FFF" stroke-linecap="round" stroke-width="3" d="M11.5,11.75 C11.75,9.5 13.75,8 16,8 C18.25,8 20.5,9.5 20.5,11.75 C20.5,14.75 16,15.5 16,19"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
@@ -52,21 +53,17 @@ public class FlatOptionPaneQuestionIcon
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Shape createInside() {
|
protected Shape createInside() {
|
||||||
Path2D q = new Path2D.Float();
|
Path2D q = new Path2D.Float( Path2D.WIND_NON_ZERO, 10 );
|
||||||
q.moveTo( 14, 20 );
|
q.moveTo( 11.5,11.75 );
|
||||||
q.lineTo( 18, 20 );
|
q.curveTo( 11.75,9.5, 13.75,8, 16,8 );
|
||||||
q.curveTo( 18, 16, 23, 16, 23, 12 );
|
q.curveTo( 18.25,8, 20.5,9.5, 20.5,11.75 );
|
||||||
q.curveTo( 23, 8, 20, 6, 16, 6 );
|
q.curveTo( 20.5,14.75, 16,15.5, 16,19 );
|
||||||
q.curveTo( 12, 6, 9, 8, 9, 12 );
|
|
||||||
q.curveTo( 9, 12, 13, 12, 13, 12 );
|
BasicStroke stroke = new BasicStroke( 3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER );
|
||||||
q.curveTo( 13, 10, 14, 9, 16, 9 );
|
|
||||||
q.curveTo( 18, 9, 19, 10, 19, 12 );
|
|
||||||
q.curveTo( 19, 15, 14, 15, 14, 20 );
|
|
||||||
q.closePath();
|
|
||||||
|
|
||||||
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
inside.append( new Rectangle2D.Float( 14, 22, 4, 4 ), false );
|
inside.append( new Ellipse2D.Float( 14.3f, 22.3f, 3.4f, 3.4f ), false );
|
||||||
inside.append( q, false );
|
inside.append( stroke.createStrokedShape( q ), false );
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,16 @@
|
|||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.RoundRectangle2D;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Warning" icon for {@link javax.swing.JOptionPane}.
|
* "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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,29 +34,30 @@ public class FlatOptionPaneWarningIcon
|
|||||||
extends FlatOptionPaneAbstractIcon
|
extends FlatOptionPaneAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatOptionPaneWarningIcon() {
|
public FlatOptionPaneWarningIcon() {
|
||||||
super( "OptionPane.icon.warningColor" );
|
super( "OptionPane.icon.warningColor", "Actions.Yellow" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<polygon fill="#EDA200" points="16 2 31 28 1 28"/>
|
<path fill="#EDA200" d="M17.7364863,3.038851 L30.2901269,25.0077221 C30.8381469,25.966757 30.5049534,27.1884663 29.5459185,27.7364863 C29.2437231,27.9091694 28.9016945,28 28.5536406,28 L3.44635936,28 C2.34178986,28 1.44635936,27.1045695 1.44635936,26 C1.44635936,25.6519461 1.53718999,25.3099175 1.70987307,25.0077221 L14.2635137,3.038851 C14.8115337,2.0798161 16.033243,1.74662265 16.9922779,2.29464259 C17.3023404,2.47182119 17.5593077,2.72878844 17.7364863,3.038851 Z"/>
|
||||||
<rect width="4" height="8" x="14" y="10" fill="#FFF"/>
|
<rect width="4" height="11" x="14" y="8" fill="#FFF" rx="2"/>
|
||||||
<rect width="4" height="4" x="14" y="21" fill="#FFF"/>
|
<circle cx="16" cy="23" r="2" fill="#FFF"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Shape createOutside() {
|
protected Shape createOutside() {
|
||||||
return FlatUIUtils.createPath( 16,2, 31,28, 1,28 );
|
return FlatUIUtils.createRoundTrianglePath( 16,0, 32,28, 0,28, 4 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Shape createInside() {
|
protected Shape createInside() {
|
||||||
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
inside.append( new Rectangle2D.Float( 14, 10, 4, 8 ), false );
|
inside.append( new RoundRectangle2D.Float( 14, 8, 4, 11, 4, 4 ), false );
|
||||||
inside.append( new Rectangle2D.Float( 14, 21, 4, 4 ), false );
|
inside.append( new Ellipse2D.Float( 14, 21, 4, 4 ), false );
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,46 +16,59 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Icon for {@link javax.swing.JRadioButton}.
|
* Icon for {@link javax.swing.JRadioButton}.
|
||||||
*
|
* <p>
|
||||||
* Note: If Component.focusWidth is greater than zero, then the outline focus border
|
* <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
|
* is painted outside of the icon bounds. Make sure that the radiobutton
|
||||||
* has margins, which are equal or greater than focusWidth.
|
* 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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatRadioButtonIcon
|
public class FlatRadioButtonIcon
|
||||||
extends FlatCheckBoxIcon
|
extends FlatCheckBoxIcon
|
||||||
{
|
{
|
||||||
protected final int centerDiameter = FlatUIUtils.getUIInt( "RadioButton.icon.centerDiameter", 8 );
|
@Styleable protected float centerDiameter = getUIFloat( "RadioButton.icon.centerDiameter", 8, style );
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintFocusBorder( Graphics2D g2 ) {
|
protected String getPropertyPrefix() {
|
||||||
// the outline focus border is painted outside of the icon
|
return "RadioButton.";
|
||||||
int wh = ICON_SIZE + (focusWidth * 2);
|
|
||||||
g2.fillOval( -focusWidth, -focusWidth, wh, wh );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintBorder( Graphics2D g2 ) {
|
protected void paintFocusBorder( Component c, Graphics2D g ) {
|
||||||
g2.fillOval( 0, 0, 15, 15 );
|
// 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
|
@Override
|
||||||
protected void paintBackground( Graphics2D g2 ) {
|
protected void paintBorder( Component c, Graphics2D g, float borderWidth ) {
|
||||||
g2.fillOval( 1, 1, 13, 13 );
|
if( borderWidth == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
g.fillOval( 0, 0, 15, 15 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
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,100 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
private Area area;
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, 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-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
|
||||||
|
if( area == null ) {
|
||||||
|
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,110 @@
|
|||||||
|
/*
|
||||||
|
* 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.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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
|
@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, 4 );
|
||||||
|
path.moveTo( mx - r, my - r );
|
||||||
|
path.lineTo( mx + r, my + r );
|
||||||
|
path.moveTo( mx - r, my + r );
|
||||||
|
path.lineTo( mx + r, my - r );
|
||||||
|
g.setStroke( new BasicStroke( closeCrossLineWidth ) );
|
||||||
|
g.draw( path );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,8 +18,9 @@ package com.formdev.flatlaf.icons;
|
|||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "closed" icon for {@link javax.swing.JTree} used by {@link javax.swing.tree.DefaultTreeCellRenderer}.
|
* "closed" icon for {@link javax.swing.JTree} used by {@link javax.swing.tree.DefaultTreeCellRenderer}.
|
||||||
@@ -31,18 +32,26 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
public class FlatTreeClosedIcon
|
public class FlatTreeClosedIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private Path2D path;
|
||||||
|
|
||||||
public FlatTreeClosedIcon() {
|
public FlatTreeClosedIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "Tree.icon.closedColor" ) );
|
super( 16, 16, UIManager.getColor( "Tree.icon.closedColor" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
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">
|
<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"/>
|
<path fill="none" stroke="#6E6E6E" d="M13,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L13,4.5 C13.8284271,4.5 14.5,5.17157288 14.5,6 L14.5,12 C14.5,12.8284271 13.8284271,13.5 13,13.5 Z"/>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 1,2, 6,2, 8,4, 15,4, 15,13, 1,13 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
|
|
||||||
|
if( path == null )
|
||||||
|
path = FlatFileViewDirectoryIcon.createFolderPath();
|
||||||
|
g.draw( path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,16 +16,23 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import javax.swing.JTree;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.plaf.TreeUI;
|
||||||
|
import com.formdev.flatlaf.ui.FlatTreeUI;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "collapsed" icon for {@link javax.swing.JTree}.
|
* "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
|
* @uiDefault Tree.icon.collapsedColor Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -34,6 +41,7 @@ public class FlatTreeCollapsedIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
private final boolean chevron;
|
private final boolean chevron;
|
||||||
|
private Path2D path;
|
||||||
|
|
||||||
public FlatTreeCollapsedIcon() {
|
public FlatTreeCollapsedIcon() {
|
||||||
this( UIManager.getColor( "Tree.icon.collapsedColor" ) );
|
this( UIManager.getColor( "Tree.icon.collapsedColor" ) );
|
||||||
@@ -41,24 +49,59 @@ public class FlatTreeCollapsedIcon
|
|||||||
|
|
||||||
FlatTreeCollapsedIcon( Color color ) {
|
FlatTreeCollapsedIcon( Color color ) {
|
||||||
super( 11, 11, color );
|
super( 11, 11, color );
|
||||||
chevron = "chevron".equals( UIManager.getString( "Component.arrowType" ) );
|
chevron = FlatUIUtils.isChevron( UIManager.getString( "Component.arrowType" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
|
setStyleColorFromTreeUI( c, g );
|
||||||
rotate( c, g );
|
rotate( c, g );
|
||||||
|
|
||||||
|
String arrowType = getStyleFromTreeUI( c, ui -> ui.iconArrowType );
|
||||||
|
boolean chevron = (arrowType != null) ? FlatUIUtils.isChevron( arrowType ) : this.chevron;
|
||||||
|
|
||||||
if( chevron ) {
|
if( chevron ) {
|
||||||
// chevron arrow
|
// 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 ) );
|
g.setStroke( new BasicStroke( 1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER ) );
|
||||||
|
if( path == null )
|
||||||
|
path = FlatUIUtils.createPath( false, 3.5,1.5, 7.5,5.5, 3.5,9.5 );
|
||||||
|
g.draw( path );
|
||||||
} else {
|
} else {
|
||||||
// triangle arrow
|
// triangle arrow
|
||||||
g.fill( FlatUIUtils.createPath( 2,1, 2,10, 10,5.5 ) );
|
if( path == null )
|
||||||
|
path = FlatUIUtils.createPath( 2,1, 2,10, 10,5.5 );
|
||||||
|
g.fill( path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setStyleColorFromTreeUI( Component c, Graphics2D g ) {
|
||||||
|
setStyleColorFromTreeUI( c, g, ui -> ui.iconCollapsedColor );
|
||||||
|
}
|
||||||
|
|
||||||
void rotate( Component c, Graphics2D g ) {
|
void rotate( Component c, Graphics2D g ) {
|
||||||
if( !c.getComponentOrientation().isLeftToRight() )
|
if( !c.getComponentOrientation().isLeftToRight() )
|
||||||
g.rotate( Math.toRadians( 180 ), width / 2., height / 2. );
|
g.rotate( Math.toRadians( 180 ), width / 2., height / 2. );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Because this icon is 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" ) );
|
super( UIManager.getColor( "Tree.icon.expandedColor" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void setStyleColorFromTreeUI( Component c, Graphics2D g ) {
|
||||||
|
setStyleColorFromTreeUI( c, g, ui -> ui.iconExpandedColor );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void rotate( Component c, Graphics2D g ) {
|
void rotate( Component c, Graphics2D g ) {
|
||||||
g.rotate( Math.toRadians( 90 ), width / 2., height / 2. );
|
g.rotate( Math.toRadians( 90 ), width / 2., height / 2. );
|
||||||
|
|||||||
@@ -16,10 +16,14 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Line2D;
|
||||||
|
import java.awt.geom.RoundRectangle2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.util.ColorFunctions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "leaf" icon for {@link javax.swing.JTree} used by {@link javax.swing.tree.DefaultTreeCellRenderer}.
|
* "leaf" icon for {@link javax.swing.JTree} used by {@link javax.swing.tree.DefaultTreeCellRenderer}.
|
||||||
@@ -37,16 +41,27 @@ public class FlatTreeLeafIcon
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
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">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<polygon fill="#6E6E6E" points="8 6 8 1 13 1 13 15 3 15 3 6"/>
|
<rect width="11" height="13" x="2.5" y="1.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
<polygon fill="#6E6E6E" points="3 5 7 5 7 1"/>
|
<line x1="5.5" x2="10.5" y1="5.5" y2="5.5" stroke="#6E6E6E" stroke-linecap="round" stroke-opacity=".6"/>
|
||||||
|
<line x1="5.5" x2="10.5" y1="8" y2="8" stroke="#6E6E6E" stroke-linecap="round" stroke-opacity=".6"/>
|
||||||
|
<line x1="5.5" x2="10.5" y1="10.5" y2="10.5" stroke="#6E6E6E" stroke-linecap="round" stroke-opacity=".6"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 8,6, 8,1, 13,1, 13,15, 3,15, 3,6 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
g.fill( FlatUIUtils.createPath( 3,5, 7,5, 7,1 ) );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
|
|
||||||
|
g.draw( new RoundRectangle2D.Float( 2.5f, 1.5f, 11, 13, 3, 3 ) );
|
||||||
|
|
||||||
|
g.setColor( ColorFunctions.fade( g.getColor(), 0.6f ) );
|
||||||
|
g.draw( new Line2D.Float( 5.5f, 5.5f, 10.5f, 5.5f ) );
|
||||||
|
g.draw( new Line2D.Float( 5.5f, 8, 10.5f, 8 ) );
|
||||||
|
g.draw( new Line2D.Float( 5.5f, 10.5f, 10.5f, 10.5f ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,11 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
@@ -31,22 +34,50 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
public class FlatTreeOpenIcon
|
public class FlatTreeOpenIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private Path2D path;
|
||||||
|
|
||||||
public FlatTreeOpenIcon() {
|
public FlatTreeOpenIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "Tree.icon.openColor" ) );
|
super( 16, 16, UIManager.getColor( "Tree.icon.openColor" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
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">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<path fill="none" stroke="#6E6E6E" d="M2,13.5 L4.11538462,8.42307692 C4.34828895,7.86410651 4.89444872,7.5 5.5,7.5 L14.75,7.5 C15.0261424,7.5 15.25,7.72385763 15.25,8 C15.25,8.06601301 15.2369281,8.13137261 15.2115385,8.19230769 L13.3846154,12.5769231 C13.151711,13.1358935 12.6055513,13.5 12,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L12,4.5 C12.8284271,4.5 13.5,5.17157288 13.5,6 L13.5,6.5 L13.5,6.5"/>
|
||||||
<polygon fill="#6E6E6E" points="1 2 6 2 8 4 14 4 14 6 3.5 6 1 11"/>
|
|
||||||
<polygon fill="#6E6E6E" points="4 7 16 7 13 13 1 13"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 1,2, 6,2, 8,4, 14,4, 14,6, 3.5,6, 1,11 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
g.fill( FlatUIUtils.createPath( 4,7, 16,7, 13,13, 1,13 ) );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER ) );
|
||||||
|
|
||||||
|
if( path == null ) {
|
||||||
|
double arc = 1.5;
|
||||||
|
double arc2 = 0.5;
|
||||||
|
path = FlatUIUtils.createPath( false,
|
||||||
|
// bottom-left of opend part
|
||||||
|
2,13.5,
|
||||||
|
// top-left of opend part
|
||||||
|
FlatUIUtils.ROUNDED, 4.5,7.5, arc,
|
||||||
|
// top-right of opend part
|
||||||
|
FlatUIUtils.ROUNDED, 15.5,7.5, arc2,
|
||||||
|
|
||||||
|
// bottom-right
|
||||||
|
FlatUIUtils.ROUNDED, 13,13.5, arc,
|
||||||
|
// bottom-left
|
||||||
|
1.5+arc,13.5, FlatUIUtils.QUAD_TO, 1.5,13.5, 1.5,13.5-arc,
|
||||||
|
// top-left
|
||||||
|
1.5,2.5+arc, FlatUIUtils.QUAD_TO, 1.5,2.5, 1.5+arc,2.5,
|
||||||
|
// top-mid-left
|
||||||
|
6.5-arc2,2.5, FlatUIUtils.QUAD_TO, 6.5,2.5, 6.5+arc2,2.5+arc2,
|
||||||
|
// top-mid-right
|
||||||
|
8.5,4.5,
|
||||||
|
// top-right
|
||||||
|
13.5-arc,4.5, FlatUIUtils.QUAD_TO, 13.5,4.5, 13.5,4.5+arc,
|
||||||
|
13.5,6.5 );
|
||||||
|
}
|
||||||
|
g.draw( path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,72 @@
|
|||||||
|
/*
|
||||||
|
* 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.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, 4 );
|
||||||
|
path.moveTo( ix, iy );
|
||||||
|
path.lineTo( ix2, iy2 );
|
||||||
|
path.moveTo( ix, iy2 );
|
||||||
|
path.lineTo( ix2, iy );
|
||||||
|
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 opened 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
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 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.themes;
|
||||||
|
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import com.formdev.flatlaf.FlatDarkLaf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Flat LaF that imitates macOS dark look.
|
||||||
|
* <p>
|
||||||
|
* The UI defaults are loaded from {@code FlatMacDarkLaf.properties},
|
||||||
|
* {@code FlatDarkLaf.properties} and {@code FlatLaf.properties}.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public class FlatMacDarkLaf
|
||||||
|
extends FlatDarkLaf
|
||||||
|
{
|
||||||
|
public static final String NAME = "FlatLaf macOS Dark";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the application look and feel to this LaF
|
||||||
|
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||||
|
*/
|
||||||
|
public static boolean setup() {
|
||||||
|
return setup( new FlatMacDarkLaf() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, FlatMacDarkLaf.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "FlatLaf macOS Dark Look and Feel";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDark() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 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.themes;
|
||||||
|
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import com.formdev.flatlaf.FlatLightLaf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Flat LaF that imitates macOS light look.
|
||||||
|
* <p>
|
||||||
|
* The UI defaults are loaded from {@code FlatMacLightLaf.properties},
|
||||||
|
* {@code FlatLightLaf.properties} and {@code FlatLaf.properties}.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public class FlatMacLightLaf
|
||||||
|
extends FlatLightLaf
|
||||||
|
{
|
||||||
|
public static final String NAME = "FlatLaf macOS Light";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the application look and feel to this LaF
|
||||||
|
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||||
|
*/
|
||||||
|
public static boolean setup() {
|
||||||
|
return setup( new FlatMacLightLaf() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, FlatMacLightLaf.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "FlatLaf macOS Light Look and Feel";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDark() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,15 +17,15 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
import java.awt.BasicStroke;
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Shape;
|
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.geom.Path2D;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicArrowButton;
|
import javax.swing.plaf.basic.BasicArrowButton;
|
||||||
|
|
||||||
@@ -38,32 +38,38 @@ public class FlatArrowButton
|
|||||||
extends BasicArrowButton
|
extends BasicArrowButton
|
||||||
implements UIResource
|
implements UIResource
|
||||||
{
|
{
|
||||||
private final boolean chevron;
|
public static final int DEFAULT_ARROW_WIDTH = 9;
|
||||||
private final Color foreground;
|
|
||||||
private final Color disabledForeground;
|
|
||||||
private final Color hoverForeground;
|
|
||||||
private final Color hoverBackground;
|
|
||||||
|
|
||||||
private int xOffset = 0;
|
protected boolean chevron;
|
||||||
private int yOffset = 0;
|
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 arrowThickness = 1;
|
||||||
|
private float xOffset = 0;
|
||||||
|
private float yOffset = 0;
|
||||||
|
private boolean roundBorderAutoXOffset = true;
|
||||||
|
|
||||||
private boolean hover;
|
private boolean hover;
|
||||||
|
private boolean pressed;
|
||||||
|
|
||||||
public FlatArrowButton( int direction, String type, Color foreground, Color disabledForeground,
|
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 );
|
super( direction, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE );
|
||||||
|
updateStyle( type, foreground, disabledForeground, hoverForeground, hoverBackground,
|
||||||
this.chevron = "chevron".equals( type );
|
pressedForeground, pressedBackground );
|
||||||
this.foreground = foreground;
|
|
||||||
this.disabledForeground = disabledForeground;
|
|
||||||
this.hoverForeground = hoverForeground;
|
|
||||||
this.hoverBackground = hoverBackground;
|
|
||||||
|
|
||||||
setOpaque( false );
|
setOpaque( false );
|
||||||
setBorder( null );
|
setBorder( null );
|
||||||
|
|
||||||
if( hoverForeground != null || hoverBackground != null ) {
|
if( hoverForeground != null || hoverBackground != null ||
|
||||||
|
pressedForeground != null || pressedBackground != null )
|
||||||
|
{
|
||||||
addMouseListener( new MouseAdapter() {
|
addMouseListener( new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mouseEntered( MouseEvent e ) {
|
public void mouseEntered( MouseEvent e ) {
|
||||||
@@ -76,30 +82,114 @@ public class FlatArrowButton
|
|||||||
hover = false;
|
hover = false;
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed( MouseEvent e ) {
|
||||||
|
if( SwingUtilities.isLeftMouseButton( e ) ) {
|
||||||
|
pressed = true;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased( MouseEvent e ) {
|
||||||
|
if( SwingUtilities.isLeftMouseButton( 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 3 */
|
||||||
|
public float getArrowThickness() {
|
||||||
|
return arrowThickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 3 */
|
||||||
|
public void setArrowThickness( float arrowThickness ) {
|
||||||
|
this.arrowThickness = arrowThickness;
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean isHover() {
|
protected boolean isHover() {
|
||||||
return hover;
|
return hover;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getXOffset() {
|
protected boolean isPressed() {
|
||||||
|
return pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getXOffset() {
|
||||||
return xOffset;
|
return xOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setXOffset( int xOffset ) {
|
public void setXOffset( float xOffset ) {
|
||||||
this.xOffset = xOffset;
|
this.xOffset = xOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getYOffset() {
|
public float getYOffset() {
|
||||||
return yOffset;
|
return yOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setYOffset( int yOffset ) {
|
public void setYOffset( float yOffset ) {
|
||||||
this.yOffset = yOffset;
|
this.yOffset = yOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 3 */
|
||||||
|
public boolean isRoundBorderAutoXOffset() {
|
||||||
|
return roundBorderAutoXOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 3 */
|
||||||
|
public void setRoundBorderAutoXOffset( boolean roundBorderAutoXOffset ) {
|
||||||
|
this.roundBorderAutoXOffset = roundBorderAutoXOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
public Dimension getPreferredSize() {
|
public Dimension getPreferredSize() {
|
||||||
return scale( super.getPreferredSize() );
|
return scale( super.getPreferredSize() );
|
||||||
@@ -112,58 +202,45 @@ public class FlatArrowButton
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paint( Graphics g ) {
|
public void paint( Graphics g ) {
|
||||||
Graphics2D g2 = (Graphics2D)g;
|
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||||
FlatUIUtils.setRenderingHints( g2 );
|
|
||||||
|
|
||||||
int width = getWidth();
|
// paint hover or pressed background
|
||||||
int height = getHeight();
|
if( isEnabled() ) {
|
||||||
boolean enabled = isEnabled();
|
Color background = (pressedBackground != null && isPressed())
|
||||||
|
? pressedBackground
|
||||||
|
: (hoverBackground != null && isHover()
|
||||||
|
? hoverBackground
|
||||||
|
: null);
|
||||||
|
|
||||||
// paint hover background
|
if( background != null ) {
|
||||||
if( enabled && isHover() && hoverBackground != null ) {
|
g.setColor( deriveBackground( background ) );
|
||||||
g.setColor( hoverBackground );
|
paintBackground( (Graphics2D) g );
|
||||||
g.fillRect( 0, 0, width, height );
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// paint arrow
|
||||||
g.setColor( enabled
|
g.setColor( deriveForeground( getArrowColor() ) );
|
||||||
? (isHover() && hoverForeground != null ? hoverForeground : foreground)
|
paintArrow( (Graphics2D) g );
|
||||||
: disabledForeground );
|
|
||||||
g.translate( x, y );
|
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Shape createArrowShape( int direction, boolean chevron, float w, float h ) {
|
protected void paintBackground( Graphics2D g ) {
|
||||||
switch( direction ) {
|
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||||
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 );
|
protected void paintArrow( Graphics2D g ) {
|
||||||
case EAST: return FlatUIUtils.createPath( !chevron, 0,0, h,(w / 2f), 0,w );
|
int x = 0;
|
||||||
default: return new Path2D.Float();
|
|
||||||
}
|
// move arrow for round borders
|
||||||
|
if( isRoundBorderAutoXOffset() ) {
|
||||||
|
Container parent = getParent();
|
||||||
|
boolean vert = (direction == NORTH || direction == SOUTH);
|
||||||
|
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,
|
||||||
|
getArrowWidth(), getArrowThickness(), getXOffset(), getYOffset() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,49 +22,90 @@ import java.awt.Component;
|
|||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.KeyboardFocusManager;
|
|
||||||
import java.awt.Paint;
|
import java.awt.Paint;
|
||||||
|
import java.util.Map;
|
||||||
import javax.swing.JComboBox;
|
import javax.swing.JComboBox;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JSpinner;
|
import javax.swing.JSpinner;
|
||||||
import javax.swing.JTable;
|
|
||||||
import javax.swing.JTextField;
|
|
||||||
import javax.swing.JTree;
|
|
||||||
import javax.swing.JViewport;
|
import javax.swing.JViewport;
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.basic.BasicBorders;
|
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}).
|
* 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,
|
* There is empty space around the component border, if Component.focusWidth is greater than zero,
|
||||||
* which is used to paint focus border.
|
* which is used to paint outer focus border.
|
||||||
*
|
* <p>
|
||||||
* Because there is empty space (if focus border is not painted),
|
* Because there is empty space (if outer focus border is not painted),
|
||||||
* UI delegates that use this border (or subclasses) must invoke
|
* 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.focusWidth int
|
||||||
* @uiDefault Component.innerFocusWidth 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.focusColor Color
|
||||||
* @uiDefault Component.borderColor Color
|
* @uiDefault Component.borderColor Color
|
||||||
* @uiDefault Component.disabledBorderColor Color
|
* @uiDefault Component.disabledBorderColor Color
|
||||||
* @uiDefault Component.focusedBorderColor 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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatBorder
|
public class FlatBorder
|
||||||
extends BasicBorders.MarginBorder
|
extends BasicBorders.MarginBorder
|
||||||
|
implements StyleableBorder
|
||||||
{
|
{
|
||||||
protected final int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
@Styleable protected int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||||
protected final int innerFocusWidth = UIManager.getInt( "Component.innerFocusWidth" );
|
@Styleable protected float innerFocusWidth = FlatUIUtils.getUIFloat( "Component.innerFocusWidth", 0 );
|
||||||
protected final Color focusColor = UIManager.getColor( "Component.focusColor" );
|
@Styleable protected float innerOutlineWidth = FlatUIUtils.getUIFloat( "Component.innerOutlineWidth", 0 );
|
||||||
protected final Color borderColor = UIManager.getColor( "Component.borderColor" );
|
/** @since 2 */ @Styleable protected float borderWidth = FlatUIUtils.getUIFloat( "Component.borderWidth", 1 );
|
||||||
protected final Color disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
|
||||||
protected final Color focusedBorderColor = UIManager.getColor( "Component.focusedBorderColor" );
|
@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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
@@ -72,93 +113,175 @@ public class FlatBorder
|
|||||||
try {
|
try {
|
||||||
FlatUIUtils.setRenderingHints( g2 );
|
FlatUIUtils.setRenderingHints( g2 );
|
||||||
|
|
||||||
boolean isCellEditor = FlatUIUtils.isTableCellEditor( c );
|
float focusWidth = scale( (float) getFocusWidth( c ) );
|
||||||
float focusWidth = isCellEditor ? 0 : getFocusWidth();
|
float focusInnerWidth = 0;
|
||||||
float borderWidth = getBorderWidth( c );
|
float borderWidth = scale( getBorderWidth( c ) );
|
||||||
float arc = isCellEditor ? 0 : getArc();
|
float arc = scale( (float) getArc( c ) );
|
||||||
|
Color outlineColor = getOutlineColor( c );
|
||||||
|
Color focusColor = null;
|
||||||
|
|
||||||
if( isFocused( c ) ) {
|
// paint outer border
|
||||||
g2.setColor( getFocusColor( c ) );
|
if( outlineColor != null || isFocused( c ) ) {
|
||||||
FlatUIUtils.paintOutlineBorder( g2, x, y, width, height, focusWidth,
|
float innerWidth = !isCellEditor( c ) && !(c instanceof JScrollPane)
|
||||||
getLineWidth() + scale( (float) innerFocusWidth ), arc );
|
? (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 ) );
|
// paint border
|
||||||
FlatUIUtils.drawRoundRectangle( g2, x, y, width, height, focusWidth, borderWidth, arc );
|
Paint borderColor = (outlineColor != null) ? outlineColor : getBorderColor( c );
|
||||||
|
FlatUIUtils.paintOutlinedComponent( g2, x, y, width, height,
|
||||||
|
focusWidth, 1, focusInnerWidth, borderWidth, arc,
|
||||||
|
focusColor, borderColor, null );
|
||||||
} finally {
|
} finally {
|
||||||
g2.dispose();
|
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 ) {
|
protected Color getFocusColor( Component c ) {
|
||||||
return focusColor;
|
return focusColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Paint getBorderColor( Component c ) {
|
protected Paint getBorderColor( Component c ) {
|
||||||
boolean enabled = c.isEnabled() && (!(c instanceof JTextComponent) || ((JTextComponent)c).isEditable());
|
return isEnabled( c )
|
||||||
return enabled
|
|
||||||
? (isFocused( c ) ? focusedBorderColor : borderColor)
|
? (isFocused( c ) ? focusedBorderColor : borderColor)
|
||||||
: disabledBorderColor;
|
: disabledBorderColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isFocused( Component c ) {
|
protected boolean isEnabled( Component c ) {
|
||||||
if( c instanceof JScrollPane ) {
|
if( c instanceof JScrollPane ) {
|
||||||
|
// check whether view component is disabled
|
||||||
JViewport viewport = ((JScrollPane)c).getViewport();
|
JViewport viewport = ((JScrollPane)c).getViewport();
|
||||||
Component view = (viewport != null) ? viewport.getView() : null;
|
Component view = (viewport != null) ? viewport.getView() : null;
|
||||||
if( view != null ) {
|
if( view != null && !isEnabled( view ) )
|
||||||
if( view.hasFocus() )
|
return false;
|
||||||
return true;
|
}
|
||||||
|
|
||||||
if( (view instanceof JTable && ((JTable)view).isEditing()) ||
|
return c.isEnabled();
|
||||||
(view instanceof JTree && ((JTree)view).isEditing()) )
|
|
||||||
{
|
|
||||||
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
|
|
||||||
if( focusOwner != null )
|
|
||||||
return SwingUtilities.isDescendingFrom( focusOwner, view );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
} else if( c instanceof JComboBox && ((JComboBox<?>)c).isEditable() ) {
|
protected boolean isCellEditor( Component c ) {
|
||||||
Component editorComponent = ((JComboBox<?>)c).getEditor().getEditorComponent();
|
return FlatUIUtils.isCellEditor( c );
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||||
boolean isCellEditor = FlatUIUtils.isTableCellEditor( c );
|
float focusWidth = scale( (float) getFocusWidth( c ) );
|
||||||
float ow = (isCellEditor ? 0 : getFocusWidth()) + getLineWidth();
|
int ow = Math.round( focusWidth + scale( (float) getLineWidth( c ) ) );
|
||||||
|
|
||||||
insets = super.getBorderInsets( c, insets );
|
insets = super.getBorderInsets( c, insets );
|
||||||
insets.top = Math.round( scale( (float) insets.top ) + ow );
|
|
||||||
insets.left = Math.round( scale( (float) insets.left ) + ow );
|
insets.top = scale( insets.top ) + ow;
|
||||||
insets.bottom = Math.round( scale( (float) insets.bottom ) + ow );
|
insets.left = scale( insets.left ) + ow;
|
||||||
insets.right = Math.round( scale( (float) insets.right ) + 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;
|
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 ) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,86 +16,186 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.GradientPaint;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.Paint;
|
import java.awt.Paint;
|
||||||
import javax.swing.JButton;
|
import javax.swing.AbstractButton;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Border for {@link javax.swing.JButton}.
|
* 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.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.disabledBorderColor Color
|
||||||
* @uiDefault Button.focusedBorderColor Color
|
* @uiDefault Button.focusedBorderColor Color
|
||||||
* @uiDefault Button.hoverBorderColor Color optional
|
* @uiDefault Button.hoverBorderColor Color optional
|
||||||
|
*
|
||||||
|
* @uiDefault Button.default.borderWidth int or float
|
||||||
* @uiDefault Button.default.borderColor Color
|
* @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.focusedBorderColor Color
|
||||||
* @uiDefault Button.default.focusColor Color
|
* @uiDefault Button.default.focusColor Color
|
||||||
* @uiDefault Button.default.borderWidth int
|
* @uiDefault Button.default.hoverBorderColor Color optional
|
||||||
* @uiDefault Button.arc int
|
*
|
||||||
|
* @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
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatButtonBorder
|
public class FlatButtonBorder
|
||||||
extends FlatBorder
|
extends FlatBorder
|
||||||
{
|
{
|
||||||
protected final Color borderColor = UIManager.getColor( "Button.borderColor" );
|
@Styleable protected int arc = UIManager.getInt( "Button.arc" );
|
||||||
protected final Color disabledBorderColor = UIManager.getColor( "Button.disabledBorderColor" );
|
|
||||||
protected final Color focusedBorderColor = UIManager.getColor( "Button.focusedBorderColor" );
|
protected Color endBorderColor = UIManager.getColor( "Button.endBorderColor" );
|
||||||
protected final Color hoverBorderColor = UIManager.getColor( "Button.hoverBorderColor" );
|
@Styleable protected Color hoverBorderColor = UIManager.getColor( "Button.hoverBorderColor" );
|
||||||
protected final Color defaultBorderColor = UIManager.getColor( "Button.default.borderColor" );
|
|
||||||
protected final Color defaultHoverBorderColor = UIManager.getColor( "Button.default.hoverBorderColor" );
|
@Styleable(dot=true) protected float defaultBorderWidth = FlatUIUtils.getUIFloat( "Button.default.borderWidth", 1 );
|
||||||
protected final Color defaultFocusedBorderColor = UIManager.getColor( "Button.default.focusedBorderColor" );
|
@Styleable(dot=true) protected Color defaultBorderColor = FlatUIUtils.getUIColor( "Button.default.startBorderColor", "Button.default.borderColor" );
|
||||||
protected final Color defaultFocusColor = UIManager.getColor( "Button.default.focusColor" );
|
protected Color defaultEndBorderColor = UIManager.getColor( "Button.default.endBorderColor" );
|
||||||
protected final int defaultBorderWidth = UIManager.getInt( "Button.default.borderWidth" );
|
@Styleable(dot=true) protected Color defaultFocusedBorderColor = UIManager.getColor( "Button.default.focusedBorderColor" );
|
||||||
protected final int arc = UIManager.getInt( "Button.arc" );
|
@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
|
@Override
|
||||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
if( FlatButtonUI.isContentAreaFilled( c ) && !FlatButtonUI.isHelpButton( c ) )
|
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 );
|
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
|
@Override
|
||||||
protected Color getFocusColor( Component c ) {
|
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
|
@Override
|
||||||
protected Paint getBorderColor( Component c ) {
|
protected Paint getBorderColor( Component c ) {
|
||||||
boolean def = FlatButtonUI.isDefaultButton( c );
|
boolean def = FlatButtonUI.isDefaultButton( c );
|
||||||
return FlatButtonUI.buttonStateColor( c,
|
Paint color = FlatButtonUI.buttonStateColor( c,
|
||||||
def ? defaultBorderColor : borderColor,
|
def ? defaultBorderColor : borderColor,
|
||||||
disabledBorderColor,
|
disabledBorderColor,
|
||||||
def ? defaultFocusedBorderColor : focusedBorderColor,
|
def ? defaultFocusedBorderColor : focusedBorderColor,
|
||||||
def ? defaultHoverBorderColor : hoverBorderColor,
|
def ? defaultHoverBorderColor : hoverBorderColor,
|
||||||
null );
|
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
|
@Override
|
||||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
public Insets getBorderInsets( Component c, Insets 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;
|
||||||
|
|
||||||
|
FlatUIUtils.setInsets( insets, UIScale.scale( FlatUIUtils.addInsets( toolbarSpacingInsets,
|
||||||
|
(margin != null && !(margin instanceof UIResource)) ? margin : toolbarMargin ) ) );
|
||||||
|
} else {
|
||||||
insets = super.getBorderInsets( c, insets );
|
insets = super.getBorderInsets( c, insets );
|
||||||
|
|
||||||
// use smaller left and right insets for icon-only buttons (so that they are square)
|
// use smaller left and right insets for icon-only or single-character buttons (so that they are square)
|
||||||
if( FlatButtonUI.isIconOnlyButton( c ) && ((JButton)c).getMargin() instanceof UIResource )
|
if( FlatButtonUI.isIconOnlyOrSingleCharacterButton( c ) && ((AbstractButton)c).getMargin() instanceof UIResource )
|
||||||
insets.left = insets.right = Math.min( insets.top, insets.bottom );
|
insets.left = insets.right = Math.min( insets.top, insets.bottom );
|
||||||
|
}
|
||||||
|
|
||||||
return insets;
|
return insets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected float getBorderWidth( Component c ) {
|
protected int getFocusWidth( Component c ) {
|
||||||
return FlatButtonUI.isDefaultButton( c ) ? scale( (float) defaultBorderWidth ) : super.getBorderWidth( c );
|
return FlatToggleButtonUI.isTabButton( c ) ? 0 : super.getFocusWidth( c );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected float getArc() {
|
protected float getBorderWidth( Component c ) {
|
||||||
return scale( (float) arc );
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,83 +20,192 @@ import static com.formdev.flatlaf.FlatClientProperties.*;
|
|||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
|
import java.awt.GradientPaint;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Insets;
|
||||||
import java.awt.Rectangle;
|
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.AbstractButton;
|
||||||
import javax.swing.ButtonModel;
|
import javax.swing.ButtonModel;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.JToggleButton;
|
||||||
import javax.swing.JToolBar;
|
import javax.swing.JToolBar;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.Border;
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.plaf.ButtonUI;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.ToolBarUI;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
|
import javax.swing.plaf.basic.BasicButtonListener;
|
||||||
import javax.swing.plaf.basic.BasicButtonUI;
|
import javax.swing.plaf.basic.BasicButtonUI;
|
||||||
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
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}.
|
* 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.minimumWidth int
|
||||||
* @uiDefault Button.iconTextGap 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.focusedBackground Color optional
|
||||||
|
* @uiDefault Button.focusedForeground Color optional
|
||||||
* @uiDefault Button.hoverBackground Color optional
|
* @uiDefault Button.hoverBackground Color optional
|
||||||
|
* @uiDefault Button.hoverForeground Color optional
|
||||||
* @uiDefault Button.pressedBackground Color optional
|
* @uiDefault Button.pressedBackground Color optional
|
||||||
|
* @uiDefault Button.pressedForeground Color optional
|
||||||
|
* @uiDefault Button.selectedBackground Color
|
||||||
|
* @uiDefault Button.selectedForeground Color
|
||||||
|
* @uiDefault Button.disabledBackground Color optional
|
||||||
* @uiDefault Button.disabledText Color
|
* @uiDefault Button.disabledText Color
|
||||||
|
* @uiDefault Button.disabledSelectedBackground Color
|
||||||
|
* @uiDefault Button.disabledSelectedForeground Color optional
|
||||||
* @uiDefault Button.default.background 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.foreground Color
|
||||||
* @uiDefault Button.default.focusedBackground Color optional
|
* @uiDefault Button.default.focusedBackground Color optional
|
||||||
|
* @uiDefault Button.default.focusedForeground Color optional
|
||||||
* @uiDefault Button.default.hoverBackground Color optional
|
* @uiDefault Button.default.hoverBackground Color optional
|
||||||
|
* @uiDefault Button.default.hoverForeground Color optional
|
||||||
* @uiDefault Button.default.pressedBackground Color optional
|
* @uiDefault Button.default.pressedBackground Color optional
|
||||||
|
* @uiDefault Button.default.pressedForeground Color optional
|
||||||
* @uiDefault Button.default.boldText boolean
|
* @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.hoverBackground Color
|
||||||
|
* @uiDefault Button.toolbar.hoverForeground Color optional
|
||||||
* @uiDefault Button.toolbar.pressedBackground Color
|
* @uiDefault Button.toolbar.pressedBackground Color
|
||||||
|
* @uiDefault Button.toolbar.pressedForeground Color optional
|
||||||
|
* @uiDefault Button.toolbar.selectedBackground Color
|
||||||
|
* @uiDefault Button.toolbar.selectedForeground Color optional
|
||||||
|
* @uiDefault Button.toolbar.disabledSelectedBackground Color optional
|
||||||
|
* @uiDefault Button.toolbar.disabledSelectedForeground Color optional
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatButtonUI
|
public class FlatButtonUI
|
||||||
extends BasicButtonUI
|
extends BasicButtonUI
|
||||||
|
implements StyleableUI
|
||||||
{
|
{
|
||||||
protected int focusWidth;
|
@Styleable protected int minimumWidth;
|
||||||
protected int arc;
|
|
||||||
protected int minimumWidth;
|
|
||||||
protected int iconTextGap;
|
protected int iconTextGap;
|
||||||
|
|
||||||
protected Color focusedBackground;
|
protected Color background;
|
||||||
protected Color hoverBackground;
|
protected Color foreground;
|
||||||
protected Color pressedBackground;
|
|
||||||
protected Color disabledText;
|
|
||||||
|
|
||||||
protected Color defaultBackground;
|
protected Color startBackground;
|
||||||
protected Color defaultForeground;
|
protected Color endBackground;
|
||||||
protected Color defaultFocusedBackground;
|
@Styleable protected Color focusedBackground;
|
||||||
protected Color defaultHoverBackground;
|
/** @since 2.3 */ @Styleable protected Color focusedForeground;
|
||||||
protected Color defaultPressedBackground;
|
@Styleable protected Color hoverBackground;
|
||||||
protected boolean defaultBoldText;
|
/** @since 2.3 */ @Styleable protected Color hoverForeground;
|
||||||
|
@Styleable protected Color pressedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable protected Color pressedForeground;
|
||||||
|
@Styleable protected Color selectedBackground;
|
||||||
|
@Styleable protected Color selectedForeground;
|
||||||
|
@Styleable protected Color disabledBackground;
|
||||||
|
@Styleable protected Color disabledText;
|
||||||
|
@Styleable protected Color disabledSelectedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable protected Color disabledSelectedForeground;
|
||||||
|
|
||||||
protected Color toolbarHoverBackground;
|
@Styleable(dot=true) protected Color defaultBackground;
|
||||||
protected Color toolbarPressedBackground;
|
protected Color defaultEndBackground;
|
||||||
|
@Styleable(dot=true) protected Color defaultForeground;
|
||||||
|
@Styleable(dot=true) protected Color defaultFocusedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color defaultFocusedForeground;
|
||||||
|
@Styleable(dot=true) protected Color defaultHoverBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color defaultHoverForeground;
|
||||||
|
@Styleable(dot=true) protected Color defaultPressedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color defaultPressedForeground;
|
||||||
|
@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;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarHoverForeground;
|
||||||
|
@Styleable(dot=true) protected Color toolbarPressedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarPressedForeground;
|
||||||
|
@Styleable(dot=true) protected Color toolbarSelectedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarSelectedForeground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarDisabledSelectedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarDisabledSelectedForeground;
|
||||||
|
|
||||||
|
// 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 Icon helpButtonIcon;
|
||||||
|
private Insets defaultMargin;
|
||||||
|
|
||||||
|
private final boolean shared;
|
||||||
|
private boolean helpButtonIconShared = true;
|
||||||
private boolean defaults_initialized = false;
|
private boolean defaults_initialized = false;
|
||||||
|
private Map<String, Object> oldStyleValues;
|
||||||
private static ComponentUI instance;
|
private AtomicBoolean borderShared;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
if( instance == null )
|
return FlatUIUtils.canUseSharedUI( c ) && !FlatUIUtils.needsLightAWTPeer( c )
|
||||||
instance = new FlatButtonUI();
|
? FlatUIUtils.createSharedUI( FlatButtonUI.class, () -> new FlatButtonUI( true ) )
|
||||||
return instance;
|
: new FlatButtonUI( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2 */
|
||||||
|
protected FlatButtonUI( boolean shared ) {
|
||||||
|
this.shared = shared;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void installUI( JComponent c ) {
|
||||||
|
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||||
|
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||||
|
else
|
||||||
|
installUIImpl( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void installUIImpl( JComponent c ) {
|
||||||
|
super.installUI( c );
|
||||||
|
|
||||||
|
installStyle( (AbstractButton) c );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -106,66 +215,249 @@ public class FlatButtonUI
|
|||||||
if( !defaults_initialized ) {
|
if( !defaults_initialized ) {
|
||||||
String prefix = getPropertyPrefix();
|
String prefix = getPropertyPrefix();
|
||||||
|
|
||||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
|
||||||
arc = UIManager.getInt( prefix + "arc" );
|
|
||||||
minimumWidth = UIManager.getInt( prefix + "minimumWidth" );
|
minimumWidth = UIManager.getInt( prefix + "minimumWidth" );
|
||||||
iconTextGap = FlatUIUtils.getUIInt( prefix + "iconTextGap", 4 );
|
iconTextGap = FlatUIUtils.getUIInt( prefix + "iconTextGap", 4 );
|
||||||
|
|
||||||
focusedBackground = UIManager.getColor( prefix + "focusedBackground" );
|
background = UIManager.getColor( prefix + "background" );
|
||||||
hoverBackground = UIManager.getColor( prefix + "hoverBackground" );
|
foreground = UIManager.getColor( prefix + "foreground" );
|
||||||
pressedBackground = UIManager.getColor( prefix + "pressedBackground" );
|
|
||||||
disabledText = UIManager.getColor( prefix + "disabledText" );
|
|
||||||
|
|
||||||
defaultBackground = UIManager.getColor( "Button.default.background" );
|
startBackground = UIManager.getColor( prefix + "startBackground" );
|
||||||
|
endBackground = UIManager.getColor( prefix + "endBackground" );
|
||||||
|
focusedBackground = UIManager.getColor( prefix + "focusedBackground" );
|
||||||
|
focusedForeground = UIManager.getColor( prefix + "focusedForeground" );
|
||||||
|
hoverBackground = UIManager.getColor( prefix + "hoverBackground" );
|
||||||
|
hoverForeground = UIManager.getColor( prefix + "hoverForeground" );
|
||||||
|
pressedBackground = UIManager.getColor( prefix + "pressedBackground" );
|
||||||
|
pressedForeground = UIManager.getColor( prefix + "pressedForeground" );
|
||||||
|
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" );
|
||||||
|
disabledSelectedForeground = UIManager.getColor( prefix + "disabledSelectedForeground" );
|
||||||
|
|
||||||
|
defaultBackground = FlatUIUtils.getUIColor( "Button.default.startBackground", "Button.default.background" );
|
||||||
|
defaultEndBackground = UIManager.getColor( "Button.default.endBackground" );
|
||||||
defaultForeground = UIManager.getColor( "Button.default.foreground" );
|
defaultForeground = UIManager.getColor( "Button.default.foreground" );
|
||||||
defaultFocusedBackground = UIManager.getColor( "Button.default.focusedBackground" );
|
defaultFocusedBackground = UIManager.getColor( "Button.default.focusedBackground" );
|
||||||
|
defaultFocusedForeground = UIManager.getColor( "Button.default.focusedForeground" );
|
||||||
defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" );
|
defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" );
|
||||||
|
defaultHoverForeground = UIManager.getColor( "Button.default.hoverForeground" );
|
||||||
defaultPressedBackground = UIManager.getColor( "Button.default.pressedBackground" );
|
defaultPressedBackground = UIManager.getColor( "Button.default.pressedBackground" );
|
||||||
|
defaultPressedForeground = UIManager.getColor( "Button.default.pressedForeground" );
|
||||||
defaultBoldText = UIManager.getBoolean( "Button.default.boldText" );
|
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" );
|
toolbarHoverBackground = UIManager.getColor( prefix + "toolbar.hoverBackground" );
|
||||||
|
toolbarHoverForeground = UIManager.getColor( prefix + "toolbar.hoverForeground" );
|
||||||
toolbarPressedBackground = UIManager.getColor( prefix + "toolbar.pressedBackground" );
|
toolbarPressedBackground = UIManager.getColor( prefix + "toolbar.pressedBackground" );
|
||||||
|
toolbarPressedForeground = UIManager.getColor( prefix + "toolbar.pressedForeground" );
|
||||||
|
toolbarSelectedBackground = UIManager.getColor( prefix + "toolbar.selectedBackground" );
|
||||||
|
toolbarSelectedForeground = UIManager.getColor( prefix + "toolbar.selectedForeground" );
|
||||||
|
toolbarDisabledSelectedBackground = UIManager.getColor( prefix + "toolbar.disabledSelectedBackground" );
|
||||||
|
toolbarDisabledSelectedForeground = UIManager.getColor( prefix + "toolbar.disabledSelectedForeground" );
|
||||||
|
|
||||||
helpButtonIcon = UIManager.getIcon( "HelpButton.icon" );
|
helpButtonIcon = UIManager.getIcon( "HelpButton.icon" );
|
||||||
|
defaultMargin = UIManager.getInsets( prefix + "margin" );
|
||||||
|
|
||||||
|
helpButtonIconShared = true;
|
||||||
defaults_initialized = 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, "opaque", false );
|
||||||
LookAndFeel.installProperty( b, "iconTextGap", scale( iconTextGap ) );
|
LookAndFeel.installProperty( b, "iconTextGap", scale( iconTextGap ) );
|
||||||
|
|
||||||
MigLayoutVisualPadding.install( b, focusWidth );
|
MigLayoutVisualPadding.install( b );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void uninstallDefaults( AbstractButton b ) {
|
protected void uninstallDefaults( AbstractButton b ) {
|
||||||
super.uninstallDefaults( b );
|
super.uninstallDefaults( b );
|
||||||
|
|
||||||
|
oldStyleValues = null;
|
||||||
|
borderShared = null;
|
||||||
|
|
||||||
MigLayoutVisualPadding.uninstall( b );
|
MigLayoutVisualPadding.uninstall( b );
|
||||||
defaults_initialized = false;
|
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 OUTLINE:
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
if( key.startsWith( "help." ) ) {
|
||||||
|
return (helpButtonIcon instanceof FlatHelpButtonIcon)
|
||||||
|
? ((FlatHelpButtonIcon)helpButtonIcon).getStyleableValue( key.substring( "help.".length() ) )
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, c.getBorder(), key );
|
||||||
|
}
|
||||||
|
|
||||||
static boolean isContentAreaFilled( Component c ) {
|
static boolean isContentAreaFilled( Component c ) {
|
||||||
return !(c instanceof AbstractButton) || ((AbstractButton)c).isContentAreaFilled();
|
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 ) {
|
static boolean isDefaultButton( Component c ) {
|
||||||
return c instanceof JButton && ((JButton)c).isDefaultButton();
|
return c instanceof JButton && ((JButton)c).isDefaultButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isIconOnlyButton( Component c ) {
|
/**
|
||||||
String text;
|
* Returns true if the button has an icon but no text,
|
||||||
return c instanceof JButton &&
|
* or it does not have an icon and the text is either "..." or one character.
|
||||||
((JButton)c).getIcon() != null &&
|
*/
|
||||||
((text = ((JButton)c).getText()) == null || text.isEmpty());
|
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 ) {
|
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 ) {
|
static boolean isToolBarButton( Component c ) {
|
||||||
return c.getParent() instanceof JToolBar;
|
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
|
@Override
|
||||||
@@ -179,26 +471,103 @@ public class FlatButtonUI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isContentAreaFilled( c ) ) {
|
if( isContentAreaFilled( c ) )
|
||||||
|
paintBackground( g, c );
|
||||||
|
|
||||||
|
paint( g, c );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void paintBackground( Graphics g, JComponent c ) {
|
||||||
Color background = getBackground( c );
|
Color background = getBackground( c );
|
||||||
if( background != null ) {
|
if( background == null )
|
||||||
|
return;
|
||||||
|
|
||||||
Graphics2D g2 = (Graphics2D) g.create();
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
try {
|
try {
|
||||||
FlatUIUtils.setRenderingHints( g2 );
|
FlatUIUtils.setRenderingHints( g2 );
|
||||||
|
|
||||||
Border border = c.getBorder();
|
boolean def = isDefaultButton( c );
|
||||||
float focusWidth = (border instanceof FlatBorder) ? scale( (float) this.focusWidth ) : 0;
|
boolean isToolBarButton = isToolBarButton( c );
|
||||||
float arc = (border instanceof FlatButtonBorder || isToolBarButton( c )) ? scale( (float) this.arc ) : 0;
|
float focusWidth = isToolBarButton ? 0 : FlatUIUtils.getBorderFocusWidth( c );
|
||||||
|
float arc = FlatUIUtils.getBorderArc( c );
|
||||||
|
float textFieldArc = 0;
|
||||||
|
|
||||||
g2.setColor( background );
|
// if toolbar button is in leading/trailing component of a text field,
|
||||||
FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc );
|
// 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 {
|
} finally {
|
||||||
g2.dispose();
|
g2.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint( Graphics g, JComponent c ) {
|
||||||
|
super.paint( FlatLabelUI.createGraphicsHTMLTextYCorrection( g, c ), c );
|
||||||
}
|
}
|
||||||
|
|
||||||
paint( g, c );
|
@Override
|
||||||
|
protected void paintIcon( Graphics g, JComponent c, Rectangle iconRect ) {
|
||||||
|
// correct icon location when using bold font for default button
|
||||||
|
int xOffset = defaultBoldPlainWidthDiff( c ) / 2;
|
||||||
|
if( xOffset > 0 ) {
|
||||||
|
boolean ltr = c.getComponentOrientation().isLeftToRight();
|
||||||
|
switch( ((AbstractButton)c).getHorizontalTextPosition() ) {
|
||||||
|
case SwingConstants.RIGHT: iconRect.x -= xOffset; break;
|
||||||
|
case SwingConstants.LEFT: iconRect.x += xOffset; break;
|
||||||
|
case SwingConstants.TRAILING: iconRect.x -= ltr ? xOffset : -xOffset; break;
|
||||||
|
case SwingConstants.LEADING: iconRect.x += ltr ? xOffset : -xOffset; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.paintIcon( g, c, iconRect );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -217,10 +586,12 @@ public class FlatButtonUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
paintText( g, b, textRect, text, b.isEnabled() ? getForeground( b ) : disabledText );
|
paintText( g, b, textRect, text, getForeground( b ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public 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 ) {
|
||||||
|
if(foreground == null)
|
||||||
|
foreground=Color.red;
|
||||||
FontMetrics fm = b.getFontMetrics( b.getFont() );
|
FontMetrics fm = b.getFontMetrics( b.getFont() );
|
||||||
int mnemonicIndex = FlatLaf.isShowMnemonics() ? b.getDisplayedMnemonicIndex() : -1;
|
int mnemonicIndex = FlatLaf.isShowMnemonics() ? b.getDisplayedMnemonicIndex() : -1;
|
||||||
|
|
||||||
@@ -230,53 +601,132 @@ public class FlatButtonUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Color getBackground( JComponent c ) {
|
protected Color getBackground( JComponent c ) {
|
||||||
if( !c.isEnabled() )
|
boolean toolBarButton = isToolBarButton( c ) || isBorderlessButton( c );
|
||||||
return null;
|
|
||||||
|
// selected state
|
||||||
|
if( ((AbstractButton)c).isSelected() ) {
|
||||||
|
// in toolbar, if toolbarDisabledSelectedBackground is null,
|
||||||
|
// use same background colors for disabled and enabled because
|
||||||
|
// we assume that toolbar icon is shown disabled
|
||||||
|
return buttonStateColor( c,
|
||||||
|
toolBarButton ? toolbarSelectedBackground : selectedBackground,
|
||||||
|
toolBarButton
|
||||||
|
? (toolbarDisabledSelectedBackground != null ? toolbarDisabledSelectedBackground : toolbarSelectedBackground)
|
||||||
|
: disabledSelectedBackground,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
toolBarButton ? toolbarPressedBackground : pressedBackground );
|
||||||
|
}
|
||||||
|
|
||||||
// toolbar button
|
// toolbar button
|
||||||
if( isToolBarButton( c ) ) {
|
if( toolBarButton ) {
|
||||||
ButtonModel model = ((AbstractButton)c).getModel();
|
Color bg = c.getBackground();
|
||||||
if( model.isPressed() )
|
return buttonStateColor( c,
|
||||||
return toolbarPressedBackground;
|
isCustomBackground( bg ) ? bg : null,
|
||||||
if( model.isRollover() )
|
null,
|
||||||
return toolbarHoverBackground;
|
null,
|
||||||
|
toolbarHoverBackground,
|
||||||
// use background of toolbar
|
toolbarPressedBackground );
|
||||||
return c.getParent().getBackground();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean def = isDefaultButton( c );
|
boolean def = isDefaultButton( c );
|
||||||
return buttonStateColor( c,
|
return buttonStateColor( c,
|
||||||
def ? defaultBackground : c.getBackground(),
|
getBackgroundBase( c, def ),
|
||||||
null,
|
disabledBackground,
|
||||||
def ? defaultFocusedBackground : focusedBackground,
|
isCustomBackground( c.getBackground() ) ? null : (def ? defaultFocusedBackground : focusedBackground),
|
||||||
def ? defaultHoverBackground : hoverBackground,
|
def ? defaultHoverBackground : hoverBackground,
|
||||||
def ? defaultPressedBackground : pressedBackground );
|
def ? defaultPressedBackground : pressedBackground );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Color getBackgroundBase( JComponent c, boolean def ) {
|
||||||
|
if( FlatUIUtils.isAWTPeer( c ) )
|
||||||
|
return background;
|
||||||
|
|
||||||
|
// 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,
|
public static Color buttonStateColor( Component c, Color enabledColor, Color disabledColor,
|
||||||
Color focusedColor, Color hoverColor, Color pressedColor )
|
Color focusedColor, Color hoverColor, Color pressedColor )
|
||||||
{
|
{
|
||||||
AbstractButton b = (c instanceof AbstractButton) ? (AbstractButton) c : null;
|
if( c == null )
|
||||||
|
return enabledColor;
|
||||||
|
|
||||||
if( !c.isEnabled() )
|
if( !c.isEnabled() )
|
||||||
return disabledColor;
|
return disabledColor;
|
||||||
|
|
||||||
if( pressedColor != null && b != null && b.getModel().isPressed() )
|
if( c instanceof AbstractButton ) {
|
||||||
|
ButtonModel model = ((AbstractButton)c).getModel();
|
||||||
|
|
||||||
|
if( pressedColor != null && model.isPressed() )
|
||||||
return pressedColor;
|
return pressedColor;
|
||||||
|
|
||||||
if( hoverColor != null && b != null && b.getModel().isRollover() )
|
if( hoverColor != null && model.isRollover() )
|
||||||
return hoverColor;
|
return hoverColor;
|
||||||
|
}
|
||||||
|
|
||||||
if( focusedColor != null && c.hasFocus() )
|
if( focusedColor != null && isFocusPainted( c ) && FlatUIUtils.isPermanentFocusOwner( c ) )
|
||||||
return focusedColor;
|
return focusedColor;
|
||||||
|
|
||||||
return enabledColor;
|
return enabledColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Color getForeground( JComponent c ) {
|
protected Color getForeground( JComponent c ) {
|
||||||
|
boolean toolBarButton = isToolBarButton( c ) || isBorderlessButton( c );
|
||||||
|
|
||||||
|
// selected state
|
||||||
|
if( ((AbstractButton)c).isSelected() ) {
|
||||||
|
return buttonStateColor( c,
|
||||||
|
toolBarButton
|
||||||
|
? (toolbarSelectedForeground != null ? toolbarSelectedForeground : c.getForeground())
|
||||||
|
: selectedForeground,
|
||||||
|
toolBarButton
|
||||||
|
? (toolbarDisabledSelectedForeground != null ? toolbarDisabledSelectedForeground : disabledText)
|
||||||
|
: (disabledSelectedForeground != null ? disabledSelectedForeground : disabledText),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
toolBarButton ? toolbarPressedForeground : pressedForeground );
|
||||||
|
}
|
||||||
|
|
||||||
|
// toolbar button
|
||||||
|
if( toolBarButton ) {
|
||||||
|
return buttonStateColor( c,
|
||||||
|
c.getForeground(),
|
||||||
|
disabledText,
|
||||||
|
null,
|
||||||
|
toolbarHoverForeground,
|
||||||
|
toolbarPressedForeground );
|
||||||
|
}
|
||||||
|
|
||||||
boolean def = isDefaultButton( c );
|
boolean def = isDefaultButton( c );
|
||||||
return def ? defaultForeground : c.getForeground();
|
return buttonStateColor( c,
|
||||||
|
getForegroundBase( c, def ),
|
||||||
|
disabledText,
|
||||||
|
isCustomForeground( c.getForeground() ) ? null : (def ? defaultFocusedForeground : focusedForeground),
|
||||||
|
def ? defaultHoverForeground : hoverForeground,
|
||||||
|
def ? defaultPressedForeground : pressedForeground );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.3 */
|
||||||
|
protected Color getForegroundBase( JComponent c, boolean def ) {
|
||||||
|
// use component foreground if explicitly set
|
||||||
|
Color fg = c.getForeground();
|
||||||
|
if( isCustomForeground( fg ) )
|
||||||
|
return fg;
|
||||||
|
|
||||||
|
return def ? defaultForeground : fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isCustomForeground( Color fg ) {
|
||||||
|
return fg != foreground;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -285,11 +735,85 @@ public class FlatButtonUI
|
|||||||
return new Dimension( helpButtonIcon.getIconWidth(), helpButtonIcon.getIconHeight() );
|
return new Dimension( helpButtonIcon.getIconWidth(), helpButtonIcon.getIconHeight() );
|
||||||
|
|
||||||
Dimension prefSize = super.getPreferredSize( c );
|
Dimension prefSize = super.getPreferredSize( c );
|
||||||
|
if( prefSize == null )
|
||||||
|
return null;
|
||||||
|
|
||||||
// apply minimum width, if not in toolbar and not a icon-only button
|
// increase width when using bold font for default button
|
||||||
if( !isToolBarButton( c ) && !isIconOnlyButton( c ) )
|
prefSize.width += defaultBoldPlainWidthDiff( 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;
|
return prefSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int defaultBoldPlainWidthDiff( JComponent c ) {
|
||||||
|
if( defaultBoldText && isDefaultButton( c ) && c.getFont() instanceof UIResource ) {
|
||||||
|
String text = ((AbstractButton)c).getText();
|
||||||
|
if( text == null || text.isEmpty() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Font font = c.getFont();
|
||||||
|
Font boldFont = font.deriveFont( Font.BOLD );
|
||||||
|
int boldWidth = c.getFontMetrics( boldFont ).stringWidth( text );
|
||||||
|
int plainWidth = c.getFontMetrics( font ).stringWidth( text );
|
||||||
|
if( boldWidth > plainWidth )
|
||||||
|
return boldWidth - plainWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateChanged( ChangeEvent e ) {
|
||||||
|
super.stateChanged( e );
|
||||||
|
|
||||||
|
// if button is in toolbar, repaint button groups
|
||||||
|
AbstractButton b = (AbstractButton) e.getSource();
|
||||||
|
Container parent = b.getParent();
|
||||||
|
if( parent instanceof JToolBar ) {
|
||||||
|
JToolBar toolBar = (JToolBar) parent;
|
||||||
|
ToolBarUI ui = toolBar.getUI();
|
||||||
|
if( ui instanceof FlatToolBarUI )
|
||||||
|
((FlatToolBarUI)ui).repaintButtonGroup( b );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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
|
||||||
|
// a 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( selectAllOnFocusPolicy == null || 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user