JavaFX实现Hosts管理工具

目前很多时候需要绑定hosts,来进行相关的测试,hosts的路径虽然是固定的,但是一般隐藏的比较深,那么如何快速修改hosts呢?这里利用JavaFX做了一个hosts管理工具,目前可以实现IP高亮,IP自动检测,监听Ctrl+S进行保存。

下载体验

https://gitee.com/acacc/JHostsManager

技术栈

  • JavaFX
  • RichTextEditor
  • Java 1.8+

支持

  • 高亮显示IP、注释等内容
  • 支持Ctrl+S进行保存

即将支持

  • 多个hosts配置支持
  • 远程hosts文件更新
  • windows下exe文件安装

部分实现

IP注释高亮

这里利用正则去识别IP与注释,并且利用RichTextEditor来进行显示,JavaFX可以加载css文件

codeArea = new CodeArea();
        codeArea.setParagraphGraphicFactory(LineNumberFactory.get(codeArea));
        codeArea.richChanges()
                .filter(ch -> !ch.getInserted().equals(ch.getRemoved())) // XXX
                .successionEnds(Duration.ofMillis(500))
                .supplyTask(this::computeHighlightingAsync)
                .awaitLatest(codeArea.richChanges())
                .filterMap(t -> {
                    if(t.isSuccess()) {
                        return Optional.of(t.get());
                    } else {
                        t.getFailure().printStackTrace();
                        return Optional.empty();
                    }
                })
                .subscribe(this::applyHighlighting);
        codeArea.replaceText(0, 0, HostsUtil.getHostsContent());

利用正则去计算哪些应该高亮,使用哪个样式

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";
    private static final String COMMENT_PATTERN = "#[^\n]*";

    private static final Pattern PATTERN = Pattern.compile(
        "(?<KEYWORD>" + KEYWORD_PATTERN + ")"
        + "|(?<COMMENT>" + COMMENT_PATTERN + ")"
    );

private static StyleSpans<Collection<String>> computeHighlighting(String text) {
        Matcher matcher = PATTERN.matcher(text);
        int lastKwEnd = 0;
        StyleSpansBuilder<Collection<String>> spansBuilder
                = new StyleSpansBuilder<>();
        while(matcher.find()) {
            String styleClass =
                    matcher.group("KEYWORD") != null ? "keyword" :
                    matcher.group("COMMENT") != null ? "comment" :
                    null; /* never happens */ assert styleClass != null;
            spansBuilder.add(Collections.emptyList(), matcher.start() - lastKwEnd);
            spansBuilder.add(Collections.singleton(styleClass), matcher.end() - matcher.start());
            lastKwEnd = matcher.end();
        }
        spansBuilder.add(Collections.emptyList(), text.length() - lastKwEnd);
        return spansBuilder.create();
    }

动态实时高亮显示

private Task<StyleSpans<Collection<String>>> computeHighlightingAsync() {
        String text = codeArea.getText();
        Task<StyleSpans<Collection<String>>> task = new Task<StyleSpans<Collection<String>>>() {
            @Override
            protected StyleSpans<Collection<String>> call() throws Exception {
                return computeHighlighting(text);
            }
        };
        executor.execute(task);
        return task;
    }

    private void applyHighlighting(StyleSpans<Collection<String>> highlighting) {
        codeArea.setStyleSpans(0, highlighting);
    }

加载css文件

Scene scene = new Scene(new StackPane(new VirtualizedScrollPane<>(codeArea)), 600, 400);
        scene.getStylesheets().add(HostsEditor.class.getResource("hosts-keywords.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.setTitle("JHosts Manager");
        primaryStage.show();

增加快捷键监听

大家理解的快捷键,可以在这里使用方便大家进行快速的更改

codeArea.setOnKeyPressed(new EventHandler<KeyEvent>()
        {
            @Override
            public void handle(KeyEvent event)
            {
                if (keyCombinationCtrlS.match(event))
                {
                    Boolean ret = HostsUtil.saveHostsContent(codeArea.getText());
                    if(ret == true){
                        System.out.println("save success!");
                        codeArea.setStyle("-fx-border-color: green;");
                    } else {
                        System.out.println("save error!");
                        codeArea.setStyle("-fx-border-color: red;");
                    }
                }
            }
        });

根据不同的电脑增加图标

增加图标是JavaFX提供的功能,目前mac上面需要特殊处理一下,代码如下

if(SystemUtils.IS_OS_MAC){
            primaryStage.getIcons().addAll(new Image("file:icon.icns"));
        } else {
            primaryStage.getIcons().addAll(new Image("file:icon.png"));
        }

结语

以上为JHosts Manager的实现,大家如果想运行可以在上面的代码仓库中下载,使用maven构建可以直接运行

1条留言
  1. test