一個簡單的閱讀器
效果示例
示例代碼
FileItem類,用來處理文件,獲取文件的前綴名和後綴名,同時獲取文件的類型
package application;
import java.io.File;
public class FileItem {
public String fileName;
public String firstName;
public File file;
public int type = BAD_FORMAT;
public static final int TEXT = 1;
public static final int IMAGE = 2;
public static final int BAD_FORMAT = -1;
private final String[] txtTypes = { "txt", "java" };
private final String[] imageTypes = { "jpg", "jpeg", "png", "bmp" };
public FileItem(File file) {
this.file = file;
fileName = file.getName();
firstName = getFileFirstName(fileName);
String suffix = getFileSuffix(fileName);
type = BAD_FORMAT;
if (contains(txtTypes, suffix))
type = TEXT;
else if (contains(imageTypes, suffix))
type = IMAGE;
}
public boolean contains(String[] types, String suffix) {
suffix = suffix.toLowerCase();
for (String s : types) {
if (s.equals(suffix))
return true;
}
return false;
}
public String getFileSuffix(String name) {
int pos = name.lastIndexOf('.');
if (pos > 0)
return name.substring(pos + 1);
return "";
}
public String getFileFirstName(String name) {
int pos = name.lastIndexOf('.');
if(pos > 0) {
return name.substring(0, pos);
}
return "";
}
}
FileListView類,該類繼承與ListView類,使用的數據源是上面定義的FileItem類的ObservableList列表
package application;
import application.FileListView.MyListCell;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.util.Callback;
public class FileListView extends ListView<FileItem> {
private ObservableList<FileItem> listData = FXCollections.observableArrayList();
public FileListView() {
setItems(listData);
setCellFactory(new Callback<ListView<FileItem>, ListCell<FileItem>>()
{
@Override
public ListCell<FileItem> call(ListView<FileItem> param)
{
return new MyListCell();
}
});
}
public ObservableList<FileItem> data() {
return listData;
}
static class MyListCell extends ListCell<FileItem> {
@Override
protected void updateItem(FileItem item, boolean empty) {
super.updateItem(item, empty);
if (item == null) {
this.setText("");
} else {
this.setText(item.firstName);
}
}
}
}
MyImagePane類繼承於Pane,作用把Image封裝成一個Pane,這個Pane完全顯示圖片,Image不屬於Node,所以要包裝成ImageView再添加到面板裏
package application;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
public class MyImagePane extends Pane {
ImageView imageView = new ImageView();
Image image;
public MyImagePane() {
getChildren().add(imageView);
}
public void showImage(Image image) {
this.image = image;
imageView.setImage(image);
layout();
}
@Override
protected void layoutChildren() {
double w = getWidth();
double h = getHeight();
imageView.resizeRelocate(0, 0, w, h);
imageView.setFitWidth(w);
imageView.setFitHeight(h);
imageView.setPreserveRatio(true);
}
}
TextFileUtils類用於讀寫File文件
package application;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class TextFileUtils {
public static String read(File f, String charset) throws Exception{
FileInputStream fstream = new FileInputStream(f);
try {
int fileSize = (int)f.length();
if(fileSize > 1024*512)
throw new Exception("File too large to read! size=" + fileSize);
byte[] buffer = new byte[fileSize];
fstream.read(buffer);
return new String(buffer, charset);
}finally {
try{
fstream.close();
}catch(Exception e) {}
}
}
public static void write(File f, String text, String charset) throws Exception
{
FileOutputStream fstream = new FileOutputStream(f);
try{
fstream.write( text.getBytes( charset ));
}finally
{
fstream.close();
}
}
}
主類
package application;
import java.io.File;
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.stage.Stage;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.image.Image;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
FileListView fileList = new FileListView();
TabPane tabPane = new TabPane();
@Override
public void start(Stage primaryStage) {
try {
initFileList();
BorderPane root = new BorderPane();
root.setLeft(fileList);
root.setCenter(tabPane);
Scene scene = new Scene(root,800,500);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public void initFileList(){
fileList.setPrefWidth(200);
File dir = new File("小仙女");
File[] files = dir.listFiles();
for(File f : files) {
FileItem fitem = new FileItem(f);
fileList.data().add(fitem);
}
fileList.setOnMouseClicked((MouseEvent event)->{
if(event.getClickCount() == 1 && event.getButton() == MouseButton.PRIMARY) {
oneClicked();
}
});
}
public void oneClicked() {
int index = fileList.getSelectionModel().getSelectedIndex();
FileItem fitem = fileList.data().get(index);
try {
openFile(fitem);
} catch (Exception e) {
e.printStackTrace();
}
}
public void openFile(FileItem fitem) throws Exception{
Tab tab = findTab(fitem);
if(tab != null) {
tabPane.getSelectionModel().select(tab);
return;
}
Node currentView = null;
if(fitem.type == FileItem.TEXT) {
String str = TextFileUtils.read(fitem.file, "GBK");
TextArea t = new TextArea();
t.setText(str);
currentView = t;
}else if(fitem.type == FileItem.IMAGE) {
Image image = new Image(fitem.file.toURI().toString());
MyImagePane t = new MyImagePane();
t.showImage(image);
currentView = t;
}else throw new Exception("不支持打開該格式");
tab = new Tab();
tab.setText(fitem.firstName);
tab.setContent(currentView);
tabPane.getTabs().add(tab);
tabPane.getSelectionModel().select(tab);
}
public Tab findTab(FileItem fitem) {
ObservableList<Tab> tabs = tabPane.getTabs();
for(Tab tab : tabs) {
if(tab.getText().equals(fitem.firstName)) {
return tab;
}
}
return null;
}
public static void main(String[] args) {
launch(args);
}
}
CSS文件
.list-view .cell
{
-fx-font: 14px "Serif";
-fx-padding: 10;
}
.text-area
{
-fx-font: 16px "微軟雅黑";
-fx-padding: 10;
}