0% found this document useful (0 votes)
11 views92 pages

Output

The document outlines a Java module for an operating system simulation, including classes for CPU management, device control, memory management, and user interface interactions. Key components include a singleton CPU class for time tracking, a device controller for managing device states, and memory management classes for handling memory allocation and deallocation. The structure supports JavaFX for the UI and utilizes logging for error handling.

Uploaded by

qaq yingfan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views92 pages

Output

The document outlines a Java module for an operating system simulation, including classes for CPU management, device control, memory management, and user interface interactions. Key components include a singleton CPU class for time tracking, a device controller for managing device states, and memory management classes for handling memory allocation and deallocation. The structure supports JavaFX for the UI and utilizes logging for error handling.

Uploaded by

qaq yingfan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 92

// Content from: .\main\java\module-info.

java

module com.example.os {
requires javafx.controls;
requires javafx.fxml;
requires java.logging;
requires jdk.jsobject;
requires javafx.web;

// 导出主类所在包
exports com.example.os.UI;

// 如果 FXML 文件需要反射加载,请开放相关包
opens com.example.os.UI to javafx.fxml;
opens com.example.os.model to javafx.base;
}

// Content from: .\main\java\com\example\os\CPU\CPU.java

package com.example.os.CPU;

import java.util.logging.Level;
import java.util.logging.Logger;

public class CPU extends Thread {


private static CPU cpu; // 单例模式的 cpu 对象
private double startTime = 0.0D; // 当前开始时间
private double stopTime = 0.0D; // 当前结束时间
private double time = 0.0D; // 运行时间
private boolean stopFlag = true; // 是否 cpu 停止

@Override
public void run() {
while(true) {
if (!this.stopFlag) {
this.cpu.time = (this.cpu.stopTime +
((double)System.currentTimeMillis() - this.cpu.startTime));
}

try {
Thread.sleep(10L);
} catch (InterruptedException var2) {
Logger.getLogger(CPU.class.getName()).log(Level.SEVERE,
(String)null, var2);
}
}
}

public CPU() {
// 设置为守护进程
this.setDaemon(true);
this.start();
}
public static CPU getInstance() {
if (cpu == null) {
cpu = new CPU();
}
return cpu;
}
public void cpuStop() {
this.cpu.stopFlag = true;
this.cpu.stopTime = this.cpu.time;
}

public void reset() {//更换进程时重新设置数值


this.cpu.cpuStop();
this.cpu.time = 0.0D;
}

public boolean isRunning() {


return !this.cpu.stopFlag;
}

public void play() {


this.cpu.startTime = (double)System.currentTimeMillis();
this.cpu.stopFlag = false;
}

public double timeProperty() {


return this.cpu.time;
}

public double getCurrentTime() {


return this.cpu.time;
}
}

// Content from: .\main\java\com\example\os\device\Device.java

package com.example.os.device;

public class Device {


private String type;
private boolean isOccupy=false;
private String PID;

public String getPID() {


return PID;
}

public void setPID(String PID) {


this.PID = PID;
}

public Device() {
}

public String getType() {


return type;
}
public void setType(String type) {
this.type = type;
}

public Device(String device) {


this.type = device;
}

public boolean isOccupy() {


return isOccupy;
}

public void setOccupy(boolean occupy) {


isOccupy = occupy;
}
}

// Content from: .\main\java\com\example\os\device\DeviceController.java

package com.example.os.device;

import java.util.ArrayList;
import java.util.List;

public class DeviceController {


private static DeviceController deviceController;
public static List<Device> deviceList = new ArrayList<Device>();

private DeviceController() {
deviceList.add(new Device("A"));
deviceList.add(new Device("A"));
deviceList.add(new Device("B"));
deviceList.add(new Device("B"));
deviceList.add(new Device("C"));
}

public static DeviceController getInstance() {


if (deviceController == null) {
deviceController = new DeviceController();
}
return deviceController;
}

public static Device getDevice(String type) {


for(int i=0;i<deviceList.size();i++) {
if(deviceList.get(i).getType().equals(type)&&!
deviceList.get(i).isOccupy()) {
return deviceList.get(i);
}
}
return null;
}

public static void resetDevice(Device device) {


device.setPID("null");
device.setOccupy(false);
}
}

// Content from: .\main\java\com\example\os\Listener\DragListener.java

package com.example.os.Listener;

import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;

public class DragListener implements EventHandler<MouseEvent> {

private double xOffset = 0;


private double yOffset = 0;
private final Stage stage;

public DragListener(Stage stage) {


this.stage = stage;
}

@Override
public void handle(MouseEvent event) {
event.consume();
if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
xOffset = event.getSceneX();
yOffset = event.getSceneY();
} else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
stage.setX(event.getScreenX() - xOffset);
if(event.getScreenY() - yOffset < 0) {
stage.setY(0);
}else {
stage.setY(event.getScreenY() - yOffset);
}
}
}

public void enableDrag(Node node) {


node.setOnMousePressed(this);
node.setOnMouseDragged(this);
}
}

// Content from: .\main\java\com\example\os\Listener\DragUtil.java

package com.example.os.Listener;

import javafx.scene.Node;
import javafx.stage.Stage;

public class DragUtil {


public static void addDragListener(Stage stage, Node root) {
new DragListener(stage).enableDrag(root);
}
}
// Content from: .\main\java\com\example\os\memory\Address.java

package com.example.os.memory;

public class Address {


private int startAddress;
private int endAddress;

public Address(int startAddress, int endAddress) {


this.startAddress = startAddress;
this.endAddress = endAddress;
}

public int getStartAddress() {


return this.startAddress;
}

public void setStartAddress(int startAddress) {


this.startAddress = startAddress;
}

public int getEndAddress() {


return endAddress;
}

public void setEndAddress(int endAddress) {


this.endAddress = endAddress;
}
}

// Content from: .\main\java\com\example\os\memory\Memory.java

package com.example.os.memory;

import com.example.os.ProcessManager.PCB;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Memory {


private static Memory memory;
private static List<PCB> pcbList = new ArrayList<>();
private LinkedList<MemoryBlock> blocks; //链式存储

private static int MEMORY_SIZE =511;

static{memory = new Memory();}

public static Memory getInstance() {return memory;}

private Memory(){
blocks = new LinkedList<>();
}

public List<PCB> getPCBList() {


return pcbList;
}

public PCB getPCB(String pid) {


for (int i = 0; i < this.pcbList.size(); ++i) {
if (((PCB)this.pcbList.get(i)).getId().equals(pid)) {
return (PCB) this.pcbList.get(i);
}
}
return null;
}
}

// Content from: .\main\java\com\example\os\memory\MemoryBlock.java

package com.example.os.memory;

import javafx.scene.paint.Color;

import java.util.Random;

public class MemoryBlock {


private Address address; // 内存块起始位置
private int endPosition; // 内存块终止位置
private String PID; // 占用内存的进程序号
private int length; // 内存块长度
private boolean isEmpty; // 占用状态
private Color color; // 设置内存块颜色
public static Color randomColor() {
Random random = new Random();
int r = random.nextInt(256);
int g = random.nextInt(256);
int b = random.nextInt(256);
return Color.rgb(r, g, b);
}

public String getPID() {


return PID;
}

public MemoryBlock(int startPosition, int length, boolean isEmpty, String PID){


address = new Address(startPosition, startPosition + length - 1);
this.endPosition = startPosition + length - 1;
this.length = length;
this.isEmpty = isEmpty;
this.PID = PID;
this.color = randomColor();
}

public MemoryBlock(MemoryBlock block,boolean isEmpty){


this(block.getStartPosition(),block.getLength(),isEmpty, "-1");
}

public int getEndPosition() {


return endPosition;
}

public Color getColor() {


return color;
}

public int getStartPosition(){


return address.getStartAddress();
}

public Address getAddress() {


return address;
}

public int getLength(){


return length;
}

public boolean isEmpty(){


return isEmpty;
}

public boolean equals(MemoryBlock block){


return block.getLength() == this.getLength() &&
block.getStartPosition()==this.getStartPosition();
}
}

// Content from: .\main\java\com\example\os\memory\MemoryController.java

package com.example.os.memory;

import com.example.os.ProcessManager.ProcessController;
import com.example.os.UI.ProcessXMLController;

import java.util.ArrayList;
import java.util.List;

public class MemoryController {


private Memory memory;
private static MemoryController memoryController;
private List<MemoryBlock> myMemoryBlockList = new ArrayList<>();
private static final int MAX_SIZE = 511;

public List<MemoryBlock> getMyMemoryBlockList() {


return myMemoryBlockList;
}

public MemoryController() {
this.memory = Memory.getInstance();
}

public static MemoryController getInstance() {


if (memoryController == null) {
memoryController = new MemoryController();
}
return memoryController;
}
/**
* description 压缩内存
* param void
* return void
**/
public static void mergeMemory()
{
int start=0;
int length;
for(int i = 0;i < memoryController.myMemoryBlockList.size(); i++)
{

System.out.println("Start="+memoryController.myMemoryBlockList.get(i).getAddress().
getStartAddress());

System.out.println("end="+memoryController.myMemoryBlockList.get(i).getAddress().ge
tEndAddress());

length=memoryController.myMemoryBlockList.get(i).getAddress().getEndAddress()
-

memoryController.myMemoryBlockList.get(i).getAddress().getStartAddress();

memoryController.myMemoryBlockList.get(i).getAddress().setStartAddress(start);

memoryController.myMemoryBlockList.get(i).getAddress().setEndAddress(start+length);

System.out.println("Start2="+memoryController.myMemoryBlockList.get(i).getAddress()
.getStartAddress());

System.out.println("end2="+memoryController.myMemoryBlockList.get(i).getAddress().g
etEndAddress());

start=start+length+1;
}
ProcessXMLController.MemoryRefresh();
}

/**
* 判断程序运行时候的进程数量,实验要求小于 10
* @return boolean
*/
public boolean hasBlankPCB() {
// System.out.println(this.memory.getPCBList().size());
return this.memory.getPCBList().size() < 10;
}

/**
* description 首次适配分配内存,有三种情况如下
* param int size 请求分配的内存块
* return MemoryBlock
**/
public MemoryBlock findBlankAddress(int size)
{
int start = 0,end;
for(int i = 0; i < myMemoryBlockList.size(); i++) {
end = myMemoryBlockList.get(i).getStartPosition() - 1;
if(( end - start + 1 ) >= size) {
MemoryBlock myMemoryBlock =new MemoryBlock(start, size,
false, ProcessController.getCurrentPid());
//添加到 list 里
myMemoryBlockList.add(myMemoryBlock);
sortList();
return myMemoryBlock;
}
start = myMemoryBlockList.get(i).getEndPosition() + 1;
}
if(start == 0 && (MAX_SIZE - start + 1) >= size) {
MemoryBlock myMemoryBlock=new MemoryBlock(start, size, false,
ProcessController.getCurrentPid());
myMemoryBlockList.add(myMemoryBlock);
sortList();
return myMemoryBlock;
} else if( ( MAX_SIZE - myMemoryBlockList.get( myMemoryBlockList.size()
- 1 ).getEndPosition() ) >= size ) {
//查看进程占用块间的空余内存是否有满足的,没有则通过以下的 if 语句来判断剩余区域有无满足块
int st = myMemoryBlockList.get(myMemoryBlockList.size() -
1).getEndPosition() + 1;
MemoryBlock myMemoryBlock=new MemoryBlock(st, size, false,
ProcessController.getCurrentPid());
myMemoryBlockList.add(myMemoryBlock);
sortList();
return myMemoryBlock;
} else {
return null;
}
}

/**
* description 内存释放
* param MemoryBlock myMemoryBlock 内存块
* return void
**/
public void release(MemoryBlock myMemoryBlock)
{
ProcessXMLController.MemoryRelease(myMemoryBlock);
myMemoryBlockList.remove(myMemoryBlock);
}

public MemoryBlock getMemoryBlock(Address address) {


for (MemoryBlock memoryBlock : myMemoryBlockList) {
if (memoryBlock.getAddress() == address) {
return memoryBlock;
}
}
return null;
}

/* *
* 创建排序的函数,每次新增内存块都要排序一次
*/
public void sortList() {
MemoryBlock myMemoryBlock;
for(int i = 0;i < myMemoryBlockList.size(); i++) {
for(int j = 0; j < myMemoryBlockList.size() - i - 1; j++) {
if(myMemoryBlockList.get(j).getStartPosition() >
myMemoryBlockList.get(j+1).getStartPosition()) {
myMemoryBlock = myMemoryBlockList.get(j);
myMemoryBlockList.set(j, myMemoryBlockList.get(j +
1));
myMemoryBlockList.set(j + 1, myMemoryBlock);
}
}
}
}
}

// Content from: .\main\java\com\example\os\model\Color.java

package com.example.os.model;

public class Color {


private String color;
private Boolean isUsed;

public Color(String color, Boolean isUsed) {


this.color = color;
this.isUsed = isUsed;
}

public String getColor() {


return color;
}

public void setColor(String color) {


this.color = color;
}

public Boolean getUsed() {


return isUsed;
}

public void setUsed(Boolean used) {


isUsed = used;
}
}

// Content from: .\main\java\com\example\os\model\Disk.java

package com.example.os.model;

// 磁盘类 c 盘
public class Disk {
// 磁盘名称
private String diskName;

public Disk(){}
public Disk(String diskName) {
this.diskName = diskName;
}

public String getDiskName() {


return this.diskName;
}

public void setDiskName(String diskName) {


this.diskName = diskName;
}

@Override
public String toString() {
return this.diskName;
}
}

// Content from: .\main\java\com\example\os\model\FAT.java

package com.example.os.model;

import com.example.os.util.FileSystemUtil;

// 文件分配表类
public class FAT {
// 盘块号
private int blockNum;
// 指向下一个 FAT/磁盘的下标(0 表示该磁盘空闲 254 表示该磁盘损坏 255 表示该文件已经结束)
private int index;
// 存放的文件类型 -1 表示文件空
private int type;
// 存放的文件内容(文件夹、文件)
private Object object;

public FAT(int blockNum){


this.blockNum=blockNum;
this.index= FileSystemUtil.SPARE;
this.type = -1;
this.object=null;
}

public FAT(int index, int type, Object object,int blockNum) {


this.blockNum=blockNum;
this.index = index;
this.type = type;
this.object = object;
}

public int getIndex() {


return index;
}
public void setIndex(int index) {
this.index = index;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
public int getBlockNum() {
return blockNum;
}
public void setBlockNum(int blockNum) {
this.blockNum = blockNum;
}
}

// Content from: .\main\java\com\example\os\model\File.java

package com.example.os.model;

import java.text.SimpleDateFormat;
import java.util.Date;

//文件类
public class File {
// 文件名称
private String fileName;
// 文件类型 写读、读
private String type;
// 文件结构
private String property;
// 文件内容
private String content;
// 父目录
private Folder parent;
// 父路径
private String location;
// 时间
private Date createTime;
// 时间
private Date reviseTime;
// 是否隐藏
private boolean isHide;
// 在盘块的位置
private int diskNum;
// 文件文本长度 getText().length() 单位字符
private int length;
// 文本文件所占磁盘的个数
private int numOfFAT;
// 文件的字节大小
private int size;

// 颜色下标
private int colorIndex;
private String space;

public File(){}

public File(String fileName) {


this.fileName = fileName;
}

public File(String fileName,String location,int diskNum,int colorIndex) {


this.fileName = fileName;
this.location = location;
this.size = 0;
this.space = "100KB";
this.createTime = new Date();
this.reviseTime = new Date();
this.diskNum = diskNum;
this.type= "写读";
this.isHide = false;
this.length = 0;
this.numOfFAT=1;
this.content = "";
this.colorIndex=colorIndex;
}

public int getColorIndex() {


return colorIndex;
}

public void setColorIndex(int colorIndex) {


this.colorIndex = colorIndex;
}

public String getType() {


return type;
}

public void setType(String type) {


this.type = type;
}

public String getFileName() {


return fileName;
}

public void setFileName(String fileName) {


this.fileName = fileName;
}

public String getProperty() {


return property;
}

public void setProperty(String property) {


this.property = property;
}

public String getContent() {


return content;
}

public void setContent(String content) {


this.content = content;
}

public Folder getParent() {


return parent;
}

public void setParent(Folder parent) {


this.parent = parent;
}

public String getLocation() {


return location;
}

public void setLocation(String location) {


this.location = location;
}

public String getReviseTime() {


SimpleDateFormat format = new SimpleDateFormat("yyyy 年 MM 月 dd 日 HH:mm:ss");
return format.format(this.reviseTime);
}

public void setReviseTime() {


this.reviseTime = new Date();
}

public String getCreateTime() {


SimpleDateFormat format = new SimpleDateFormat("yyyy 年 MM 月 dd 日 HH:mm:ss");
return format.format(this.createTime);
}

public void setCreateTime() {


this.createTime = new Date();
}

public boolean isHide() {


return isHide;
}

public void setHide(boolean hide) {


isHide = hide;
}

public int getDiskNum() {


return diskNum;
}

public void setDiskNum(int diskNum) {


this.diskNum = diskNum;
}
public int getLength() {
return length;
}

public void setLength(int length) {


this.length = length;
}

public int getNumOfFAT() {


return numOfFAT;
}

public void setNumOfFAT(int numOfFAT) {


this.numOfFAT = numOfFAT;
}

public int getSize() {


return size;
}

public void setSize(int size) {


this.size = size;
}

public String getSpace() {


return space;
}

public void setSpace(String space) {


this.space = space;
}

@Override
public String toString() {
return this.fileName;
}

// Content from: .\main\java\com\example\os\model\Folder.java

package com.example.os.model;

import javafx.scene.control.TreeItem;

import java.text.SimpleDateFormat;
import java.util.Date;

//文件夹类
public class Folder {
// 文件夹名称
private String folderName;
// 文件夹类型
private String type;
// 文件夹结构
private String property;
// 文件夹子孩子的个数(最多 8 个)
private int childNum;
// 父路径
private String location;
// 时间
private Date createTime;
// 时间
private Date reviseTime;
// 是否只读
private boolean isReadOnly;
// 是否隐藏
private boolean isHide;
// 在盘块的位置
private int diskNum;
// 文件的字节大小
private int size;
private String space;
// 文本文件所占磁盘的个数
private int numOfFAT;
// 颜色下标
private int colorIndex;
// 对应的树节点
private TreeItem<String> folderTreeItem;

public Folder() {
}

public Folder(String folderName) {


this.folderName = folderName;
}

public Folder(String folderName, String location, int diskNum,int colorIndex) {


this.folderName = folderName;
this.location = location;
this.size = 0;
this.numOfFAT=1;
this.space = "100KB";
this.createTime = new Date();
this.reviseTime = new Date();
this.diskNum = diskNum;
this.type = "写读";
this.isReadOnly = false;
this.isHide = false;
this.childNum = 0;
this.colorIndex=colorIndex;
}

public TreeItem<String> getFolderTreeItem() {


return folderTreeItem;
}

public void setFolderTreeItem(TreeItem<String> folderTreeItem) {


this.folderTreeItem = folderTreeItem;
}

public int getColorIndex() {


return colorIndex;
}

public void setColorIndex(int colorIndex) {


this.colorIndex = colorIndex;
}

public String getFolderName() {


return this.folderName;
}

public void setFolderName(String folderName) {


this.folderName = folderName;
}

public String getType() {


return this.type;
}

public void setType(String type) {


this.type = type;
}

public String getProperty() {


return this.property;
}

public void setProperty(String property) {


this.property = property;
}

public int getChildNum() {


return this.childNum;
}

public void setChildNum(int childNum) {


this.childNum = childNum;
}

public String getLocation() {


return this.location;
}

public void setLocation(String location) {


this.location = location;
}

public String getReviseTime() {


SimpleDateFormat format = new SimpleDateFormat("yyyy 年 MM 月 dd 日 HH:mm:ss");
return format.format(this.reviseTime);
}

public void setReviseTime() {


this.reviseTime = new Date();
}

public String getCreateTime() {


SimpleDateFormat format = new SimpleDateFormat("yyyy 年 MM 月 dd 日 HH:mm:ss");
return format.format(this.createTime);
}

public void setCreateTime(Date createTime) {


this.createTime = createTime;
}

public boolean isReadOnly() {


return this.isReadOnly;
}

public void setReadOnly(boolean readOnly) {


this.isReadOnly = readOnly;
}

public boolean isHide() {


return this.isHide;
}

public void setHide(boolean hide) {


this.isHide = hide;
}

public int getDiskNum() {


return this.diskNum;
}

public void setDiskNum(int diskNum) {


this.diskNum = diskNum;
}

public int getSize() {


return this.size;
}

public void setSize(int size) {


this.size = size;
}

public String getSpace() {


return this.space;
}

public void setSpace(String space) {


this.space = space;
}

public int getNumOfFAT() {


return this.numOfFAT;
}

public void setNumOfFAT(int numOfFAT) {


this.numOfFAT = numOfFAT;
}

public boolean hasChild() {


return this.childNum > 0;
}

// 所含文件数量
public boolean addChildNum() {
if (this.childNum < 8) {
this.childNum++;
return true;
}
return false;
}

public boolean decChildNum() {


if (this.childNum > 0) {
this.childNum--;
return true;
}
return false;
}

public String toString() {


return this.folderName;
}
}

// Content from: .\main\java\com\example\os\model\OpenFile.java

package com.example.os.model;

// 打开的文件类
public class OpenFile {
//
private int flag;
// 文件对象
private File file;

public OpenFile() {
}

public int getFlag() {


return flag;
}

public void setFlag(int flag) {


this.flag = flag;
}

/**
* 获取打开的文件对象
*
* @return file
*/
public File getFile() {
return file;
}

/**
* 设置打开的文件对象
*
* @param file
*/
public void setFile(File file) {
this.file = file;
}
}
// Content from: .\main\java\com\example\os\model\OpenFiles.java

package com.example.os.model;

import com.example.os.util.FileSystemUtil;

import java.util.ArrayList;
import java.util.List;

// 打开的文件列表类
public class OpenFiles {
// 打开的文件列表
private List<OpenFile> files;
// 列表中文件的数量
private int length;

public OpenFiles() {
// 默认新建一个长度为 5 的列表
this.files = new ArrayList(FileSystemUtil.num);
// 列表中文件的个数
this.length = 0;
}

// 添加已打开文件
public void addFile(OpenFile openFile) {
this.files.add(openFile);
}

// 删除已打开文件
public void removeFile(OpenFile openFile) {
this.files.remove(openFile);
}

// 获取已打开文件列表
public List<OpenFile> getFiles() {
return this.files;
}

// 赋值
public void setFiles(List<OpenFile> files) {
this.files = files;
}

public int getLength() {


return length;
}

public void setLength(int length) {


this.length = length;
}
}

// Content from: .\main\java\com\example\os\ProcessManager\PCB.java

package com.example.os.ProcessManager;
import javafx.scene.paint.Color;

import java.util.Random;

public class PCB {


private String id; // 唯一标识
private int status; // 状态
private int priority; // 优先级
private int type; // 程序类型
private Double restRunTime; // 程序剩余运行时间
private Double totalRunTime; // 总运行时间
private Double lastRestRunTime; // 时间片剩余时间
private boolean isInterrupt; // 是否中断

public PCB() {
}

public PCB(String id, int priority, Double restRunTime) {


this.id = id;
this.priority = priority;
this.restRunTime = restRunTime;
this.totalRunTime = restRunTime;
// CPU 赋值
this.lastRestRunTime = restRunTime;
}

public String getId() {


return id;
}

public void setId(String id) {


this.id = id;
}

public int getStatus() {


return status;
}

public void setStatus(int status) {


this.status = status;
}

public int getPriority() {


return priority;
}

public void setPriority(int priority) {


this.priority = priority;
}

public int getType() {


return type;
}

public void setType(int type) {


this.type = type;
}
public Double getRestRunTime() {
return restRunTime;
}

public void setRestRunTime(Double restRunTime) {


this.restRunTime = restRunTime;
}

public Double getTotalRunTime() {


return totalRunTime;
}

public void setTotalRunTime(Double totalRunTime) {


this.totalRunTime = totalRunTime;
}

public Double getLastRestRunTime() {


return lastRestRunTime;
}

public void setLastRestRunTime(Double lastRestRunTime) {


this.lastRestRunTime = lastRestRunTime;
}

public boolean isInterrupt() {


return isInterrupt;
}

public void setInterrupt(boolean interrupt) {


isInterrupt = interrupt;
}

// Content from: .\main\java\com\example\os\ProcessManager\Process.java

package com.example.os.ProcessManager;

import com.example.os.device.*;
import com.example.os.memory.*;

public class Process {


/**
* PCB : 进程控制块
* Address : 进程内存地址
* Device : 进程所需要的设备
* isUser : 判断该进程是不是用户进程,true 表示是,false 表示是系统级进程
* id : 进程 id
* priority : 进程优先级
* restRunTime : 进程剩余运行时间
* totalRunTime : 进程总运行时间
* lastRestRunTime : 进程运行最后剩余时间
* status : 进程状态字,相当于 psw
* 值为 0 : 就绪态
* 值为 1 : 运行态或者被中断
* 值为 -1 : 阻塞态
*/
private PCB pcb;
private Address address;
private Device device;
private String deviceType;
private boolean isUser;
private int status;

public Process(PCB pcb, Address address, boolean isUser, Device device) {


this.pcb = pcb;
this.address = address;
this.isUser = isUser;
this.device = device;
}

public String getDeviceType() {


return deviceType;
}

public void setDeviceType(String deviceType) {


this.deviceType = deviceType;
}

public Process(PCB pcb) {


this.address = new Address(0, 0);
this.isUser = false;
this.device = null;
}

// 设置就绪态
public void setReady() {
this.setStatus(0);
}
// 设置运行态
public void setRunning() {
this.setStatus(1);
}
// 设置阻塞态
public void setBlock() {
this.setStatus(-1);
}
public PCB getPcb() {
return pcb;
}

public void setPcb(PCB pcb) {


this.pcb = pcb;
}

public Address getAddress() {


return address;
}

public void setAddress(Address address) {


this.address = address;
}

public Device getDevice() {


return device;
}

public void setDevice(Device device) {


this.device = device;
}

public boolean isUser() {


return isUser;
}

public void setUser(boolean user) {


isUser = user;
}

public Device Device() {


return device;
}

public void Device(Device device) {


this.device = device;
}

public int getStatus() {


return status;
}

public void setStatus(int status) {


this.getPcb().setStatus(status);
this.status = status;
}
}

// Content from: .\main\java\com\example\os\ProcessManager\ProcessController.java

package com.example.os.ProcessManager;

import com.example.os.CPU.CPU;
import com.example.os.UI.ProcessXMLController;
import com.example.os.device.Device;
import com.example.os.device.DeviceController;
import com.example.os.memory.Address;
import com.example.os.memory.Memory;
import com.example.os.memory.MemoryBlock;
import com.example.os.memory.MemoryController;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class ProcessController implements Runnable{


/* *
* runningProcess : 当前运行进程
* hangOutProcess : 空闲进程
* currentPID : 进程 PID
* MAX_PRIORITY : 进程优先级最高为 10
* MIN_PRIORITY : 进程优先级最低为 0
* MAX_REST_RUN_TIME :
* runningQueue : 运行队列
* readyQueue : 就绪队列
* blockedQueue : 阻塞队列
* timeChip : 时间片
*/
private static ProcessController processController;
private Process runningProcess;
private Process hangOutProcess = createHangOutProcess();

public List<Process> getRunningQueue() {


return runningQueue;
}

public List<Process> getReadyQueue() {


return readyQueue;
}

public List<Process> getBlockedQueue() {


return blockedQueue;
}

private static int currentPID = 0;


public static final int MAX_PRIORITY = 5;
public static final int MIN_PRIORITY = 0;
public static final int MAX_REST_RUN_TIME = 5;

private List<Process> runningQueue = new ArrayList<>(); // 被中断队列


private List<Process> readyQueue = new ArrayList<>(); // 时间片轮转的进程队列
private List<Process> blockedQueue = new ArrayList<>(); // 阻塞队列
private double timeChip = 2.0D;
// 时间片
private double allRunTime = 0D;
// 轮转运行时间

// CPU 单例模型调用
private CPU cpu=CPU.getInstance();
// 内存分配器
private MemoryController mc = MemoryController.getInstance();
private Memory memory = Memory.getInstance();

/**
* test 测试函数
*/
public static void main(String[] args) {
CPU.getInstance();
new Thread(ProcessController.getInstance()).start();
}

/**
* description 创建闲置进程
* param null
* createTime 2021/10/10 11:16
**/
public static Process createHangOutProcess() {
return new Process(new PCB("#hang out", MIN_PRIORITY, (double) 0));
}

/**
* 提供给内存模块的获取 PID 的方法
* */
public static String getCurrentPid() {
return "#" + currentPID;
}

public Process getRunningProcess() {


return runningProcess;
}

public Process getHangOutProcess() {


return hangOutProcess;
}

public double getAllRunTime() {


return allRunTime;
}

/**
* 这里拿来监视 cpu 的运行时间,或者用 runningProcess 在此运行
*/
@Override
public void run() {
this.runningProcess=this.hangOutProcess;
while (true) {
// 判断 cpu 有无手动停止
if (cpu.isRunning()) {
create();
// cpu 刷新时间单位
double runtime = 0;
allRunTime = 0;
double first = cpu.getCurrentTime();
boolean interrupt = false;
// 时间片轮转函数
while (allRunTime < timeChip &&
processController.runningProcess != processController.hangOutProcess
&& !interrupt){
// 进程运行结束
if(runningProcess.getPcb().getRestRunTime() <= 0){
System.out.println("进程结束 : [ id : " +
runningProcess.getPcb().getId() + " ]");
destroy(runningProcess);
runningProcess = hangOutProcess;

// 尝试从被抢占队列中获取进程
Process runningPro = runningQueenToRunning();
if (runningPro != null) {
runningProcess = runningPro;
break;
} else {
runningPro = readyQueenToRunning();//尝试在
ready 队列中获取进程
if (runningPro != null) {
runningProcess = runningPro;
break;
}
}
break;
}
runtime = (cpu.getCurrentTime() - first) / 1000;
allRunTime = allRunTime + runtime;

//更新进程的剩余运行时间

runningProcess.getPcb().setRestRunTime(runningProcess.getPcb().getRestRunTime() -
runtime);
first = cpu.getCurrentTime();

//检测有无抢占进程
for(int i = 0; i < readyQueue.size(); i++) {
if(readyQueue.get(i).getPcb().getPriority() >
runningProcess.getPcb().getPriority()) {
interrupt(readyQueue.get(i));
interrupt = true;
break;
}
}

try {
Thread.sleep(100L);
} catch (InterruptedException e) {
System.out.printf(e.toString());
}
}
//时间片轮转结束的情况
if(allRunTime >= timeChip) {
Process p=runningQueenToRunning();
readyQueue.add(runningProcess);
if(p!=null)
{
runningProcess=p;
}
else {
runningProcess = hangOutProcess;
}
}
//判断没有阻塞队列时,cpu 正常从就绪队列中获取进程
if(runningProcess == hangOutProcess) {
Process process = readyQueenToRunning();
if (process != null) {
runningProcess = process;
} else {
runningProcess = hangOutProcess;
}
}
//打印 cpu 运行进程
if(runningProcess == hangOutProcess)
{
System.out.println("hangOutProcess");
}
else {
System.out.println("Cpu 进程: [ id :" +
runningProcess.getPcb().getId() +" ;" +
" 优先级 : " +
runningProcess.getPcb().getPriority() + " ; 设备类型"+runningProcess.getDeviceType()
+"]");
}
//以下三个循环为打印三个队列里的进程
System.out.println("以下是就绪队列");
for(int i = 0; i < readyQueue.size(); i++)
{
System.out.println("就绪队列: [ id :" +
readyQueue.get(i).getPcb().getId() +" ;" +
" 优先级 : " +
readyQueue.get(i).getPcb().getPriority() + " ; 设备类
型"+readyQueue.get(i).getDeviceType()+"]");
}

System.out.println("以下是被中断队列,每次时间片轮转后都增加一点优先级");
for(int i = 0; i < runningQueue.size(); i++)
{

runningQueue.get(i).getPcb().setPriority( runningQueue.get(i).getPcb().getPriority(
) + 1 );
System.out.println("中断队列: [ id :"
+runningQueue.get(i).getPcb().getId() +" ;" +
" 优先级 : " +
runningQueue.get(i).getPcb().getPriority() +" ; 设备类
型"+runningQueue.get(i).getDeviceType()+ "]");
}

System.out.println("以下是阻塞队列");
for(int i = 0; i < blockedQueue.size(); i++)
{
System.out.println("阻塞队列: [ id :" +
blockedQueue.get(i).getPcb().getId() +" ;" +
" 优先级 : " +
blockedQueue.get(i).getPcb().getPriority() + " ; 设备类
型"+blockedQueue.get(i).getDeviceType()+"]");
}
} else {
try {
Thread.sleep(10L);
} catch (Exception e) {

}
}
}
}

public void runningToReady() {


runningProcess.setReady();
readyQueue.add(runningProcess);
}

/**
* 进程创建函数
* 在这里就分配好资源,然后通过 getFreeDevice 函数实现模拟多线程进程请求资源
* @return Process
*/
public Process create() {

double GenerationProbability = Math.random();


if (GenerationProbability <= 0.3 || blockedQueue.size() > 4) {
return null;
}

// 设置进程创建时间
try {
Thread.sleep((long) (GenerationProbability * 100));
} catch (InterruptedException e) {
System.out.printf(e.toString());
}

if (!mc.hasBlankPCB()) {
return null;
}
// 分配随机内存空间
int size = (int)(Math.random() * 512.0D / 8.0D) + 30;

//TODO:首次适配需要改动,内存块用新的

// 判断 memoryBlock 能够 findBlankAddress 找到空闲块,能的话获取 address,没有返回 null


Address address;
MemoryBlock memoryBlock = mc.findBlankAddress(size);
if (memoryBlock != null) {
address = memoryBlock.getAddress();
} else {
address = null;
}

// 判断是否有多余的空间,没有返回 null,在 process 里增加 type 参数,每个进程获得的 device 都是那五个,


// 不用 new,需要改动的地方有:onCreate,getFreeDevice,destroy;
if (address == null) {
return null;
} else {
// todo : 设备管理写完,添加部分
DeviceController dc = DeviceController.getInstance();
PCB pcb = new PCB("#" + currentPID++, getRandomPriority(),
getRandomRestRunTime());

String type = getRandomDevice();


Device device = dc.getDevice(type);
Process process = new Process(pcb, address, true, device);
process.setDeviceType(type);
process.setDevice(device);
//获取到空闲设备,设置设备占用信息
if(device!=null) {
device.setPID("#"+(currentPID-1));
device.setOccupy(true);
ready(process);
}
//没有空闲设备,阻塞进程
else {
System.out.println("没有设备");
block(process);
}
//如果获取设备,则直接进入就绪队列 ready(),否则设置 block()
ProcessXMLController.MemoryOccupy(memoryBlock);
return process;
}
}
public static String getRandomDevice() {
Random random=new Random();
int num=random.nextInt(10);
if(num%3==0) {
return "A";
}
if(num%3==1) {
return "B";
}
if(num%3==2) {
return "C";
}
return "A";
}

/**
* 包括内存释放,进程销毁,设备释放
*/
public boolean destroy(Process process) {
//todo:释放设备后就要调用 getFreeDevice(),再根据返回进程来调用 awake():done
// 设备释放

//TODO:释放内存需要改动,内存块用新的:done
System.out.println("销毁进程 [" + "id : " + process.getPcb().getId()
+" ]");
mc.release(mc.getMemoryBlock(process.getAddress()));
runningQueue.remove(process);
blockedQueue.remove(process);
readyQueue.remove(process);

Device device = process.getDevice();


//设备释放
DeviceController dc=DeviceController.getInstance();
dc.resetDevice(device);

Process blockedProcess = getFreeDevice(device);


if (blockedProcess != null) {
this.awake(blockedProcess);
}

// todo : 记得要改

return true;
}

/*
* 新建进程到就绪队列
* */
public void ready(Process process) {
readyQueue.add(process);
process.setReady();
}

/**
* 阻塞进程
* 设置阻塞类型并把程序放到阻塞对象中
* @param process
*/
public void block(Process process) {
blockedQueue.add(process);
process.setBlock();
}

/**
* 唤醒进程
* */
public void awake(Process process) {
this.blockToReady(process);
// todo : 设备分配:Done
}

/**
* 将进程放入内存中
* @param process
* todo : 代写,等内存管理写完
*/
public void store(Process process) {

/**
* 阻塞队列完成资源请求到就绪队列,remove 只有一个元素的数组不知道会不会出错,调用之前先判断是否满足抢占 cpu
*/
public void blockToReady(Process prc)
{
readyQueue.add(prc);
blockedQueue.remove(prc);
prc.setReady();
}

/**
* readyQueenToRunning 就绪态到进程态,
* @return Process 进程
*/
public Process readyQueenToRunning() {
if(readyQueue.size() > 0) {
Process process=null;
process=readyQueue.get(0);
readyQueue.remove(process);
process.setRunning();
return process;
}
else {
return null;
}
}

/**
* runningQueenToRunning
* 先判断是否中断表中是否存在进程,有则开始中断
* 先调用这个再调用 readyToRunning;
* @return Process 进程
*/
public Process runningQueenToRunning() {
if(runningQueue.size()>0) {
Process process=null;
process=runningQueue.get(0);
runningQueue.remove(process);
return process;
} else {
return null;
}
}

/**
* 发生抢占 cpu 的状况
* @param process
*/
public void interrupt(Process process) {
runningQueue.add(runningProcess);
runningProcess=process;
readyQueue.remove(process);
}

/**
* getFreeDevice 释放设备后判断阻塞队列有无因为此设备而被阻塞的进程并分配设备给此进程,然后调用进程到就绪队列
* @param device
* @return
*/
public Process getFreeDevice(Device device) {
Process process = null;
for (int i = 0; i < this.blockedQueue.size(); i++) {
//todo:还需要更改,把 PID 设置一下,并设置占用状态,设置进程设备
if(blockedQueue.get(i).getDeviceType() == device.getType()) {
device.setOccupy(true);
device.setPID(this.blockedQueue.get(i).getPcb().getId());
this.blockedQueue.get(i).setDevice(device);
process = this.blockedQueue.get(i);
break;
}
}
return process;
}

/**
* ProcessController 单例模式
* @return ProcessController 进程控制类
*/
public static ProcessController getInstance() {
if (processController == null) {
processController = new ProcessController();
}
return processController;
}

/**
* 随机生成程序优先级
* @return int 优先级
*/
private static int getRandomPriority() {
Random random=new Random();
return random.nextInt(MAX_PRIORITY) + 1;
}
/**
* getRandomRestRunTime 获取随机程序运行剩余时间,值为 1 ~ 4
* @return double 运行时间
*/
private static double getRandomRestRunTime() {
return (Math.random() * 3.0D) + 1;
}
}

// Content from: .\main\java\com\example\os\service\FATService.java

package com.example.os.service;

import com.example.os.model.*;
import com.example.os.util.FileSystemUtil;
import javafx.scene.control.TreeItem;

import java.util.ArrayList;
import java.util.List;

// 文件分配表服务类
public class FATService {
// 文件分配表列表
private static FAT[] myFAT;
// 已打开的文件列表对象{length,files}
private static OpenFiles openFiles;
// 颜色列表
private static ArrayList<Color> colorArrayList;

public FATService() {
openFiles = new OpenFiles();
}

/**
* 获取文件分配表
*/
public static FAT[] getMyFAT() {
return myFAT;
}

/**
* 设置文件分配表
*
* @param myFAT
*/
public static void setMyFAT(FAT[] myFAT) {
FATService.myFAT = myFAT;
}

/**
* 获取指定文件分配表
*
* @param index
* @return
*/
public static FAT getFAT(int index) {
return myFAT[index];
}
/**
* 获取已打开的文件列表对象
*
* @return
*/
public static OpenFiles getOpenFiles() {
return openFiles;
}

/**
* 设置已打开的文件列表对象
*
* @param openFiles
*/
public static void setOpenFiles(OpenFiles openFiles) {
FATService.openFiles = openFiles;
}

/**
* 添加已打开的文件
*/
public void addOpenFile(FAT fat, int flag) {
OpenFile openFile = new OpenFile();
openFile.setFile((File) fat.getObject());
openFile.setFlag(flag);
openFiles.addFile(openFile);
}

/**
* 移除已打开的文件
*/
public void removeOpenFile(FAT fat) {
for (int i = 0; i < openFiles.getFiles().size(); i++) {
if (openFiles.getFiles().get(i).getFile() == fat.getObject()) {
openFiles.getFiles().remove(i);
}
}
}

/**
* 检查该文件是否打开
*/
public boolean checkOpenFile(FAT fat) {
for (int i = 0; i < openFiles.getFiles().size(); i++) {
if (openFiles.getFiles().get(i).getFile() == fat.getObject()) {
return true;
}
}
return false;
}

/**
* 初始化磁盘块分配状态
*/
public void initFAT() {
myFAT = new FAT[128];
// 初始化文件分配表所占的磁盘块 一个文件分配表占两个盘块
myFAT[0] = new FAT(FileSystemUtil.END, FileSystemUtil.DISK, null, 0);
myFAT[1] = new FAT(FileSystemUtil.END, FileSystemUtil.DISK, null, 1);
// 初始化 c 盘所占的磁盘块
myFAT[2] = new FAT(FileSystemUtil.END, FileSystemUtil.DISK, new Disk("D"),
2);
for (int i = 3; i < 128; i++) {
// 磁盘默认空闲
myFAT[i] = new FAT(i);
}

// 初始化颜色分配表 23 种
colorArrayList = new ArrayList<>();
int n ;
char[] chars
={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
for (int i = 0; i < 128; i++) {
String s ="";
for (int j=0;j<6;j++){
n = (int) (Math.random() * (15));
s=s+chars[n];
}
Color color = new Color("#"+s, false);
colorArrayList.add(color);
}
System.out.println(colorArrayList.size());
}

/**
* 随机获取颜色下标
*/
public int getColorIndex() {
int n = (int) (Math.random() * (colorArrayList.size()-1));
System.out.println(n);
int i;
for ( i= 0; i < colorArrayList.size(); i++) {
if(!colorArrayList.get(i).getUsed()){
break;
}
}
if(i==colorArrayList.size()){
n = (int) (Math.random() * (colorArrayList.size()-1));
return n;
}
while (colorArrayList.get(n).getUsed()) {
n = (int) (Math.random() * (colorArrayList.size()-1));
}
colorArrayList.get(n).setUsed(true);
return n;
}

/**
* 设置颜色为未使用
*/
public void setColorIndex(int colorIndex) {
colorArrayList.get(colorIndex).setUsed(false);
}

/**
* 获取颜色
*/
public String getColor(int colorIndex) {
return colorArrayList.get(colorIndex).getColor();
}

/**
* 创建文件夹
*/
public int creatFolder(String path) {
String folderName = null;
boolean canName = true;
int index = 1;
Folder folder;
// 文件夹默认命名
do {
folderName = "新建文件夹";
canName = true;
folderName = folderName + index;

for (int i = 0; i < myFAT.length; i++) {


int index1 = myFAT[i].getIndex();
if (index1 != FileSystemUtil.SPARE && index1 != FileSystemUtil.BAD
&& myFAT[i].getType() == FileSystemUtil.FOLDER) {
folder = (Folder) myFAT[i].getObject();
// 重新遍历
if (path.equals(folder.getLocation()) &&
folderName.equals(folder.getFolderName())) {
// 继续循环,
canName = false;
}
}
}
index++;
} while (!canName);

index = this.searchEmptyMyFAT();
// 磁盘分配错误
if (index == FileSystemUtil.ERROR) {
return FileSystemUtil.ERROR;
} else {
int colorIndex = getColorIndex();
folder = new Folder(folderName, path, index, colorIndex);
myFAT[index] = new FAT(FileSystemUtil.END, FileSystemUtil.FOLDER,
folder, index);
return index;
}
}

/**
* 创建文件
*/
public int creatFile(String path) {
String fileName = null;
boolean canName = true;
int index = 1;

File file;
// 文件默认命名
do {
fileName = "新建文件";
canName = true;
fileName = fileName + index;

for (int i = 0; i < myFAT.length; i++) {


int index1 = myFAT[i].getIndex();
if (index1 != FileSystemUtil.SPARE && index1 != FileSystemUtil.BAD
&& myFAT[i].getType() == FileSystemUtil.FILE) {
file = (File) myFAT[i].getObject();
// 重新遍历
if (path.equals(file.getLocation()) &&
fileName.equals(file.getFileName())) {
// 继续循环,
canName = false;
}
}
}
index++;
} while (!canName);

index = this.searchEmptyMyFAT();
// 磁盘分配错误
if (index == FileSystemUtil.ERROR) {
return FileSystemUtil.ERROR;
} else {
int colorIndex = getColorIndex();
file = new File(fileName, path, index, colorIndex);
myFAT[index] = new FAT(FileSystemUtil.END, FileSystemUtil.FILE, file,
index);
return index;
}
}

/**
* 查找空的磁盘块下标
*/
public int searchEmptyMyFAT() {
for (int i = 0; i < myFAT.length; i++) {
if (myFAT[i].getIndex() == FileSystemUtil.SPARE) {
return i;
}
}
return FileSystemUtil.ERROR;
}

/**
* 磁盘已使用的个数
*/
public int getNumOfFAT() {
int n = 0;
for (int i = 0; i < myFAT.length; i++) {
if (myFAT[i].getIndex() != FileSystemUtil.SPARE &&
myFAT[i].getIndex() != FileSystemUtil.BAD) {
n++;
}
}
return n;
}

/**
* 磁盘未被占用的个数(不包括坏的)
*/
public int getSpaceOfFAT() {
int n = 0;
for (int i = 3; i < myFAT.length; i++) {
if (myFAT[i].getIndex() == FileSystemUtil.SPARE) {
n++;
}
}
return n;
}

/**
* 保存已修改的文件
*
* @param fat 文件对象
* @param content 后来输入的文件内容
*/
public boolean saveToModifyFATS2(FAT fat, String content) {
// 获取新的文本字节长度长度
int length = content.getBytes().length;
System.out.println("文本长度:" + length);
// 获取新的文本所占磁盘块数
int num = FileSystemUtil.getNumOfFAT(length);
System.out.println("所占磁盘块数:" + num);
// 获取原来文件所占的磁盘块数
int oldNum = ((File) fat.getObject()).getNumOfFAT();
// 获取文件的初始化盘块下标
int begin = ((File) fat.getObject()).getDiskNum();
// 该盘块指向的下个盘块下标
int index = begin;
int pre = 3;
// 磁盘块数量增多
int n;
if (num > oldNum) {
n = num - oldNum;
if (this.getSpaceOfFAT() < n) {
// 提示保存的内容已经超过磁盘的容量
return false;
} else {
File file = (File) fat.getObject();
file.setContent(content);
file.setLength(length);
file.setNumOfFAT(num);
while (index != FileSystemUtil.END) {
// 设置新的文本内容 长度 磁盘块数 本来已经分配的磁盘块数据更新
myFAT[index].setObject(file);
pre = index;
index = myFAT[index].getIndex();
}
// 找新的磁盘块 分配新的磁盘块
int space = this.searchEmptyMyFAT();
index = pre;
myFAT[index].setIndex(space);
for (int i = 1; i <= n; i++) {
if (i == n) {
myFAT[space] = new FAT(FileSystemUtil.END,
FileSystemUtil.FILE, file, space);
} else {
myFAT[space] = new FAT(FileSystemUtil.END,
FileSystemUtil.FILE, file, space);
myFAT[space].setIndex(this.searchEmptyMyFAT());
}
space = this.searchEmptyMyFAT();
}
}
} else {
File file = (File) fat.getObject();
file.setContent(content);
file.setLength(length);
file.setNumOfFAT(num);
// 磁盘块数量减少或不变
n = oldNum - num;
int i = 0;
while (index != FileSystemUtil.END) {
// 设置新的文本内容 长度 磁盘块数 本来已经分配的磁盘块数据更新
i++;
if (i < num) {
myFAT[index].setObject(file);
pre = index;
index = myFAT[index].getIndex();
} else if (i == num) {
myFAT[index].setObject(file);
pre = index;
index = myFAT[index].getIndex();
myFAT[pre].setIndex(FileSystemUtil.END);
} else {
pre = index;
index = myFAT[index].getIndex();
myFAT[pre] = new FAT(pre);
}
}
}
return true;
}

/**
* 获取指定路径下的文件夹
*/
public List<Folder> getFolders(String path) {
ArrayList<Folder> list = new ArrayList<>();
for (int i = 0; i < myFAT.length; i++) {
int index = myFAT[i].getIndex();
Object object = myFAT[i].getObject();
if (index != FileSystemUtil.SPARE && index != FileSystemUtil.BAD &&
object instanceof Folder && ((Folder) object).getLocation().equals(path)) {
list.add((Folder) object);
}
}
return list;
}

/**
* 获取指定路径下的文件
*/
public List<File> getFiles(String path) {
ArrayList<File> list = new ArrayList<>();
for (int i = 0; i < myFAT.length; i++) {
int index = myFAT[i].getIndex();
Object object = myFAT[i].getObject();
if (index != FileSystemUtil.SPARE && index != FileSystemUtil.BAD &&
object instanceof File && ((File) object).getLocation().equals(path)) {
list.add((File) object);
}
}
return list;
}

/**
* 判断新的文件名是否重复
*/
public boolean isFileNameSame(String path, String name) {
ArrayList<File> list = (ArrayList) getFiles(path);
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getFileName().equals(name)) {
return true;
}
}
return false;
}

/**
* 判断新的文件夹名是否重复
*/
public boolean isFolderNameSame(String path, String name) {
ArrayList<Folder> list = (ArrayList) getFolders(path);
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getFolderName().equals(name)) {
return true;
}
}
return false;
}

/**
* 获取具体的文件夹
*/
public FAT getFolderFAT(String path, String name) {
for (int i = 0; i < myFAT.length; i++) {
int index = myFAT[i].getIndex();
Object object = myFAT[i].getObject();
if (index == FileSystemUtil.END && object instanceof Folder &&
((Folder) object).getLocation().equals(path) && ((Folder)
object).getFolderName().equals(name)) {
return myFAT[i];
}
}
return null;
}

/**
* 获取具体的文件
*/
public FAT getFileFAT(String path, String name) {
for (int i = 0; i < myFAT.length; i++) {
int index = myFAT[i].getIndex();
Object object = myFAT[i].getObject();
if (index == FileSystemUtil.END && object instanceof File && ((File)
object).getLocation().equals(path) && ((File) object).getFileName().equals(name)) {
return myFAT[i];
}
}
return null;
}

/**
* 获取指定路径下文件分配表
*/
public List<FAT> getFATs(String path) {
List<FAT> fats = new ArrayList<>();
int i;
int index;
Object object;
for (i = 0; i < myFAT.length; i++) {
index = myFAT[i].getIndex();
object = myFAT[i].getObject();
if (index == FileSystemUtil.END && object instanceof File && ((File)
object).getLocation().equals(path)) {
fats.add(myFAT[i]);
}
}

for (i = 0; i < myFAT.length; i++) {


index = myFAT[i].getIndex();
object = myFAT[i].getObject();
if (index == FileSystemUtil.END && object instanceof Folder &&
((Folder) object).getLocation().equals(path)) {
fats.add(myFAT[i]);
}
}
return fats;
}

/**
* 获取某个文件夹的大小
*/
public int getFolderSize(Folder folder) {
int size = 0;
String path = folder.getLocation() + folder.getFolderName() + "\\";
for (int i = 0; i < myFAT.length; i++) {
int type = myFAT[i].getType();
Object object = myFAT[i].getObject();
if (type == FileSystemUtil.FILE && ((File)
object).getLocation().contains(path)) {
size = size + ((File) object).getSize();
} else if ((type == FileSystemUtil.FOLDER && ((Folder)
object).getLocation().contains(path))) {
size = size + ((Folder) object).getSize();
}
}
return size;
}

/**
* 获取某个文件夹所包含的子文件夹个数
*/
public int getFolderChildSize(Folder folder) {
int size = 0;
String path = folder.getLocation()+ "\\" + folder.getFolderName();
for (int i = 0; i < myFAT.length; i++) {
int type = myFAT[i].getType();
Object object = myFAT[i].getObject();
if ((type == FileSystemUtil.FOLDER && ((Folder)
object).getLocation().contains(path))) {
size++;
}
}
return size;
}

/**
* 获取某个文件夹所包含的子文件夹个数
*/
public int getFileChildSize(Folder folder) {
int size = 0;
String path = folder.getLocation() + "\\" + folder.getFolderName();
for (int i = 0; i < myFAT.length; i++) {
int type = myFAT[i].getType();
Object object = myFAT[i].getObject();
if (type == FileSystemUtil.FILE && ((File)
object).getLocation().contains(path)) {
size++;
}
}
return size;
}

/**
* 根据 TreeItem 来获取对应的 Folder FAT
* */
public FAT getTreeItemFAT(TreeItem<String> treeItem){
for (int i = 0; i < myFAT.length; i++) {
Object object = myFAT[i].getObject();
if(myFAT[i].getType()==FileSystemUtil.FOLDER&&((Folder)
(object)).getFolderTreeItem().equals(treeItem)){
return myFAT[i];
}
}
return null;
}

/***?
* 判断当前目录下的文件或文件夹数已够 8 个
*/
public boolean isEight(String path) {
return getFATs(path).size() > 7;
}

/**
* 文件夹重命名 修改文件或文件夹路径
*/
public void modifyLocation(String oldPath, String newPath) {
for (int i = 0; i < myFAT.length; i++) {
int index = myFAT[i].getIndex();
Object object = myFAT[i].getObject();
if (index != FileSystemUtil.SPARE && index != FileSystemUtil.BAD) {
// 找到旧路径名包含需要修改的名称
if (myFAT[i].getType() == FileSystemUtil.FILE) {
if (((File) object).getLocation().contains(oldPath)) {
// 将旧的路径名替换成新的路径名
((File) object).setLocation(((File)
object).getLocation().replace(oldPath, newPath));
}
} else if (myFAT[i].getType() == FileSystemUtil.FOLDER && ((Folder)
object).getLocation().contains(oldPath)) {
// 将旧的路径名替换成新的路径名
((Folder) object).setLocation(((Folder)
object).getLocation().replace(oldPath, newPath));
}
}
}
}

/**
* 删除文件或文件夹
* 0 文件正在打开,不能删除
* 1 文件夹不为空,不能删除
*/
public int delete(FAT fat) {
if (fat.getType() == FileSystemUtil.FILE) {
// 文件删除
int i;
for (i = 0; i < openFiles.getFiles().size(); i++) {
if (openFiles.getFiles().get(i).getFile().equals(fat.getObject()))
{
// 提示文件正在打开,不能删除
return 0;
}
}

for (i = 0; i < myFAT.length; i++) {


int index = myFAT[i].getIndex();
if (index != FileSystemUtil.SPARE && index != FileSystemUtil.BAD &&
myFAT[i].getType() == FileSystemUtil.FILE &&
myFAT[i].getObject().equals(fat.getObject())) {
// 删除文件,将该文件分配表 磁盘块号设为空闲 内容清空
myFAT[i].setIndex(FileSystemUtil.SPARE);
myFAT[i].setType(-1);
myFAT[i].setObject(null);
System.out.println("----------------------------》删除文件");
}
}
} else {
// 文件夹删除 path 父目录路径
String path = ((Folder) fat.getObject()).getLocation();
String folderPath = path + "\\" + ((Folder)
fat.getObject()).getFolderName();
System.out.println("路径:" + folderPath);
int index = 0;

for (int i = 3; i < myFAT.length; i++) {


int next = myFAT[i].getIndex();
// 该磁盘不为空 不坏
if (next != FileSystemUtil.SPARE && next != FileSystemUtil.BAD) {
Object object = myFAT[i].getObject();
if (myFAT[i].getType() == FileSystemUtil.FOLDER) {
// folderPath 路径下是否有文件夹
if (((Folder) object).getLocation().equals(folderPath)) {
return 1;
}
} else if (myFAT[i].getType() == FileSystemUtil.FILE) {
if (((File) object).getLocation().equals(folderPath)) {
return 1;
}
}

if (myFAT[i].getType() == FileSystemUtil.FOLDER &&


myFAT[i].getObject().equals(fat.getObject())) {
index = i;
}
}
}
// 删除文件夹 将该文件夹分配表 磁盘块号设为空闲 内容清空
myFAT[index].setIndex(FileSystemUtil.SPARE);
myFAT[index].setType(-1);
myFAT[index].setObject(null);
System.out.println("----------------------------》");
}
return -1;
}

// Content from: .\main\java\com\example\os\UI\AppMain.java

package com.example.os.UI;

import javafx.application.Application;

public class AppMain {


public static void main(String[] args) {
Application.launch(LoginMain.class, args);
}
}

// Content from: .\main\java\com\example\os\UI\AttributeXMLControl.java

package com.example.os.UI;

import com.example.os.model.FAT;
import com.example.os.model.File;
import com.example.os.model.Folder;
import com.example.os.service.FATService;
import com.example.os.util.FileSystemUtil;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;

import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;

public class AttributeXMLControl implements Initializable {

private static final ArrayList<FAT> fatArrayList = new ArrayList<>();


@FXML
private Label containFile;
@FXML
private Label fileName;
@FXML
private RadioButton readOnly;
@FXML
private RadioButton readWrite;
@FXML
private Button buttonEnsure;
@FXML
private Button buttonCancel;
@FXML
private Label size;
@FXML
private Label reviseTime;
@FXML
private Label createTime;
@FXML
private Button buttonUse;
@FXML
private Label fileStyle;
@FXML
private Label fileLocation;
@FXML
private ImageView fileImg;
@FXML
private Label startBlock;
@FXML
private Label blockNum;

private FAT fat;


private FATService fatService;
private int fileNum;
private int folderNum;
private String path;

// 添加 fat
public static void addFatArrayList(FAT fat) {
fatArrayList.add(fat);
}

// 删除 fat
public static void removeFatArrayList(FAT fat) {
fatArrayList.remove(fat);
}

// 初始化
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
fatService = new FATService();
// 不为零,记录是哪个 fat
int length = fatArrayList.size();
if (length != 0) {
fat = fatArrayList.get(length - 1);
}
if (fat.getType() == FileSystemUtil.FOLDER) {
// 文件夹
Folder folder = (Folder) fat.getObject();
fileName.setText(folder.getFolderName());
fileImg.setImage(new Image(FileSystemUtil.folderPath));
fileStyle.setText("文件夹");
fileLocation.setText(folder.getLocation());
size.setText(fatService.getFolderSize(folder) + "B");
folderNum = fatService.getFolderChildSize(folder);
fileNum = fatService.getFileChildSize(folder);
containFile.setText(fileNum + "个文件 " + folderNum + "个文件夹");
createTime.setText(folder.getCreateTime());
reviseTime.setText(folder.getReviseTime());
readWrite.selectedProperty().setValue(true);
readOnly.selectedProperty().setValue(false);
readOnly.setDisable(true);
readWrite.setDisable(true);
startBlock.setText(folder.getDiskNum()+"");
blockNum.setText("1");
} else {
// 文件
File file = (File) fat.getObject();
fileName.setText(file.getFileName());
fileImg.setImage(new Image(FileSystemUtil.filePath));
fileStyle.setText("文件夹");
fileLocation.setText(file.getLocation());
size.setText(file.getSize() + "B");
path = file.getLocation() + "\\" + file.getFileName();
folderNum = fatService.getFolders(path).size();
fileNum = fatService.getFiles(path).size();
containFile.setText(fileNum + "个文件 " + folderNum + "个文件夹");
createTime.setText(file.getCreateTime());
reviseTime.setText(file.getReviseTime());
startBlock.setText(file.getDiskNum()+"");
blockNum.setText(file.getNumOfFAT()+"");
String type = file.getType();
if (type.equals("写读")) {
readWrite.selectedProperty().setValue(true);
} else {
readOnly.selectedProperty().setValue(true);
}

// 修改属性按钮
readOnly.selectedProperty().addListener(new ChangeListener<Boolean>() {
//readOnly 监听单独
@Override
public void changed(ObservableValue<? extends Boolean> observable,
Boolean oldValue, Boolean newValue) {
readWrite.selectedProperty().setValue(!newValue);
}
});

readWrite.selectedProperty().addListener(new ChangeListener<Boolean>()
{ //readOnly 监听单独
@Override
public void changed(ObservableValue<? extends Boolean> observable,
Boolean oldValue, Boolean newValue) {
readOnly.selectedProperty().setValue(!newValue);
}
});
// 确定
buttonEnsure.setOnAction(actionEvent -> {
if (readOnly.selectedProperty().getValue()) {
file.setType("读");
} else {
file.setType("写读");
}
// 当前窗体
Stage stage = (Stage) buttonCancel.getScene().getWindow();
stage.close();
});
// 取消
buttonCancel.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
// 当前窗体
Stage stage = (Stage) buttonCancel.getScene().getWindow();
stage.close();
}
});
// 应用
buttonUse.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
if (readOnly.selectedProperty().getValue()) {
file.setType("读");
} else {
file.setType("写读");
}
// 当前窗体
Stage stage = (Stage) buttonCancel.getScene().getWindow();
stage.close();
}
});
}
}
}

// Content from: .\main\java\com\example\os\UI\FileMain.java

package com.example.os.UI;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class FileMain extends Application {

public static Stage stage = new Stage();


public static Parent page;
public static Scene scene = null;
public static Stage LoginStage;
@Override
public void start(Stage primaryStage) throws Exception{
LoginStage = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("/fxml/view.fxml"));
primaryStage.setTitle("File");
Scene scene = new Scene(root);
scene.setFill(Color.TRANSPARENT);
primaryStage.setScene(scene);
primaryStage.initStyle(StageStyle.TRANSPARENT);//设定窗口无边框
primaryStage.show();
}

public void loginFileController() throws Exception {


start(stage);
}
}

// Content from: .\main\java\com\example\os\UI\FileXMLController.java

package com.example.os.UI;

import com.example.os.Listener.DragUtil;
import com.example.os.model.FAT;
import com.example.os.model.File;
import com.example.os.model.Folder;
import com.example.os.model.OpenFiles;
import com.example.os.service.FATService;
import com.example.os.util.FileSystemUtil;
import com.example.os.util.GUI;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

public class FileXMLController implements Initializable {


// label 集合
private static final List<Label> labelList = new ArrayList<Label>();
public static ObservableList<FAT> FATsModels =
FXCollections.observableArrayList();
public static ObservableList<File> FilesModels =
FXCollections.observableArrayList();
public static String path = "/Users/yingfan/Desktop";
public static FATService fatService = null;
public static FAT[] myFAT = null;
public static OpenFiles openFiles = null;
public static Stage stage;//新建窗口
// 右击面板菜单
private static ContextMenu PaneContextMenu;
// 右击书目录菜单
private static ContextMenu TreeContextMenu;
// 单击标志
private static Button flagButton;
@FXML
Button filePaneFileBtn;
@FXML
Button folderPaneFileBtn;
// 设置文件树目录
boolean isFirst = true;
// 当前的树节点
private TreeItem<String> currentTreeItem;
// 右击书目录的树节点
private TreeItem<String> rightClickTreeItem;
// 右击书目录的路径
private String rightClickTreePath;
// 磁盘树节点
private TreeItem<String> treeDiskItem;
@FXML
private AnchorPane rootPane;
// 圆
@FXML
private PieChart circleView;

//盘块详情面板
@FXML
private AnchorPane DiskBlockPane;

// 文件图标面板
@FXML
private FlowPane filePane;
// 文件树目录
@FXML
private TreeView<String> treeView;
// 文件打开目录表格
@FXML
private TableView<File> fileTable;
@FXML
private TableColumn<File, String> fileName;
@FXML
private TableColumn<File, String> fileStyle;
@FXML
private TableColumn<File, Integer> startNum;
@FXML
private TableColumn<File, String> fileLocation;
// 文件分配表格
@FXML
private TableView<FAT> fatTable;
@FXML
private TableColumn<FAT, Integer> num;
// 文件右击事件
@FXML
private TableColumn<FAT, Integer> index;
//饼图
@FXML
private PieChart pieChart;
//用于路径搜索的输入框
@FXML
private TextField searchPath;
//饼图文字
@FXML
private Label pieChartTextBusy;
@FXML
private Label pieChartTextSpace;

@FXML
private ImageView backIcon;

@FXML
private ImageView outIcon;

@FXML
private AnchorPane top;

// back
@FXML
void back() {
FileMain.stage.hide();
LoginMain.LoginStage.show();
}

// out
@FXML
void out() {
Stage stage = (Stage) top.getScene().getWindow();
stage.close();
}

void addListener(){

// 添加窗体拖动
DragUtil.addDragListener(FileMain.LoginStage, top);
// 添加退出程序按钮
outIcon.setOnMouseEntered(e -> outIcon.setCursor(Cursor.HAND));

// 添加返回按钮
backIcon.setOnMouseEntered(e -> backIcon.setCursor(Cursor.HAND));
}

@FXML
void searchFile(ActionEvent event) {
String inputPath;
inputPath = searchPath.getText();
if (fatService.getFATs(inputPath).size() == 0) {
GUI.contentOutGUI("搜索的内容为空,请输入正确的路径!");
return;
}
setFilePane(inputPath);
path = inputPath;
// 获取当前目录的文件夹对象
String folderPath = "";
String folderName = "";
if (!path.equals("D:")) {
String[] pathArray = path.split("\\\\|:");
System.out.println(pathArray.length);
folderName = pathArray[pathArray.length - 1];
for (int i = 0; i < pathArray.length - 1; i++) {
if (i == 0) {
folderPath = folderPath + pathArray[i] + ":";
} else if(!pathArray[i].equals("")){
folderPath = folderPath + "\\"+ pathArray[i];
}
}
System.out.println(folderPath+" "+folderName);
FAT fat = fatService.getFolderFAT(folderPath, folderName);
currentTreeItem = ((Folder) (fat.getObject())).getFolderTreeItem();
} else {
currentTreeItem=treeDiskItem;
}
// 把对应的书目录展开
TreeItem<String> item = currentTreeItem;
while (!item.equals(treeDiskItem)){
item.setExpanded(true);
item=item.getParent();
}
treeDiskItem.setExpanded(true);
// 设置查询的文件夹被选中
treeView.getSelectionModel().select(currentTreeItem);
System.out.println(currentTreeItem.getValue());
}

// 初始化
@Override
public void initialize(URL location, ResourceBundle resources) {
// 初始化
init();
// 菜单栏初始化
initMenu();
// 设置文件树目录
setTree();
// 设置面板的文件图标
setFilePane("D:");
// 设置盘块号状态
setFATStatue();
// 设置打开文件状态
setFileStatue();
// 设置面板右击事件
setPaneRightClick();
// 饼状图改变事件
changPie();

initDiskBlockPane();
// 添加监听函数
addListener();
}

// 菜单栏初始化
private void initMenu() {
// 右击面板菜单初始化
PaneContextMenu = new ContextMenu();
MenuItem M1 = new MenuItem("新建文件");
MenuItem M2 = new MenuItem("新建文件夹");
// MenuItem 点击
PaneContextMenu.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
int index;
String name;
if (event.getTarget().equals(M1)) {
if (fatService.isEight(path)) {
GUI.contentOutGUI("已达到最大容量!");
return;
}
index = fatService.creatFile(path);
if(index == FileSystemUtil.ERROR){
GUI.contentOutGUI("已达到磁盘最大容量!");
}
System.out.println("新建文件成功! 文件路径:" + ((File)
myFAT[index].getObject()).getFileName());
// 设置文件面板图标
setFilePane(path);
changPie();
} else if (event.getTarget().equals(M2)) {
if (fatService.isEight(path)) {
GUI.contentOutGUI("已达到最大容量!");
return;
}
index = fatService.creatFolder(path);
if(index==FileSystemUtil.ERROR){
GUI.contentOutGUI("已达到磁盘最大容量!");
}
Folder folder = ((Folder) myFAT[index].getObject());
name = folder.getFolderName();
System.out.println("新建文件夹成功! 文件夹名:" + name);
// 设置文件树结构
Node folderPicIcon = new ImageView(new
Image(getClass().getResourceAsStream(FileSystemUtil.folderTreePath), 18, 18, false,
false));
TreeItem<String> treeFolderItem = new TreeItem<String>(name,
folderPicIcon);
currentTreeItem.getChildren().add(treeFolderItem);
// 设置树结构
folder.setFolderTreeItem(treeFolderItem);
// 设置文件面板图标
setFilePane(path);
changPie();
}
// 初始化盘块号状态
setFATStatue();
// 设置颜色变化
setDiskBlockPane();
}
});
PaneContextMenu.getItems().addAll(M1, M2);

// 右击树菜单初始化
TreeContextMenu =new ContextMenu();
MenuItem M3 = new MenuItem("新建文件");
MenuItem M4 = new MenuItem("新建文件夹");
MenuItem M5 = new MenuItem("删除");
MenuItem M6 = new MenuItem("重命名");
// MenuItem 点击
TreeContextMenu.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
int index;
String name;
if (event.getTarget().equals(M3)) {
// 新建文件
if (fatService.isEight(rightClickTreePath)) {
GUI.contentOutGUI("已达到最大容量!");
return;
}
index = fatService.creatFile(rightClickTreePath);
System.out.println("新建文件成功! 文件路径:" + ((File)
myFAT[index].getObject()).getFileName());
// 设置文件面板图标
if(rightClickTreePath.equals(path)){
setFilePane(path);
}
changPie();
} else if (event.getTarget().equals(M4)) {
// 新建文件夹
if (fatService.isEight(rightClickTreePath)) {
GUI.contentOutGUI("已达到最大容量!");
return;
}
index = fatService.creatFolder(rightClickTreePath);
Folder folder = ((Folder) myFAT[index].getObject());
name = folder.getFolderName();
System.out.println("新建文件夹成功! 文件夹名:" + name);
// 设置文件树结构
Node folderPicIcon = new ImageView(new
Image(getClass().getResourceAsStream(FileSystemUtil.folderTreePath), 18, 18, false,
false));
TreeItem<String> treeFolderItem = new TreeItem<String>(name,
folderPicIcon);
rightClickTreeItem.getChildren().add(treeFolderItem);
// 设置树结构
folder.setFolderTreeItem(treeFolderItem);
// 设置文件面板图标
if(rightClickTreePath.equals(path)){
setFilePane(path);
changPie();
}
}else if (event.getTarget().equals(M5)) {
// 删除
if(rightClickTreeItem.getValue().equals("D:")){
GUI.contentOutGUI("D 盘不能删除!");
return;
}
FAT fat =fatService.getTreeItemFAT(rightClickTreeItem);
Folder folder =(Folder) fat.getObject();
index = fatService.delete(fat);
if (index == 1) {
GUI.contentOutGUI("文件夹内容不为空,不能删除!");
return;
}
TreeItem<String> parentItem = rightClickTreeItem.getParent();
parentItem.getChildren().remove(rightClickTreeItem);
// 把对应的颜色置为未使用
int colorIndex = folder.getColorIndex();
fatService.setColorIndex(colorIndex);
// 刷新图标面板
String location =getPath(parentItem);
if(location.equals(path)){
setFilePane(path);
}
// 设置颜色变化
setDiskBlockPane();
setFATStatue();
changPie();
}else if (event.getTarget().equals(M6)) {
// 重命名
if(rightClickTreeItem.getValue().equals("D:")){
GUI.contentOutGUI("D 盘不能重命名!");
return;
}
FAT fat =fatService.getTreeItemFAT(rightClickTreeItem);
Folder folder =(Folder) fat.getObject();
// 文件夹重命名
TextArea textArea = new TextArea();
textArea.setText(folder.getFolderName());
textArea.setWrapText(true);
textArea.setPrefSize(500,270);
textArea.setLayoutY(30);
Button writeBtn = new Button("保存");
Button cancelBtn = new Button("取消");
AnchorPane anchorPane = new AnchorPane();
AnchorPane anchorPane1 = new AnchorPane();
anchorPane1.setPrefSize(496,50);
anchorPane1.setLayoutY(298);
anchorPane1.setLayoutX(2);
anchorPane1.setStyle("-fx-background-color:white;");
anchorPane1.getChildren().add(writeBtn);
anchorPane1.getChildren().add(cancelBtn);
writeBtn.setStyle("-fx-background-color: #D5D5D5;"+
"-fx-border-color: #C4C4C4;"+
"-fx-border-radius:0;"+
"-fx-border-style:solid;"+
"-fx-border-width:1px;");
writeBtn.setPrefSize(90,15);
writeBtn.setLayoutX(100);
writeBtn.setLayoutY(12);
cancelBtn.setStyle("-fx-background-color: #D5D5D5;"+
"-fx-border-color: #C4C4C4;"+
"-fx-border-radius:0;"+
"-fx-border-style:solid;"+
"-fx-border-width:1px;");
cancelBtn.setPrefSize(90,15);
cancelBtn.setLayoutX(300);
cancelBtn.setLayoutY(12);
ImageView imageView = new ImageView();
imageView.setImage(new
Image(getClass().getResourceAsStream(FileSystemUtil.delPath), 17, 17, false,
false));
Label label1=new Label("",imageView);
label1.setLayoutX(470);
label1.setLayoutY(7);
anchorPane.getChildren().add(textArea);
anchorPane.getChildren().add(label1);
anchorPane.getChildren().add(anchorPane1);
anchorPane.setStyle("-fx-background-color:#666666;"
+ //设置背景颜色
"-fx-text-fill:#FF0000;" + //设置字体颜色
"-fx-border-radius:0;" + //设置边框圆角
"-fx-border-style:solid;"+ //设置边框样式
"-fx-border-width:2;"
);
textArea.setStyle("-fx-background-color:white;" + //设置背
景颜色
"-fx-text-fill:black;" +//设置字体颜色
"-fx-font-size:20;"+
"-fx-border-radius:0;" + //设置边框圆角
"-fx-border-color:black;"+ //设置边框颜色
"-fx-border-style:solid;"+ //设置边框样式
"-fx-border-width:2;" //设置边框宽度
);
Stage dialogStage = new Stage();
Scene dialogScene = new Scene(anchorPane, 500, 350);
dialogStage.setScene(dialogScene);
dialogStage.initStyle(StageStyle.UNDECORATED);
dialogStage.show();
// 窗体拖动
DragUtil.addDragListener(dialogStage,anchorPane);
label1.setOnMouseClicked(mouseEvent -> {
if(mouseEvent.getClickCount()==1)
dialogStage.close();
});
dialogStage.show();

cancelBtn.setOnAction(e -> {
dialogStage.close();
});

writeBtn.setOnAction(e -> {
// 重命名
String folderName = textArea.getText();
System.out.println(rightClickTreePath+" "+folderName);
FAT fat1 =
fatService.getTreeItemFAT(rightClickTreeItem.getParent());
String location ="D:";
if(fat1!=null){
location=((Folder)fat1.getObject()).getLocation();
}
if (fatService.isFolderNameSame(location, folderName)) {
GUI.contentOutGUI("名字重复!");
dialogStage.close();
return;
}
// 刷新书目录上的文件夹名称
rightClickTreeItem.setValue(folderName);
// 修改路径目录名称
String newName = getPath(rightClickTreeItem);
fatService.modifyLocation(rightClickTreePath, newName);
folder.setFolderName(folderName);
// 刷新面板图标内容
TreeItem<String> parentItem =
rightClickTreeItem.getParent();
String folderLocation = folder.getLocation();
if(folderLocation.equals(path)){
setFilePane(path);
}
dialogStage.close();
});
}

// 初始化盘块号状态
setFATStatue();
// 设置颜色变化
setDiskBlockPane();
}
});
TreeContextMenu.getItems().addAll(M3,M4,M5,M6);
}

// 饼状图实时更新
private void changPie() {
int busy = fatService.getNumOfFAT();
int space = fatService.getSpaceOfFAT();
ObservableList<PieChart.Data> pieChartData =
FXCollections.observableArrayList(
new PieChart.Data("占用", busy),
new PieChart.Data("空闲", space));
pieChart.setData(pieChartData);
pieChart.setLegendVisible(false);
pieChart.setTitle("磁盘利用情况");
pieChart.getStylesheets().add("/css/chart.css");
pieChartTextSpace.setText("空闲:" + space);
pieChartTextBusy.setText("占用:" + busy);
}

// 初始化盘块颜色使用详情
private void initDiskBlockPane() {
for (int j = 0; j < 16; j++) {
for (int i = 0; i < 8; i++) {
Label label = new Label();
label.setStyle("-fx-background-color:grey;" + "-fx-border:none");
label.setPrefSize(20, 10);
label.setMinSize(20, 10);
label.setMaxSize(20, 10);
label.setLayoutX(25 * i + 4);
label.setLayoutY(12 * j + 32);
DiskBlockPane.getChildren().add(label);
labelList.add(label);
// 点击事件
label.setOnMouseClicked(event -> {
MouseButton button = event.getButton();
// 右击事件
if (event.getClickCount() == 1) {
setLabelStyle(labelList.indexOf(label));
}
});
}
}
labelList.get(0).setStyle("-fx-background-color:yellow;" +
"-fx-border-style: solid;" +
"-fx-border-color: black");
labelList.get(1).setStyle("-fx-background-color:yellow;" +
"-fx-border-style: solid;" +
"-fx-border-color: black");
labelList.get(2).setStyle("-fx-background-color:yellowgreen;" +
"-fx-border-style: solid;" +
"-fx-border-color: black");
}
// 点击 label 弹出属性
private void setLabelStyle(int index) {
FAT fat = myFAT[index];
if(myFAT[index].getType()==FileSystemUtil.FOLDER){
// 属性
Parent root = null;
// 传值到令外一个窗体
AttributeXMLControl.addFatArrayList(fat);
try {
root =
FXMLLoader.load(getClass().getResource("/fxml/attribute.fxml"));
} catch (IOException e) {
e.printStackTrace();
}
Stage dialogStage = new Stage();
Scene dialogScene = new Scene(root, 387, 504);
dialogStage.getIcons().add(new
Image(getClass().getResourceAsStream(FileSystemUtil.folderPath), 10, 10, false,
false));
dialogStage.setScene(dialogScene);
dialogStage.show();
// 监听窗体关闭
dialogStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
// 移除已打开的文件夹属性
AttributeXMLControl.removeFatArrayList(fat);
}
});
}else if(myFAT[index].getType()==FileSystemUtil.FILE){
// 属性
Parent root = null;
// 传值到令外一个窗体
AttributeXMLControl.addFatArrayList(fat);
try {
root =
FXMLLoader.load(getClass().getResource("/fxml/attribute.fxml"));
} catch (IOException e) {
e.printStackTrace();
}
Stage dialogStage = new Stage();
Scene dialogScene = new Scene(root, 387, 504);
dialogStage.getIcons().add(new
Image(getClass().getResourceAsStream(FileSystemUtil.filePath), 10, 10, false,
false));
dialogStage.setScene(dialogScene);
dialogStage.show();
// 监听窗体关闭
dialogStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
// 移除已打开的文件夹属性
AttributeXMLControl.removeFatArrayList(fat);
}
});
}
}

// 盘块颜色使用详情实时更新
private void setDiskBlockPane() {
for (int i = 3; i < myFAT.length; i++) {
Object object = myFAT[i].getObject();
if (myFAT[i].getType() == FileSystemUtil.FILE) {
File file = (File) object;
int colorIndex = file.getColorIndex();
labelList.get(i).setStyle("-fx-background-color:" +
fatService.getColor(colorIndex) + " ;" +
"-fx-border-style: solid;" +
"-fx-border-color: black");
} else if (myFAT[i].getType() == FileSystemUtil.FOLDER) {
Folder folder = (Folder) object;
int colorIndex = folder.getColorIndex();
labelList.get(i).setStyle("-fx-background-color:" +
fatService.getColor(colorIndex) + " ;" +
"-fx-border-style: solid;" +
"-fx-border-color: black");
} else {
labelList.get(i).setStyle("-fx-background-color:grey;");
}
}
}

// 设置搜索路径
private void setSearchPath() {
searchPath.setText(path);
}

// 设置面板右击事件
private void setPaneRightClick() {
PaneContextMenu.hide();
filePane.setOnMouseClicked(event -> {
MouseButton button = event.getButton();
//右键点击
if (button == MouseButton.SECONDARY) {
double x = event.getScreenX();
double y = event.getScreenY();
PaneContextMenu.show(filePane, x, y);
} else{
if(!(flagButton==null)){
flagButton.setStyle("-fx-background-color:white");
}
PaneContextMenu.hide();
}
});
}

// 设置面板的文件图标
private void setFilePane(String location) {
// 清空面板
filePane.getChildren().clear();
List<FAT> fatList = fatService.getFATs(location);
String name;
for (int i = 0; i < fatList.size(); i++) {
// 文件夹
if (fatList.get(i).getType() == FileSystemUtil.FOLDER) {
name = ((Folder) fatList.get(i).getObject()).getFolderName();

ImageView folderIcon = new ImageView(new


Image(getClass().getResourceAsStream(FileSystemUtil.folderPath), 80, 80, false,
false));
Label labelItem = new Label(name, folderIcon);
labelItem.setWrapText(true);
labelItem.setPrefWidth(120);
labelItem.setPrefHeight(150);
labelItem.setAlignment(Pos.CENTER);
labelItem.setContentDisplay(ContentDisplay.TOP);
folderPaneFileBtn = new Button();
folderPaneFileBtn.setStyle("-fx-background-color:white;"
+ //设置背景颜色
"-fx-background-radius:20;" + //设置背景圆角
"-fx-text-fill:#FF0000;" + //设置字体颜色
"-fx-border-radius:20;" + //设置边框圆角
"-fx-border-color:white;" //设置边框颜色
);
folderPaneFileBtn.setGraphic(labelItem);
// 获取该节点对应的 FAT 表
FAT fat = fatService.getFolderFAT(location, name);
setRightMenuFolder(folderPaneFileBtn, fat);
filePane.getChildren().add(folderPaneFileBtn);
} else {
// 文件
name = ((File) fatList.get(i).getObject()).getFileName();

ImageView fileIcon = new ImageView(new


Image(getClass().getResourceAsStream(FileSystemUtil.filePath), 80, 80, false,
false));
Label labelItem = new Label(name, fileIcon);
labelItem.setWrapText(true);
labelItem.setPrefWidth(120);
labelItem.setPrefHeight(150);
labelItem.setAlignment(Pos.CENTER);
labelItem.setContentDisplay(ContentDisplay.TOP);
filePaneFileBtn = new Button();
filePaneFileBtn.setStyle("-fx-background-color:white;" + //
设置背景颜色
"-fx-background-radius:20;" + //设置背景圆角
"-fx-text-fill:#FF0000;" + //设置字体颜色
"-fx-border-radius:20;" + //设置边框圆角
"-fx-border-color:white;" //设置边框颜色
//"-fx-border-style:dashed;"+ //设置边框样式
//"-fx-border-width:5;"+ //设置边框宽度
//"-fx-border-insets:-5" //设置边框插入值
);
filePaneFileBtn.setGraphic(labelItem);
// 获取该节点对应的 FAT 表
FAT fat = fatService.getFileFAT(location, name);
setRightMenuFile(filePaneFileBtn, fat);
filePane.getChildren().add(filePaneFileBtn);
}
}
}

// 设置文件夹右击事件
private void setRightMenuFolder(Button folderPaneFileBtn, FAT fat) {
Folder folder = ((Folder) fat.getObject());
ContextMenu folderPaneContextMenu = new ContextMenu();
// 右击文件菜单初始化
MenuItem M1 = new MenuItem("打开");
MenuItem M2 = new MenuItem("重命名");
MenuItem M3 = new MenuItem("删除");
MenuItem M4 = new MenuItem("属性");
folderPaneContextMenu.getItems().addAll(M1, M2, M3, M4);
folderPaneContextMenu.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (event.getTarget().equals(M1)) {
// 修改该文件夹的修改时间
folder.setReviseTime();
// 打开文件夹
// 获取文件夹点击的路径值,展示该路径下的文件、文件夹内容
path = path + "\\"+ folder.getFolderName() ;
setFilePane(path);
// 设置当前路径
setSearchPath();
// 设置当前树结构对象
currentTreeItem = folder.getFolderTreeItem();
} else if (event.getTarget().equals(M2)) {
// 文件夹重命名
TextArea textArea = new TextArea();
textArea.setText(folder.getFolderName());
textArea.setWrapText(true);
textArea.setPrefSize(500,270);
textArea.setLayoutY(30);
Button writeBtn = new Button("保存");
Button cancelBtn = new Button("取消");
AnchorPane anchorPane = new AnchorPane();
AnchorPane anchorPane1 = new AnchorPane();
anchorPane1.setPrefSize(496,50);
anchorPane1.setLayoutY(298);
anchorPane1.setLayoutX(2);
anchorPane1.setStyle("-fx-background-color:white;");
anchorPane1.getChildren().add(writeBtn);
anchorPane1.getChildren().add(cancelBtn);
writeBtn.setStyle("-fx-background-color: #D5D5D5;"+
"-fx-border-color: #C4C4C4;"+
"-fx-border-radius:0;"+
"-fx-border-style:solid;"+
"-fx-border-width:1px;");
writeBtn.setPrefSize(90,15);
writeBtn.setLayoutX(100);
writeBtn.setLayoutY(12);
cancelBtn.setStyle("-fx-background-color: #D5D5D5;"+
"-fx-border-color: #C4C4C4;"+
"-fx-border-radius:0;"+
"-fx-border-style:solid;"+
"-fx-border-width:1px;");
cancelBtn.setPrefSize(90,15);
cancelBtn.setLayoutX(300);
cancelBtn.setLayoutY(12);
ImageView imageView = new ImageView();
imageView.setImage(new
Image(getClass().getResourceAsStream(FileSystemUtil.delPath), 17, 17, false,
false));
Label label1=new Label("",imageView);
label1.setLayoutX(470);
label1.setLayoutY(7);
anchorPane.getChildren().add(textArea);
anchorPane.getChildren().add(label1);
anchorPane.getChildren().add(anchorPane1);
anchorPane.setStyle("-fx-background-color:#666666;"
+ //设置背景颜色
"-fx-text-fill:#FF0000;" + //设置字体颜色
"-fx-border-radius:0;" + //设置边框圆角
"-fx-border-style:solid;"+ //设置边框样式
"-fx-border-width:2;"
);
textArea.setStyle("-fx-background-color:white;" + //设置背
景颜色
"-fx-text-fill:black;" +//设置字体颜色
"-fx-font-size:20;"+
"-fx-border-radius:0;" + //设置边框圆角
"-fx-border-color:black;"+ //设置边框颜色
"-fx-border-style:solid;"+ //设置边框样式
"-fx-border-width:2;" //设置边框宽度
);
Stage dialogStage = new Stage();
Scene dialogScene = new Scene(anchorPane, 500, 350);
dialogStage.setScene(dialogScene);
dialogStage.initStyle(StageStyle.UNDECORATED);
dialogStage.show();
// 窗体拖动
DragUtil.addDragListener(dialogStage,anchorPane);
label1.setOnMouseClicked(mouseEvent -> {
if(mouseEvent.getClickCount()==1)
dialogStage.close();
});
dialogStage.show();

cancelBtn.setOnAction(e -> {
dialogStage.close();
});
writeBtn.setOnAction(e -> {
// 重命名
String name = textArea.getText();
if (fatService.isFolderNameSame(path, name)) {
GUI.contentOutGUI("名字重复!");
dialogStage.close();
return;
}
// 刷新书目录上的文件夹名称
TreeItem<String> treeItem = folder.getFolderTreeItem();
treeItem.setValue(name);
// 修改路径目录名称

fatService.modifyLocation((path+"\\"+folder.getFolderName()), (path+ "\\" +name));


folder.setFolderName(name);
// 刷新面板图标内容
setFilePane(path);
dialogStage.close();
});
} else if (event.getTarget().equals(M3)) {
// 删除
int index = fatService.delete(fat);
if (index == 1) {
GUI.contentOutGUI("文件夹内容不为空,不能删除!");
return;
}
// 删除书目录上对应的树节点
TreeItem<String> treeItem = folder.getFolderTreeItem();
currentTreeItem.getChildren().remove(treeItem);
// 把对应的颜色置为未使用
int colorIndex = folder.getColorIndex();
fatService.setColorIndex(colorIndex);
// 刷新图标面板
setFilePane(path);
// 设置颜色变化
setDiskBlockPane();
setFATStatue();
changPie();
} else if (event.getTarget().equals(M4)) {
// 属性
Parent root = null;
// 传值到令外一个窗体
AttributeXMLControl.addFatArrayList(fat);
try {
root =
FXMLLoader.load(getClass().getResource("/fxml/attribute.fxml"));
} catch (IOException e) {
e.printStackTrace();
}
Stage dialogStage = new Stage();
Scene dialogScene = new Scene(root, 387, 504);
dialogStage.getIcons().add(new
Image(getClass().getResourceAsStream(FileSystemUtil.folderPath), 10, 10, false,
false));
dialogStage.setScene(dialogScene);
dialogStage.show();
// 监听窗体关闭
dialogStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
// 移除已打开的文件夹属性
AttributeXMLControl.removeFatArrayList(fat);
}
});
}
}
});
folderPaneFileBtn.setContextMenu(folderPaneContextMenu);

// 设置文件夹双击事件
folderPaneFileBtn.setOnMouseClicked(event -> {
MouseButton button = event.getButton();
// 双击事件
if (event.getClickCount() == 2) {
// 打开文件夹
// 获取文件夹点击的路径值,展示该路径下的文件、文件夹内容
path = path+ "\\" + folder.getFolderName() ;
setFilePane(path);
// 设置当前路径
setSearchPath();
// 设置当前树结构对象
currentTreeItem = folder.getFolderTreeItem();
} else if(event.getClickCount() == 1){
if(!(flagButton==null)){
flagButton.setStyle("-fx-background-color:white");
}
folderPaneFileBtn.setStyle("-fx-background-
color:rgba(51,204,255,0.2);");
flagButton=folderPaneFileBtn;
}
});
}

// 设置文件右击事件 双击事件
private void setRightMenuFile(Button filePaneFileBtn, FAT fat) {
File file = ((File) fat.getObject());
ContextMenu filePaneContextMenu = new ContextMenu();
// 右击文件菜单初始化
MenuItem M1 = new MenuItem("读文件");
MenuItem M2 = new MenuItem("写文件");
MenuItem M3 = new MenuItem("重命名");
MenuItem M4 = new MenuItem("删除");
MenuItem M5 = new MenuItem("属性");
filePaneContextMenu.getItems().addAll(M1, M2, M3, M4, M5);
filePaneContextMenu.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (event.getTarget().equals(M1)) {
// 判断该文件是否已经打开
if (fatService.checkOpenFile(fat)) {
GUI.contentOutGUI("该文件已经打开了,不能重复打开!");
return;
}
System.out.println("文件是否已经打开");
// 显示文件内容
String contentText = file.getContent();
AnchorPane anchorPane = new AnchorPane();
ImageView imageView = new ImageView();
imageView.setImage(new
Image(getClass().getResourceAsStream(FileSystemUtil.delPath), 17, 17, false,
false));
Label label = new Label();
label.setText(contentText);
label.setPrefSize(500,270);
label.setLayoutY(30);
label.setAlignment(Pos.TOP_LEFT);
Label label1=new Label("",imageView);
label1.setLayoutX(470);
label1.setLayoutY(7);
anchorPane.getChildren().add(label);
anchorPane.getChildren().add(label1);
anchorPane.setStyle("-fx-background-color:#666666;"
+ //设置背景颜色
"-fx-text-fill:#FF0000;" + //设置字体颜色
"-fx-border-radius:0;" + //设置边框圆角
"-fx-border-style:solid;"+ //设置边框样式
"-fx-border-width:2;"
);
label.setStyle("-fx-background-color:white;" + //设置背景颜色
"-fx-text-fill:black;" +//设置字体颜色
"-fx-font-size:20;"+
"-fx-font-weight: bold;"+
"-fx-border-radius:0;" + //设置边框圆角
"-fx-border-color:black;"+ //设置边框颜色
"-fx-border-style:solid;"+ //设置边框样式
"-fx-border-width:2;" //设置边框宽度
);
Stage dialogStage = new Stage();
Scene dialogScene = new Scene(anchorPane, 500, 300);
dialogStage.setScene(dialogScene);
dialogStage.setTitle(file.getFileName());
dialogStage.initStyle(StageStyle.UNDECORATED);
label1.setOnMouseClicked(mouseEvent -> {
if(mouseEvent.getClickCount()==1)
dialogStage.close();
// 移除打开文件序列
fatService.removeOpenFile(fat);
// 刷新文件打开状态表
setFileStatue();
});
dialogStage.show();
// 窗体拖动
DragUtil.addDragListener(dialogStage,anchorPane);
// 添加到打开文件序列中
fatService.addOpenFile(fat, 0);
// 刷新文件打开状态表
setFileStatue();
} else if (event.getTarget().equals(M2)) {
// 判断该文件是否可写
if (file.getType().equals("读")) {
GUI.contentOutGUI("该文件只能读,不能写!");
return;
}
// 判断该文件是否已经打开
if (fatService.checkOpenFile(fat)) {
GUI.contentOutGUI("该文件已经打开了,不能重复打开!");
return;
}
// 写文件
TextArea textArea = new TextArea();
textArea.setText(file.getContent());
textArea.setWrapText(true);
textArea.setPrefSize(500,270);
textArea.setLayoutY(30);
Button writeBtn = new Button("保存");
Button cancelBtn = new Button("取消");
AnchorPane anchorPane = new AnchorPane();
AnchorPane anchorPane1 = new AnchorPane();
anchorPane1.setPrefSize(496,50);
anchorPane1.setLayoutY(298);
anchorPane1.setLayoutX(2);
anchorPane1.setStyle("-fx-background-color:white;");
anchorPane1.getChildren().add(writeBtn);
anchorPane1.getChildren().add(cancelBtn);
writeBtn.setStyle("-fx-background-color: #D5D5D5;"+
"-fx-border-color: #C4C4C4;"+
"-fx-border-radius:0;"+
"-fx-border-style:solid;"+
"-fx-border-width:1px;");
writeBtn.setPrefSize(90,15);
writeBtn.setLayoutX(100);
writeBtn.setLayoutY(12);
cancelBtn.setStyle("-fx-background-color: #D5D5D5;"+
"-fx-border-color: #C4C4C4;"+
"-fx-border-radius:0;"+
"-fx-border-style:solid;"+
"-fx-border-width:1px;");
cancelBtn.setPrefSize(90,15);
cancelBtn.setLayoutX(300);
cancelBtn.setLayoutY(12);
ImageView imageView = new ImageView();
imageView.setImage(new
Image(getClass().getResourceAsStream(FileSystemUtil.delPath), 17, 17, false,
false));
Label label1=new Label("",imageView);
label1.setLayoutX(470);
label1.setLayoutY(7);
anchorPane.getChildren().add(textArea);
anchorPane.getChildren().add(label1);
anchorPane.getChildren().add(anchorPane1);
anchorPane.setStyle("-fx-background-color:#666666;"
+ //设置背景颜色
"-fx-text-fill:#FF0000;" + //设置字体颜色
"-fx-border-radius:0;" + //设置边框圆角
"-fx-border-style:solid;"+ //设置边框样式
"-fx-border-width:2;"
);
textArea.setStyle("-fx-background-color:white;" + //设置背
景颜色
"-fx-text-fill:black;" +//设置字体颜色
"-fx-font-size:20;"+
"-fx-border-radius:0;" + //设置边框圆角
"-fx-border-color:black;"+ //设置边框颜色
"-fx-border-style:solid;"+ //设置边框样式
"-fx-border-width:2;" //设置边框宽度
);
Stage dialogStage = new Stage();
Scene dialogScene = new Scene(anchorPane, 500, 350);
dialogStage.setScene(dialogScene);
dialogStage.setTitle(file.getFileName());
dialogStage.initStyle(StageStyle.UNDECORATED);
dialogStage.show();
// 窗体拖动
DragUtil.addDragListener(dialogStage,anchorPane);
label1.setOnMouseClicked(mouseEvent -> {
if(mouseEvent.getClickCount()==1)
dialogStage.close();
// 移除打开文件序列
fatService.removeOpenFile(fat);
// 刷新文件打开状态表
setFileStatue();
});
// 窗体拖动
DragUtil.addDragListener(dialogStage,anchorPane);
dialogStage.show();
// 添加到打开文件序列中
fatService.addOpenFile(fat, 0);
// 刷新文件打开状态表
setFileStatue();

writeBtn.setOnAction(e -> {
String text = textArea.getText();
boolean isOut = fatService.saveToModifyFATS2(fat, text);
if (!isOut) {
GUI.contentOutGUI("磁盘容量已满,保存失败!");
} else {
file.setReviseTime();
file.setSize(text.getBytes().length);
}
// 移除打开文件序列
fatService.removeOpenFile(fat);
// 刷新文件打开状态表
setFileStatue();
// 刷新文件分配表状态
setFATStatue();
// 设置颜色变化
setDiskBlockPane();
dialogStage.close();
});
cancelBtn.setOnAction(e -> {
dialogStage.close();
fatService.removeOpenFile(fat);
// 刷新文件打开状态表
setFileStatue();
});

// 监听窗体关闭
dialogStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
System.out.println("移除打开文件序列");
// 移除打开文件序列
fatService.removeOpenFile(fat);
// 刷新文件打开状态表
setFileStatue();
}
});
} else if (event.getTarget().equals(M3)) {
// 文件重命名
TextArea textArea = new TextArea();
textArea.setText(file.getFileName());
textArea.setWrapText(true);
textArea.setPrefSize(500,270);
textArea.setLayoutY(30);
Button writeBtn = new Button("保存");
Button cancelBtn = new Button("取消");
AnchorPane anchorPane = new AnchorPane();
AnchorPane anchorPane1 = new AnchorPane();
anchorPane1.setPrefSize(496,50);
anchorPane1.setLayoutY(298);
anchorPane1.setLayoutX(2);
anchorPane1.setStyle("-fx-background-color:white;");
anchorPane1.getChildren().add(writeBtn);
anchorPane1.getChildren().add(cancelBtn);
writeBtn.setStyle("-fx-background-color: #D5D5D5;"+
"-fx-border-color: #C4C4C4;"+
"-fx-border-radius:0;"+
"-fx-border-style:solid;"+
"-fx-border-width:1px;");
writeBtn.setPrefSize(90,15);
writeBtn.setLayoutX(100);
writeBtn.setLayoutY(12);
cancelBtn.setStyle("-fx-background-color: #D5D5D5;"+
"-fx-border-color: #C4C4C4;"+
"-fx-border-radius:0;"+
"-fx-border-style:solid;"+
"-fx-border-width:1px;");
cancelBtn.setPrefSize(90,15);
cancelBtn.setLayoutX(300);
cancelBtn.setLayoutY(12);
ImageView imageView = new ImageView();
imageView.setImage(new
Image(getClass().getResourceAsStream(FileSystemUtil.delPath), 17, 17, false,
false));
Label label1=new Label("",imageView);
label1.setLayoutX(470);
label1.setLayoutY(7);
anchorPane.getChildren().add(textArea);
anchorPane.getChildren().add(label1);
anchorPane.getChildren().add(anchorPane1);
anchorPane.setStyle("-fx-background-color:#666666;"
+ //设置背景颜色
"-fx-text-fill:#FF0000;" + //设置字体颜色
"-fx-border-radius:0;" + //设置边框圆角
"-fx-border-style:solid;"+ //设置边框样式
"-fx-border-width:2;"
);
textArea.setStyle("-fx-background-color:white;" + //设置背
景颜色
"-fx-text-fill:black;" +//设置字体颜色
"-fx-font-size:20;"+
"-fx-border-radius:0;" + //设置边框圆角
"-fx-border-color:black;"+ //设置边框颜色
"-fx-border-style:solid;"+ //设置边框样式
"-fx-border-width:2;" //设置边框宽度
);
Stage dialogStage = new Stage();
Scene dialogScene = new Scene(anchorPane, 500, 350);
dialogStage.setScene(dialogScene);
dialogStage.setTitle(file.getFileName());
dialogStage.initStyle(StageStyle.UNDECORATED);
dialogStage.show();
// 窗体拖动
DragUtil.addDragListener(dialogStage,anchorPane);
label1.setOnMouseClicked(mouseEvent -> {
if(mouseEvent.getClickCount()==1)
dialogStage.close();
});
dialogStage.show();
writeBtn.setOnAction(e -> {
// 重命名
String name = textArea.getText();
if (fatService.isFileNameSame(path, name)) {
GUI.contentOutGUI("名字重复!");
dialogStage.close();
return;
}
file.setFileName(name);
// 刷新面板图标内容
setFilePane(path);
dialogStage.close();
});
cancelBtn.setOnAction(e -> {
dialogStage.close();
});

} else if (event.getTarget().equals(M4)) {
// 删除文件
int index = fatService.delete(fat);
if (index == 0) {
GUI.contentOutGUI("文件正在打开,不能删除!");
}
// 把对应的颜色置为未使用
int colorIndex = file.getColorIndex();
fatService.setColorIndex(colorIndex);
// 刷新文件分配表
setFATStatue();
// 刷新面板图标内容
setFilePane(path);
// 设置颜色变化
setDiskBlockPane();
changPie();
} else if (event.getTarget().equals(M5)) {
// 属性
Parent root = null;
// 传值到令外一个窗体
AttributeXMLControl.addFatArrayList(fat);
try {
root =
FXMLLoader.load(getClass().getResource("/fxml/attribute.fxml"));
} catch (IOException e) {
e.printStackTrace();
}
Stage dialogStage = new Stage();
Scene dialogScene = new Scene(root, 387, 504);
Image i =new Image("/img/华为.png");
dialogStage.getIcons().add(i);
dialogStage.setScene(dialogScene);
dialogStage.show();
// 监听窗体关闭
dialogStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
// 移除已打开的文件夹属性
AttributeXMLControl.removeFatArrayList(fat);
}
});
}
}
});
filePaneFileBtn.setContextMenu(filePaneContextMenu);

// 设置文件双击事件
filePaneFileBtn.setOnMouseClicked(event -> {
MouseButton button = event.getButton();
// 双击事件
if (event.getClickCount() == 2) {
// 判断该文件是否已经打开
if (fatService.checkOpenFile(fat)) {
GUI.contentOutGUI("该文件已经打开了,不能重复打开!");
return;
}
System.out.println("文件是否已经打开");
// 显示文件内容
String contentText = file.getContent();
AnchorPane anchorPane = new AnchorPane();
ImageView imageView = new ImageView();
imageView.setImage(new
Image(getClass().getResourceAsStream(FileSystemUtil.delPath), 17, 17, false,
false));
Label label = new Label();
label.setText(contentText);
label.setPrefSize(500,270);
label.setLayoutY(30);
label.setAlignment(Pos.TOP_LEFT);
Label label1=new Label("",imageView);
label1.setLayoutX(470);
label1.setLayoutY(7);
anchorPane.getChildren().add(label);
anchorPane.getChildren().add(label1);
anchorPane.setStyle("-fx-background-color:#666666;" + //设置背
景颜色
"-fx-text-fill:#FF0000;" + //设置字体颜色
"-fx-border-radius:0;" + //设置边框圆角
"-fx-border-style:solid;"+ //设置边框样式
"-fx-border-width:2;"
);
label.setStyle("-fx-background-color:white;" + //设置背景颜色
"-fx-text-fill:black;" +//设置字体颜色
"-fx-font-size:20;"+
"-fx-font-weight: bold;"+
"-fx-border-radius:0;" + //设置边框圆角
"-fx-border-color:black;"+ //设置边框颜色
"-fx-border-style:solid;"+ //设置边框样式
"-fx-border-width:2;" //设置边框宽度
);
Stage dialogStage = new Stage();
Scene dialogScene = new Scene(anchorPane, 500, 300);
dialogStage.setScene(dialogScene);
dialogStage.setTitle(file.getFileName());
dialogStage.initStyle(StageStyle.UNDECORATED);
label1.setOnMouseClicked(mouseEvent -> {
if(mouseEvent.getClickCount()==1)
dialogStage.close();
// 移除打开文件序列
fatService.removeOpenFile(fat);
// 刷新文件打开状态表
setFileStatue();
});
dialogStage.show();
// 窗体拖动
DragUtil.addDragListener(dialogStage,anchorPane);
// 添加到打开文件序列中
fatService.addOpenFile(fat, 0);
// 刷新文件打开状态表
setFileStatue();
} else if(event.getClickCount() == 1){
if(!(flagButton==null)){
flagButton.setStyle("-fx-background-color:white");
}
filePaneFileBtn.setStyle("-fx-background-
color:rgba(51,204,255,0.2);");
flagButton=filePaneFileBtn;
}
});
}

// 设置树结构
private void setTree() {
Node fileDiskIcon = new ImageView(new
Image(getClass().getResourceAsStream(FileSystemUtil.diskPath), 20, 20, false,
false));
treeDiskItem = new TreeItem<String>("D:", fileDiskIcon);
currentTreeItem = treeDiskItem;
// 是否默认打开文件夹
treeDiskItem.setExpanded(false);
treeView.setRoot(currentTreeItem);
// 遍历该磁盘下的文件夹列表
String location = "D:";
// 递归调用遍历文件夹
setFolderTree(treeDiskItem, location);
if (isFirst) {
isFirst = false;
// 点击事件
treeView.setOnMouseClicked(event -> {
MouseButton button = event.getButton();
// 右击事件
if(button == MouseButton.SECONDARY){
Node node = event.getPickResult().getIntersectedNode();
if (node instanceof Text || (node instanceof TreeCell &&
((TreeCell) node).getText() != null)) {
rightClickTreeItem =
treeView.getSelectionModel().getSelectedItem();
// 设置当前的路径
rightClickTreePath = getPath(rightClickTreeItem);
System.out.println("右击的树路径" + rightClickTreePath);
double x = event.getScreenX();
double y = event.getScreenY();
TreeContextMenu.show(treeView, x, y);
}
}else if (event.getClickCount() == 1) {
// 单击事件
TreeContextMenu.hide();
Node node = event.getPickResult().getIntersectedNode();
if (node instanceof Text || (node instanceof TreeCell &&
((TreeCell) node).getText() != null)) {
currentTreeItem =
treeView.getSelectionModel().getSelectedItem();
// 设置当前的路径
path = getPath(currentTreeItem);
System.out.println("单击的路径" + path);
// 设置当前路径
setSearchPath();
// 获取文件树目录点击的路径值,展示该路径下的文件、文件夹内容
setFilePane(path);
}
}
});
}
}

// 获取当前树节点的路径,进入该文件夹
private String getPath(TreeItem<String> treeItem) {
String name = "";
String path = treeItem.getValue();
if(!treeItem.equals(treeDiskItem)){
while (!treeItem.equals(treeDiskItem) || name == null) {
treeItem = treeItem.getParent();
path = "\\"+name + path;
name = treeItem.getValue();
}
path = "D:" + path;
}
System.out.println(path);
return path;
}

// 递归调用遍历文件夹
private void setFolderTree(TreeItem<String> treeItem, String location) {
List<Folder> folderList = fatService.getFolders(location);
for (int i = 0; i < folderList.size(); i++) {
Folder folder = folderList.get(i);
String folderName = folder.getFolderName();
String location1 = folderList.get(i).getLocation() + "\\"+ folderName;
Node folderPicIcon = new ImageView(new
Image(getClass().getResourceAsStream(FileSystemUtil.folderPath), 18, 18, false,
false));
TreeItem<String> treeFolderItem = new TreeItem<String>(folderName,
folderPicIcon);
treeItem.getChildren().add(treeFolderItem);
// 递归调用遍历
setFolderTree(treeFolderItem, location1);
}
}

// 设置打开文件状态
private void setFileStatue() {
fileTable.getItems().clear();
openFiles = FATService.getOpenFiles();
fileName.setCellValueFactory(new PropertyValueFactory<File,
String>("fileName"));
fileStyle.setCellValueFactory(new PropertyValueFactory<File,
String>("type"));
startNum.setCellValueFactory(new PropertyValueFactory<File,
Integer>("diskNum"));
fileLocation.setCellValueFactory(new PropertyValueFactory<File,
String>("location"));
for (int i = 0; i < openFiles.getFiles().size(); i++) {
FilesModels.add(openFiles.getFiles().get(i).getFile());
}
fileTable.setItems(FilesModels);
fileTable.refresh();
}

// 设置盘块号状态
private void setFATStatue() {
fatTable.getItems().clear();
num.setCellValueFactory(new PropertyValueFactory<FAT,
Integer>("blockNum"));
index.setCellValueFactory(new PropertyValueFactory<FAT, Integer>("index"));
for (int i = 0; i < myFAT.length; i++) {
FATsModels.add(myFAT[i]);
}
fatTable.setItems(FATsModels);
fatTable.refresh();
}

// 初始化
private void init() {
// 文件分配表对象
fatService = new FATService();
fatService.initFAT();
myFAT = FATService.getMyFAT();
}
}

// Content from: .\main\java\com\example\os\UI\JavaApp.java

package com.example.os.UI;

public class JavaApp {


com.example.os.UI.ProcessMain processMain;
FileMain fileMain;
public void login() throws Exception {
System.out.println("login Choice...");
}

/**
* description 登录 Process 控制面板
* param void
* return void
* author pc
* createTime 2021/10/27
**/
public void loginProcess() throws Exception {
System.out.println("login Process...");
if (processMain == null) {
processMain = new com.example.os.UI.ProcessMain();
processMain.loginProcessController();
} else {
ProcessXMLController.MemoryRefresh();
processMain.LoginStage.show();
}
LoginMain.LoginStage.hide();
}
/**
* description 磁盘管理的进入
* param void
* return void
* author pc
* createTime 2021/10/27
**/
public void loginFile() throws Exception {
System.out.println("login File...");
if (fileMain == null) {
fileMain = new FileMain();
fileMain.loginFileController();
} else {
fileMain.LoginStage.show();
}
LoginMain.LoginStage.hide();
}
}

// Content from: .\main\java\com\example\os\UI\LoginMain.java

package com.example.os.UI;

/**
* @description:陆界面,加载主界面,进行用户的选择
* @projectName:DPYos
* @see:com.test
* @author: pc
* @createTime:2021/10/16 14:19
* @version:1.0
*/
import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;

public class LoginMain extends Application {

private Scene scene;


private WebView webView;
private WebEngine webEngine;

public static JavaApp javaApp = new JavaApp();

/** 用于与 Javascript 引擎通信。 */


private JSObject javascriptConnector;

public static Stage LoginStage;

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

LoginStage = primaryStage;
webView = new WebView();
webEngine = webView.getEngine();

webEngine.load(getClass().getResource("/html/index.html").toExternalForm());
webEngine.getLoadWorker().stateProperty().addListener((observable,
oldValue, newValue) -> {
if (Worker.State.SUCCEEDED == newValue ) {

// 在 web 引擎页面中设置一个名为“javaConnector”的接口对象
javascriptConnector = (JSObject)
webEngine.executeScript("window");
javascriptConnector.setMember("JavaApp", javaApp);

System.out.println(javascriptConnector.getMember("JavaApp"));
}
});
scene = new Scene(webView);
scene.setOnKeyPressed(new EventHandler<>() {
@Override
public void handle(KeyEvent keyEvent) {
if (keyEvent.getCode() == KeyCode.ESCAPE) {
primaryStage.close();
}
}
});

primaryStage.setFullScreen(true);
primaryStage.setScene(scene);
primaryStage.show();
}
}

// Content from: .\main\java\com\example\os\UI\ProcessMain.java


package com.example.os.UI;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Color;

import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class ProcessMain extends Application {

public static Stage stage = new Stage();


public static Parent page;
public static Scene scene = null;
public static Stage LoginStage;
@Override
public void start(Stage primaryStage) throws Exception {

LoginStage = primaryStage;
page = FXMLLoader.load(getClass().getResource("/fxml/sample.fxml"));
scene = new Scene(page);

scene.getStylesheets().add(getClass().getResource("/css/sample.css").toExternalForm
());
scene.getStylesheets().add("org/kordamp/bootstrapfx/bootstrapfx.css");
primaryStage.initStyle(StageStyle.TRANSPARENT);//设定窗口无边框
scene.setFill(Color.TRANSPARENT);
primaryStage.setScene(scene);
primaryStage.show();
}

public void loginProcessController() throws Exception {


start(stage);
}
}

// Content from: .\main\java\com\example\os\UI\ProcessXMLController.java

package com.example.os.UI;

import com.example.os.CPU.CPU;
import com.example.os.Listener.DragUtil;
import com.example.os.ProcessManager.Process;
import com.example.os.ProcessManager.ProcessController;
import com.example.os.device.Device;
import com.example.os.device.DeviceController;
import com.example.os.memory.Address;
import com.example.os.memory.MemoryBlock;
import com.example.os.memory.MemoryController;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.*;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.net.URL;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
import java.util.ResourceBundle;

public class ProcessXMLController implements Initializable {

@FXML
private NumberAxis x;

@FXML
private NumberAxis y;

@FXML
private Button startButton;

@FXML
private Button stopStart;

@FXML
private LineChart<?, ?> lineChart;

@FXML
private Label priority;

@FXML
private Label equipment;

@FXML
private Label completion;

@FXML
private ProgressBar timeClip;

@FXML
private Label processPercentage;
@FXML
private AnchorPane ProcessBlock;

@FXML
private ProgressIndicator ProcessIndicator;

@FXML
private Pane Interrupter1;

@FXML
private Label InterrupterLabel1;

@FXML
private Pane Interrupter2;

@FXML
private Label InterrupterLabel2;

@FXML
private Pane Interrupter3;

@FXML
private Label InterrupterLabel3;

@FXML
private Pane Interrupter4;

@FXML
private Label InterrupterLabel4;

@FXML
private Pane Interrupter5;

@FXML
private Label InterrupterLabel5;

@FXML
private Pane Ready1;

@FXML
private Label ReadyLabel1;

@FXML
private Pane Ready2;

@FXML
private Label ReadyLabel2;

@FXML
private Pane Ready3;

@FXML
private Label ReadyLabel3;

@FXML
private Pane Ready4;

@FXML
private Label ReadyLabel4;
@FXML
private Pane Ready5;

@FXML
private Label ReadyLabel5;

@FXML
private Pane Blocked1;

@FXML
private Label BlockedLabel1;

@FXML
private Pane Blocked2;

@FXML
private Label BlockedLabel2;

@FXML
private Pane Blocked3;

@FXML
private Label BlockedLabel3;

@FXML
private Pane Blocked4;

@FXML
private Label BlockedLabel4;

@FXML
private Pane Blocked5;

@FXML
private Label BlockedLabel5;

@FXML
private AnchorPane DA1;

@FXML
private AnchorPane DB2;

@FXML
private AnchorPane DB1;

@FXML
private AnchorPane DA2;

@FXML
private AnchorPane DeviceCUsed;

@FXML
private Label DeviceCProcess;

@FXML
private AnchorPane DeviceBUsed2;

@FXML
private Label DeviceBProcess2;

@FXML
private AnchorPane DeviceBUsed1;

@FXML
private Label DeviceBProcess1;

@FXML
private AnchorPane DeviceAUsed2;

@FXML
private Label DeviceAProcess2;

@FXML
private AnchorPane DeviceAUsed1;

@FXML
private Label DeviceAProcess1;

@FXML
private AnchorPane DC;

@FXML
private AnchorPane top;

@FXML
private ImageView backIcon;

@FXML
private ImageView outIcon;

@FXML
private StackPane mainPane;

@FXML
private BorderPane root;

private TimerChart tc;


private static List<Label> labels = new ArrayList<>();
private static Color DefaultColor = Color.rgb(215, 215,215);
private static List<Pane> InterrupterPane = new ArrayList<>();
private static List<Pane> ReadyPane = new ArrayList<>();
private static List<Pane> BlockedPane = new ArrayList<>();
private static List<Label> InterrupterLabels = new ArrayList<>();
private static List<Label> ReadyLabels = new ArrayList<>();
private static List<Label> BlockedLabels = new ArrayList<>();
private static Thread LabelThread;
// 面板 CPU 和队列面板的进程
private static Thread LabelThread1;
// 设备使用面板记载
private static Thread LabelThread2;
// 正在运行的进程加载面板
private static DeviceController deviceController =
DeviceController.getInstance(); // 设备控制器
private static ProcessController processController =
ProcessController.getInstance(); // 进程控制器
com.example.os.ProcessManager.Process lastProcess = null;
com.example.os.ProcessManager.Process process = null;
Address lastAddress=null;
String pid;

// 设备面板加载
@FXML
void start(ActionEvent event) {
if (!CPU.getInstance().isRunning()) {
System.out.println("开始进程测试 :");
CPU.getInstance().play();
tc.start();
try {
LabelThread.notify();
LabelThread1.notify();
LabelThread2.notify();
} catch (Exception e) {
System.out.println("标签线程已经启动了");
}
}
}

@FXML
void stop(ActionEvent event) {
System.out.println("暂停");
CPU.getInstance().cpuStop();
tc.cancel();
tc.reset();
LabelThread.interrupt();
LabelThread1.interrupt();
LabelThread2.interrupt();
}

/**
* description 内存块压缩碎片,整体刷新,
* 调用 mergeMemory() (dongye)
* 调用 MemoryRefresh() (pc)
* param void
* return void
* author pc
* createTime 2021/10/22
**/
@FXML
void compress(ActionEvent event) {
if (!CPU.getInstance().isRunning()) {
MemoryController.getInstance().mergeMemory();
MemoryRefresh();
} else {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("警告");
alert.setHeaderText("抱歉,CPU 还在运行中\n" +
"如果想要进行压缩操作,请将 CPU 暂停");
alert.showAndWait();
}
}
@FXML
void back(MouseEvent event) {
ProcessMain.stage.hide();
LoginMain.LoginStage.show();
}

/**
* description 程序退出
* param void
* return void
* author pc
* createTime 2021/10/23
**/
@FXML
void out(MouseEvent event) {
Stage stage = (Stage) top.getScene().getWindow();
stage.close();
}

/**
* description 更新时间片完成度
* param
* return
* author pc
* createTime 2021/10/21
**/
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {

XYChart.Series way1 = new XYChart.Series();


XYChart.Series way2 = new XYChart.Series();
XYChart.Series way3 = new XYChart.Series();
way1.setName("Running");
way2.setName("Blocked");
way3.setName("Ready");
lineChart.getData().addAll(way1, way2, way3);
Thread thread = new Thread(ProcessController.getInstance());
thread.setDaemon(true);
thread.start();
while (!QueuePaneInit()) {}
QueueRefresh();
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 16; j ++) {
Label label = new Label();
label.setLayoutX(i * 17 + 2);
label.setLayoutY(j * 17 + 2);
ProcessBlock.getChildren().add(label);
label.setMinSize(15, 15);
label.setPrefSize(15, 15);
label.setMaxSize(15, 15);
label.setId("diskLabel");
labels.add(label);
}
}

LabelThread = new Thread(() -> {

while (true) {
Platform.runLater(new Runnable() {
@Override
public void run() {

timeClip.setProgress(processController.getAllRunTime() / 2.0);

if ( processController.getRunningProcess() !=
null
&&
processController.getRunningProcess() !=

processController.getHangOutProcess()) {

com.example.os.ProcessManager.Process
process = processController.getRunningProcess();
Color color =
findColorFromMemoryBlock(process.getPcb().getId());
ProcessIndicator.setStyle("-fx-progress-
color: rgb(" + (int) (color.getRed() * 255) +"," +(int) (color.getGreen() * 255)
+"," + (int) (color.getBlue() * 255) +");");
double value =
process.getPcb().getRestRunTime()
/
process.getPcb().getTotalRunTime() * 100;

completion.setText((100 - (int)value) +
"%");
ProcessIndicator.setProgress(1.0 -
value / 100);

equipment.setText(process.getDeviceType());

priority.setText(String.valueOf(process.getPcb().getPriority()));

processPercentage.setText(process.getPcb().getId());
}
QueueRefresh();
}
});
try {
Thread.sleep(50L);
} catch (Exception e) {

}
}
});
LabelThread.setDaemon(true);

// 多线程加载面板
LabelThread1 = new Thread(() -> {

while (true) {
Platform.runLater(new Runnable() {
@Override
public void run() {
List<Device> deviceList =
deviceController.deviceList;
if (deviceList.get(0).isOccupy()) {
DA1.setVisible(false);
DeviceAUsed1.setVisible(true);

DeviceAProcess1.setText(deviceList.get(0).getPID());
} else {
DA1.setVisible(true);
DeviceAUsed1.setVisible(false);
}

if (deviceList.get(1).isOccupy()) {
DA2.setVisible(false);
DeviceAUsed2.setVisible(true);

DeviceAProcess2.setText(deviceList.get(1).getPID());
} else {
DA2.setVisible(true);
DeviceAUsed2.setVisible(false);
}

if (deviceList.get(2).isOccupy()) {
DB1.setVisible(false);
DeviceBUsed1.setVisible(true);

DeviceBProcess1.setText(deviceList.get(2).getPID());
} else {
DB1.setVisible(true);
DeviceBUsed1.setVisible(false);
}

if (deviceList.get(3).isOccupy()) {
DB2.setVisible(false);
DeviceBUsed2.setVisible(true);

DeviceBProcess2.setText(deviceList.get(3).getPID());
} else {
DB2.setVisible(true);
DeviceBUsed2.setVisible(false);
}

if (deviceList.get(4).isOccupy()) {
DC.setVisible(false);
DeviceCUsed.setVisible(true);

DeviceCProcess.setText(deviceList.get(4).getPID());
} else {
DC.setVisible(true);
DeviceCUsed.setVisible(false);
}
}
});
try {
Thread.sleep(100L);
} catch (Exception e) {

}
}
});
LabelThread1.setDaemon(true);
LabelThread2 = new Thread(() -> {
while (true) {
process = processController.getRunningProcess();
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
if (process ==
processController.getHangOutProcess()) {
return;
}
else {
pid=process.getPcb().getId();
}
Address address=null;
for(int
i=0;i<MemoryController.getInstance().getMyMemoryBlockList().size();i++)
{

if(MemoryController.getInstance().getMyMemoryBlockList().get(i).getPID()
.equals(pid)){

address=MemoryController.getInstance().getMyMemoryBlockList().get(i).getAddress();
}
}

if (lastAddress == null) {
lastAddress = address;
}

for (int i =
lastAddress.getStartAddress();
i <= lastAddress.getEndAddress();
i++) {
labels.get(i).setBorder(null);
}
for (int i = address.getStartAddress();
i <= address.getEndAddress(); i++)
{
labels.get(i).setBorder(new
Border(new BorderStroke(Paint.valueOf("#FB0D11"),
BorderStrokeStyle.SOLID,
new CornerRadii(2), new BorderWidths(2))));
}
lastProcess = process;
lastAddress=address;
} catch (Exception e) {
System.out.println(" 刷新频率对准中 ");
}
}
});

try {
Thread.sleep(50L);
} catch (Exception e) {
}
}
});
LabelThread2.setDaemon(true);

tc = new TimerChart(this);
// 每隔 0.5 s 更新
tc.setPeriod(Duration.seconds(0.5));
LabelThread.start();
LabelThread1.start();
LabelThread2.start();

x.setLowerBound(0.0D);
x.setUpperBound(10.0D);
y.setLowerBound(0.0D);
y.setUpperBound(5);
tc.valueProperty().addListener(new ChangeListener<ArrayList<Integer>>()
{
/*
* description 实现对于 lineChart 的图像更新
* param void
* return void
* author pc
* createTime 2021/10/20
**/
public double cur = 0;
@Override
public void changed(ObservableValue<? extends ArrayList<Integer>>
observableValue, ArrayList<Integer> integers, ArrayList<Integer> t1) {
if (t1 != null) {
XYChart.Data<Number,Number> d1 = new
XYChart.Data<>(cur,t1.get(0));
XYChart.Data<Number,Number> d2 = new
XYChart.Data<>(cur,t1.get(1));
XYChart.Data<Number,Number> d3 = new
XYChart.Data<>(cur,t1.get(2));
cur += 0.5;
way1.getData().add(d1);
way2.getData().add(d2);
way3.getData().add(d3);
}
}
});
MemoryInit();
addListener();
}

void addListener(){

// 添加窗体拖动
DragUtil.addDragListener(ProcessMain.LoginStage, top);

// 添加退出程序按钮
outIcon.setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
outIcon.setCursor(Cursor.HAND);
}
});

// 添加返回按钮
backIcon.setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
backIcon.setCursor(Cursor.HAND);
}
});
}

/**
* description 初始化队列面板 , 中断队列,就绪队列,阻塞队列
* param void
* return boolean
* author pc
* createTime 2021/10/22
**/
public boolean QueuePaneInit() {
InterrupterPane.add(Interrupter1);
InterrupterPane.add(Interrupter2);
InterrupterPane.add(Interrupter3);
InterrupterPane.add(Interrupter4);
InterrupterPane.add(Interrupter5);

ReadyPane.add(Ready1);
ReadyPane.add(Ready2);
ReadyPane.add(Ready3);
ReadyPane.add(Ready4);
ReadyPane.add(Ready5);

BlockedPane.add(Blocked1);
BlockedPane.add(Blocked2);
BlockedPane.add(Blocked3);
BlockedPane.add(Blocked4);
BlockedPane.add(Blocked5);

BlockedLabels.add(BlockedLabel1);
BlockedLabels.add(BlockedLabel2);
BlockedLabels.add(BlockedLabel3);
BlockedLabels.add(BlockedLabel4);
BlockedLabels.add(BlockedLabel5);

ReadyLabels.add(ReadyLabel1);
ReadyLabels.add(ReadyLabel2);
ReadyLabels.add(ReadyLabel3);
ReadyLabels.add(ReadyLabel4);
ReadyLabels.add(ReadyLabel5);

InterrupterLabels.add(InterrupterLabel1);
InterrupterLabels.add(InterrupterLabel2);
InterrupterLabels.add(InterrupterLabel3);
InterrupterLabels.add(InterrupterLabel4);
InterrupterLabels.add(InterrupterLabel5);
return true;
}

// 内存块初始化刷新
public static void MemoryInit() {
Platform.runLater(new Runnable() {
@Override
public void run() {
for (Label label : labels) {
label.setBackground(new Background(new
BackgroundFill(DefaultColor, null, null)));
}
}
});
}

// 内存块 整体刷新 更新
public static void MemoryRefresh() {
List<MemoryBlock> MemoryBlocks =
MemoryController.getInstance().getMyMemoryBlockList();
Platform.runLater(new Runnable() {
@Override
public void run() {
for(int i=0;i<=511;i++)
{
labels.get(i).setBackground(
new Background(new
BackgroundFill(DefaultColor,null,null)));
labels.get(i).setBorder(null);
}

for (MemoryBlock memoryBlock : MemoryBlocks) {


for (int i =
memoryBlock.getAddress().getStartAddress(); i <=
memoryBlock.getAddress().getEndAddress(); i++) {

labels.get(i).setBackground(new Background(new
BackgroundFill(
memoryBlock.getColor(), null, null
)));

}
}
}
});
}

// 内存块局部刷新
public static void MemoryRelease(MemoryBlock memoryBlock) {
Platform.runLater(new Runnable() {
@Override
public void run() {
for (int i = memoryBlock.getAddress().getStartAddress(); i
<= memoryBlock.getAddress().getEndAddress(); i++) {
labels.get(i).setBackground(new Background(new
BackgroundFill(
DefaultColor, null, null
)));
}
}
});
}

// 内存占用块 刷新
public static void MemoryOccupy(MemoryBlock memoryBlock) {
Platform.runLater(new Runnable() {
@Override
public void run() {
for (int i = memoryBlock.getStartPosition(); i <=
memoryBlock.getEndPosition(); i++) {
labels.get(i).setBackground(new Background(new
BackgroundFill(
memoryBlock.getColor(), null, null
)));
}
}
});
}

/**
* description 进程队列刷新函数
* param void
* return void
* author pc
* createTime 2021/10/22
**/
public static void QueueRefresh() {
List<com.example.os.ProcessManager.Process> InterrupterProcess =
ProcessController.getInstance().getRunningQueue();
List<com.example.os.ProcessManager.Process> ReadyProcess =
ProcessController.getInstance().getReadyQueue();
List<com.example.os.ProcessManager.Process> BlockedProcess =
ProcessController.getInstance().getBlockedQueue();
Platform.runLater(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
if (i < InterrupterProcess.size()) {
com.example.os.ProcessManager.Process process =
InterrupterProcess.get(i);
InterrupterPane.get(i).setBackground(new
Background(new BackgroundFill(

findColorFromMemoryBlock(process.getPcb().getId()), null, null)));

InterrupterLabels.get(i).setText(process.getPcb().getId());
} else {
InterrupterPane.get(i).setBackground(new
Background(new BackgroundFill(
DefaultColor, null, null)));
InterrupterLabels.get(i).setText(" ");
}

if (i < BlockedProcess.size()) {
Process process = BlockedProcess.get(i);
BlockedPane.get(i).setBackground(new
Background(new BackgroundFill(

findColorFromMemoryBlock(process.getPcb().getId()), null, null)));

BlockedLabels.get(i).setText(process.getPcb().getId());
} else {
BlockedPane.get(i).setBackground(new
Background(new BackgroundFill(
DefaultColor, null, null)));
BlockedLabels.get(i).setText(" ");
}

if (i < ReadyProcess.size()) {
com.example.os.ProcessManager.Process process =
ReadyProcess.get(i);
ReadyPane.get(i).setBackground(new
Background(new BackgroundFill(

findColorFromMemoryBlock(process.getPcb().getId()), null, null)));

ReadyLabels.get(i).setText(process.getPcb().getId());
} else {
ReadyPane.get(i).setBackground(new
Background(new BackgroundFill(
DefaultColor, null, null)));
ReadyLabels.get(i).setText(" ");
}
}
}
});
}

static List<MemoryBlock> memoryBlockList =


MemoryController.getInstance().getMyMemoryBlockList();
/**
* description
* param String PID 父进程的 PID
* return Color 返回内存块的颜色
* author pc
* createTime 2021/10/22
**/
public static Color findColorFromMemoryBlock(String PID) {
for (MemoryBlock memoryBlock : memoryBlockList) {
if (memoryBlock.getPID().equals(PID)) {
return memoryBlock.getColor();
}
}
return DefaultColor;
}
}

// Content from: .\main\java\com\example\os\UI\TimerChart.java

package com.example.os.UI;

import com.example.os.ProcessManager.ProcessController;

import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import java.util.ArrayList;

public class TimerChart extends ScheduledService<ArrayList<Integer>> {


ProcessXMLController main;
public TimerChart(ProcessXMLController main){
this.main = main;
}
public Task<ArrayList<Integer>> createTask(){
Task<ArrayList<Integer>> task = new Task<ArrayList<Integer>>() {
@Override
protected ArrayList<Integer> call() throws Exception {
ArrayList<Integer> list = new ArrayList();

list.add(ProcessController.getInstance().getRunningQueue().size());

list.add(ProcessController.getInstance().getBlockedQueue().size());

list.add(ProcessController.getInstance().getReadyQueue().size());
return list;
}
};
return task;
}
}

// Content from: .\main\java\com\example\os\util\FileSystemUtil.java

package com.example.os.util;

public class FileSystemUtil {


// D:\大三上学期\操作系统实验\源码\test03\DPYos\src\main\resources\img\folder.png D:\大三上学期\操作
系统实验\源码\test03\DPYos\src\main\resources\img\filePic.png
public static int num = 5;
public static String folderPath = "/img/folder.png";
public static String folderTreePath = "/img/folderPic.png";
public static String filePath = "/img/filePic.png";
public static String diskPath = "/img/diskPic.png";
public static String delPath = "/img/del.png";
public static String warnPath ="/img/warn.png";
// 表示该磁盘块已结束
public static int END = 255;
// 表示该磁盘块空闲
public static int SPARE = 0;
// 表示该磁盘块损坏
public static int BAD = 254;
// 表示该磁盘块存放 c 盘
public static int DISK = 0;
// 表示该磁盘块存放文件夹
public static int FOLDER = 1;
// 表示该磁盘块存放文件
public static int FILE = 2;
// 错误返回值
public static int ERROR = -1;
public static int flagRead = 0;
public static int flagWrite = 1;

public FileSystemUtil() {
}

// 根据文本内容的长度获取所占磁盘的块数 64-> 一磁盘


public static int getNumOfFAT(int length) {
if (length <= 64) {
return 1;
} else {
int n = 0;
if (length % 64 == 0) {
n = length / 64;
} else {
n = length / 64;
n++;
}
return n;
}
}

// Content from: .\main\java\com\example\os\util\GUI.java

package com.example.os.util;

import com.example.os.Listener.DragUtil;
import javafx.scene.Scene;
import javafx.scene.control.DialogPane;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class GUI {


// 弹窗警告
public static void contentOutGUI(String context){
// 显示文件内容
AnchorPane anchorPane = new AnchorPane();
anchorPane.setPrefSize(300,40);
anchorPane.setStyle("-fx-background-color: #eeeeee;");
ImageView imageView = new ImageView();
ImageView imageView1 = new ImageView();
imageView.setImage(new Image(FileSystemUtil.warnPath, 25, 25, false,
false));
imageView1.setImage(new Image(FileSystemUtil.delPath, 10, 10, false,
false));
Label label1=new Label("",imageView1);
Label label = new Label();
label.setText(context);
label.setPrefSize(250,30);
label.setLayoutX(44);
label.setLayoutY(8);
label.setStyle("-fx-font-weight: bold;"+"-fx-text-fill: red;");
label1.setLayoutX(235);
label1.setLayoutY(3);
anchorPane.getChildren().add(label);
anchorPane.getChildren().add(imageView);
anchorPane.getChildren().add(label1);
Stage dialogStage = new Stage();
Scene dialogScene = new Scene(anchorPane,250,40);
imageView.setLayoutX(10);
imageView.setLayoutY(10);
dialogStage.setScene(dialogScene);
dialogStage.initStyle(StageStyle.UNDECORATED);
// 窗体拖动
DragUtil.addDragListener(dialogStage,anchorPane);
dialogStage.show();
label1.setOnMouseClicked(mouseEvent -> {
if(mouseEvent.getClickCount()==1)
dialogStage.close();
});
}

You might also like