Closed GoogleCodeExporter closed 9 years ago
It would be handy to have a standard file chooser dialog. Below is an implementation from one of my projects. -------------------------------------------------------------------------------- ---------- package assessin.ui.lanterna; import com.googlecode.lanterna.TerminalFacade; import com.googlecode.lanterna.gui.*; import com.googlecode.lanterna.gui.GUIScreen.Position; import com.googlecode.lanterna.gui.Theme.Category; import com.googlecode.lanterna.gui.Theme.Definition; import com.googlecode.lanterna.gui.component.*; import com.googlecode.lanterna.gui.component.Panel.Orientation; import com.googlecode.lanterna.gui.dialog.DialogButtons; import com.googlecode.lanterna.gui.dialog.DialogResult; import com.googlecode.lanterna.gui.dialog.MessageBox; import com.googlecode.lanterna.gui.layout.BorderLayout; import com.googlecode.lanterna.gui.layout.HorisontalLayout; import com.googlecode.lanterna.gui.layout.LinearLayout; import com.googlecode.lanterna.input.Key; import com.googlecode.lanterna.terminal.TerminalSize; import java.io.File; // TODO: Localization /** * Created by dboitnot on 12/6/13. */ public class FileChooser extends Window { private static final int PATH_LABEL_WIDTH = 60; private static final TerminalSize LIST_SIZE = new TerminalSize(30, 10); // mode-specific behavior private static enum Mode { OPEN("Open", false) { @Override public boolean checkFile(File f, GUIScreen owner) { if (!f.exists()) { showFileNotFoundMessage(owner); return false; } if (!f.isFile()) { MessageBox.showMessageBox(owner, "Invalid Selection", "The file path you entered is not a regular file."); return false; } return true; } @Override public Interactable defaultFocusedComponent(FileChooser chooser) { return chooser.fileList; } }, SAVE("Save", true) { @Override public boolean checkFile(File f, GUIScreen owner) { if (f.isDirectory()) { MessageBox.showMessageBox(owner, "Invalid Selection", "The file path you entered is a directory."); return false; } File parent = f.getParentFile(); if (parent == null || !parent.exists() || !parent.isDirectory()) { MessageBox.showMessageBox(owner, "Invalid Selection", "You cannot save files to this location."); return false; } if (f.exists() && MessageBox.showMessageBox(owner, "Overwrite File?", "Are you sure you want to overwrite this file:\n\n" + f.getName(), DialogButtons.YES_NO) != DialogResult.YES) { return false; } return true; } @Override public Interactable defaultFocusedComponent(FileChooser chooser) { return chooser.selectionTextBox; } }; private final String confirmButtonText; private final boolean allowNotExists; Mode(String confirmButtonText, boolean allowNotExists) { this.confirmButtonText = confirmButtonText; this.allowNotExists = allowNotExists; } // Mode-specific file check, return true if file is acceptable. public abstract boolean checkFile(File f, GUIScreen owner); public abstract Interactable defaultFocusedComponent(FileChooser chooser); } private final Label pathLabel; private final ActionListBox dirList; private final ActionListBox fileList; private final TextBox selectionTextBox; private final Button confirmButton; private final Mode mode; private File dir; private boolean showHidden = false; private File confirmedSelection = null; private FileChooser(String title, Mode mode) { super(title); this.mode = mode; // Put some vertical space between components Panel rootPanel = new Panel(Orientation.VERTICAL); ((LinearLayout) rootPanel.getLayoutManager()).setPadding(1); addComponent(rootPanel); // Directory list on the left, file list on the right Panel listPanel = new Panel(Panel.Orientation.HORISONTAL); dirList = styledListBox(listPanel); fileList = styledListBox(listPanel); rootPanel.addComponent(listPanel); // Path label shows current directory pathLabel = new Label("", PATH_LABEL_WIDTH); rootPanel.addComponent(pathLabel); // The selection text box needs to handle the Enter key differently. selectionTextBox = new TextBox("") { @Override public Result keyboardInteraction(Key key) { if (key.getKind() == Key.Kind.Enter) { browseTo(getSelection()); return Result.EVENT_HANDLED; } return super.keyboardInteraction(key); } }; rootPanel.addComponent(selectionTextBox, HorisontalLayout.GROWS_HORIZONTALLY); // Buttons Panel bottomPanel = new Panel(Orientation.HORISONTAL); bottomPanel.setLayoutManager(new BorderLayout()); rootPanel.addComponent(bottomPanel, HorisontalLayout.GROWS_HORIZONTALLY); Panel buttonPanel = new Panel(Orientation.HORISONTAL); confirmButton = new Button(mode.confirmButtonText, new Action() { @Override public void doAction() { confirm(); } }); buttonPanel.addComponent(confirmButton); buttonPanel.addComponent(new Button("Cancel", new Action() { @Override public void doAction() { close(); } })); bottomPanel.addComponent(buttonPanel, BorderLayout.RIGHT); } private ActionListBox styledListBox(Panel panel) { ActionListBox ret = new ActionListBox(LIST_SIZE) { @Override protected Definition getListItemThemeDefinition(Theme theme) { return theme.getDefinition(Category.TEXTBOX_FOCUSED); } @Override protected Definition getSelectedListItemThemeDefinition(Theme theme) { return theme.getDefinition(Category.BUTTON_INACTIVE); } }; panel.addComponent(ret); return ret; } private void setDir(File d) { dir = d; String txt = d.getAbsolutePath() + File.separator; if (txt.length() > PATH_LABEL_WIDTH) txt = "..." + txt.substring(txt.length() - PATH_LABEL_WIDTH + 3); pathLabel.setText(txt); refreshLists(); } private void setSelection(File f) { if (f == null) { selectionTextBox.setText(""); return; } File parent = f.getParentFile(); String txt; if (parent == null) { // This shouldn't happen. txt = f.getAbsolutePath(); } else { setDir(parent); txt = f.getName(); } selectionTextBox.setText(txt); setFocus(confirmButton); } private File getSelection() { String txt = selectionTextBox.getText(); if (txt.length() < 1) return null; File f = new File(txt); if (!f.isAbsolute()) f = new File(dir.getAbsolutePath() + File.separator + f.getPath()); // Try expanding tilde if (!f.exists() && txt.startsWith("~")) { f = new File(System.getProperty("user.home") + File.separator + txt.substring(1)); } return f; } private void browseTo(File f) { if (f == null) return; if (f.isDirectory()) { setDir(f); setSelection(null); } else if (!f.exists()) { File parent = f.getParentFile(); if (parent != null && parent.isDirectory() && mode.allowNotExists) { setSelection(f); } else { showFileNotFoundMessage(getOwner()); } } else { setSelection(f); } } private void refreshLists() { dirList.clearItems(); fileList.clearItems(); File parent = dir.getParentFile(); if (parent != null) dirList.addAction("..", browseAction(parent)); File[] files = dir.listFiles(); if (files == null) return; for (File f: files) { if (f.isHidden() && !showHidden) continue; if (f.isDirectory()) { dirList.addAction(f.getName(), browseAction(f)); } else { fileList.addAction(f.getName(), browseAction(f)); } } } private void confirm() { File f = getSelection(); if (f == null) return; if (!mode.checkFile(f, getOwner())) return; confirmedSelection = f; close(); } private Action browseAction(final File f) { return new Action() { @Override public void doAction() { browseTo(f); } }; } private static void showFileNotFoundMessage(GUIScreen owner) { MessageBox.showMessageBox(owner, "File Not Found", "The file path you entered could not be found."); } private static File chooseFile(GUIScreen owner, String title, Mode mode, File initialSelection) { FileChooser chooser = new FileChooser(title, mode); Interactable focus = mode.defaultFocusedComponent(chooser); if (initialSelection == null) { chooser.setDir(new File("").getAbsoluteFile()); } else if (initialSelection.isDirectory()) { chooser.setDir(initialSelection); } else { chooser.setSelection(initialSelection.getAbsoluteFile()); focus = chooser.confirmButton; } chooser.setFocus(focus); owner.showWindow(chooser, Position.CENTER); return chooser.confirmedSelection; } public static File chooseFileForOpen(GUIScreen screen, String title, File defaultFile) { return chooseFile(screen, title, Mode.OPEN, defaultFile); } public static File chooseFileForOpen(GUIScreen screen, File defaultFile) { return chooseFileForOpen(screen, "Open File", defaultFile); } public static File chooseFileForOpen(GUIScreen screen, String title) { return chooseFileForOpen(screen, title, null); } public static File chooseFileForOpen(GUIScreen screen) { return chooseFileForOpen(screen, (File)null); } public static File chooseFileForSave(GUIScreen screen, String title, File defaultFile) { return chooseFile(screen, title, Mode.SAVE, defaultFile); } public static File chooseFileForSave(GUIScreen screen, File defaultFile) { return chooseFileForSave(screen, "Save As", defaultFile); } public static File chooseFileForSave(GUIScreen screen, String title) { return chooseFileForSave(screen, title, null); } public static File chooseFileForSave(GUIScreen screen) { return chooseFileForSave(screen, (File) null); } public static void main(String[] args) { GUIScreen gui = TerminalFacade.createGUIScreen(); gui.getScreen().startScreen(); System.out.println("Chose: " + chooseFileForSave(gui)); gui.getScreen().stopScreen(); } } -------------------------------------------------------------------------------- ----------
Original issue reported on code.google.com by dboit...@gmail.com on 17 Dec 2013 at 1:07
dboit...@gmail.com
Adding a simple file dialog to 2.1.x-branch, just need to adjust the colors a little bit.
Original comment by mab...@gmail.com on 8 Feb 2014 at 1:35
mab...@gmail.com
Original issue reported on code.google.com by
dboit...@gmail.com
on 17 Dec 2013 at 1:07