Refactor LazyDocumentListener

This commit is contained in:
Reinhard Pointner 2016-08-10 18:43:26 +08:00
parent 7ac41d2c36
commit 4b25cd6983
6 changed files with 59 additions and 100 deletions

View File

@ -29,7 +29,6 @@ import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.event.DocumentEvent;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
@ -192,22 +191,15 @@ public class ListPanel extends JComponent {
editor.setFont(new Font(MONOSPACED, PLAIN, 14));
// update format on change
editor.getDocument().addDocumentListener(new LazyDocumentListener(20) {
private Color valid = editor.getForeground();
private Color invalid = Color.red;
@Override
public void update(DocumentEvent evt) {
try {
String expression = editor.getText().trim();
setFormat(expression.isEmpty() ? null : new ExpressionFormat(expression));
editor.setForeground(valid);
} catch (ScriptException e) {
editor.setForeground(invalid);
}
editor.getDocument().addDocumentListener(new LazyDocumentListener(20, evt -> {
try {
String expression = editor.getText().trim();
setFormat(expression.isEmpty() ? null : new ExpressionFormat(expression));
editor.setForeground(editor.getForeground());
} catch (ScriptException e) {
editor.setForeground(Color.RED);
}
});
}));
return editor;
}

View File

@ -106,17 +106,13 @@ class BindingDialog extends JDialog {
}
// update preview on change
DocumentListener changeListener = new LazyDocumentListener(1000) {
DocumentListener changeListener = new LazyDocumentListener(1000, evt -> {
// ignore lazy events that come in after the window has been closed
if (bindingModel.executor.isShutdown())
return;
@Override
public void update(DocumentEvent evt) {
// ignore lazy events that come in after the window has been closed
if (bindingModel.executor.isShutdown())
return;
bindingModel.setModel(getSampleExpressions(), new MediaBindingBean(getInfoObject(), getMediaFile()));
}
};
bindingModel.setModel(getSampleExpressions(), new MediaBindingBean(getInfoObject(), getMediaFile()));
});
// update example bindings on change
infoTextField.getDocument().addDocumentListener(changeListener);

View File

@ -50,7 +50,6 @@ import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.event.DocumentEvent;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
@ -332,13 +331,9 @@ public class FormatDialog extends JDialog {
editor.setFont(new Font(MONOSPACED, PLAIN, 14));
// update format on change
editor.getDocument().addDocumentListener(new LazyDocumentListener() {
@Override
public void update(DocumentEvent e) {
checkFormatInBackground();
}
});
editor.getDocument().addDocumentListener(new LazyDocumentListener(evt -> {
checkFormatInBackground();
}));
return editor;
}

View File

@ -60,7 +60,6 @@ import javax.swing.RowSorter.SortKey;
import javax.swing.SortOrder;
import javax.swing.border.CompoundBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
@ -219,29 +218,25 @@ class HistoryDialog extends JDialog {
});
// update sequence and element filter on change
filterEditor.getDocument().addDocumentListener(new LazyDocumentListener() {
filterEditor.getDocument().addDocumentListener(new LazyDocumentListener(evt -> {
List<HistoryFilter> filterList = new ArrayList<HistoryFilter>();
@Override
public void update(DocumentEvent e) {
List<HistoryFilter> filterList = new ArrayList<HistoryFilter>();
// filter by all words
for (String word : SPACE.split(filterEditor.getText())) {
filterList.add(new HistoryFilter(word));
}
// use filter on both tables
for (JTable table : Arrays.asList(sequenceTable, elementTable)) {
TableRowSorter sorter = (TableRowSorter) table.getRowSorter();
sorter.setRowFilter(RowFilter.andFilter(filterList));
}
if (sequenceTable.getSelectedRow() < 0 && sequenceTable.getRowCount() > 0) {
// selection lost, maybe due to filtering, auto-select next row
sequenceTable.getSelectionModel().addSelectionInterval(0, 0);
}
// filter by all words
for (String word : SPACE.split(filterEditor.getText())) {
filterList.add(new HistoryFilter(word));
}
});
// use filter on both tables
for (JTable table : Arrays.asList(sequenceTable, elementTable)) {
TableRowSorter sorter = (TableRowSorter) table.getRowSorter();
sorter.setRowFilter(RowFilter.andFilter(filterList));
}
if (sequenceTable.getSelectedRow() < 0 && sequenceTable.getRowCount() > 0) {
// selection lost, maybe due to filtering, auto-select next row
sequenceTable.getSelectionModel().addSelectionInterval(0, 0);
}
}));
// install context menu
sequenceTable.addMouseListener(contextMenuProvider);

View File

@ -35,7 +35,6 @@ import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableColumnModel;
@ -180,13 +179,9 @@ public class SubtitleViewer extends JFrame {
};
// update sequence and element filter on change
editor.getDocument().addDocumentListener(new LazyDocumentListener(0) {
@Override
public void update(DocumentEvent e) {
setTableFilter(editor.getText());
}
});
editor.getDocument().addDocumentListener(new LazyDocumentListener(0, evt -> {
setTableFilter(editor.getText());
}));
return editor;
}

View File

@ -1,60 +1,46 @@
package net.filebot.util.ui;
import java.util.function.Consumer;
import javax.swing.Timer;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public abstract class LazyDocumentListener implements DocumentListener {
private DocumentEvent lastEvent;
public class LazyDocumentListener implements DocumentListener {
private Timer timer;
public LazyDocumentListener() {
this(200);
private DocumentEvent lastEvent = null;
public LazyDocumentListener(Consumer<DocumentEvent> handler) {
this(200, handler);
}
public LazyDocumentListener(int delay) {
if (delay >= 0) {
timer = new Timer(delay, evt -> {
update(lastEvent);
// we don't need it anymore
lastEvent = null;
});
timer.setRepeats(false);
}
}
public void defer(DocumentEvent e) {
lastEvent = e;
if (timer != null) {
// defer update
timer.restart();
} else {
// update immediately
update(lastEvent);
}
public LazyDocumentListener(int delay, Consumer<DocumentEvent> handler) {
timer = new Timer(delay, evt -> {
handler.accept(lastEvent);
lastEvent = null;
});
timer.setRepeats(false);
}
@Override
public void changedUpdate(DocumentEvent e) {
defer(e);
public void changedUpdate(DocumentEvent evt) {
lastEvent = evt;
timer.restart();
}
@Override
public void insertUpdate(DocumentEvent e) {
defer(e);
public void insertUpdate(DocumentEvent evt) {
lastEvent = evt;
timer.restart();
}
@Override
public void removeUpdate(DocumentEvent e) {
defer(e);
public void removeUpdate(DocumentEvent evt) {
lastEvent = evt;
timer.restart();
}
public abstract void update(DocumentEvent e);
}