当前位置: 首页 > news >正文

Javafx实现浏览器

        浏览器是一种计算机程序,主要用于显示互联网上的网页。通过浏览器,用户可以访问各种网站、搜索引擎、在线应用程序、社交媒体等。常见的浏览器包括Google Chrome、Mozilla Firefox、Safari、Microsoft Edge、Opera等。浏览器的功能不仅限于浏览网页,还包括下载文件、管理书签、保存密码、清除浏览数据等。浏览器已成为人们日常生活中必不可少的工具之一。

        下面我们使用JavaFx来实现一下浏览器,代码如下:


import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.*;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebHistory;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BrowserApplication extends Application {
    private static String URL = "https://www.fmill.cn/";
    private String url = URL;
    private String content;

    private Stage stage;
    private WebEngine engine;
    private TextField urlField;

    public BrowserApplication() {
    }

    public BrowserApplication(String url) {
        this.url = url;
        URL = url;
    }

    public BrowserApplication setAutoRefresh() {
        return this;
    }

    @Override
    public void start(Stage primaryStage) {
        stage = primaryStage;
        AnchorPane root = new AnchorPane();
//
        HBox topBox = new HBox();
        topBox.setPrefHeight(30);
        topBox.setPrefWidth(1000);
//        topBox.setStyle("-fx-border-color: #999");

        int len = 60;
        urlField = new TextField();
        urlField.setPrefWidth(916 - len);
        urlField.setPrefHeight(30);
        setSearchTextFieldStyle(urlField);

        Image iconImage = JavaFxUtils.getIconImage();
        Label homeLabel = newLabel(JavaFxUtils.getHomeImage());
        Label backLabel = newLabel(JavaFxUtils.getPrevImage());
        Label nextLabel = newLabel(JavaFxUtils.getNextImage());
        Label freshLabel = newLabel(JavaFxUtils.getFreshImage());
        Label moreLabel = newLabel(JavaFxUtils.getMoreImage());

        topBox.getChildren().addAll(backLabel, nextLabel, freshLabel, homeLabel, urlField, moreLabel);

        WebView browser = new WebView();
        browser.setPrefWidth(1000);
        browser.setPrefHeight(800);
        AnchorPane.setTopAnchor(browser, 30.0);
        //获取web浏览器引擎内核对象
        engine = browser.getEngine();

        engine.getLoadWorker().stateProperty().addListener((obs, oldValue, newValue) -> {
            System.out.println(oldValue + "->" + newValue);
            reload();
            if (newValue == Worker.State.SUCCEEDED) {
                System.out.println("finished loading");

            }
        });

        urlField.setText(this.url);
        urlField.setOnAction(e -> {
            href(urlField.getText());
        });
//        urlField.textProperty().bind(engine.locationProperty());

        System.out.println("是否开启脚本:" + engine.isJavaScriptEnabled());
        engine.userAgentProperty().addListener(((observable, oldValue, newValue) -> {
            System.out.println("userAgent:" + oldValue + "," + newValue);
        }));
        if (content != null) {
            engine.loadContent(content);
        } else {
            href(url);
        }
        engine.locationProperty().addListener((event, o, n) -> {
            System.out.println(o + "->" + n);
        });

        root.getChildren().addAll(topBox, browser);

        primaryStage.setTitle("小筱浏览器");
        stage.getIcons().add(iconImage);
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.setWidth(1020);
        primaryStage.setHeight(850);
        primaryStage.show();
        primaryStage.widthProperty().addListener((event, o, n) -> {
            if (n != null) {
                browser.setPrefWidth(n.doubleValue() - 20);
                topBox.setPrefWidth(n.doubleValue() - 10);
                urlField.setPrefWidth(n.doubleValue() - 110 - len);
            }
        });
        primaryStage.heightProperty().addListener((event, o, n) -> {
            browser.setPrefHeight(n.doubleValue() - 50);
        });
        homeLabel.setOnMouseClicked(event -> {
            System.out.println("首页");
            href("https://www.fmill.cn");
        });
        backLabel.setOnMouseClicked(event -> {
            WebHistory history = engine.getHistory();
            if (history.getCurrentIndex() > 0) {
                history.go(-1);
            }
        });
        nextLabel.setOnMouseClicked(event -> {
            WebHistory history = engine.getHistory();
            if (history.getCurrentIndex() < history.getEntries().size() - 1) {
                history.go(+1);
            }
        });
        freshLabel.setOnMouseClicked(event -> {
            String location = engine.getLocation();
            href(location);
        });

        root.setOnKeyPressed(event -> {
            if (event.getCode().equals(KeyCode.F5)) {
                System.out.println("刷新页面");
                engine.reload();
                String location = engine.getLocation();
                System.out.println(location);
                this.url = location;
                URL = this.url;
            }
        });
        engine.onStatusChangedProperty().addListener((event, o, n) -> {
            System.out.println("onStatusChangedProperty");
        });
        primaryStage.setOnCloseRequest(event -> {
            primaryStage.close();
        });
    }

    private void href(String openUrl) {
        engine.load(openUrl);
        this.url = openUrl;
        URL = this.url;
        this.urlField.setText(openUrl);
    }

    private void reload() {
        String location = engine.getLocation();
        WebHistory history = engine.getHistory();
        System.out.println(history.getCurrentIndex());
        if (!this.url.equals(location)) {
            System.out.println("网址发生改变...");
            this.url = location;
            URL = this.url;
            this.urlField.setText(location);
        } else {
            System.out.println("网址未发生变动");
        }
    }

    private static Label newLabel(Image image) {
        Label label = new Label();
        label.setBackground(getBackground(image));
        label.setPrefWidth(30);
        label.setPrefHeight(30);
        label.setMinWidth(30);
        label.setMinHeight(30);
        return label;
    }

    public static Background getBackground(Image image) {
        return new Background(new BackgroundImage(image, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER, BackgroundSize.DEFAULT));
    }

    private void setSearchTextFieldStyle(TextField urlField) {
        urlField.setStyle("-fx-border-color: #e2e2e2;-fx-background-color: #e2e2e2;-fx-border-radius: 10px;-fx-background-radius: 10px;-fx-highlight-fill: #a4adc7;-fx-highlight-text-fill: #000000;");
        urlField.setOnMousePressed(event ->
                urlField.setStyle("-fx-border-color: #29aff8;-fx-background-color: #fff;-fx-border-radius: 10px;-fx-highlight-fill: #a4adc7;-fx-highlight-text-fill: #000000;"));
        urlField.setOnMouseExited(event ->
                urlField.setStyle("-fx-border-color: #ced0d5;-fx-background-color: #fff;-fx-border-radius: 10px;-fx-highlight-fill: #a4adc7;-fx-highlight-text-fill: #000000;"));
    }

    public void setUrl(String url) {
        this.url = url;
        URL = this.url;
    }

    public BrowserApplication setContent(String content) {
        this.content = content;
        return this;
    }
}

        其中获取Image这里需要自己定义:

        图标在下面,有需要的话自己抓取:

        输入百度链接,效果如下:

相关文章:

  • 【UGUI】sprite精灵的创建与编辑
  • 【LeetCode刷题笔记】103. 二叉树的锯齿形层序遍历
  • 基于ssm vue的风景文化管理平台源码和论文
  • Scrum敏捷开发流程及支撑工具
  • 计数问题(数位DP)
  • C/C++内存管理
  • 【软件测试】技术精选:Jmeter常见的几种报错
  • IDEA2023版本创建Sping项目只能勾选17和21,却无法使用Java8?(已解决)
  • qt使用qproperty在css中设置自定义的qobject类属性
  • 微服务保护
  • 【电子取证篇】汽车取证数据提取与汽车取证实例浅析(附标准下载)
  • YOLOv8改进 | 2023 | SCConv空间和通道重构卷积(精细化检测,又轻量又提点)
  • 外包干了4年,技术退步太明显了。。。。。
  • Java分布式全局唯一Id:id生成要求、为什么不用UUID、生成分布式雪花Id
  • Flask 快速入门
  • 鸿蒙(HarmonyOS)应用开发——构建页面(题目答案)
  • 主要分布式文件系统架构对比分析:GFS vs. Tectonic vs. JuiceFS
  • 从零开始训练一个ChatGPT大模型(低资源,1B3)
  • 【C++】期末复习题(一)
  • 25、pytest的测试报告插件allure
  • 郑培凯:汤显祖的“至情”与罗汝芳的“赤子之心”
  • 海北州委常委、常务副州长桑本履新青海省供销社理事会主任
  • 做街坊们的“健康管家”,她把专科护理服务送上门
  • 普京提议恢复直接谈判,泽连斯基:望俄明日停火,乌愿谈判
  • 德国将不再公布对乌克兰军事支持的细节
  • 富家罹盗与财富迷思:《西游记》与《蜃楼志》中的强盗案