-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathChainedDocumentFilter.java
More file actions
144 lines (130 loc) · 3.46 KB
/
ChainedDocumentFilter.java
File metadata and controls
144 lines (130 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import java.awt.Component;
import java.awt.KeyboardFocusManager;
import java.awt.Toolkit;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.text.*;
/**
* A single DocumentFilter can be set on an AbstractDocument. There may be
* times when you wish to perform multiple filtering of the data as it is
* added to a Document. By extending the ChainedDocumentFilter instead of
* the DocumentFilter you will receive added flexibility in that the
* filter can be used stand alone or with other ChainedDocumentFilters.
*
* Whenever one filter step fails, the chaining of the filters is also
* terminated. In this case is it recommended you invoke the
* provideErrorFeedback() method to provide user feedback.
*/
abstract class ChainedDocumentFilter extends DocumentFilter
{
private DocumentFilter filter;
/**
* Standard constructor for standalone usage
*/
public ChainedDocumentFilter()
{
this( null );
}
/**
* Constructor used when further filtering is required after this
* filter has been applied.
*/
public ChainedDocumentFilter(DocumentFilter filter)
{
setFilter( filter );
}
/**
* Get the next filter in the chain.
*
* @return the next filter in the chain
*/
public DocumentFilter getFilter()
{
return filter;
}
/**
* Set the next filter in the chain
*
* @param filter
*/
public void setFilter(DocumentFilter filter)
{
this.filter = filter;
}
/**
* Install this filter on the AbstractDocument
*
* @param components the text components that will use this filter
*/
public void installFilter(JTextComponent... components)
{
for (JTextComponent component : components)
{
Document doc = component.getDocument();
if (doc instanceof AbstractDocument)
{
((AbstractDocument)doc).setDocumentFilter( this );
}
}
}
/**
* Remove this filter from the AbstractDocument
*
* @param compoents remove the filter from the specified text components
*/
public void uninstallFilter(JTextComponent... components)
{
for (JTextComponent component : components)
{
Document doc = component.getDocument();
if (doc instanceof AbstractDocument)
{
((AbstractDocument)doc).setDocumentFilter( null );
}
}
}
/**
* Provide appropriate LAF feedback when a filter error occurs.
*/
public void provideErrorFeedback()
{
LookAndFeel laf = UIManager.getLookAndFeel();
if (laf == null)
{
Toolkit.getDefaultToolkit().beep();
}
else
{
KeyboardFocusManager fm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
Component component = fm.getFocusOwner();
laf.provideErrorFeedback( component );
}
}
@Override
public void insertString(FilterBypass fb, int offs, String str, AttributeSet a)
throws BadLocationException
{
if (filter == null)
super.insertString(fb, offs, str, a);
else
filter.insertString(fb, offs, str, a);
}
@Override
public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a)
throws BadLocationException
{
if (filter == null)
super.replace(fb, offs, length, str, a);
else
filter.replace(fb, offs, length, str, a);
}
@Override
public void remove(DocumentFilter.FilterBypass fb, int offset, int length)
throws BadLocationException
{
if (filter == null)
super.remove(fb, offset, length);
else
filter.remove(fb, offset, length);
}
}