javaFx(7)文本閱讀器

一個簡單的閱讀器

效果示例

這裏寫圖片描述

示例代碼

這裏寫圖片描述

FileItem類,用來處理文件,獲取文件的前綴名和後綴名,同時獲取文件的類型

package application;

import java.io.File;

public class FileItem {
    public String fileName;   // 文件名
    public String firstName;  // 前綴名
    public File file;
    public int type = BAD_FORMAT; // 1, 文本文件; 2,圖片文件; -1, 不支持的文件類型

    // 文件類型常量
    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" };

    // 構造函數,傳入一個file並取得file的名字和類型
    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) {
            // FX框架要求必須先調用 super.updateItem()
            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進行擺放,使其適應父窗口
        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) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    // 打開左側文件
    public void openFile(FileItem fitem) throws Exception{

        // 查看選項卡是否打開
        Tab tab = findTab(fitem);

        if(tab != null) {

            // 設置爲選中的選項卡
            // int pos = tabPane.getTabs().indexOf(tab);  // 獲取id
            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文件

/* JavaFX CSS - Leave this comment until you have at least create one rule which uses -fx-Property */

.list-view .cell 
{
    -fx-font: 14px "Serif";
    -fx-padding: 10;
}

.text-area
{
    -fx-font: 16px "微軟雅黑";
    -fx-padding: 10;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章