From 7a55041dd8940f529ab47284ee722e286b2e47e6 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Tue, 22 Dec 2020 14:28:34 +0100 Subject: [PATCH] New: SearchBar --- src/be/nikiroo/utils/ui/SearchBar.java | 148 +++++++++++++++++++++++ src/be/nikiroo/utils/ui/clear-16x16.png | Bin 0 -> 1232 bytes src/be/nikiroo/utils/ui/search-16x16.png | Bin 0 -> 1274 bytes 3 files changed, 148 insertions(+) create mode 100644 src/be/nikiroo/utils/ui/SearchBar.java create mode 100644 src/be/nikiroo/utils/ui/clear-16x16.png create mode 100644 src/be/nikiroo/utils/ui/search-16x16.png diff --git a/src/be/nikiroo/utils/ui/SearchBar.java b/src/be/nikiroo/utils/ui/SearchBar.java new file mode 100644 index 0000000..ffbc78b --- /dev/null +++ b/src/be/nikiroo/utils/ui/SearchBar.java @@ -0,0 +1,148 @@ +package be.nikiroo.utils.ui; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.io.IOException; +import java.io.InputStream; + +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; + +import be.nikiroo.utils.IOUtils; + +/** + * A generic search/filter bar. + * + * @author niki + */ +public class SearchBar extends ListenerPanel { + static private final long serialVersionUID = 1L; + static private ImageIcon searchIcon; + static private ImageIcon clearIcon; + + private JButton search; + private JTextField text; + private JButton clear; + + private boolean realTime; + + /** + * Create a new {@link SearchBar}. + */ + public SearchBar() { + setLayout(new BorderLayout()); + + // TODO: make an option to change the default setting here: + // (can already be manually toggled by the user) + realTime = true; + + if (searchIcon == null) + searchIcon = getIcon("search-16x16.png"); + if (clearIcon == null) + clearIcon = getIcon("clear-16x16.png"); + + search = new JButton(searchIcon); + if (searchIcon == null) { + search.setText("[s]"); + } + UIUtils.setButtonPressed(search, realTime); + search.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + realTime = !realTime; + UIUtils.setButtonPressed(search, realTime); + text.requestFocus(); + + if (realTime) { + fireActionPerformed(getText()); + } + } + }); + + text = new JTextField(); + text.addKeyListener(new KeyAdapter() { + @Override + public void keyTyped(final KeyEvent e) { + super.keyTyped(e); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + boolean empty = (text.getText().isEmpty()); + clear.setVisible(!empty); + + if (realTime) { + fireActionPerformed(getText()); + } + } + }); + } + }); + text.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (!realTime) { + fireActionPerformed(getText()); + } + } + }); + + clear = new JButton(clearIcon); + if (clearIcon == null) { + clear.setText("(c)"); + } + clear.setBackground(text.getBackground()); + clear.setVisible(false); + clear.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + text.setText(""); + clear.setVisible(false); + text.requestFocus(); + + fireActionPerformed(getText()); + } + }); + + add(search, BorderLayout.WEST); + add(text, BorderLayout.CENTER); + add(clear, BorderLayout.EAST); + } + + /** + * Return the current text displayed by this {@link SearchBar}, or an empty + * {@link String} if none. + * + * @return the text, cannot be NULL + */ + public String getText() { + // Should usually not be NULL, but not impossible + String text = this.text.getText(); + return text == null ? "" : text; + } + + @Override + public void setEnabled(boolean enabled) { + search.setEnabled(enabled); + clear.setEnabled(enabled); + text.setEnabled(enabled); + super.setEnabled(enabled); + } + + private ImageIcon getIcon(String name) { + InputStream in = IOUtils.openResource(SearchBar.class, name); + if (in != null) { + try { + return new ImageIcon(IOUtils.toByteArray(in)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return null; + } +} diff --git a/src/be/nikiroo/utils/ui/clear-16x16.png b/src/be/nikiroo/utils/ui/clear-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..3ea2622aa1ef1f9ad0b85322e5388be709d5c678 GIT binary patch literal 1232 zcmZuxc~H|w6y9(I0Vz0A4N){{?u3wEViF`Gas?743|Anc&Ts{dSfMl^n5t0_E9z+R z06FYbtL@kpYAXy-og%1XQQ}k-D4?J~O+f|$k*nr)?SGx=?!5Qy`}TV?Z+G7A(deiM zHy5f4LdZ?63X8?)@!l5MW6u@3$6;{T9;^vQ=-Nrwzf&A>OiNS6Y7pAXM#x-*&^)Hh zR)lg1ghrAPQj{aKJiDqXCIBJ3_0f^>N-Pj90Pz+Ao1btd7OnvJyaD-Z5R8Fn6nvlA zgoEJo6a+s#<39rW{*(MZ;64Fg<(QxkZ~^S!AR8d(&1C+_uox%yTLT~U1a%Dr^$bZ~ zO$z`dQ#Mi8b3w}k&ds}mC;j3{Ag00pwk5jmhIn{t1pqM%#Dgw+^*7=f-~x!O^P%-E z8|#}z{jWviAZ@xwKXKltd&C34cX%fBMtem0CHb`$_UTK${nIf3900*zAZr`sAFmcZ zot6Ov%me>9D6ahC6PqMx?H2*?pMrl$6-%4KYwD2#@H#+vvDr(jXMF!~-M=B{`T%Fg zK1R~6rCI~Kaaaw&zH9raqLool#=bMd{&kX?SLT_R#rU?Hbr%@5!z)uwtojj7CvaW> zvtfMsC#R`}SJ`dAY6V8)l=u0z)fX)EFCVh%tn7!tZU=VD4DDjas_OPtl@I7OLs-VT zWfS(;v;ca1djLD$z1sq?4Pe87jd{zKbg*!D(P85kr+KM*Dk1ie%Cq+!C_ZR56(3on zH*lB?Dw~sbwkkg_*I>*GNH@sD1V<{@9V$snO-)SNqK?xB1_p}#*Trp4(nLmvhJ?ta z(r}e3C@9F!&(DX?_lrsN_mfKqk$}sk(`b}cG`>dX!{hQ~{>$i0SLa0zWb#UtZY7oK z&0spZEx}D<@8Y&Je6u@^vxFriujV-{^LC=~yq-G^;k_fq*r@l-`2Qozynnwrfh^l+ zK5#H2-8!zfTWcBAk+d&Iw+2|Ov7`j+tASVBNEjy!cBF){ITLxqz+A4wh7K$Z?VNo( zx|I~(^R{Tu+$2>bqblZPIo=GsmWxVro3@mY+9Hqa{x!ghBz@c4@G@?fTX_td!` zCY+C|d+WzlQ7OqPO>bl7p1t8233-+aHy3iID3h)($4WMBR4VVc3HaY#&7|xc9T{6e zy+fhgW>r*dN$Mp6Tv6?#h~RMfsbYL)mQkrQrl%P7inJU(1|%UQgpiO43BPy=p^(WG zghW6{6a-OZFi8KC@NrhUA)^2%h_PBMB&6|Tf2>nTWCB8r7Zb{S{1qXjRz`)@gd`vO E2T8{XCIA2c literal 0 HcmV?d00001 diff --git a/src/be/nikiroo/utils/ui/search-16x16.png b/src/be/nikiroo/utils/ui/search-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..0164b31df14111b448b3b008d87a9cff5e708808 GIT binary patch literal 1274 zcmah}YfO`86n?QVKp--}LF<583Y1~BZ9qcfM6kqm0x3{LXc?E5ixRnLnV>OthRe7J z8a8BHB0(wPUYRl&&;b<~*CKalX`x&?AY2TIn{F99-G1%Y-sJn<_d7Y~d7kr}H(xG0 z;F8%<+);#(8H>pXg56yA7-8T|A|DHeO+Vh--y5M9MJ9hn8^AZ7&kXWM=#CRYqD+K7 zKuGi}LTMC)wxSTCmm*}HQt?yZIfRb*vHdu{kkH%P+uGWyR4QdM*%BW22*x55dqB5jQOd;*jZh`V5hu$%ste z+1UY1*CL5WQr7nN_Tu8=S+R_D|1so%c(;t~fXCG~Km#ZLZE$dK&{0@!msXvTki+ij_FzsZh^(xwZ|{-{ zMOiU%3E*B#L2*dhJ?{17mX;Qf4d#H`;<~!0&z?&p66kAaXlQI~Y;tn)@bEDAVYcpq zW(k7=ba(TAmw}_LxxPi4vZLe<&(rQ>J-2RfDVhe<-kw3X6{{PI|{@H?|x%Ii_b~ zg*m16fB_)An9G+Kvb=;sANVj%VTRp8$i!0j=%KO-8weT-S^mC;YCU}`gw=e&zJVG8 z7Q>rkGsTaB#R&`vo{NeRVdDJBH*6z5zlXW#!2d)d%DtAzy_@rWM^?>oSEgueQT#(g z=d0Qu<+Fvh#GdHA39o3)^Pyldot}E+J#YMU^ORU#>Y4cNQ;*w8Rj4ROtIRmCKE->P zUiif03|k~0ygfAeex#(O^wp%?UO>8kVYz-LakiQ3mG~7~g4h?>B%)9@;9stww`FFT zUB37pq;{Shx0Dh`36W;kmq^&j#67z6=Zti3sL8%d6PxDx@@Z&W#<{HG z=Ici3DD=H56hsSS>HM3qupt_SMj=z&$rKL`jY4