0.0.3: FINISH PORTING
-- TDirectoryList
- - Also add keyboard navigation
-- TFileOpen
- - Also add keyboard navigation
-
0.0.4: NEW STUFF
- Making TMenu keyboard accelerators active/inactive
public final void enableSecondaryEventReceiver(final TWidget widget) {
assert (secondaryEventReceiver == null);
assert (secondaryEventHandler == null);
- assert (widget instanceof TMessageBox);
+ assert ((widget instanceof TMessageBox)
+ || (widget instanceof TFileOpenBox));
secondaryEventReceiver = widget;
secondaryEventHandler = new WidgetEventHandler(this, false);
(new Thread(secondaryEventHandler)).start();
/**
* TDirectoryList shows the files within a directory.
*/
-public class TDirectoryList extends TWidget {
+public final class TDirectoryList extends TWidget {
/**
* Files in the directory.
/**
* Root path containing files to display.
*/
- public File path;
+ private File path;
+
+ /**
+ * Set the new path to display.
+ *
+ * @param path new path to list files for
+ */
+ public void setPath(String path) {
+ this.path = new File(path);
+ reflow();
+ }
+
+ /**
+ * Get the path that is being displayed.
+ *
+ * @return the path
+ */
+ public File getPath() {
+ return path;
+ }
/**
* Vertical scrollbar.
// Build a list of files in this directory
File [] newFiles = path.listFiles();
- for (int i = 0; i < newFiles.length; i++) {
- if (newFiles[i].getName().startsWith(".")) {
- continue;
+ if (newFiles != null) {
+ for (int i = 0; i < newFiles.length; i++) {
+ if (newFiles[i].getName().startsWith(".")) {
+ continue;
+ }
+ if (newFiles[i].isDirectory()) {
+ continue;
+ }
+ files.add(newFiles[i]);
}
- if (newFiles[i].isDirectory()) {
- continue;
- }
- files.add(newFiles[i]);
}
for (int i = 0; i < files.size(); i++) {
public TDirectoryList(final TWidget parent, final String path, final int x,
final int y, final int width, final int height, final TAction action) {
+ super(parent, x, y, width, height);
this.path = new File(path);
this.action = action;
files = new ArrayList<File>();
CellAttributes color = null;
int begin = vScroller.getValue();
int topY = 0;
- for (int i = begin; i < files.size() - 1; i++) {
+ for (int i = begin; i < files.size(); i++) {
String line = renderFile(i);
if (hScroller.getValue() < line.length()) {
line = line.substring(hScroller.getValue());
}
}
+ if (isAbsoluteActive()) {
+ color = getTheme().getColor("tdirectorylist");
+ } else {
+ color = getTheme().getColor("tdirectorylist.inactive");
+ }
+
// Pad the rest with blank lines
for (int i = topY; i < getHeight() - 1; i++) {
getScreen().hLineXY(0, i, getWidth() - 1, ' ', color);
} else if (keypress.equals(kbRight)) {
hScroller.increment();
} else if (keypress.equals(kbUp)) {
- vScroller.decrement();
+ if (files.size() > 0) {
+ if (selectedFile >= 0) {
+ if (selectedFile > 0) {
+ selectedFile--;
+ }
+ } else {
+ selectedFile = files.size() - 1;
+ }
+ path = files.get(selectedFile);
+ }
} else if (keypress.equals(kbDown)) {
- vScroller.increment();
+ if (files.size() > 0) {
+ if (selectedFile >= 0) {
+ if (selectedFile < files.size() - 1) {
+ selectedFile++;
+ }
+ } else {
+ selectedFile = 0;
+ }
+ path = files.get(selectedFile);
+ }
} else if (keypress.equals(kbPgUp)) {
vScroller.bigDecrement();
} else if (keypress.equals(kbPgDn)) {
vScroller.bigIncrement();
} else if (keypress.equals(kbHome)) {
vScroller.toTop();
+ if (files.size() > 0) {
+ selectedFile = 0;
+ path = files.get(selectedFile);
+ }
} else if (keypress.equals(kbEnd)) {
vScroller.toBottom();
+ if (files.size() > 0) {
+ selectedFile = files.size() - 1;
+ path = files.get(selectedFile);
+ }
+ } else if (keypress.equals(kbTab)) {
+ getParent().switchWidget(true);
+ } else if (keypress.equals(kbShiftTab) || keypress.equals(kbBackTab)) {
+ getParent().switchWidget(false);
+ } else if (keypress.equals(kbEnter)) {
+ if (selectedFile >= 0) {
+ path = files.get(selectedFile);
+ dispatch();
+ }
} else {
// Pass other keys (tab etc.) on
super.onKeypress(keypress);
public class TDirectoryTreeItem extends TTreeItem {
/**
- * Directory entry corresponding to this list item.
+ * File corresponding to this list item.
*/
- File dir;
+ private File file;
+
+ /**
+ * Get the File corresponding to this list item.
+ *
+ * @return the File
+ */
+ public final File getFile() {
+ return file;
+ }
/**
* Called when this item is expanded or collapsed. this.expanded will be
*/
@Override
public void onExpand() {
- // System.err.printf("onExpand() %s\n", dir);
+ // System.err.printf("onExpand() %s\n", file);
- if (dir == null) {
+ if (file == null) {
return;
}
getChildren().clear();
// Make sure we can read it before trying to.
- if (dir.canRead()) {
+ if (file.canRead()) {
setSelectable(true);
} else {
setSelectable(false);
}
- assert (dir.isDirectory());
+ assert (file.isDirectory());
setExpandable(true);
if ((isExpanded() == false) || (isExpandable() == false)) {
return;
}
- for (File file: dir.listFiles()) {
+ for (File f: file.listFiles()) {
// System.err.printf(" -> file %s %s\n", file, file.getName());
- if (file.getName().startsWith(".")) {
+ if (f.getName().startsWith(".")) {
// Hide dot-files
continue;
}
- if (!file.isDirectory()) {
+ if (!f.isDirectory()) {
continue;
}
try {
TDirectoryTreeItem item = new TDirectoryTreeItem(getTreeView(),
- file.getCanonicalPath(), false, false);
+ f.getCanonicalPath(), false, false);
item.level = this.level + 1;
getChildren().add(item);
super(view, text, false);
- List<String> parentPaths = new LinkedList<String>();
+ List<String> parentFiles = new LinkedList<String>();
boolean oldExpanded = expanded;
// Convert to canonical path
- File rootPath = new File(text);
- rootPath = rootPath.getCanonicalFile();
+ File rootFile = new File(text);
+ rootFile = rootFile.getCanonicalFile();
if (openParents == true) {
setExpanded(true);
// Go up the directory tree
- File parent = rootPath.getParentFile();
+ File parent = rootFile.getParentFile();
while (parent != null) {
- parentPaths.add(rootPath.getName());
- rootPath = rootPath.getParentFile();
- parent = rootPath.getParentFile();
+ parentFiles.add(rootFile.getName());
+ rootFile = rootFile.getParentFile();
+ parent = rootFile.getParentFile();
}
}
- dir = rootPath;
- if (rootPath.getParentFile() == null) {
+ file = rootFile;
+ if (rootFile.getParentFile() == null) {
// This is a filesystem root, use its full name
- setText(rootPath.getCanonicalPath());
+ setText(rootFile.getCanonicalPath());
} else {
// This is a relative path. We got here because openParents was
// false.
assert (openParents == false);
- setText(rootPath.getName());
+ setText(rootFile.getName());
}
onExpand();
if (openParents == true) {
- TDirectoryTreeItem childPath = this;
- Collections.reverse(parentPaths);
- for (String p: parentPaths) {
- for (TWidget widget: childPath.getChildren()) {
+ TDirectoryTreeItem childFile = this;
+ Collections.reverse(parentFiles);
+ for (String p: parentFiles) {
+ for (TWidget widget: childFile.getChildren()) {
TDirectoryTreeItem child = (TDirectoryTreeItem) widget;
if (child.getText().equals(p)) {
- childPath = child;
- childPath.setExpanded(true);
- childPath.onExpand();
+ childFile = child;
+ childFile.setExpanded(true);
+ childFile.onExpand();
break;
}
}
}
unselect();
- getTreeView().setSelected(childPath);
+ getTreeView().setSelected(childFile);
setExpanded(oldExpanded);
}
getTreeView().reflow();
return text;
}
+ /**
+ * Set field text.
+ *
+ * @param text the new field text
+ */
+ public final void setText(String text) {
+ this.text = text;
+ position = 0;
+ windowStart = 0;
+ }
+
/**
* If true, only allow enough characters that will fit in the width. If
* false, allow the field to scroll to the right.
/**
* The right-side directory list pane.
*/
- @SuppressWarnings("unused")
private TDirectoryList directoryList;
/**
private TButton openButton;
/**
- * Update the fields in response to other field updates.
+ * See if there is a valid filename to return. If the filename is a
+ * directory, then
*
- * @param enter if true, the user manually entered a filename
+ * @param newFilename the filename to check and return
*/
- @SuppressWarnings("unused")
- private void onUpdate(boolean enter) throws IOException {
- String newFilename = entryField.getText();
+ private void checkFilename(final String newFilename) throws IOException {
File newFile = new File(newFilename);
if (newFile.exists()) {
- if (enter) {
- if (newFile.isFile()) {
- filename = entryField.getText();
- getApplication().closeWindow(this);
- }
- if (newFile.isDirectory()) {
- treeViewRoot = new TDirectoryTreeItem(treeView,
- entryField.getText(), true);
- treeView.setTreeRoot(treeViewRoot, true);
- treeView.reflow();
- }
+ if (newFile.isFile()) {
+ filename = newFilename;
+ getApplication().closeWindow(this);
+ return;
+ }
+ if (newFile.isDirectory()) {
+ treeViewRoot = new TDirectoryTreeItem(treeView, newFilename,
+ true);
+ treeView.setTreeRoot(treeViewRoot, true);
+ treeView.reflow();
openButton.setEnabled(false);
- } else {
- if (newFile.isFile()) {
- openButton.setEnabled(true);
- } else {
- openButton.setEnabled(false);
- }
+ directoryList.setPath(newFilename);
}
- } else {
- openButton.setEnabled(false);
}
}
entryField = addField(1, 1, getWidth() - 4, false,
(new File(path)).getCanonicalPath(),
new TAction() {
- public void DO() {}
+ public void DO() {
+ try {
+ checkFilename(entryField.getText());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
}, null);
+ entryField.onKeypress(new TKeypressEvent(kbEnd));
// Add directory treeView
treeView = addTreeView(1, 3, 30, getHeight() - 6,
new TAction() {
- public void DO() {}
+ public void DO() {
+ TTreeItem item = treeView.getSelected();
+ File selectedDir = ((TDirectoryTreeItem) item).getFile();
+ try {
+ directoryList.setPath(selectedDir.getCanonicalPath());
+ openButton.setEnabled(false);
+ activate(directoryList);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
}
);
treeViewRoot = new TDirectoryTreeItem(treeView, path, true);
// Add directory files list
directoryList = addDirectoryList(path, 34, 3, 28, getHeight() - 6,
new TAction() {
- public void DO() {}
+ public void DO() {
+ try {
+ File newPath = directoryList.getPath();
+ entryField.setText(newPath.getCanonicalPath());
+ entryField.onKeypress(new TKeypressEvent(kbEnd));
+ openButton.setEnabled(true);
+ activate(entryField);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
}
);
// Setup button actions
openButton = addButton(openLabel, this.getWidth() - 12, 3,
new TAction() {
- public void DO() {}
+ public void DO() {
+ try {
+ checkFilename(entryField.getText());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
}
);
openButton.setEnabled(false);
}
);
+ // Default to the directory list
+ activate(directoryList);
+
// Set the secondaryFiber to run me
getApplication().enableSecondaryEventReceiver(this);
/**
* Set the displayable text for this item.
*
- * @param the displayable text for this item
+ * @param text the displayable text for this item
*/
public final void setText(final String text) {
this.text = text;
/**
* Recursively expand the tree into a linear array of items.
*
- * @param prefix = vertical bar of parent levels and such that is set on
+ * @param prefix vertical bar of parent levels and such that is set on
* each child
- * @param last = if true, this is the "last" leaf node of a tree
- * @param additional items to add to the array
+ * @param last if true, this is the "last" leaf node of a tree
+ * @return additional items to add to the array
*/
public List<TTreeItem> expandTree(final String prefix, final boolean last) {
List<TTreeItem> array = new ArrayList<TTreeItem>();
}
}
}
+ } else if (keypress.equals(kbTab)) {
+ getParent().switchWidget(true);
+ return;
+ } else if (keypress.equals(kbShiftTab)
+ || keypress.equals(kbBackTab)) {
+ getParent().switchWidget(false);
+ return;
} else if (selectedItem != null) {
// Give the TTreeItem a chance to handle arrow keys
selectedItem.onKeypress(keypress);
} else {
// Pass other keys (tab etc.) on to TWidget's handler.
super.onKeypress(keypress);
+ return;
}
// Update the screen after any thing has expanded/contracted
public void onKeypress(final TKeypressEvent keypress) {
if ((children.size() == 0)
- // TODO
- // || (cast(TTreeView)this)
+ || (this instanceof TTreeView)
|| (this instanceof TText)
) {
package jexer.demos;
import java.io.*;
+import java.util.*;
import jexer.*;
+import jexer.event.*;
import jexer.menu.*;
/**
addWindowMenu();
}
-
+
/**
* Public constructor.
*
super(input, output);
addAllWidgets();
}
-
+
+ /**
+ * Handle menu events.
+ *
+ * @param menu menu event
+ * @return if true, the event was processed and should not be passed onto
+ * a window
+ */
+ @Override
+ public boolean onMenu(TMenuEvent menu) {
+ if (menu.getId() == TMenu.MID_OPEN_FILE) {
+ try {
+ String filename = fileOpenBox(".");
+ if (filename != null) {
+ try {
+ File file = new File(filename);
+ StringBuilder fileContents = new StringBuilder();
+ Scanner scanner = new Scanner(file);
+ String EOL = System.getProperty("line.separator");
+
+ try {
+ while(scanner.hasNextLine()) {
+ fileContents.append(scanner.nextLine() + EOL);
+ }
+ new DemoTextWindow(this, filename,
+ fileContents.toString());
+ } finally {
+ scanner.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+ return super.onMenu(menu);
+ }
+
/**
* Public constructor.
*
*/
private TText textField;
+ /**
+ * Public constructor makes a text window out of any string.
+ *
+ * @param parent the main application
+ * @param title the text string
+ * @param text the text string
+ */
+ public DemoTextWindow(final TApplication parent, final String title,
+ final String text) {
+
+ super(parent, title, 0, 0, 44, 20, RESIZABLE);
+ textField = addText(text, 1, 1, 40, 16);
+ }
+
/**
* Public constructor.
*
* @param parent the main application
*/
public DemoTextWindow(final TApplication parent) {
- super(parent, "Text Areas", 0, 0, 44, 20, RESIZABLE);
-
- textField = addText(
+ this(parent, "Text Area",
"This is an example of a reflowable text field. Some example text follows.\n" +
"\n" +
"This library implements a text-based windowing system loosely\n" +
"This library is licensed LGPL (\"GNU Lesser General Public License\")\n" +
"version 3 or greater. See the file COPYING for the full license text,\n" +
"which includes both the GPL v3 and the LGPL supplemental terms.\n" +
-"\n",
- 1, 1, 40, 16);
+"\n");
+
}
/**