Verwenden von DocumentFilter.filterbypass
-
27-10-2019 - |
Frage
Ich möchte eine solche Methode auf meinem haben DocumentFilter
public void replaceUpdate(int offset, int length, String text) {
try {
super.replace(byPass, offset, length, text, null);
} catch (BadLocationException ex) {
//error
}
}
Um eine Instanz von Filterbypass (Bypass on Method oben) zu erhalten, muss ich von der überschriebenen Methode InsertString erhalten:
private FilterBypass byPass;
@Override
public void insertString(DocumentFilter.FilterBypass fb,
int offset, String string, AttributeSet att)
throws BadLocationException {
byPass = fb;
//some stuff here
super.insertString(fb, offset, string, att);
}
Aber das verursacht mir einige Probleme. Kann jemand eine andere Möglichkeit vorschlagen, eine Filterbypass zu bekommen? Ich kann keinen Weg finden, einen Verweis auf die zu bekommen FilterBypass
anders.
Wenn ich seine Methoden außer Kraft setzen sollte, wie sollte es sein?
Lösung
Hier finden Sie beispielsweise eine SSCCE mit einem Documentfilter, der den Benutzer daran hindert, Nummern in das Dokument einzugeben, aber den Schwung -Timer dies ermöglicht.
import java.awt.event.*;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.text.*;
public class DocFilterPanel extends JPanel {
private JTextArea textArea = new JTextArea(12, 50);
private MyDocFilter myDocFilter = new MyDocFilter();
public DocFilterPanel() {
((PlainDocument) textArea.getDocument()).setDocumentFilter(myDocFilter);
int vsbPolicy = JScrollPane.VERTICAL_SCROLLBAR_ALWAYS;
int hsbPolicy = JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED;
add(new JScrollPane(textArea, vsbPolicy , hsbPolicy));
int timerDelay = 1000;
new Timer(timerDelay , new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myDocFilter.setFilter(false);
textArea.append("12345\n");
myDocFilter.setFilter(true);
}
}).start();
}
private static void createAndShowGui() {
DocFilterPanel docFilterPanel = new DocFilterPanel();
JFrame frame = new JFrame("DocFilterTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(docFilterPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyDocFilter extends DocumentFilter {
private static final String REMOVE_REGEX = "\\d";
private boolean filter = true;
public boolean isFilter() {
return filter;
}
public void setFilter(boolean filter) {
this.filter = filter;
}
@Override
public void insertString(FilterBypass fb, int offset, String text,
AttributeSet attr) throws BadLocationException {
if (filter) {
text = text.replaceAll(REMOVE_REGEX, "");
}
super.insertString(fb, offset, text, attr);
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text,
AttributeSet attrs) throws BadLocationException {
if (filter) {
text = text.replaceAll(REMOVE_REGEX, "");
}
super.replace(fb, offset, length, text, attrs);
}
}
Andere Tipps
Ich mochte die Lösung von @Hovercraft, aber es gab mir Probleme mit Parallelität. Ich habe dies gelöst, indem ich den Filter synchronisierte, der im Textbereich umschaltete. So was:
synchronized (textArea) {
myDocFilter.setFilter(false);
textArea.append("12345\n");
myDocFilter.setFilter(true);
}