日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

基于JavaFX的Linux进程树

發布時間:2025/3/15 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于JavaFX的Linux进程树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

最近學Linux,有一個Linux進程樹的作業,本來是有C源碼的,為了練手,寫了一個Java帶有GUI版本的。
本博客和源代碼原創,轉載請注明!
本文鏈接
個人博客:https://ronglin.fun/?p=138
PDF鏈接:見博客網站
CSDN: https://blog.csdn.net/RongLin02/article/details/116244641
先看成果,可配合一起食用:Linux學習之打印進程樹

源代碼

工程目錄結構如下:

源碼一共700多行

Fxml文件

Main.fxml 文件,用Scene Builder生成的

<?xml version="1.0" encoding="UTF-8"?><?import javafx.scene.text.*?> <?import javafx.scene.control.*?> <?import java.lang.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.layout.AnchorPane?><BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller.MainController"><top><HBox alignment="CENTER" prefHeight="50.0" prefWidth="600.0" BorderPane.alignment="CENTER"><children><HBox alignment="CENTER" nodeOrientation="LEFT_TO_RIGHT" prefHeight="50.0" prefWidth="325.0"><children><Label fx:id="Label_Time" style="-fx-background-color: #D4F2E7;" text="1970年01月01日00:00:00" underline="true"><font><Font size="18.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0"><children><Button fx:id="button_fresh" mnemonicParsing="false" onAction="#freshPage" prefHeight="50.0" prefWidth="150.0" text="刷新" textAlignment="CENTER" textFill="RED" HBox.hgrow="ALWAYS"><font><Font size="24.0" /></font></Button></children></HBox><HBox alignment="CENTER" prefHeight="50.0" prefWidth="325.0"><children><Label fx:id="Label_IP" style="-fx-background-color: #D4F2E7;" text="192.168.255.255" underline="true"><font><Font size="18.0" /></font></Label></children></HBox></children></HBox></top><left><ScrollPane fitToHeight="true" fitToWidth="true" prefWidth="400.0"><content><VBox><children><TreeView fx:id="treeView_procs" VBox.vgrow="ALWAYS" /></children></VBox></content></ScrollPane></left><center><GridPane alignment="CENTER" gridLinesVisible="true" style="-fx-background-color: #87CEFA;" BorderPane.alignment="CENTER"><columnConstraints><ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /><ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /></columnConstraints><rowConstraints><RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /><RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /><RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /><RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /><RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /><RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /><RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /><RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /><RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /><RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /></rowConstraints><children><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0"><children><Label text="Name:"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1"><children><Label fx:id="Label_Name" text="systemd" textAlignment="CENTER" underline="true"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="1"><children><Label text="State:"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1"><children><Label fx:id="Label_State" text="S" underline="true"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="2"><children><Label text="Pid:" textAlignment="CENTER"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2"><children><Label fx:id="Label_Pid" text="1" underline="true"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="3"><children><Label text="PPid:" textAlignment="CENTER"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="3"><children><Label fx:id="Label_PPid" text="0" underline="true"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="4"><children><Label text="NStgid:"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="4"><children><Label fx:id="Label_NStgid" text="1" underline="true"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="5"><children><Label text="NSpid:"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="5"><children><Label fx:id="Label_NSpid" text="1" underline="true"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="6"><children><Label text="NSpgid:"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="6"><children><Label fx:id="Label_NSpgid" text="1" underline="true"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="7"><children><Label text="NSsid:"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="7"><children><Label fx:id="Label_NSsid" text="1" underline="true"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="8"><children><Label text="Threads:"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="8"><children><Label fx:id="Label_Threads" text="1" underline="true"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="9"><children><Label text="By:"><font><Font size="24.0" /></font></Label></children></HBox><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="9"><children><Label text="RongLin"><font><Font size="24.0" /></font></Label></children></HBox></children></GridPane></center> </BorderPane>

controller

MainController.java文件

package Controller;import application.Readproc; import application.Process; import java.net.InetAddress; import java.net.URL; import java.net.UnknownHostException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.ResourceBundle;import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeView; import javafx.util.Duration; import javafx.fxml.Initializable;public class MainController implements Initializable{final String ROOT = "/proc";@FXMLprivate Label Label_IP;@FXMLprivate Label Label_Time;@FXMLprivate Label Label_Name;@FXMLprivate Label Label_State;@FXMLprivate Label Label_Pid;@FXMLprivate Label Label_PPid;@FXMLprivate Label Label_NStgid;@FXMLprivate Label Label_NSpid;@FXMLprivate Label Label_NSpgid;@FXMLprivate Label Label_NSsid;@FXMLprivate Label Label_Threads;@FXMLprivate Button button_fresh;@FXMLprivate TreeView<Process> treeView_procs;private TreeItem<Process> rootItem = null;@Overridepublic void initialize(URL location, ResourceBundle resources) {//ip地址初始化InetAddress localAddress=null;try {localAddress=InetAddress.getLocalHost();} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();}Label_IP.setText(localAddress.getHostAddress());//時間初始化EventHandler<ActionEvent> timeUpdate =e->{final String TimePattern="yyyy年MM月dd日 HH:mm:ss";SimpleDateFormat dateFormat=new SimpleDateFormat(TimePattern);Label_Time.setText(dateFormat.format(new Date(System.currentTimeMillis())));};//500ms獲取一下系統時間Timeline animation = new Timeline(new KeyFrame(Duration.millis(500), timeUpdate));animation.setCycleCount(Timeline.INDEFINITE);animation.play();//初始化樹視圖initTreeView();//初始化表格initGridPane();}private void initTreeView(){//System.out.println("初始化了樹視圖");Readproc.readFile(ROOT);Process zero = new Process();zero.setPid(0);zero.setName("zero");rootItem = new TreeItem<Process> (zero);treeView_procs.setRoot(rootItem);treeView_procs.setShowRoot(false);//設置點擊節點觸發效果treeView_procs.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem <Process>>() {@Overridepublic void changed(ObservableValue<? extends TreeItem<Process>> observable,TreeItem<Process> oldValue, TreeItem<Process> newValue) {// TODO Auto-generated method stubif(newValue != null)showGridPane(newValue.getValue());}});DFSSetupTreeItem(rootItem,0);}private void DFSSetupTreeItem(TreeItem<Process> pitem,int ppid){for(int i=0;i<Readproc.procNum;i++){if(Readproc.procs[i].getPPid() == ppid){TreeItem<Process> item = new TreeItem<Process> (Readproc.procs[i]);pitem.getChildren().add(item);DFSSetupTreeItem(item,Readproc.procs[i].getPid());}}}private void initGridPane(){//System.out.println("初始化了表格");Label_Name.setText("0");Label_State.setText("0");Label_Pid.setText("0");Label_PPid.setText("0");Label_NStgid.setText("0");Label_NSpid.setText("0");Label_NSpgid.setText("0");Label_NSsid.setText("0");Label_Threads.setText("0"); }private void showGridPane(Process proc){//System.out.println("初始化了表格");Label_Name.setText(proc.getName());Label_State.setText(proc.getState());Label_Pid.setText(Integer.toString(proc.getPid()));Label_PPid.setText(Integer.toString(proc.getPPid()));Label_NStgid.setText(Integer.toString(proc.getNStgid()));Label_NSpid.setText(Integer.toString(proc.getNSpid()));Label_NSpgid.setText(Integer.toString(proc.getNSpgid()));Label_NSsid.setText(Integer.toString(proc.getNSsid()));Label_Threads.setText(Integer.toString(proc.getThreads())); } @FXMLvoid freshPage(ActionEvent event) {Readproc.procNum = 0;Readproc.readFile(ROOT);initGridPane();if(rootItem != null){rootItem.getChildren().clear();DFSSetupTreeItem(rootItem,0);}}}

控制器的難點在于TreeView的初始化,點擊TreeView節點的觸發和左上角的時間自動更新,源碼上都有,JavaFX的模板性很強,就這樣用就可以,要想知道原理,可以去查詢API。

Application

這中間有3個類,一個是運行類
Main.java

package application;import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.layout.BorderPane;public class Main extends Application {@Overridepublic void start(Stage primaryStage) {try {BorderPane mainPane = FXMLLoader.load(getClass().getResource("/Fxml/Main.fxml"));Scene mainScene = new Scene(mainPane,800,600);primaryStage.setScene(mainScene);primaryStage.setTitle("Linux進程樹");primaryStage.show(); } catch(Exception e) {e.printStackTrace();}}public static void main(String[] args) {launch(args);} }

一個是進程類,Process.java

package application;public class Process {String Name;String State;int Pid;int PPid;int NStgid;int NSpid;int NSpgid;int NSsid;int Threads;public String getName() {return Name;}public void setName(String name) {Name = name;}public String getState() {return State;}public void setState(String state) {State = state;}public int getPid() {return Pid;}public void setPid(int pid) {Pid = pid;}public int getPPid() {return PPid;}public void setPPid(int pPid) {PPid = pPid;}public int getNStgid() {return NStgid;}public void setNStgid(int nStgid) {NStgid = nStgid;}public int getNSpid() {return NSpid;}public void setNSpid(int nSpid) {NSpid = nSpid;}public int getNSpgid() {return NSpgid;}public void setNSpgid(int nSpgid) {NSpgid = nSpgid;}public int getNSsid() {return NSsid;}public void setNSsid(int nSsid) {NSsid = nSsid;}public int getThreads() {return Threads;}public void setThreads(int threads) {Threads = threads;}// public String toString() // { // String str ="Name:" + this.Name + "\n" + // "State:" + this.State + "\n" + // "Pid:" + this.Pid + "\n" + // "PPid:" + this.PPid + "\n" + // "NStgid:" + this.NStgid + "\n" + // "NSpid:" + this.NSpid + "\n" + // "NSpgid:" + this.NSpgid + "\n" + // "NSsid:" + this.NSsid + "\n" + // "Threads:" + this.Threads + "\n"; // return str; // }public String toString(){return this.Pid+":"+this.Name;} }

一個是從文件中讀取進程信息的類,定義的都是靜態方法
Readproc.java

package application;import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern;public class Readproc {final static int MAX = 1024*1024;final static int MAX_PROC_NUM= 1024;public static Process[] procs = new Process[MAX_PROC_NUM];public static int procNum = 0;static byte[] buff = new byte[MAX];public static boolean readFile(String path){File rootFile = new File(path);if(! rootFile.exists()){System.out.println("目錄不存在");return false;}procNum = 0;File[] procFiles = rootFile.listFiles();for(File file : procFiles){if(isNumeric(file.getName()) == true){procs[procNum] = getProcessFromStatus(file);if(procs[procNum] != null)procNum++;}}return true;}private static boolean isNumeric(String str){Pattern pattern = Pattern.compile("[0-9]*");Matcher isNum = pattern.matcher(str);if (!isNum.matches()){return false;}else {return true;}}private static Process getProcessFromStatus(File file){Process proc = new Process();int len = 0;FileInputStream input = null ;StringBuffer buffer = new StringBuffer();String path = file.getPath() + "/status";try {input = new FileInputStream(path);} catch (FileNotFoundException e) {// TODO Auto-generated catch block//e.printStackTrace();System.out.println(path);System.out.println("status文件沒找到");return null;}try {while(( (len = input.read(buff) )!= -1 )){buffer.append(new String(buff,0,len));}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println("status文件讀寫失敗");return null;}String[] statusPart = buffer.toString().split("\\s+");for(int i=0;i<statusPart.length;i++){if(statusPart[i].compareTo("Name:") == 0){proc.Name = new String(statusPart[i+1]);}else if(statusPart[i].compareTo("State:") == 0){proc.State = new String(statusPart[i+1] + statusPart[i+2]);}else if(statusPart[i].compareTo("Pid:") == 0){proc.Pid = Integer.parseInt(statusPart[i+1]);}else if(statusPart[i].compareTo("PPid:") == 0){proc.PPid = Integer.parseInt(statusPart[i+1]);}else if(statusPart[i].compareTo("NStgid:") == 0){proc.NStgid = Integer.parseInt(statusPart[i+1]);}else if(statusPart[i].compareTo("NSpid:") == 0){proc.NSpid = Integer.parseInt(statusPart[i+1]);}else if(statusPart[i].compareTo("NSpgid:") == 0){proc.NSpgid = Integer.parseInt(statusPart[i+1]);}else if(statusPart[i].compareTo("NSsid:") == 0){proc.NSsid = Integer.parseInt(statusPart[i+1]);}else if(statusPart[i].compareTo("Threads:") == 0){proc.Threads = Integer.parseInt(statusPart[i+1]);}}try {input.close();} catch (IOException e) {// TODO Auto-generated catch block//e.printStackTrace();System.out.println("input流關閉失敗");return null;}return proc;}// public static void main(String[] args) { // Readproc.readFile("F:/Desktop/proc"); // // System.out.println("共有"+procNum+"個進程"); // // for(int i=0;i<procNum;i++) // { // System.out.println(procs[i]); // } // // }}

總結

原理很簡單,難點在于JavaFX基本控件的使用和GUI的布局,丑了一點,不過重點在于熟悉Linux系統的進程概念。
代碼原創,歡迎指點,=w=

總結

以上是生活随笔為你收集整理的基于JavaFX的Linux进程树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。