大家好,今天给大家带来了使用JavaFX定制自己的浏览器
这是一个桌面应用可以使用jar方式运行,也可以用别的工具打包成exe,本人因不喜欢模块化,因此未使用FXML,纯代码加css方式实现的,大家先看看效果
下面为结构图,代码一字不漏全在下面,可以直接复制粘贴运行,就创建普通的项目就行,不要用模块化
创建项目
1.先创建一个最普通的maven项目这里我就不演示了直接给大家看pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>MyBrowser</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-web</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<!-- <mainClass>启动类位置</mainClass> -->
<mainClass>com.kur.ban.BrowserStart</mainClass>
</manifest>
</archive>
<descriptorRefs>
<!-- jar 携带依赖 -->
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
创建BrowserApplication类
创建BrowserApplication继承Application重写start方法
package com.kur.ban;
import cn.hutool.core.lang.Console;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.ListChangeListener;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import java.awt.*;
import java.io.File;
public class BrowserApplication extends Application {
private static final Log log = LogFactory.get();
/**
* @init() 此方法为初始化方法
* @start() 此方法为运行中方法
* @stop() 此方法在窗口关闭时调用
*/
@Override
public void init() throws Exception {
super.init();
log.info("正在初始化...");
//下面的操作为创建一个txt文件,用来记录下载历史
//获取系统的\
String property = System.getProperty("file.separator");
File file = new File("D:" + property + "Browser");
//file.exists() 此方法为检测路径是否存在
if (file.exists()) {
String path = file.getAbsolutePath() + property + "download.txt";
File download = new File(path);
if (download.exists()) {
log.info("默认存放下载记录的文件已存在");
} else {
if (download.createNewFile()) {
log.info("成功创建默认存放下载记录的文件");
} else {
log.debug("创建默认存放下载记录的文件失败");
}
}
} else {
//file.mkdir() 此方法为创建文件夹的方法
if (file.mkdir()) {
String path = file.getAbsolutePath() + property + "download.txt";
File download = new File(path);
//download.createNewFile() 此方法为创建文件
if (download.createNewFile()) {
log.info("成功创建默认存放下载记录的文件");
}
log.info("成功创建存放下载记录的文件的目标文件夹");
}
}
}
double x = 0; //记录x轴坐标
double y = 0; //记录y轴坐标
@Override
public void start(Stage stage) throws Exception {
//创建布局
BorderPane borderPane = new BorderPane();
borderPane.setId("borderPane");
//创建场景
Scene scene = new Scene(borderPane);
//把场景放入到窗口
stage.setScene(scene);
stage.setWidth(1500);
stage.setHeight(800);
//因为是浏览器所以使用TabPane新建和删除页面
TabPane tabPane = new TabPane();
//通过方法返回一个tab
Tab tab = Element_Tab.getTab(tabPane, stage);
//添加一个tab
tabPane.getTabs().add(tab);
// tabPane.getSelectionModel().select(tab);
//返回一个HBox布局,里面放着各种按钮
HBox hBox = Element_TopButton.getTopButton(stage);
//把tabPane放在borderPane的中间位置
borderPane.setCenter(tabPane);
//把hBox放在borderPane的上面
borderPane.setTop(hBox);
//设置窗口的样式,设置成无任何样式跟按钮,按钮需要全部自定义
stage.initStyle(StageStyle.TRANSPARENT);
//显示窗口
stage.show();
//给tabPane添加监听,监听tab面板增加和减少
tabPane.getTabs().addListener(new ListChangeListener<Tab>() {
@Override
public void onChanged(Change<? extends Tab> change) {
//默认选中新增加的tab面板
tabPane.getSelectionModel().select(change.getList().size() - 1);
if (change.getList().size() == 0) {
log.debug("所有的tab窗口都被关闭了,自动结束程序运行!");
Console.log("--------------------------------");
stage.close();
Platform.exit();
}
}
});
//鼠标按压事件
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
//mouseEvent.getScreenX()获取鼠标在屏幕上的坐标
//stage.getX() 获取窗口的坐标
x = mouseEvent.getScreenX() - stage.getX();
y = mouseEvent.getScreenY() - stage.getY();
}
});
//鼠标拖动事件
scene.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
stage.setX(mouseEvent.getScreenX() - x);
stage.setY(mouseEvent.getScreenY() - y);
}
});
//添加css样式
scene.getStylesheets().addAll("/css/tabPane.css",
"/css/topButton.css",
"/css/textFiled.css",
"/css/button.css",
"/css/hBox.css",
"/css/topHBox.css",
"/css/progressBar.css",
"/css/menuBar.css",
"/css/label.css"
);
//添加图标
stage.getIcons().add(new Image("icon/system.jpeg"));
}
@Override
public void stop() throws Exception {
super.stop();
}
}
创建启动类BrowserStart
package com.kur.ban;
import javafx.application.Application;
//因为未使用模块化所以需要此启动方式,不然会报javafx缺少组件的错误
public class BrowserStart {
public static void main(String[] args){
Application.launch(BrowserApplication.class, args);
}
}
创建Element_Tab
package com.kur.ban;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import javafx.collections.ListChangeListener;
import javafx.concurrent.Worker;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLConnection;
import java.util.*;
public class Element_Tab {
private static String tittle;
public static Tab getTab(TabPane tabPane, Stage stage) throws IOException {
Log log = LogFactory.get();
Tab tab = new Tab();
BorderPane borderPane = new BorderPane();
tab.setContent(borderPane);
WebView webView = new WebView();
WebEngine engine = webView.getEngine();
engine.load("https://www.baidu.com");
webView.setContextMenuEnabled(true);
TextField textField = Element_TextFiled.getTextField(engine);
textField.setId("textFiled");
Button retreat = Element_Button.retreat(engine);
Button advance = Element_Button.advance(engine);
Button refresh = Element_Button.refresh(engine);
Button go = Element_Button.go(textField, engine);
Button addTab = Element_Button.addTab(tabPane, stage);
MenuBar menuBar = Element_MenuBar.getMenuBar(engine, stage);
MenuBar downloadMenuBar = new MenuBar();
downloadMenuBar.setId("downloadMenuBar");
Menu downloadMenu = new Menu("下载管理");
downloadMenu.setId("downloadMenu");
downloadMenuBar.getMenus().addAll(downloadMenu);
HBox topHBox = new HBox(retreat, advance, textField, go, addTab, refresh, menuBar, downloadMenuBar);
topHBox.setId("topHBox");
topHBox.setFillHeight(true);
borderPane.setTop(topHBox);
borderPane.setCenter(webView);
ProgressBar progressBar = Element_ProgressBar.getProgressBar(webView, engine);
progressBar.setId("progressBar");
borderPane.setBottom(progressBar);
engine.getLoadWorker().stateProperty().addListener((observableValue, state, t1) -> {
if (t1 == Worker.State.FAILED) {
engine.reload();
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.initOwner(stage);
alert.setTitle("加载错误");
alert.setContentText("您的网址有误! 请输入正确的网址." + "\n检查网络连接是否正常.");
alert.getButtonTypes().addListener((ListChangeListener<ButtonType>) change -> {
Button button = (Button) change.getList();
button.setOnAction(actionEvent -> {
textField.isFocused();
engine.reload();
});
});
alert.show();
}
});
engine.titleProperty().addListener((observableValue, oldValue, newValue) -> {
tab.setText(newValue);
if (newValue != null) {
String[] split = newValue.split(" ");
List<String> list = Arrays.stream(split).toList();
tittle = list.get(0);
}
});
engine.locationProperty().addListener((observableValue, oldValue, newValue) -> {
String contentTypeFromName = URLConnection.guessContentTypeFromName(newValue);
if (contentTypeFromName != null) {
String extName = FileUtil.extName(newValue);
DownloadProgram program = new DownloadProgram();
program.downloadBefore(newValue, tittle, stage, downloadMenu, extName);
}
});
String property = System.getProperty("file.separator");
String path = "D:" + property + "Browser" + property + "download.txt";
FileReader fileReader = new FileReader(path, "UTF-8");
HashMap<String, String> map = new HashMap<>();
String[] str = new String[50];
int i = 0;
for (String readLine : fileReader.readLines()) {
String trim = readLine.trim();
if (!trim.isEmpty()) {
String[] split = trim.split("&");
List<String> list = Arrays.stream(split).toList();
File file = new File(list.get(1));
if (file.exists()) {
i = i + 1;
log.info("检测到文件[ " + list.get(0) + " ]存在");
map.put(list.get(0), list.get(1));
str[i] = list.get(0);
VBox vBox = Element_MenuItem.getItem(list.get(0), map.get(list.get(0)));
MenuItem menuItem = new MenuItem();
menuItem.setGraphic(vBox);
downloadMenu.getItems().addAll(menuItem);
} else {
log.info("检测到文件[ " + list.get(0) + " ]不存在");
}
}
}
for (String key : str) {
if (key != null) {
System.out.println("map.get(key) = " + map.get(key));
}
}
String del = "D:" + property + "Browser" + property + "download.txt";
File file = new File(del);
if (file.exists()) {
if (file.delete()) {
log.info("成功删除文件:" + del);
} else {
log.info("删除失败: " + del);
}
}
CreateFile.newFile();
File write = new File(del);
if (write.exists()) {
FileWriter fileWriter = new FileWriter(write);
for (String key : str) {
if (key != null) {
fileWriter.append("\n" + key + "&" + map.get(key));
}
}
}
return tab;
}
}
创建CreateFile
package com.kur.ban;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import java.io.File;
import java.io.IOException;
public class CreateFile {
private static final Log log = LogFactory.get();
public static void newFile() throws IOException {
//获取系统的\
String property = System.getProperty("file.separator");
File file = new File("D:" + property + "Browser");
//file.exists() 此方法为检测路径是否存在
if (file.exists()) {
String path = file.getAbsolutePath() + property + "download.txt";
File download = new File(path);
if (download.exists()) {
log.info("默认存放下载记录的文件已存在");
} else {
if (download.createNewFile()) {
log.info("成功创建默认存放下载记录的文件");
} else {
log.debug("创建默认存放下载记录的文件失败");
}
}
} else {
//file.mkdir() 此方法为创建文件夹的方法
if (file.mkdir()) {
String path = file.getAbsolutePath() + property + "download.txt";
File download = new File(path);
//download.createNewFile() 此方法为创建文件
if (download.createNewFile()) {
log.info("成功创建默认存放下载记录的文件");
}
log.info("成功创建存放下载记录的文件的目标文件夹");
}
}
}
}
创建Element_Button
package com.kur.ban;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import javafx.scene.control.Button;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebHistory;
import javafx.stage.Stage;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Element_Button {
private static final Log log = LogFactory.get();
public static Button retreat(WebEngine engine) {
ImageView image = new ImageView(new Image("icon/img_1.png", 29, 29, true, true));
Button button = new Button("", image);
button.setId("retreat");
button.setPrefWidth(4);
button.setPrefHeight(32);
button.setOnAction(actionEvent -> {
WebHistory history = engine.getHistory();
try {
history.go(-1);
} catch (Exception e) {
log.debug("-1索引越界");
throw new RuntimeException(e);
}
});
return button;
}
public static Button advance(WebEngine engine) {
ImageView image = new ImageView(new Image("icon/img_1.png", 29, 29, true, true));
Button button = new Button("", image);
button.setId("advance");
button.setPrefWidth(40);
button.setPrefHeight(32);
image.setRotate(180);
button.setOnAction(actionEvent -> button.setOnAction(actionEvent1 -> {
WebHistory history = engine.getHistory();
try {
history.go(1);
} catch (Exception e) {
log.debug("1索引越界");
throw new RuntimeException(e);
}
}));
return button;
}
public static Button refresh(WebEngine engine) {
ImageView image = new ImageView(new Image("icon/img_2.png", 29, 29, true, true));
Button button = new Button("", image);
button.setId("refresh");
button.setPrefWidth(40);
button.setPrefHeight(32);
button.setOnAction(actionEvent -> engine.reload());
return button;
}
public static Button addTab(TabPane tabPane, Stage stage) {
ImageView image = new ImageView(new Image("icon/img_5.png", 29, 29, true, true));
Button button = new Button("", image);
button.setId("addTab");
button.setPrefWidth(40);
button.setPrefHeight(32);
button.setOnAction(actionEvent -> {
try {
Tab tab = Element_Tab.getTab(tabPane, stage);
tabPane.getTabs().addAll(tab);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
return button;
}
public static Button go(TextField textField, WebEngine engine) {
Button button = new Button("Go");
button.setId("go");
button.setPrefWidth(48);
button.setPrefHeight(40);
button.setOnAction(actionEvent -> engine.load(textField.getText()));
return button;
}
}
创建Element_AlertStage
package com.kur.ban;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Element_AlertStage {
public static Stage getAlertStage(Stage stage) {
Stage alertStage = new Stage();
AnchorPane anchorPane = new AnchorPane();
Scene scene = new Scene(anchorPane);
alertStage.setScene(scene);
alertStage.setWidth(250);
alertStage.setHeight(200);
alertStage.initStyle(StageStyle.TRANSPARENT);
alertStage.initModality(Modality.APPLICATION_MODAL);
alertStage.initOwner(stage);
ToggleGroup group = new ToggleGroup();
RadioButton min = new RadioButton("最小化到系统托盘");
min.setId("min");
min.setSelected(true);
RadioButton max = new RadioButton("退出班班浏览器");
max.setId("max");
min.setToggleGroup(group);
max.setToggleGroup(group);
Button sure = new Button("确定");
sure.setId("sure");
Button close = new Button("关闭");
close.setId("close");
anchorPane.getChildren().addAll(close, min, max, sure);
scene.getStylesheets().addAll("/css/alert.css");
alertStage.show();
AnchorPane.setTopAnchor(close, 00.0);
AnchorPane.setLeftAnchor(close, alertStage.getWidth() - close.getWidth());
AnchorPane.setTopAnchor(min, 70.0);
AnchorPane.setLeftAnchor(min, alertStage.getWidth() / 2 - min.getWidth() / 2);
AnchorPane.setTopAnchor(max, 100.0);
AnchorPane.setLeftAnchor(max, alertStage.getWidth() / 2 - min.getWidth() / 2);
AnchorPane.setTopAnchor(sure, 140.0);
AnchorPane.setLeftAnchor(sure, alertStage.getWidth() / 2 - sure.getWidth() / 2);
sure.setOnAction(actionEvent -> {
if (min.isSelected()) {
Platform.setImplicitExit(false);
Element_SystemTray.getSystemTray(stage);
alertStage.close();
stage.hide();
} else {
alertStage.close();
stage.close();
Platform.exit();
}
});
close.setOnAction(actionEvent -> alertStage.close());
return alertStage;
}
}
创建Element_HistoryStage
package com.kur.ban;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebHistory;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Element_HistoryStage {
public static Stage getHistoryStage(WebEngine engine, Stage stage) {
Stage historyStage = new Stage();
ListView<String> listView = new ListView<>();
Scene scene = new Scene(listView);
historyStage.setScene(scene);
historyStage.setWidth(300);
historyStage.setHeight(600);
historyStage.initStyle(StageStyle.UTILITY);
historyStage.initModality(Modality.APPLICATION_MODAL);
historyStage.setX(1200);
historyStage.setY(200);
historyStage.initOwner(stage);
historyStage.setTitle("历史记录");
ObservableList<String> list = FXCollections.observableArrayList();
ObservableList<WebHistory.Entry> history = engine.getHistory().getEntries();
history.forEach(entry -> {
String url = entry.getUrl();
String title = entry.getTitle();
list.add(title + "\n" + url);
});
listView.setItems(list);
listView.getSelectionModel().selectedItemProperty().addListener((observableValue, s, t1) -> {
String[] split = t1.split("\n");
List<String> urlList = Arrays.stream(split).toList();
engine.load(urlList.get(1));
});
scene.getStylesheets().addAll("/css/listView.css");
return historyStage;
}
}
创建Element_MenuBar
package com.kur.ban;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.input.KeyCombination;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;
public class Element_MenuBar {
public static MenuBar getMenuBar(WebEngine engine, Stage stage) {
MenuBar menuBar = new MenuBar();
menuBar.setId("toolBar");
Menu menu = new Menu("工具");
menu.setId("toolMenu");
MenuItem history = new MenuItem("历史记录");
history.setId("history");
history.setAccelerator(KeyCombination.valueOf("ctrl+h"));
menu.getItems().addAll(history);
menuBar.getMenus().add(menu);
history.setOnAction(actionEvent -> Element_HistoryStage.getHistoryStage(engine, stage).show());
return menuBar;
}
}
创建Element_MenuItem
package com.kur.ban;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import java.awt.*;
import java.io.File;
import java.io.IOException;
public class Element_MenuItem {
private static final Log log= LogFactory.get();
public static VBox getItem(String tittle,String saveFile){
VBox vBox = new VBox();
HBox hBox = new HBox();
Label tittleLabel = new Label();
tittleLabel.setText(tittle);
Label saveFileLabel = new Label();
saveFileLabel.setMaxWidth(200);
saveFileLabel.setMinWidth(200);
saveFileLabel.setText(saveFile);
Button open = new Button("打开文件夹");
Button delete = new Button("删除");
hBox.getChildren().addAll(saveFileLabel, open, delete);
vBox.getChildren().addAll(tittleLabel, hBox);
hBox.setSpacing(5);
vBox.setAlignment(Pos.CENTER);
hBox.setAlignment(Pos.CENTER);
vBox.setMinWidth(150);
open.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
System.out.println(saveFileLabel.getText());
File file = new File(saveFileLabel.getText());
Desktop desktop = Desktop.getDesktop();
try {
desktop.open(new File(file.getParent()));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
delete.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
File file = new File(saveFileLabel.getText());
if (file.delete()){
delete.setText("已删除");
delete.setDisable(true);
log.info("成功删除文件: [ "+saveFileLabel.getText()+" ]");
}else {
log.info("删除失败: [ "+saveFileLabel.getText()+" ]");
}
}
});
return vBox;
}
}
创建Element_ProgressBar
package com.kur.ban;
import javafx.scene.control.ProgressBar;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
public class Element_ProgressBar {
public static ProgressBar getProgressBar(WebView webView, WebEngine engine) {
ProgressBar progressBar = new ProgressBar();
progressBar.getStylesheets().addAll("/css/progressBar.css");
webView.widthProperty().addListener((observableValue, number, xin) -> progressBar.setPrefWidth(xin.doubleValue()));
engine.getLoadWorker().progressProperty().addListener((observableValue, number, t1) -> progressBar.setProgress(t1.doubleValue()));
return progressBar;
}
}
创建Element_SystemTray
package com.kur.ban;
import javafx.application.Platform;
import javafx.stage.Stage;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Element_SystemTray {
public static void getSystemTray(Stage stage) {
SystemTray systemTray = SystemTray.getSystemTray();
Image image = Toolkit.getDefaultToolkit().getImage("D:\\JavaFXCode\\MyBrowser\\src\\main\\resources\\icon\\img_2.png");
PopupMenu popupMenu = new PopupMenu();
MenuItem item1 = new MenuItem("quit");
item1.setFont(new Font("微软雅黑", Font.BOLD, 20));
MenuItem item2 = new MenuItem("show");
popupMenu.add(item1);
popupMenu.add(item2);
popupMenu.setFont(new Font("微软雅黑", Font.BOLD, 20));
TrayIcon trayIcon = new TrayIcon(image, "班班浏览器", popupMenu);
trayIcon.setImageAutoSize(true);
try {
systemTray.add(trayIcon);
} catch (AWTException e) {
throw new RuntimeException(e);
}
item1.addActionListener(e -> {
Platform.runLater(stage::close);
systemTray.remove(trayIcon);
Platform.exit();
});
item2.addActionListener(e -> {
Platform.runLater(stage::show);
systemTray.remove(trayIcon);
});
trayIcon.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
Platform.runLater(stage::show);
systemTray.remove(trayIcon);
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
}
}
创建Element_TextFiled
package com.kur.ban;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import javafx.application.Platform;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.web.WebEngine;
import java.net.MalformedURLException;
import java.net.URL;
public class Element_TextFiled {
private static final Log log=LogFactory.get();
public static TextField getTextField(WebEngine engine) {
TextField textField = new TextField();
textField.setPrefWidth(900);
textField.setPrefHeight(40);
textField.setText(engine.getLocation());
engine.locationProperty().addListener((observableValue, s, t1) -> textField.setText(t1));
textField.setOnKeyReleased(keyEvent -> {
if (keyEvent.getCode() == KeyCode.ENTER) {
String text = textField.getText();
Platform.runLater(() -> {
String url = toURL(text);
if (url == null) {
url = toURL("https://" + text);
}
engine.load(url);
});
}
});
return textField;
}
public static String toURL(String url) {
try {
return new URL(url).toExternalForm();
} catch (MalformedURLException e) {
log.debug("网址解析失败:"+e.getMessage());
return null;
}
}
}
创建Element_TopButton
package com.kur.ban;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Element_TopButton {
public static HBox getTopButton(Stage stage) {
Button min = new Button("最小化");
min.setId("min");
Button max = new Button("最大化");
max.setId("max");
Button close = new Button("关闭");
close.setId("close");
HBox hBox = new HBox();
hBox.setId("hBox");
hBox.getChildren().addAll(min, max, close);
hBox.setAlignment(Pos.BASELINE_RIGHT);
close.setOnAction(actionEvent -> {
Stage alertStage = Element_AlertStage.getAlertStage(stage);
alertStage.show();
});
max.setOnAction(actionEvent -> {
boolean fullScreen = stage.isFullScreen();
stage.setFullScreen(!fullScreen);
});
min.setOnAction(actionEvent -> stage.setIconified(true));
hBox.setOnMouseClicked(mouseEvent -> {
if (mouseEvent.getClickCount() == 2) {
stage.setMaximized(!stage.isMaximized());
}
});
return hBox;
}
}
创建DownloadProgram
package com.kur.ban;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import java.awt.*;
import java.io.File;
import java.io.IOException;
public class DownloadProgram {
private File saveFile = null;
/**
*
* @param url 文件下载地址
* @param tittle 文件的标题
* @param stage 用来子窗口的父窗口
* @param downloadMenu 把生成的MenuItem放入menu
* @param extName 根据网址解析的文件类型,比如exe,MP3之类的
*/
public void downloadBefore(String url, String tittle, Stage stage, Menu downloadMenu, String extName) {
FileChooser chooser = new FileChooser();
Log log = LogFactory.get();
//如果文件类型是exe的话文件保存框的保存类型就只有exe格式
//下面以此类推
if (extName.equals("exe")){
chooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("应用程序", "*.exe"));
}else if (extName.equals("png")){
chooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("图片类型", "*.png"));
} else if (extName.equals("jpg")) {
chooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("图片类型", "*.jpg"));
}else if (extName.equals("jpeg")) {
chooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("图片类型", "*.jpeg"));
}else if (extName.equals("txt")) {
chooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("文本类型", "*.txt"));
}else if (extName.equals("mp3")) {
chooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("音乐类型", "*.mp3"));
}else if (extName.equals("mp4")) {
chooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("视频类型", "*.mp4"));
}else if (extName.equals("zip")) {
chooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("压缩文件", "*.zip"));
}else if (extName.equals("tar.gz")) {
chooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("压缩文件", "*.tar.gz"));
}
//文件的默认保存的文件名是标题加文件类型
chooser.setInitialFileName(tittle + "." + extName);
Stage fileStage = new Stage();
fileStage.setWidth(600);
fileStage.setHeight(500);
fileStage.initOwner(stage);
chooser.setTitle(tittle);
//如果文件类型是下面的类型才会弹出文件保存框
if (extName.equals("exe")||extName.equals("png")||extName.equals("jpg")||
extName.equals("jpeg")||extName.equals("txt")||extName.equals("mp3")||
extName.equals("mp4")||extName.equals("zip")||extName.equals("tag.gz")
){
saveFile = chooser.showSaveDialog(fileStage);
}
//saveFile 文件保存路径
if (saveFile != null) {
log.info("文件名称是:"+saveFile.getName());
tittle=saveFile.getName();
//创建MenuItem
MenuItem menuItem = new MenuItem();
VBox vBox = new VBox();
HBox hBox = new HBox();
//显示标题的label
Label tittleLabel = new Label();
//显示状态消息的label
Label msgLabel = new Label();
msgLabel.setMinWidth(60);
msgLabel.setMaxWidth(60);
//下载进度条
ProgressBar progressBar = new ProgressBar();
progressBar.setMinWidth(133);
progressBar.setMaxWidth(133);
//往menu添加menuItem
downloadMenu.getItems().addAll(menuItem);
//两个功能按钮
Button open = new Button("打开文件夹");
hBox.setSpacing(5);
//把组件放进布局里
hBox.getChildren().addAll(msgLabel, progressBar, open);
vBox.getChildren().addAll(tittleLabel, hBox);
tittleLabel.setText(saveFile.getName());
vBox.setAlignment(Pos.CENTER);
hBox.setAlignment(Pos.CENTER);
vBox.setMinWidth(150);
//DownloadUtils 下载工具类,使用了javafx的多线程
DownloadUtils downloadUtils = new DownloadUtils();
downloadUtils.setUrl(url);
downloadUtils.setSaveFile(saveFile);
downloadUtils.start();
//graphic- 新的对话框图形
menuItem.setGraphic(vBox);
String finalTittle = tittle;
//此监听返回下载进度
downloadUtils.progressProperty().addListener((observableValue, oldValue, newValue) -> {
progressBar.setProgress(newValue.doubleValue());
//如果下载完成就往下载历史文件写入记录
if (newValue.doubleValue() >= 1) {
//下载完成就取消多线程
downloadUtils.cancel();
//根据系统获取\
String property = System.getProperty("file.separator");
//下载历史文件路径
String path = "D:" + property + "Browser" + property + "download.txt";
File write = new File(path);
FileWriter fileWriter = new FileWriter(write, "UTF-8");
//写入记录
fileWriter.append(finalTittle + "&" + saveFile+"\n");
log.info("成功下载文件");
log.info("写入下载记录成功");
}
});
//监听下载时的消息
downloadUtils.messageProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) {
msgLabel.setText(newValue);
}
});
//打开文件夹
open.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
Desktop desktop = Desktop.getDesktop();
try {
desktop.open(new File(saveFile.getParent()));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
}
}
}
创建DownloadUtils
package com.kur.ban;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 此类为JavaFX多线程类
* 继承Service重写方法
*/
public class DownloadUtils extends Service<Double> {
private final StringProperty url = new SimpleStringProperty();
private File saveFile;
public String getUrl() {
return url.get();
}
public void setUrl(String url) {
this.url.set(url);
}
public File getSaveFile() {
return saveFile;
}
public void setSaveFile(File saveFile) {
this.saveFile = saveFile;
}
protected Task<Double> createTask() {
final String newLoc = getUrl();
final File saveFile = getSaveFile();
return new Task<>() {
protected Double call() throws Exception {
//根据收到的网址返回HttpURLConnection
HttpURLConnection urlConnection = (HttpURLConnection) new URL(newLoc).openConnection();
//根据HttpURLConnection返回InputStream流
InputStream inputStream = urlConnection.getInputStream();
//输入流
FileOutputStream outputStream = new FileOutputStream(saveFile);
//获取要下载文件的总字节数
int length = urlConnection.getContentLength();
//每次下载的字节数
int sum;
//下载字节数的总和
long downloadSize = 0;
//进度条
double progress = 0;
byte[] bytes = new byte[4096];
//下面就是读取流和输入流操作
while ((sum = inputStream.read(bytes)) != -1) {
downloadSize += sum;
outputStream.write(bytes, 0, sum);
progress = downloadSize / (double) length;
//更新Service类进度条方法的值
this.updateProgress(downloadSize, length);
if (progress <= 0.1) {
//更新Service类进消息方法的值
this.updateMessage("开始下载");
} else if (progress < 0.4) {
this.updateMessage("请耐心等待");
} else if (progress < 0.8) {
this.updateMessage("马上就好");
} else if (progress < 1) {
this.updateMessage("即将完成");
} else if (progress >= 1) {
this.updateMessage("下载成功");
}
}
inputStream.close();
outputStream.close();
return progress;
}
};
}
}
css样式:alert.css
#sure{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-font-size: 15px;
-fx-padding: 5px 10px 5px 10px;
-fx-cursor: HAND;
}
#close{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-font-size: 15px;
-fx-padding: 5px 10px 5px 10px;
-fx-cursor: HAND;
}
#sure:hover {
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#close:hover {
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#sure:pressed {
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#close:pressed {
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#min{
-fx-font-size:14px;
-fx-text-fill:#303133;
}
#max{
-fx-font-size:14px;
-fx-text-fill:#303133;
}
#min > .radio{
-fx-pref-width:16px;
-fx-pref-height:16px;
-fx-background-color: #F2F3F5;
-fx-background-radius:8px;
-fx-background-insets: 0;
-fx-border-color:#D4D7DE;
-fx-border-radius:8px;
}
#max > .radio{
-fx-pref-width:16px;
-fx-pref-height:16px;
-fx-background-color: #F2F3F5;
-fx-background-radius:8px;
-fx-background-insets: 0;
-fx-border-color:#D4D7DE;
-fx-border-radius:8px;
}
#min > .radio > .dot{
-fx-background-color: transparent;
-fx-background-insets: 0;
-fx-padding: 3px;
}
#max > .radio > .dot{
-fx-background-color: transparent;
-fx-background-insets: 0;
-fx-padding: 3px;
}
#min:selected{
-fx-text-fill:#5C80EF;
}
#max:selected{
-fx-text-fill:#5C80EF;
}
#min:selected > .radio{
-fx-background-color: #5C80EF;
-fx-border-color:transparent;
}
#max:selected > .radio{
-fx-background-color: #5C80EF;
-fx-border-color:transparent;
}
#min:selected > .radio > .dot{
-fx-background-insets: 0;
-fx-background-color: rgb(255,255,255);
}
#max:selected > .radio > .dot{
-fx-background-insets: 0;
-fx-background-color: rgb(255,255,255);
}
.scene{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
}
button.css
#retreat{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-cursor: HAND;
}
#retreat:hover {
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#retreat:pressed {
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#advance{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-cursor: HAND;
}
#advance:hover {
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#advance:pressed {
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#refresh{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-cursor: HAND;
}
#refresh:hover {
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#refresh:pressed {
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#addTab{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-cursor: HAND;
}
#addTab:hover {
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#addTab:pressed {
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#go{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-cursor: HAND;
}
#go:hover {
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#go:pressed {
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#download{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-cursor: HAND;
}
#download:hover {
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#download:pressed {
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
hbox.css
#hBox{
-fx-spacing: 5px;
}
label.css
.label{
-fx-text-fill: #130c0e;
}
listview.css
.list-view {
-fx-border-color: rgba(193, 197, 205, 1) rgba(193, 197, 205, 1) rgba(193, 197, 205, 1) rgba(193, 197, 205, 1);
-fx-border-width: 1px 1px 1px 1px;
-fx-background-insets: 0px 0px 0px 0px;
}
.list-view .list-cell {
-fx-background-color: rgba(255, 255, 255, 1);
-fx-font-size: 15px;
-fx-text-fill: rgba(117, 117, 117, 1);
-fx-padding: 10px 0px 10px 5px;
-fx-border-color: rgba(0, 0, 0, 0) rgba(0, 0, 0, 0) rgba(235, 238, 245, 1) rgba(0, 0, 0, 0);
}
.list-view .list-cell:odd {
-fx-background-color: rgba(255, 255, 255, 1);
}
.list-view .list-cell:hover {
-fx-background-color: rgba(245, 247, 250, 1);
}
.list-view:focused .list-cell:selected {
-fx-background-color: rgba(236, 245, 255, 1);
-fx-text-fill: rgba(117, 117, 117, 1);
}
.list-view .scroll-bar .decrement-arrow {
-fx-min-width: 0px;
-fx-min-height: 0px;
-fx-pref-width: 0px;
-fx-pref-height: 0px;
visibility: hidden;
}
.list-view .scroll-bar .increment-arrow {
-fx-min-width: 0px;
-fx-min-height: 0px;
-fx-pref-width: 0px;
-fx-pref-height: 0px;
visibility: hidden;
}
.list-view .scroll-bar .decrement-button {
-fx-min-width: 0px;
-fx-min-height: 0px;
-fx-pref-width: 0px;
-fx-pref-height: 0px;
visibility: hidden;
}
.list-view .scroll-bar .increment-button {
-fx-min-width: 0px;
-fx-min-height: 0px;
-fx-pref-width: 0px;
-fx-pref-height: 0px;
visibility: hidden;
}
.list-view .scroll-bar:vertical {
-fx-padding: 0px 0px 0px 0px;
-fx-pref-width: 9px;
-fx-background-color: rgba(255, 255, 255, 1);
}
.list-view .scroll-bar:vertical .thumb {
-fx-background-color: rgba(221, 222, 224, 1);
-fx-background-insets: 0px 0px 0px 0px;
-fx-background-radius: 5px 5px 5px 5px;
}
.list-view .scroll-bar:vertical .thumb:pressed {
-fx-background-color: rgba(199, 201, 204, 1);
}
.list-view:focused {
-fx-border-color: rgba(50, 150, 255, 1) rgba(50, 150, 255, 1) rgba(50, 150, 255, 1) rgba(50, 150, 255, 1);
}
menubar.css
#toolBar{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-cursor: HAND;
-fx-max-height: 40px;
-fx-max-width: 58px;
-fx-alignment: center;
}
#toolMenu{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-cursor: HAND;
-fx-alignment: center;
-fx-border-width: 0px;
}
#toolMenu:hover {
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-background-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(255, 255, 255, 1);
}
#toolMenu:pressed {
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-background-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(255, 255, 255, 1);
}
#history{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-cursor: HAND;
-fx-border-radius: 5px 5px 5px 5px;
}
#history:hover{
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#history:pressed{
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#downloadMenuBar{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-max-height: 40px;
-fx-max-width: 68px;
-fx-alignment: center;
}
#downloadMenu{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-alignment: center;
-fx-border-width: 0px;
-fx-min-width: 68px;
-fx-min-height: 40px;
}
.menu-item{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
}
.menu-item:hover{
-fx-background-color: rgba(64, 158, 255, 1);
}
progressbar.css
.progress-bar {
-fx-indeterminate-bar-length: 70;
-fx-indeterminate-bar-animation-time: 1.5;
}
.progress-bar > .track {
-fx-background-color: #F2F3F5;
-fx-border-color: #D4D7DE;
-fx-border-radius: 3px;
}
.progress-bar > .bar {
-fx-pref-height: 6px;
-fx-background-insets: 0;
-fx-background-radius: 3px;
-fx-background-color:#5C80EF;
}
tabpane.css
.tab-pane {
-fx-border-color: rgba(193, 197, 205, 1) rgba(193, 197, 205, 1) rgba(193, 197, 205, 1) rgba(193, 197, 205, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-border-width: 0px;
-fx-tab-min-width: 100px;
-fx-tab-max-width: 150px;
-fx-tab-min-height: 30px;
}
.tab-pane .tab-header-background {
-fx-background-color: rgba(0, 0, 0, 0);
-fx-border-color: rgba(228, 231, 237, 1) rgba(228, 231, 237, 1) rgba(228, 231, 237, 1) rgba(228, 231, 237, 1);
-fx-border-width: 0px 0px 0px 0px;
}
.tab-pane:top .tab-header-area {
-fx-background-insets: 0px 0px 1px 0px;
-fx-padding: 5px 2px 5px 0px;
}
.tab-pane:focused .tab:selected {
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
}
.tab-pane:focused .tab:selected .tab-label {
-fx-text-fill: rgba(64, 158, 255, 1);
}
.tab-pane:focused .tab:hover .tab-label {
-fx-text-fill: rgba(64, 158, 255, 1);
}
.tab-pane .tab {
-fx-padding: 1px 16px 1px 16px;
-fx-cursor: HAND;
-fx-background-color: rgba(0, 0, 0, 0);
-fx-border-width: 0px 0px 0px 0px;
-fx-border-color: rgba(228, 231, 237, 1) rgba(228, 231, 237, 1) rgba(228, 231, 237, 1) rgba(228, 231, 237, 1);
}
.tab-pane .tab .tab-label {
-fx-font-size: 15px;
}
.tab-pane .tab .focus-indicator {
-fx-border-width: 0px 0px 3px 0px;
}
textfiled.css
#textFiled{
-fx-text-fill: #303133;
-fx-font-size: 14px;
-fx-font-weight: 500;
-fx-border-color: #D4D7DE;
-fx-border-radius: 3px;
-fx-background-radius: 3px;
-fx-background-insets:0;
-fx-background-color:transparent;
}
topbutton.css
#min{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-font-size: 15px;
-fx-padding: 5px 10px 5px 10px;
-fx-cursor: HAND;
}
#max{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-font-size: 15px;
-fx-padding: 5px 10px 5px 10px;
-fx-cursor: HAND;
}
#close{
-fx-background-color: rgba(236, 245, 255, 1);
-fx-background-radius: 5px 5px 5px 5px;
-fx-border-color: rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1) rgba(179, 216, 255, 1);
-fx-border-radius: 5px 5px 5px 5px;
-fx-text-fill: rgba(64, 158, 255, 1);
-fx-font-size: 15px;
-fx-padding: 5px 10px 5px 10px;
-fx-cursor: HAND;
}
#min:hover {
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#max:hover {
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#close:hover {
-fx-background-color: rgba(64, 158, 255, 1);
-fx-border-color: rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1) rgba(64, 158, 255, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#min:pressed {
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#max:pressed {
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
#close:pressed {
-fx-background-color: rgba(58, 142, 230, 1);
-fx-border-color: rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1) rgba(58, 142, 230, 1);
-fx-text-fill: rgba(255, 255, 255, 1);
}
tophbox.css
#topHBox{
-fx-padding: 0px 0px 5px 0px;
-fx-alignment: center;
-fx-spacing: 10px;
}