javafx 创建windows程序记录1 创建项目及准备

Main函数

使用idea 或 e(fx)lipse创建javafx项目,自动生成的入口文件

    private static final Logger logger = Logger.getLogger(Main.class.getName());
	private Stage stage;
	private ShowPhotoController showPhotoController;

	@Override
	public void start(Stage primaryStage) throws Exception {

		this.stage = primaryStage;
		primaryStage.setTitle("魑魅魍魉");  //程序标题
		primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("images/icon.png"))); //设置图标
		//primaryStage.initStyle(StageStyle.UNDECORATED);// 隐藏标题栏
		initRootLayout();  //此处设置程序进入界面
		
		//程序关闭时操作
		stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
			@Override
			public void handle(WindowEvent event) {
				if (showPhotoController != null) {
					showPhotoController.closeMonitor();
				}
				Platform.exit();
			}
		});
	}

private void initRootLayout() {
		try {
			FXMLLoader loader = new FXMLLoader();
			loader.setLocation(getClass().getResource("login/activity_login.fxml")); // 静态读取,无法获取controller
			GridPane rootLayout = loader.load();  //activity_login.fxml的跟标签必须是GridPane  若返回其他则相应修改
			Scene scene = new Scene(rootLayout, width, height);  //新建场景
			stage.setScene(scene); //设置场景

			LoginController loginController = loader.getController();  //获取场景对应的Controller 用于控制页面显示
			loginController.init(stage);

			stage.show();  //显示页面
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	private double width = 562; // 窗口宽度
	private double height = 342; // 窗口高度
//部分代码省略

.fxml 界面

界面可视化需要添加插件 Scene builder 网上有教程,请自行百度

  // 注意此处设置对应的controller
<GridPane fx:id="root" alignment="center" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.login.LoginController">
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<?import com.jfoenix.controls.JFXTextField?>
<?import com.jfoenix.controls.JFXPasswordField?>
<?import com.jfoenix.controls.JFXButton?>
<GridPane fx:id="root" alignment="center" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.login.LoginController">
   <children>
      <Pane fx:id="root_view" prefHeight="342.0" prefWidth="562.0" >
          <children>

              <Label layoutX="160.0" layoutY="200.0" prefHeight="23.0" prefWidth="80" text="用户名:" textAlignment="CENTER" textFill="WHITE"
                     style="-fx-font-size:16px;fx-text-fill:WHITE;-fx-prompt-text-fill:WHITE;"
              />

              <JFXTextField fx:id="userName"  onKeyPressed="#usernamePressed" layoutX="240" layoutY="190.0"
                            minWidth="160"
                            prefHeight="23.0" prefWidth="100.0" promptText="请输入用户名"
                            style="-fx-font-size:16px;-fx-text-fill:white;-fx-prompt-text-fill:white;" >
              </JFXTextField>


              <Label layoutX="160.0" layoutY="240.0" prefHeight="23.0" prefWidth="80" text="密   码:" textAlignment="CENTER" textFill="WHITE"
                     style="-fx-font-size:16px;-fx-text-fill:WHITE;-fx-prompt-text-fill:WHITE;"
              />
              <JFXPasswordField fx:id="password" layoutX="240.0" layoutY="230.0"
                                minWidth="160"
                                prefHeight="23.0" prefWidth="100.0" onKeyPressed="#passwordPressed"
                                promptText="请输入密码" style="-fx-font-size:16px;-fx-text-fill:white;-fx-prompt-text-fill:white;">
              </JFXPasswordField>

              <JFXButton fx:id="btn_login" buttonType="RAISED"
                         layoutX="220.0" layoutY="280.0"
                         onAction="#onLogin" prefHeight="35" prefWidth="100" style="-fx-font-size:14px;-fx-background-color:WHITE;" text="登录" />

          </children>
      </Pane>
   </children>
    <columnConstraints>
        <ColumnConstraints />
    </columnConstraints>
    <rowConstraints>
        <RowConstraints />
    </rowConstraints>
</GridPane>

CONTROLLER 用于操作页面显示,处理数据等

	//所有.fxml页面的fx:id 在controller中需要使用@FXML注解声明
	@FXML
	private TextField userName;
	@FXML
	private TextField password;
	@FXML
	private JFXButton btn_login;  //使用JFXButton需要导入jar包
	@FXML
	private Pane root_view;
	
	private Stage primaryStage;
	private Preferences prefs;  //实现缓存数据
	public void init(Stage primaryStage) {
		this.primaryStage = primaryStage;
		//设置页面背景 背景路径为工程跟路径开始,最终打包时,需将其目录拷贝到打包文件夹下
		BackgroundImage myBI = new BackgroundImage(new Image("images/login.bg", 562, 342, false, true), BackgroundRepeat.REPEAT,
				BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT, BackgroundSize.DEFAULT);
		root_view.setBackground(new Background(myBI));
		
		prefs = Preferences.userNodeForPackage(Main.class);  //实现用户缓存

		String username = prefs.get("username", "");
		userName.setText(username);  //自动填入缓存的账号
		
		if (!StringUtil.isEmpty(username)) {  //账号不为空,自动选中密码输入框
			password.requestFocus();
			password.selectAll();
		}
	}

	public void initialize() {
	//会先调用
	}

	@FXML
	public void passwordPressed(KeyEvent keyEvent) {
		KeyCode code = keyEvent.getCode();
		if (code == KeyCode.ENTER) {
			onLogin();
		}
	}
	@FXML
	public void usernamePressed(KeyEvent keyEvent) {
		KeyCode code = keyEvent.getCode();
		if (code == KeyCode.ENTER) {
			password.requestFocus();
		}
	}

@FXML
	public void onLogin() {
		String userNameText = userName.getText();
		String passwordText = password.getText();

		if (StringUtil.isEmpty(userNameText)) {
			ToastUtil.toast("请输入用户名", 1500);
			return;
		}

		if (StringUtil.isEmpty(passwordText)) {
			ToastUtil.toast("请输入密码", 1500);
			return;
		}

		HashMap<String, String> hashMap = new HashMap<>();
		hashMap.put("username", userNameText);
		hashMap.put("password", MD5Util.getMD5Str(passwordText));

		btn_login.setDisable(true); // 点击之后按钮不可用
		//封装的网络请求
		DialogUtil.showDialog1(primaryStage, "正在登录...");
		HttpUtil.getInstance().post(hashMap, HttpUtil.uri_login, new HttpCallBack() {
			@Override
			public void success(String success) {
				System.out.println("success>>" + success);
				saveUserNameAndPassword(userNameText, passwordText);
				saveSuccessData(success);
				parseSuccess(success);
			}

			@Override
			public void fail(String fail) {
				Platform.runLater(new Runnable() { // 主线程中完成
					@Override
					public void run() {
						btn_login.setDisable(false); // 还原按钮
						DialogUtil.dismissDialog();
						ToastUtil.toast(fail, 1500);
					}
				});
			}
		});
	}

其他内容

在这里插入图片描述
需要导入的包,若复制本程序,请注意版本
导包右键——》add as lib…
本程序使用OKHTTP
在这里插入图片描述

使用到的工具类

1、DialogUtil
package sample.utils;

import com.jfoenix.controls.JFXAlert;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXDialogLayout;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class DialogUtil {

	private static JFXAlert alert;

	public static void showDialog(Stage primaryStage, String title, String message, String btnStr) {
		alert = new JFXAlert(primaryStage);
		alert.initModality(Modality.APPLICATION_MODAL);
		alert.setOverlayClose(false);
		JFXDialogLayout layout = new JFXDialogLayout();
		layout.setHeading(new Label(title));
		layout.setBody(new Label(message));
		JFXButton closeButton = new JFXButton(btnStr);
		closeButton.getStyleClass().add("dialog-accept");
		closeButton.setOnAction(event -> alert.hideWithAnimation());
		layout.setActions(closeButton);
		alert.setContent(layout);
		alert.show();
	}

	public static void showDialog1(Stage primaryStage, String message) {
		alert = new JFXAlert(primaryStage);
		alert.initModality(Modality.APPLICATION_MODAL);
		alert.setOverlayClose(false);
		JFXDialogLayout layout = new JFXDialogLayout();
		VBox vBox = new VBox();
		ProgressBar progressBar = new ProgressBar();
		vBox.getChildren().add(progressBar);
		vBox.setAlignment(Pos.CENTER);
		vBox.getChildren().add(new Label(message));
		layout.setBody(vBox);
		alert.setContent(layout);
		alert.show();
	}

	public static void dismissDialog() {
		if (alert != null) {
			alert.hide();
		}
	}

}

2、HttpCallBack 及,网络请求 HttpUtil
package sample.utils;

public interface HttpCallBack {
	void success(String success);

	void fail(String fail);
}
/
package sample.utils;

import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.omg.Messaging.SYNC_WITH_TRANSPORT;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class HttpUtil {
	private static String PrefixURL ="http://localhost:9000";
	public static String uri_login = "/login";
	
	private final OkHttpClient mOkHttpClient;
	private volatile static HttpUtil INSTANCE;

	private Interceptor netCacheInterceptor = new Interceptor() {
		@Override
		public Response intercept(Chain chain) throws IOException {
			Request request = chain.request();
			HttpUrl httpUrl = request.url().newBuilder().build();
			Request build;
			System.out.println("请求地址》》" + httpUrl.url());
			if (!StringUtil.isEmpty(session)) {
				build = request.newBuilder()
						// add common header
						.addHeader("contentType", "application/json; charset=utf-8").addHeader("cookie", session)
						.url(httpUrl).build();
			} else {
				build = request.newBuilder()
						// add common header
						.addHeader("contentType", "application/json; charset=utf-8").url(httpUrl).build();
			}
			Response response = chain.proceed(build);
			return response;
		}
	};

	public HttpUtil() {
		OkHttpClient.Builder builder = new OkHttpClient.Builder();
		// 设置超时
		builder.connectTimeout(60, TimeUnit.SECONDS);
		builder.readTimeout(60, TimeUnit.SECONDS);
		builder.writeTimeout(60, TimeUnit.SECONDS);
		// 错误重连
		// builder.retryOnConnectionFailure(true);
		//设置拦截器
		// builder.addInterceptor(netCacheInterceptor);
		mOkHttpClient = builder.build();
	}
//单例
	public static HttpUtil getInstance() {
		if (INSTANCE == null) {
			synchronized (HttpUtil.class) {
				if (INSTANCE == null) {
					INSTANCE = new HttpUtil();
				}
			}
		}
		return INSTANCE;
	}
	
	/**
	get请求
	*/
	public void get(String uri, HttpCallBack callBack) {
		Request request = new Request.Builder().addHeader("Content-Type", "application/json; charset=utf-8")
				.url(PrefixURL + uri).get().build();
		Call call = mOkHttpClient.newCall(request);
		call.enqueue(new Callback() {
			@Override
			public void onFailure(Call call, IOException e) {
				callBack.fail("请求失败");
			}

			@Override
			public void onResponse(Call call, okhttp3.Response response) throws IOException {
				boolean successful = response.isSuccessful();  
				String success = response.body().string();  //返回结果
				if (successful) {
					callBack.success(success);
				} else {
					callBack.fail("请求失败");
				}

			}
		});
	}

	private String session;  //请求的session
	public void post(Map<String, String> map, String uri, HttpCallBack callBack) {
		FormBody.Builder builder = new FormBody.Builder();
		for (String in : map.keySet()) {
			builder.add(in, map.get(in));
		}
		RequestBody body = builder.build();
		Request.Builder builder1 = new Request.Builder();
		builder1.addHeader("Content-Type", "application/json; charset=utf-8");
		if (!StringUtil.isEmpty(session)) {
			builder1.addHeader("cookie", session);
		}
		Request request = builder1.url(PrefixURL + uri).post(body).build();
		Call call = mOkHttpClient.newCall(request);
		call.enqueue(new Callback() {
			@Override
			public void onFailure(Call call, IOException e) {
				System.out.println("请求失败");
				callBack.fail("请求失败");
			}

			@Override
			public void onResponse(Call call, okhttp3.Response response) throws IOException {
				Headers headers = response.headers();
				List<String> cookies = headers.values("Set-Cookie");
				if (cookies.size() > 0) {
					String s = cookies.get(0);
					session = s.substring(0, s.indexOf(";"));  //取到session 用户下次请求 无session不影响
					System.out.println("session>>>" + session);
				}

				boolean successful = response.isSuccessful();
				String success = response.body().string();
				// System.out.println("请求结果>>>"+success);
				if (successful) {
						callBack.success(success);
				} else {
					  callBack.fail("请求失败");
				}
			}
		});
	}

/**
* 带token请求
*/
	public void postToken(Map<String, String> map, String uri, HttpCallBack callBack, String token) {
		FormBody.Builder builder = new FormBody.Builder();
		for (String in : map.keySet()) {
			builder.add(in, map.get(in));
		}
		RequestBody body = builder.build();
		Request request = new Request.Builder().addHeader("Content-Type", "application/json; charset=utf-8")
				.addHeader("Authorization", "Bearer " + token).url(PrefixURL + uri).post(body).build();
		Call call = mOkHttpClient.newCall(request);
		call.enqueue(new Callback() {
			@Override
			public void onFailure(Call call, IOException e) {
				callBack.fail("请求失败");
			}

			@Override
			public void onResponse(Call call, okhttp3.Response response) throws IOException {
				boolean successful = response.isSuccessful();
				String success = response.body().string();
				if (successful) {
					callBack.success(success);
				} else {
					callBack.fail("请求失败");
				}
			}
		});
	}

	private String BASE_PIC_URL = "http://localhost:8888";
 //上传文件
	public void uploadFile(Map<String, String> map, File[] files, String uri, HttpCallBack callBack) {
		MultipartBody.Builder builder = new MultipartBody.Builder();
		builder.setType(MultipartBody.FORM);
		builder.addFormDataPart("参数1", map.get("参数1"));
		builder.addFormDataPart("参数2", map.get("参数2"));
		for (int i = 0; i < files.length; i++) {
			File file = files[i];
			System.out.println("file>>" + file.getPath());
			int num = file.getName().indexOf(".");
			RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpeg"), file);// 将file转换成RequestBody文件
																							// 这里以MP4视频为例
			builder.addFormDataPart("photos[" + file.getName().substring(0, num) + "]", file.getName().toLowerCase(), fileBody);
		}
		MultipartBody requestBody = builder.build();
		Request request = new Request.Builder().url(BASE_PIC_URL + uri).post(requestBody).build();

		Call call = mOkHttpClient.newCall(request);
		call.enqueue(new Callback() {
			@Override
			public void onFailure(Call call, IOException e) {
				System.out.println("上传图片》》失败");
				callBack.fail("上传失败");
			}

			@Override
			public void onResponse(Call call, Response response) throws IOException {
				boolean successful = response.isSuccessful();
				String success = response.body().string();
				System.out.println("上传图片》》success》》" + success);
				if (successful) {
					callBack.success(success);
				} else {
					callBack.fail("上传失败");
				}
			}
		});
	}

/**
请求体 json传参
**/
	public void postJson(JSONObject jsonObject, String uri, HttpCallBack callBack) {
		MediaType JSON = MediaType.parse("application/json; charset=utf-8");
		RequestBody body = RequestBody.create(JSON, String.valueOf(jsonObject));

		Request.Builder builder1 = new Request.Builder();
		builder1.addHeader("Content-Type", "application/json; charset=utf-8");
		if (!StringUtil.isEmpty(session)) {
			builder1.addHeader("cookie", session);
		}
		Request request = builder1.url(PrefixURL + uri).post(body).build();

		Call call = mOkHttpClient.newCall(request);
		call.enqueue(new Callback() {
			@Override
			public void onFailure(Call call, IOException e) {
				System.out.println("请求失败");
				callBack.fail("请求失败");
			}

			@Override
			public void onResponse(Call call, okhttp3.Response response) throws IOException {
				Headers headers = response.headers();
				List<String> cookies = headers.values("Set-Cookie");
				if (cookies.size() > 0) {
					String s = cookies.get(0);
					session = s.substring(0, s.indexOf(";"));
					System.out.println("session>>>" + session);
				}

				boolean successful = response.isSuccessful();
				String success = response.body().string();
				// System.out.println("请求结果>>>"+success);
				if (successful) {
					callBack.success(success);
				} else {
					callBack.fail("请求失败");
				}
			}
		});
	}
}


3、MD5Util
package sample.utils;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Util {

	public static String getMD5Str(String str) {
		byte[] digest = null;
		try {
			MessageDigest md5 = MessageDigest.getInstance("md5");
			digest = md5.digest(str.getBytes("utf-8"));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		// 16是表示转换为16进制数
		String md5Str = new BigInteger(1, digest).toString(16);
		return md5Str;
	}

}
4、StringUtil
package sample.utils;

public class StringUtil {

	public static boolean isEmpty(String str) {
		return str == null || str.length() == 0 || str.trim() == "";
	}

}

5、ToastUtil 貌似是从哪copy的
package sample.utils;

import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import java.util.Timer;
import java.util.TimerTask;

/*
 *@author unclezs.com
 *@date 2019.07.06 12:46
 */
public class ToastUtil {
	private static Stage stage = new Stage();
	private static Label label = new Label();
	static {
		stage.initStyle(StageStyle.TRANSPARENT);// 舞台透明
	}

	// 默认3秒
	public static void toast(String msg) {
		toast(msg, 3000);
	}

	/**
	 * 指定时间消失
	 * 
	 * @param msg
	 * @param time
	 */
	public static void toast(String msg, int time) {
		label.setText(msg);
		TimerTask task = new TimerTask() {
			@Override
			public void run() {
				Platform.runLater(() -> stage.close());
			}
		};
		init(msg);
		Timer timer = new Timer();
		timer.schedule(task, time);
		stage.show();
	}

	// 设置消息
	private static void init(String msg) {
		Label label = new Label(msg);// 默认信息
		label.setStyle("-fx-background: rgba(56,56,56,0.7);-fx-border-radius: 25;-fx-background-radius: 25");// label透明,圆角
		label.setTextFill(Color.rgb(225, 255, 226));// 消息字体颜色
		label.setPrefHeight(50);
		label.setPadding(new Insets(15));
		label.setAlignment(Pos.CENTER);// 居中
		label.setFont(new Font(20));// 字体大小
		Scene scene = new Scene(label);
		scene.setFill(null);// 场景透明
		stage.setScene(scene);
	}
}

图片压缩库

thumbnailator-0.4.8.jar

// outPath 输入路径文件夹 
//File[] files 要压缩的图片文件列表
	Thumbnails.of(files)
					.scale(1f)
					.outputQuality(0.8f)
					.toFiles(new File(outPath),Rename.NO_CHANGE);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值