|
35 | 35 | import java.awt.Color; |
36 | 36 | import java.awt.Component; |
37 | 37 | import java.awt.Dimension; |
| 38 | +import java.awt.Font; |
38 | 39 | import java.awt.GridLayout; |
39 | 40 | import java.awt.Window; |
40 | 41 | import java.awt.event.FocusEvent; |
|
55 | 56 | import javax.swing.DefaultListModel; |
56 | 57 | import javax.swing.ImageIcon; |
57 | 58 | import javax.swing.JButton; |
| 59 | +import javax.swing.JCheckBox; |
58 | 60 | import javax.swing.JDialog; |
59 | 61 | import javax.swing.JLabel; |
60 | 62 | import javax.swing.JList; |
|
65 | 67 | import javax.swing.ScrollPaneConstants; |
66 | 68 | import javax.swing.SwingConstants; |
67 | 69 | import javax.swing.SwingUtilities; |
68 | | -import javax.swing.border.CompoundBorder; |
69 | 70 | import javax.swing.border.EmptyBorder; |
70 | | -import javax.swing.border.MatteBorder; |
71 | 71 | import javax.swing.event.DocumentEvent; |
72 | 72 | import javax.swing.event.DocumentListener; |
73 | 73 |
|
@@ -96,7 +96,7 @@ public class SwingSearchBar extends JTextField { |
96 | 96 | private static final int MAX_RESULTS = 8; |
97 | 97 |
|
98 | 98 | private static final Color SELECTED_COLOR = new Color(70, 152, 251); |
99 | | - private static final Color HEADER_COLOR = new Color(128, 128, 128); |
| 99 | + private static final Color HEADER_COLOR = new Color(234, 234, 234); |
100 | 100 | private static final int ICON_SIZE = 16; |
101 | 101 | private static final int PAD = 5; |
102 | 102 |
|
@@ -249,25 +249,38 @@ private class SwingSearchPanel extends JPanel { |
249 | 249 |
|
250 | 250 | private final SearchOperation operation; |
251 | 251 | private final Map<Class<?>, SearchEvent> allResults; |
| 252 | + private final Map<Class<?>, JCheckBox> headerCheckboxes; |
252 | 253 | private final JList<SearchResult> resultsList; |
253 | 254 |
|
254 | 255 | public SwingSearchPanel() { |
255 | 256 | operation = searchService.search(// |
256 | 257 | event -> threadService.queue(() -> update(event))); |
257 | 258 |
|
258 | 259 | allResults = new HashMap<>(); |
| 260 | + headerCheckboxes = new HashMap<>(); |
259 | 261 |
|
260 | 262 | resultsList = new JList<>(); |
261 | 263 | resultsList.setCellRenderer((list, value, index, isSelected, |
262 | 264 | cellHasFocus) -> { |
263 | 265 | if (isHeader(value)) { |
264 | | - final JLabel header = new JLabel(value.name()); |
265 | | - header.setBorder(new CompoundBorder(// |
266 | | - new EmptyBorder(PAD, PAD, 0, PAD), |
267 | | - new MatteBorder(0, 0, 1, 0, Color.gray))); |
268 | | - header.setBackground(HEADER_COLOR); |
269 | | - header.setEnabled(false); |
270 | | - return header; |
| 266 | + final Searcher searcher = ((SearchResultHeader) value).searcher(); |
| 267 | + final JCheckBox headerBox = // |
| 268 | + new JCheckBox(searcher.title(), searcher.enabled()); |
| 269 | + headerBox.setFont(smaller(headerBox.getFont(), 2)); |
| 270 | + headerBox.setBackground(HEADER_COLOR); |
| 271 | + headerCheckboxes.put(searcher.getClass(), headerBox); |
| 272 | + |
| 273 | + final JPanel headerInnerPane = new JPanel(); |
| 274 | + headerInnerPane.setLayout(new GridLayout(1, 1)); |
| 275 | + headerInnerPane.add(headerBox); |
| 276 | + headerInnerPane.setBackground(HEADER_COLOR); |
| 277 | + |
| 278 | + final JPanel headerOuterPane = new JPanel(); |
| 279 | + headerOuterPane.setLayout(new GridLayout(1, 1)); |
| 280 | + headerOuterPane.add(headerInnerPane); |
| 281 | + headerOuterPane.setBackground(list.getBackground()); |
| 282 | + headerOuterPane.setBorder(new EmptyBorder(PAD, 0, 0, 0)); |
| 283 | + return headerOuterPane; |
271 | 284 | } |
272 | 285 | final JPanel item = new JPanel(); |
273 | 286 | item.setLayout(new BoxLayout(item, BoxLayout.X_AXIS)); |
@@ -303,6 +316,16 @@ public SwingSearchPanel() { |
303 | 316 | if (lse.getValueIsAdjusting()) return; |
304 | 317 | final SearchResult result = resultsList.getSelectedValue(); |
305 | 318 | if (result == null || isHeader(result)) { |
| 319 | + if (result != null) { |
| 320 | + final JCheckBox checkBox = headerCheckboxes.get( |
| 321 | + ((SearchResultHeader) result).searcher().getClass()); |
| 322 | + System.out.println("GOT A CHECKBOX: " + checkBox); |
| 323 | + checkBox.setSelected(!checkBox.isSelected()); |
| 324 | + checkBox.repaint(); |
| 325 | + resultsList.repaint(); |
| 326 | + System.out.println("TOGGLED IT: state -> " + checkBox.isSelected()); |
| 327 | + } |
| 328 | + |
306 | 329 | // clear details pane |
307 | 330 | detailsTitle.setText(""); |
308 | 331 | detailsProps.removeAll(); |
@@ -392,6 +415,10 @@ private int rowCount() { |
392 | 415 | return resultsList.getModel().getSize(); |
393 | 416 | } |
394 | 417 |
|
| 418 | + private Font smaller(Font font, int decrement) { |
| 419 | + return new Font(font.getFontName(), font.getStyle(), font.getSize() - decrement); |
| 420 | + } |
| 421 | + |
395 | 422 | /** Executes the default search action. */ |
396 | 423 | private void execute() { |
397 | 424 | assertDispatchThread(); |
@@ -425,7 +452,7 @@ private void rebuild() { |
425 | 452 | .limit(MAX_RESULTS).collect(Collectors.toList()); |
426 | 453 |
|
427 | 454 | // Add section header. |
428 | | - listModel.addElement(new SearchResultHeader(searcher.title())); |
| 455 | + listModel.addElement(new SearchResultHeader(searcher)); |
429 | 456 |
|
430 | 457 | // Add results as entries. |
431 | 458 | for (final SearchResult result : results) { |
@@ -514,15 +541,19 @@ public void keyPressed(final KeyEvent e) { |
514 | 541 | /** A header dividing search result entries. */ |
515 | 542 | private class SearchResultHeader implements SearchResult { |
516 | 543 |
|
517 | | - private final String title; |
| 544 | + private final Searcher searcher; |
| 545 | + |
| 546 | + public SearchResultHeader(final Searcher searcher) { |
| 547 | + this.searcher = searcher; |
| 548 | + } |
518 | 549 |
|
519 | | - public SearchResultHeader(final String title) { |
520 | | - this.title = title; |
| 550 | + public Searcher searcher() { |
| 551 | + return searcher; |
521 | 552 | } |
522 | 553 |
|
523 | 554 | @Override |
524 | 555 | public String name() { |
525 | | - return title; |
| 556 | + return searcher.title(); |
526 | 557 | } |
527 | 558 |
|
528 | 559 | @Override |
|
0 commit comments