Skip to content

Commit 1c4789b

Browse files
committed
LoggingPanel: add gui for text filtering
1 parent f510812 commit 1c4789b

File tree

2 files changed

+157
-11
lines changed

2 files changed

+157
-11
lines changed

src/main/java/org/scijava/ui/swing/console/LoggingPanel.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
package org.scijava.ui.swing.console;
3232

3333
import java.awt.*;
34+
import java.util.function.Predicate;
3435

3536
import javax.swing.*;
3637
import javax.swing.text.AttributeSet;
@@ -42,26 +43,22 @@
4243

4344
import net.miginfocom.swing.MigLayout;
4445

45-
import org.scijava.console.OutputListener;
4646
import org.scijava.log.IgnoreAsCallingClass;
47+
import org.scijava.log.LogLevel;
4748
import org.scijava.log.LogListener;
4849
import org.scijava.log.LogMessage;
4950
import org.scijava.log.LogService;
5051
import org.scijava.log.Logger;
51-
import org.scijava.log.LogLevel;
5252
import org.scijava.thread.ThreadService;
5353
import org.scijava.ui.swing.StaticSwingUtils;
5454

5555
/**
56-
* LoggingPanel can display log message and console output as a list, and
57-
* provides convenient ways for the user to filter this list.
58-
* LoggingPanel implements {@link LogListener} and {@link OutputListener}, that
59-
* way it can receive log message and console output from {@link LogService},
60-
* {@link Logger} and {@link org.scijava.console.ConsoleService}
56+
* {@link LoggingPanel} can displays log messages, and provides convenient ways
57+
* for the user to filter this list. LoggingPanel can receive log messages from
58+
* {@link LogService} and {@link Logger}.
6159
*
6260
* @see LogService
6361
* @see Logger
64-
* @see org.scijava.console.ConsoleService
6562
* @author Matthias Arzt
6663
*/
6764
@IgnoreAsCallingClass
@@ -75,12 +72,14 @@ public class LoggingPanel extends JPanel implements LogListener
7572
private static final AttributeSet STYLE_TRACE = normal(Color.GRAY);
7673
private static final AttributeSet STYLE_OTHERS = normal(Color.GRAY);
7774

75+
private final TextFilterField textFilter = new TextFilterField(" Text Search (Alt-F)");
7876
private JTextPane textPane;
7977
private JScrollPane scrollPane;
8078

8179
private StyledDocument doc;
8280

8381
private final LogFormatter formatter = new LogFormatter();
82+
private Predicate<String> filter = text -> true;
8483

8584
private final ThreadService threadService;
8685

@@ -103,6 +102,8 @@ public void messageLogged(LogMessage message) {
103102
// -- Helper methods --
104103

105104
private void appendText(final String text, final AttributeSet style) {
105+
if(!filter.test(text)) return;
106+
106107
threadService.queue(new Runnable() {
107108

108109
@Override
@@ -120,8 +121,14 @@ public void run() {
120121
});
121122
}
122123

123-
private synchronized void initGui() {
124-
setLayout(new MigLayout("inset 0", "[grow,fill]", "[grow,fill,align top]"));
124+
// -- Helper methods --
125+
126+
private void initGui() {
127+
128+
setLayout(new MigLayout("insets 0", "[grow]", "[][grow]"));
129+
130+
textFilter.setChangeListener(this::updateFilter);
131+
add(textFilter.getComponent(), "grow, wrap");
125132

126133
textPane = new JTextPane();
127134
textPane.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
@@ -148,7 +155,11 @@ private synchronized void initGui() {
148155
scrollPane.getHorizontalScrollBar().setUnitIncrement(charWidth);
149156
scrollPane.getVerticalScrollBar().setUnitIncrement(2 * lineHeight);
150157

151-
add(scrollPane);
158+
add(scrollPane, "grow");
159+
}
160+
161+
private void updateFilter() {
162+
filter = textFilter.getFilter();
152163
}
153164

154165
private static AttributeSet getLevelStyle(int i) {
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* #%L
3+
* SciJava UI components for Java Swing.
4+
* %%
5+
* Copyright (C) 2010 - 2017 Board of Regents of the University of
6+
* Wisconsin-Madison.
7+
* %%
8+
* Redistribution and use in source and binary forms, with or without
9+
* modification, are permitted provided that the following conditions are met:
10+
*
11+
* 1. Redistributions of source code must retain the above copyright notice,
12+
* this list of conditions and the following disclaimer.
13+
* 2. Redistributions in binary form must reproduce the above copyright notice,
14+
* this list of conditions and the following disclaimer in the documentation
15+
* and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
21+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27+
* POSSIBILITY OF SUCH DAMAGE.
28+
* #L%
29+
*/
30+
31+
package org.scijava.ui.swing.console;
32+
33+
import java.awt.*;
34+
import java.util.function.Predicate;
35+
36+
import javax.swing.*;
37+
import javax.swing.border.EmptyBorder;
38+
import javax.swing.event.DocumentEvent;
39+
import javax.swing.event.DocumentListener;
40+
41+
/**
42+
* {@link TextFilterField} provides a {@link JTextField} and derives text filter
43+
* from the content.
44+
*
45+
* @author Matthias Arzt
46+
*/
47+
class TextFilterField {
48+
49+
private final JTextField textField = new JTextField();
50+
51+
private JLabel prompt = new JLabel();
52+
53+
private Predicate<String> filter = null;
54+
55+
private Runnable changeListener = null;
56+
57+
// -- constructor --
58+
59+
TextFilterField(String textForPrompt) {
60+
initPrompt(textForPrompt);
61+
textField.getDocument().addDocumentListener(new DocumentListener() {
62+
63+
@Override
64+
public void insertUpdate(DocumentEvent documentEvent) {
65+
onUserInputChanged();
66+
}
67+
68+
@Override
69+
public void removeUpdate(DocumentEvent documentEvent) {
70+
onUserInputChanged();
71+
}
72+
73+
@Override
74+
public void changedUpdate(DocumentEvent documentEvent) {
75+
onUserInputChanged();
76+
}
77+
});
78+
}
79+
80+
// -- TextFilterField methods --
81+
82+
public JTextField getComponent() {
83+
return textField;
84+
}
85+
86+
public void setChangeListener(Runnable changeListener) {
87+
this.changeListener = changeListener;
88+
}
89+
90+
public Predicate<String> getFilter() {
91+
if (filter == null) filter = calculateFilter();
92+
return filter;
93+
}
94+
95+
// -- Helper methods --
96+
97+
private Predicate<String> calculateFilter() {
98+
String text = textField.getText();
99+
final String[] words = text.split(" ");
100+
return s -> {
101+
for (String word : words)
102+
if (!s.contains(word)) return false;
103+
return true;
104+
};
105+
}
106+
107+
private void onUserInputChanged() {
108+
filter = null;
109+
updatePromptVisibility();
110+
notifyChangeListener();
111+
}
112+
113+
private void notifyChangeListener() {
114+
if (changeListener != null) changeListener.run();
115+
}
116+
117+
private void initPrompt(String text) {
118+
prompt.setText(text);
119+
prompt.setFont(textField.getFont().deriveFont(Font.ITALIC));
120+
prompt.setForeground(changeAlpha(textField.getForeground(), 128));
121+
prompt.setBorder(new EmptyBorder(textField.getInsets()));
122+
prompt.setHorizontalAlignment(JLabel.LEADING);
123+
textField.setLayout(new BorderLayout());
124+
textField.add(prompt);
125+
updatePromptVisibility();
126+
}
127+
128+
private static Color changeAlpha(Color color, int alpha) {
129+
return new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
130+
}
131+
132+
private void updatePromptVisibility() {
133+
prompt.setVisible(textField.getDocument().getLength() == 0);
134+
}
135+
}

0 commit comments

Comments
 (0)