一个简单的阅读器
效果示例
示例代码
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 : 14 px "Serif" ;
-fx-padding : 10 ;
}
.text-area
{
-fx-font : 16 px "微软雅黑" ;
-fx-padding : 10 ;
}