IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JavaFx:窗口切换和ListView以及TableView的值绑定 -> 正文阅读

[Java知识库]JavaFx:窗口切换和ListView以及TableView的值绑定

1. 声明

当前内容主要用于本人学习和使用JavaFx实现窗口切换,以及为ListView和TableView绑定数据的操作

主要坑

  1. 由于前面使用了openjfx 11的版本,结果在为ListView获取点击事件的时候出现了字节码不匹配的错误(果断切换回jdk自带的javafx)
  2. TableView绑定数据时需要将bean的属性和字段绑定

2. 前期工作(切换jdk8的javafx)

找到java的jdk目录下jfxrt.jar这个jar包就可以了
在这里插入图片描述
将之前的openjfx 11的版本从库中删除,添加这个即可
在这里插入图片描述

3.开始使用SceneBuilder画图(实现登录和数据展示页面)

在这里插入图片描述
在这里插入图片描述
然后为其添加各种fx:id和点击事件

最后fxml为

1.login.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>


<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.151" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.hy.java.gui.javafx.iotdb.controller.LoginController">
   <children>
      <Pane prefHeight="404.0" prefWidth="600.0">
         <children>
            <Button layoutX="396.0" layoutY="331.0" mnemonicParsing="false" onAction="#login" text="登录" />
            <Label layoutX="133.0" layoutY="116.0" text="ip" />
            <TextField fx:id="iotdbIp" layoutX="246.0" layoutY="107.0" />
            <Label layoutX="133.0" layoutY="168.0" text="port" />
            <TextField fx:id="iotdbPort" layoutX="246.0" layoutY="159.0" />
            <Label layoutX="133.0" layoutY="228.0" text="username" />
            <TextField fx:id="iotdbUsername" layoutX="246.0" layoutY="219.0" />
            <Label layoutX="168.0" layoutY="32.0" text="欢迎使用IOTDB可视化访问工具">
               <font>
                  <Font size="18.0" />
               </font>
            </Label>
            <Label layoutX="133.0" layoutY="283.0" text="password" />
            <TextField fx:id="iotdbPassword" layoutX="246.0" layoutY="274.0" />
            <Label fx:id="loginMsg" layoutX="197.0" layoutY="336.0" prefHeight="20.0" prefWidth="150.0" />
         </children>
      </Pane>
   </children>
</VBox>

2.main.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>


<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="601.0" prefWidth="874.0" xmlns="http://javafx.com/javafx/8.0.151" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.hy.java.gui.javafx.iotdb.controller.MainController">
   <children>
      <SplitPane dividerPositions="0.17879948914431673" prefHeight="606.0" prefWidth="874.0">
        <items>
          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
               <children>
                  <ListView fx:id="storageGroupList" prefHeight="499.0" prefWidth="136.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
               </children>
            </AnchorPane>
          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
               <children>
                  <TableView fx:id="mpInfo" prefHeight="499.0" prefWidth="639.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                    <columns>
                        <TableColumn prefWidth="97.0" text="测点名称">
					       
					     </TableColumn>
					     <TableColumn prefWidth="98.0" text="当前时间">
					       
					     </TableColumn>
					     <TableColumn prefWidth="119.0" text="当前值">
					        
					    </TableColumn>
                    </columns>
                  </TableView>
               </children>
            </AnchorPane>
        </items>
      </SplitPane>
   </children>
</VBox>

4. 简单的实现

1.关于窗口切换,个人简单的思路就是使用全局的进行标记,然后调用Stage的hide()和show(),来完成窗口的显示和隐藏,完成窗口的切换

1.基本的controller层

LoginController

package com.hy.java.gui.javafx.iotdb.controller;

import java.io.IOException;

import com.hy.java.gui.javafx.iotdb.AppConstant;
import com.hy.java.gui.javafx.iotdb.properties.IotDBProperties;
import com.hy.java.gui.javafx.iotdb.utils.MsgUtils;
import com.hy.java.gui.javafx.iotdb.utils.NumberUtils;
import com.hy.java.gui.javafx.iotdb.utils.StringUtils;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.scene.control.Alert.AlertType;
/**
 * 
 * @author hy
 * @createTime 2021-07-25 17:09:00
 * @description 主要的登录界面
 *
 */
public class LoginController {
	@FXML
	TextField iotdbIp;
	@FXML
	TextField iotdbPort;
	@FXML
	TextField iotdbUsername;
	@FXML
	TextField iotdbPassword;
	@FXML
	Label loginMsg;

	@FXML
	public void login(Event event) {
		// 检查登录参数是否填写完毕
		boolean check = loginCheck();
		if (check) {
			IotDBProperties iotDBProperties = createIotDBProperties();
			boolean checkCanConnectionTODB = checkCanConnectionTODB(iotDBProperties);
			if (!checkCanConnectionTODB) {
				MsgUtils.alert(AlertType.ERROR, "错误", "打开连接失败!");
				loginMsg.setText("打开连接失败!");
				loginMsg.setTextFill(Color.RED);
			} else {
				// 直接打开另外一个界面
				try {
					if (AppConstant.mainStage == null) {
						openMainStage(new Stage());
					}else {
						openMainStage(AppConstant.mainStage);
					}

				} catch (IOException e) {
					e.printStackTrace();
					MsgUtils.alert(AlertType.ERROR, "错误", e.getMessage());
				}

			}
		}

	}

	private void openMainStage(Stage mainStage) throws IOException {
		Parent root = FXMLLoader.load(getClass().getResource("../resources/main.fxml"));
		Scene scene = new Scene(root, 500, 450);
		mainStage.setTitle("open other window");
		mainStage.setScene(scene);
		mainStage.setOnCloseRequest((event) -> {
			AppConstant.loginStage.show();
			mainStage.close();
		});
		// 保存上一次的状态
		AppConstant.mainStage = mainStage;
		AppConstant.loginStage.hide();
		mainStage.show();
	}

	private boolean loginCheck() {
		String ipString = iotdbIp.getText();
		String portString = iotdbPort.getText();
		String usernameString = iotdbUsername.getText();
		String passwordString = iotdbPassword.getText();

		if (StringUtils.isEmpty(ipString)) {
			iotdbIp.setText(AppConstant.DEFAULT_IP);
		}
		if (StringUtils.isEmpty(portString)) {
			iotdbPort.setText(String.valueOf(AppConstant.DEFAULT_PORT));
		} else {
			boolean intNum = NumberUtils.isIntNum(portString);
			if (!intNum) {
				MsgUtils.alert(AlertType.ERROR, "错误", "当前输入的端口=" + portString + "不是整数");
				return false;
			}
		}
		if (StringUtils.isEmpty(usernameString)) {
			iotdbUsername.setText(AppConstant.DEFAULT_USERNAME);
		}
		if (StringUtils.isEmpty(passwordString)) {
			iotdbPassword.setText(AppConstant.DEFAULT_PASSWORD);
		}
		return true;

	}

	private IotDBProperties createIotDBProperties() {
		String ipString = iotdbIp.getText();
		String portString = iotdbPort.getText();
		String usernameString = iotdbUsername.getText();
		String passwordString = iotdbPassword.getText();
		IotDBProperties iotDBProperties = new IotDBProperties();
		iotDBProperties.setIp(ipString);
		iotDBProperties.setPort(portString);
		iotDBProperties.setUsername(usernameString);
		iotDBProperties.setPassword(passwordString);
		return iotDBProperties;
	}

	private boolean checkCanConnectionTODB(IotDBProperties iotDBProperties) {
		return true;
	}

}

MainController

package com.hy.java.gui.javafx.iotdb.controller;

import java.net.URL;
import java.util.ResourceBundle;
import com.hy.java.gui.javafx.iotdb.pojo.MeasurementPointData;
import com.sun.javafx.scene.control.skin.LabeledText;
import javafx.collections.ObservableList;
import javafx.event.EventTarget;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ListView;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
/**
 * 
 * @author hy
 * @createTime 2021-07-25 17:08:29
 * @description 主要查看iotdb数据的地方
 *
 */
public class MainController implements Initializable {
	@FXML
	ListView<String> storageGroupList; // 左边显示存储组
	@FXML
	TableView<MeasurementPointData> mpInfo; // 右边存放mpInfo的信息

	@Override
	public void initialize(URL arg0, ResourceBundle arg1) {
		// TODO Auto-generated method stub
		// SimpleListProperty<String> storageGroupDatas=new
		// SimpleListProperty<String>();
		ObservableList<String> items = storageGroupList.getItems();
		items.add("root.test.machine");
		items.add("root.test.machine1");
		// 开始获取当前的table中的数据,必须通过点击事件获取,例如点击左边的测点
		storageGroupList.setOnMouseClicked((event) -> {
			// System.out.println("listView==>event=" + event);
			EventTarget target = event.getTarget();
			System.out.println(target);
			// 这里不能执行强制类型转换操作,由于字节码文件不支持(54,而当前为52)
			if (target == null) {
				return;
			}
			if (target instanceof LabeledText) {
				LabeledText clickLabeledText = (LabeledText) target;
				String text = clickLabeledText.getText();

				System.out.println("获取当前点击的目标存储组为:" + text);
				// 下面这里可能从iotdb中获取实际的数据,并加载数据到TableView
				setMpDataFromDB(text);
			}

		});

		ObservableList<TableColumn<MeasurementPointData, ?>> columns = mpInfo.getColumns();
		columns.clear();
		// 开始将列的值与当前的javabean的属性进行绑定
		TableColumn<MeasurementPointData, Object> columne1 = new TableColumn<MeasurementPointData, Object>("测点名称");
		TableColumn<MeasurementPointData, Object> columne2 = new TableColumn<MeasurementPointData, Object>("时间");
		TableColumn<MeasurementPointData, Object> columne3 = new TableColumn<MeasurementPointData, Object>("值");
		columne1.setCellValueFactory(new PropertyValueFactory<MeasurementPointData, Object>("mpName"));
		columne2.setCellValueFactory(new PropertyValueFactory<MeasurementPointData, Object>("timestamp"));
		columne3.setCellValueFactory(new PropertyValueFactory<MeasurementPointData, Object>("value"));
		columns.add(columne1);
		columns.add(columne2);
		columns.add(columne3);


	}

	private void setMpDataFromDB(String storageGroupName) {
		// 这里应该从iotdb数据库中加载数据
		ObservableList<MeasurementPointData> items = mpInfo.getItems();
		items.clear();
		MeasurementPointData mpData = new MeasurementPointData();
		mpData.setMpName("root.test.machine.value");
		mpData.setTimestamp("1");
		mpData.setValue("999");
		items.add(mpData);
		System.out.println(items);
	}

}

2.程序常量类和pojo类和properties类

package com.hy.java.gui.javafx.iotdb;

import javafx.stage.Stage;

/**
 * 
 * @author hy
 * @createTime 2021-07-25 13:49:05
 * @description 定义系统运行中的常量部分
 *
 */
public  abstract class AppConstant {
	public static final String DEFAULT_IP = "localhost";
	public static final int DEFAULT_PORT = 6667;
	public static final String DEFAULT_USERNAME = "root";
	public static final String DEFAULT_PASSWORD = "root";
	//public static final String LOGIN_RESOURCE_LOCATION="";
	//public static final String MAIN_RESOURCE_LOCATION="../main";
	public static Stage loginStage;
	public static Stage mainStage;
}

package com.hy.java.gui.javafx.iotdb.pojo;

import javafx.beans.property.SimpleStringProperty;

public class MeasurementPointData {
	private String mpName;
	private String timestamp;
	private String value;
	// 省略getset之类的方法
	
}

package com.hy.java.gui.javafx.iotdb.properties;

public class IotDBProperties {
	private String ip;
	private String port;
	private String username;
	private String password;
	// 省略getset之类的方法

}

3.各种工具类

package com.hy.java.gui.javafx.iotdb.utils;

import java.util.Optional;

import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Alert.AlertType;

public abstract class MsgUtils {
	public static void alert(AlertType alertType, String title, String msg) {
		Alert alert = new Alert(alertType, msg, ButtonType.YES, ButtonType.NO);
		alert.setTitle(title);
		alert.setHeaderText("");
		Optional<ButtonType> showAndWait = alert.showAndWait();
		if (showAndWait.get() == ButtonType.YES) {
			alert.close();
		}
	}
}

package com.hy.java.gui.javafx.iotdb.utils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public abstract class NumberUtils {
	private static final String INT_STRING_REGEX = "^\\d+$";
	private static final Pattern INT_STRING_PATTERN = Pattern.compile(INT_STRING_REGEX);

	public static boolean isIntNum(String text) {
		Matcher matcher = INT_STRING_PATTERN.matcher(text);
		return matcher.matches();
	}
}

package com.hy.java.gui.javafx.iotdb.utils;

public abstract class StringUtils {
	public static boolean isEmpty(String text) {
		if (text == null || "".equals(text.trim())) {
			return true;
		}
		return false;
	}
}

实际入口类

package com.hy.java.gui.javafx.iotdb;

import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class IotdbJavaFxApplication extends Application {

	@Override
	public void start(Stage stage) throws Exception {
		Parent root = FXMLLoader.load(getClass().getResource("resources/login.fxml"));
		Scene scene = new Scene(root, 500, 450);
		stage.setTitle("iotdb view login");
		stage.setScene(scene);
		stage.setOnShown(new EventHandler() {

			@Override
			public void handle(Event event) {
				// TODO Auto-generated method stub
				System.out.println("event=" + event);

			}
		});
		AppConstant.loginStage = stage;
		stage.show();
	}

	public static void main(String[] args) {
		launch(args);
	}

}

5. 测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

并且实现了点击关闭,可以返回到登录界面

6. 总结

1.对于javafx的版本,尽量按照jdk版本选择javafx,否则出现奇怪的问题

2.对于为TableVie绑定值的时候需要手动使用columne1.setCellValueFactory(new PropertyValueFactory<MeasurementPointData, Object>("mpName"));方式设置取址工厂,这样才会将取值和javabean联系在一起

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章           查看所有文章
加:2021-07-26 11:56:40  更:2021-07-26 11:59:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/27 5:41:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码