/* * Beanfabrics Framework Copyright (C) by Michael Karneim, beanfabrics.org * Use is subject to license terms. See license.txt. */ package org.beanfabrics.swt.samples.filebrowser; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.text.DateFormat; import java.util.Date; import org.beanfabrics.BnModelObserver; import org.beanfabrics.ModelProvider; import org.beanfabrics.Path; import org.beanfabrics.View; import org.beanfabrics.model.AbstractPM; import org.beanfabrics.model.DatePM; import org.beanfabrics.model.IntegerPM; import org.beanfabrics.model.MapPM; import org.beanfabrics.model.PMManager; import org.beanfabrics.model.TextPM; import org.beanfabrics.support.Service; import org.beanfabrics.swt.model.ImageTextPM; import org.beanfabrics.swt.table.BnTableDecorator; import org.beanfabrics.swt.table.ViewConfigBuilder; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; /** * This sample contains a file browser implemented with SWT and Beanfabrics. * * @author Michael Karneim */ public class FileBrowser { public static void main(String args[]) { try { Display display = Display.getDefault(); Shell shell = new Shell(display); shell.setLayout(new FillLayout()); FileBrowser browser = new FileBrowser(shell); browser.setDirectory(new File(System.getProperty("user.home"))); shell.open(); shell.layout(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } browser.dispose(); } catch (Exception e) { e.printStackTrace(); } System.exit(0); // Necessary because the FileInfoRegistry uses some Swing code } private FileBrowserModel model; private FileBrowserView view; /** * The FileBrowser is a kind of facade that shields FileBrowserModel and * FileBrowserView for convenience. */ public FileBrowser(Shell shell) { this.model = new FileBrowserModel(); this.view = new FileBrowserView(shell, SWT.NONE); this.view.setPresentationModel(this.model); } public void setDirectory(File file) { model.setDirectory(file); } public void dispose() { model.dispose(); } /** * This is the model for a file entry used as row model in the table of * files. */ private static class FileEntry extends AbstractPM { File file; FileInfoRegistry fileInfoRegistry; boolean useFileInfoName = true; ImageTextPM name = new ImageTextPM(); DatePM lastModified = new DatePM(); IntegerPM size = new IntegerPM(); public FileEntry(File file) { PMManager.setup(this); this.file = file; name.setText(file.getName()); DateFormat format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM); lastModified.setFormat(format); lastModified.setDate(new Date(file.lastModified())); if (file.isDirectory()) { size.setText(null); } else { size.setLong(file.length()); } updateIcon(); } public FileEntry(File file, String displayName) { this(file); name.setText(displayName); useFileInfoName = false; } @Service public void setFileInfoRegistry(FileInfoRegistry reg) { this.fileInfoRegistry = reg; updateIcon(); } private void updateIcon() { // if the FileInfoRegistry is available we can load the file icon and name if (this.fileInfoRegistry != null && this.file != null) { name.setImage(fileInfoRegistry.getImage(file)); if (useFileInfoName) { name.setText(this.fileInfoRegistry.getName(file)); } } else { name.setImage(null); } } } /** * The model for the file browser. */ private static class FileBrowserModel extends AbstractPM { FileInfoRegistry fileInfoRegistry; File directory; TextPM directoryPath = new TextPM(); MapPM<File, FileEntry> files = new MapPM<File, FileEntry>(); public FileBrowserModel() { PMManager.setup(this); this.fileInfoRegistry = new FileInfoRegistry(); // adding the FileInfoRegistry to the context makes it accessible for all child nodes this.getContext().addService(FileInfoRegistry.class, this.fileInfoRegistry); } public void setDirectory(File dir) { this.directory = dir; refresh(); } private void refresh() { directoryPath.setText(directory.getAbsolutePath()); // clear rows files.clear(); fileInfoRegistry.clear(); // disposes unused images // add a new row for parent directory File parent = directory.getParentFile(); if (parent != null) { files.put(parent, new FileEntry(parent, "..")); } // add new rows for all files in this directory for (File file : directory.listFiles()) { files.put(file, new FileEntry(file)); } } public void dispose() { fileInfoRegistry.clear(); } public void enterSelectedDirectory() { File oldDir = this.directory; File nextDir = files.getSelectedKeys().getFirst(); if (nextDir.isDirectory()) { setDirectory(nextDir); // select old directory in list if (files.containsKey(oldDir)) { files.getSelectedKeys().add(oldDir); } } } } /** * The view on the file browser implemented as an SWT Composite. */ private static class FileBrowserView extends Composite implements View<FileBrowserModel> { private Table table; private BnTableDecorator bnTable; private ModelProvider localModelProvider; private BnModelObserver titleObserver; public FileBrowserView(Composite parent, int style) { super(parent, style); // setLayout(new FillLayout()); // this is the table that shows the files table = new Table(this, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER); table.addKeyListener(new KeyAdapter() { @Override public void keyPressed(final KeyEvent e) { if (e.keyCode == 13) { // Enter-Key pressed getPresentationModel().enterSelectedDirectory(); } } }); table.addMouseListener(new MouseAdapter() { @Override public void mouseDoubleClick(MouseEvent mouseevent) { getPresentationModel().enterSelectedDirectory(); } }); //table.setLinesVisible(true); table.setHeaderVisible(true); // this BnTable decorates the table above and does the Beanfabrics model binding bnTable = new BnTableDecorator(table); // define the provider of the model bnTable.setModelProvider(getLocalModelProvider()); // define the path to the model bnTable.setPath(new Path("files")); // define the columns bnTable.setViewConfig(new ViewConfigBuilder().addColumn().setPath("name").setHeader("File").setWidth(180).addColumn().setPath("lastModified").setHeader("Last Modified").setWidth(160).addColumn().setPath("size").setHeader("Size") .setWidth(80).buildViewConfig()); // this observer is responsible for sync'ing the window title titleObserver = new BnModelObserver(); titleObserver.setModelProvider(getLocalModelProvider()); titleObserver.setPath(new Path("directoryPath")); titleObserver.addPropertyChangeListener(new PropertyChangeListener() { // whenever 'directoryPath' has changed this method is called public void propertyChange(PropertyChangeEvent evt) { TextPM directoryPath = (TextPM)titleObserver.getPresentationModel(); if (directoryPath != null) { getShell().setText(directoryPath.getText()); } } }); } @Override protected void checkSubclass() { // Disable the check that prevents subclassing of SWT components } public FileBrowserModel getPresentationModel() { return getLocalModelProvider().getPresentationModel(); } public void setPresentationModel(FileBrowserModel pModel) { getLocalModelProvider().setPresentationModel(pModel); } private ModelProvider getLocalModelProvider() { if (localModelProvider == null) { localModelProvider = new ModelProvider(); // @wb:location=42,439 localModelProvider.setPresentationModelType(FileBrowserModel.class); } return localModelProvider; } } }