22
33import com .xwintop .xJavaFxTool .services .debugTools .SwitchHostsToolService ;
44import com .xwintop .xJavaFxTool .view .debugTools .SwitchHostsToolView ;
5-
6- import java .net .URL ;
7- import java .util .ResourceBundle ;
8-
5+ import javafx .concurrent .Task ;
96import javafx .event .ActionEvent ;
107import javafx .fxml .FXML ;
118import javafx .scene .control .TreeItem ;
129import lombok .Getter ;
1310import lombok .Setter ;
1411import lombok .extern .slf4j .Slf4j ;
12+ import org .fxmisc .richtext .CodeArea ;
13+ import org .fxmisc .richtext .LineNumberFactory ;
14+ import org .fxmisc .richtext .model .StyleSpans ;
15+ import org .fxmisc .richtext .model .StyleSpansBuilder ;
16+
17+ import java .net .URL ;
18+ import java .time .Duration ;
19+ import java .util .Collection ;
20+ import java .util .Collections ;
21+ import java .util .Optional ;
22+ import java .util .ResourceBundle ;
23+ import java .util .concurrent .ExecutorService ;
24+ import java .util .concurrent .Executors ;
25+ import java .util .regex .Matcher ;
26+ import java .util .regex .Pattern ;
27+
1528/**
1629 * @ClassName: SwitchHostsToolController
1730 * @Description: 切换Hosts工具
2336@ Setter
2437@ Slf4j
2538public class SwitchHostsToolController extends SwitchHostsToolView {
26-
2739 private SwitchHostsToolService switchHostsToolService = new SwitchHostsToolService (this );
2840
41+ private static final String KEYWORD_PATTERN = "([1-9]|[1-9]\\ d|1\\ d{2}|2[0-4]\\ d|25[0-5])(\\ .(\\ d|[1-9]\\ d|1\\ d{2}|2[0-4]\\ d|25[0-5])){3}\\ b" ;
42+ private static final String COMMENT_PATTERN = "#[^\n ]*" ;
43+ private static final Pattern PATTERN = Pattern .compile ("(?<KEYWORD>" + KEYWORD_PATTERN + ")" + "|(?<COMMENT>" + COMMENT_PATTERN + ")" );
44+ private ExecutorService executor ;
45+
2946 @ Override
3047 public void initialize (URL location , ResourceBundle resources ) {
3148 try {
3249 initView ();
3350 initEvent ();
3451 initService ();
3552 } catch (Exception e ) {
36- e .printStackTrace ();
37- log .error (e .getMessage ());
53+ log .error ("加载报错" , e );
3854 }
3955 }
4056
4157 private void initView () {
58+ executor = Executors .newSingleThreadExecutor ();
59+ hostTextArea = new CodeArea ();
60+ hostTextArea .setParagraphGraphicFactory (LineNumberFactory .get (hostTextArea ));
61+ hostTextArea .richChanges ()
62+ .filter (ch -> !ch .getInserted ().equals (ch .getRemoved ())) // XXX
63+ .successionEnds (Duration .ofMillis (500 ))
64+ .supplyTask (this ::computeHighlightingAsync )
65+ .awaitLatest (hostTextArea .richChanges ())
66+ .filterMap (t -> {
67+ if (t .isSuccess ()) {
68+ return Optional .of (t .get ());
69+ } else {
70+ t .getFailure ().printStackTrace ();
71+ return Optional .empty ();
72+ }
73+ })
74+ .subscribe (this ::applyHighlighting );
75+
4276 TreeItem <String > treeItem = new TreeItem <String >("Hosts" );
4377 treeItem .setExpanded (true );
4478 hostFileTreeView .setRoot (treeItem );
@@ -82,4 +116,38 @@ private void editAction(ActionEvent event) throws Exception {
82116 @ FXML
83117 private void deleteAction (ActionEvent event ) {
84118 }
119+
120+ private Task <StyleSpans <Collection <String >>> computeHighlightingAsync () {
121+ String text = hostTextArea .getText ();
122+ Task <StyleSpans <Collection <String >>> task = new Task <StyleSpans <Collection <String >>>() {
123+ @ Override
124+ protected StyleSpans <Collection <String >> call () throws Exception {
125+ return computeHighlighting (text );
126+ }
127+ };
128+ executor .execute (task );
129+ return task ;
130+ }
131+
132+ private void applyHighlighting (StyleSpans <Collection <String >> highlighting ) {
133+ hostTextArea .setStyleSpans (0 , highlighting );
134+ }
135+
136+ private static StyleSpans <Collection <String >> computeHighlighting (String text ) {
137+ Matcher matcher = PATTERN .matcher (text );
138+ int lastKwEnd = 0 ;
139+ StyleSpansBuilder <Collection <String >> spansBuilder
140+ = new StyleSpansBuilder <>();
141+ while (matcher .find ()) {
142+ String styleClass =
143+ matcher .group ("KEYWORD" ) != null ? "keyword" :
144+ matcher .group ("COMMENT" ) != null ? "comment" :
145+ null ; /* never happens */ assert styleClass != null ;
146+ spansBuilder .add (Collections .emptyList (), matcher .start () - lastKwEnd );
147+ spansBuilder .add (Collections .singleton (styleClass ), matcher .end () - matcher .start ());
148+ lastKwEnd = matcher .end ();
149+ }
150+ spansBuilder .add (Collections .emptyList (), text .length () - lastKwEnd );
151+ return spansBuilder .create ();
152+ }
85153}
0 commit comments