From: Kevin Lamonte Date: Sat, 28 Mar 2015 17:01:43 +0000 (-0400) Subject: stubs for TFileOpenBox, cleanup putStringXY X-Git-Url: https://git.nikiroo.be/?a=commitdiff_plain;h=0d47c5460c8e9d1198928308767a63ad35f46eb8;p=nikiroo-utils.git stubs for TFileOpenBox, cleanup putStringXY --- diff --git a/README.md b/README.md index 9ffed93..693e278 100644 --- a/README.md +++ b/README.md @@ -175,11 +175,10 @@ Many tasks remain before calling this version 1.0: 0.0.3: FINISH PORTING -- TTreeView - - Also add keyboard navigation - TDirectoryList - Also add keyboard navigation - TFileOpen + - Also add keyboard navigation 0.0.4: NEW STUFF diff --git a/src/jexer/TApplication.java b/src/jexer/TApplication.java index a37cf03..d0c34bf 100644 --- a/src/jexer/TApplication.java +++ b/src/jexer/TApplication.java @@ -31,6 +31,7 @@ package jexer; import java.io.InputStream; +import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.Collections; @@ -646,7 +647,7 @@ public class TApplication implements Runnable { // Draw the menu title getScreen().hLineXY(x, 0, menu.getTitle().length() + 2, ' ', menuColor); - getScreen().putStrXY(x + 1, 0, menu.getTitle(), menuColor); + getScreen().putStringXY(x + 1, 0, menu.getTitle(), menuColor); // Draw the highlight character getScreen().putCharXY(x + 1 + menu.getMnemonic().getShortcutIdx(), 0, menu.getMnemonic().getShortcut(), menuMnemonicColor); @@ -1820,4 +1821,30 @@ public class TApplication implements Runnable { return new TTerminalWindow(this, x, y, flags); } + /** + * Convenience function to spawn an file open box. + * + * @param path path of selected file + * @return the result of the new file open box + */ + public final String fileOpenBox(final String path) throws IOException { + + TFileOpenBox box = new TFileOpenBox(this, path, TFileOpenBox.Type.OPEN); + return box.getFilename(); + } + + /** + * Convenience function to spawn an file open box. + * + * @param path path of selected file + * @param type one of the Type constants + * @return the result of the new file open box + */ + public final String fileOpenBox(final String path, + final TFileOpenBox.Type type) throws IOException { + + TFileOpenBox box = new TFileOpenBox(this, path, type); + return box.getFilename(); + } + } diff --git a/src/jexer/TButton.java b/src/jexer/TButton.java index ce04f5c..0fc36a2 100644 --- a/src/jexer/TButton.java +++ b/src/jexer/TButton.java @@ -158,11 +158,11 @@ public final class TButton extends TWidget { if (inButtonPress) { getScreen().putCharXY(1, 0, ' ', buttonColor); - getScreen().putStrXY(2, 0, mnemonic.getRawLabel(), buttonColor); + getScreen().putStringXY(2, 0, mnemonic.getRawLabel(), buttonColor); getScreen().putCharXY(getWidth() - 1, 0, ' ', buttonColor); } else { getScreen().putCharXY(0, 0, ' ', buttonColor); - getScreen().putStrXY(1, 0, mnemonic.getRawLabel(), buttonColor); + getScreen().putStringXY(1, 0, mnemonic.getRawLabel(), buttonColor); getScreen().putCharXY(getWidth() - 2, 0, ' ', buttonColor); getScreen().putCharXY(getWidth() - 1, 0, diff --git a/src/jexer/TCheckbox.java b/src/jexer/TCheckbox.java index 1562ca0..e15a47f 100644 --- a/src/jexer/TCheckbox.java +++ b/src/jexer/TCheckbox.java @@ -127,7 +127,7 @@ public final class TCheckbox extends TWidget { getScreen().putCharXY(1, 0, ' ', checkboxColor); } getScreen().putCharXY(2, 0, ']', checkboxColor); - getScreen().putStrXY(4, 0, label, checkboxColor); + getScreen().putStringXY(4, 0, label, checkboxColor); } /** diff --git a/src/jexer/TDirectoryList.java b/src/jexer/TDirectoryList.java new file mode 100644 index 0000000..3a09bf3 --- /dev/null +++ b/src/jexer/TDirectoryList.java @@ -0,0 +1,313 @@ +/** + * Jexer - Java Text User Interface + * + * License: LGPLv3 or later + * + * This module is licensed under the GNU Lesser General Public License + * Version 3. Please see the file "COPYING" in this directory for more + * information about the GNU Lesser General Public License Version 3. + * + * Copyright (C) 2015 Kevin Lamonte + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * http://www.gnu.org/licenses/, or write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * @author Kevin Lamonte [kevin.lamonte@gmail.com] + * @version 1 + */ +package jexer; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import jexer.bits.CellAttributes; +import jexer.event.TKeypressEvent; +import jexer.event.TMouseEvent; +import static jexer.TKeypress.*; + +/** + * TDirectoryList shows the files within a directory. + */ +public class TDirectoryList extends TWidget { + + /** + * Files in the directory. + */ + private List files; + + /** + * Selected file. + */ + private int selectedFile = -1; + + /** + * Root path containing files to display. + */ + public File path; + + /** + * Vertical scrollbar. + */ + private TVScroller vScroller; + + /** + * Horizontal scrollbar. + */ + private THScroller hScroller; + + /** + * Maximum width of a single line. + */ + private int maxLineWidth; + + /** + * The action to perform when the user selects an item. + */ + private TAction action = null; + + /** + * Perform user selection action. + */ + public void dispatch() { + assert (selectedFile >= 0); + assert (selectedFile < files.size()); + if (action != null) { + action.DO(); + } + } + + /** + * Format one of the entries for drawing on the screen. + * + * @param index index into files + * @return the line to draw + */ + private String renderFile(int index) { + File file = files.get(index); + String name = file.getName(); + if (name.length() > 20) { + name = name.substring(0, 17) + "..."; + } + return String.format("%-20s %5dk", name, (file.length() / 1024)); + } + + /** + * Resize for a new width/height. + */ + public void reflow() { + + // Reset the lines + selectedFile = -1; + maxLineWidth = 0; + files.clear(); + + // 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[i].isDirectory()) { + continue; + } + files.add(newFiles[i]); + } + + for (int i = 0; i < files.size(); i++) { + String line = renderFile(i); + if (line.length() > maxLineWidth) { + maxLineWidth = line.length(); + } + } + + // Start at the top + if (vScroller == null) { + vScroller = new TVScroller(this, getWidth() - 1, 0, + getHeight() - 1); + } else { + vScroller.setX(getWidth() - 1); + vScroller.setHeight(getHeight() - 1); + } + vScroller.setBottomValue(files.size() - getHeight() - 1); + vScroller.setTopValue(0); + vScroller.setValue(0); + if (vScroller.getBottomValue() < 0) { + vScroller.setBottomValue(0); + } + vScroller.setBigChange(getHeight() - 1); + + // Start at the left + if (hScroller == null) { + hScroller = new THScroller(this, 0, getHeight() - 1, + getWidth() - 1); + } else { + hScroller.setY(getHeight() - 1); + hScroller.setWidth(getWidth() - 1); + } + hScroller.setRightValue(maxLineWidth - getWidth() + 1); + hScroller.setLeftValue(0); + hScroller.setValue(0); + if (hScroller.getRightValue() < 0) { + hScroller.setRightValue(0); + } + hScroller.setBigChange(getWidth() - 1); + } + + /** + * Public constructor. + * + * @param parent parent widget + * @param path directory path, must be a directory + * @param x column relative to parent + * @param y row relative to parent + * @param width width of text area + * @param height height of text area + */ + public TDirectoryList(final TWidget parent, final String path, final int x, + final int y, final int width, final int height) { + + this(parent, path, x, y, width, height, null); + } + + /** + * Public constructor. + * + * @param parent parent widget + * @param path directory path, must be a directory + * @param x column relative to parent + * @param y row relative to parent + * @param width width of text area + * @param height height of text area + * @param action action to perform when an item is selected + */ + public TDirectoryList(final TWidget parent, final String path, final int x, + final int y, final int width, final int height, final TAction action) { + + this.path = new File(path); + this.action = action; + files = new ArrayList(); + reflow(); + } + + /** + * Draw the files list. + */ + @Override + public void draw() { + CellAttributes color = null; + int begin = vScroller.getValue(); + int topY = 0; + for (int i = begin; i < files.size() - 1; i++) { + String line = renderFile(i); + if (hScroller.getValue() < line.length()) { + line = line.substring(hScroller.getValue()); + } else { + line = ""; + } + if (i == selectedFile) { + color = getTheme().getColor("tdirectorylist.selected"); + } else if (isAbsoluteActive()) { + color = getTheme().getColor("tdirectorylist"); + } else { + color = getTheme().getColor("tdirectorylist.inactive"); + } + String formatString = "%-" + Integer.toString(getWidth() - 1) + "s"; + getScreen().putStringXY(0, topY, String.format(formatString, line), + color); + topY++; + if (topY >= getHeight() - 1) { + break; + } + } + + // Pad the rest with blank lines + for (int i = topY; i < getHeight() - 1; i++) { + getScreen().hLineXY(0, i, getWidth() - 1, ' ', color); + } + } + + /** + * Handle mouse press events. + * + * @param mouse mouse button press event + */ + @Override + public void onMouseDown(final TMouseEvent mouse) { + if (mouse.isMouseWheelUp()) { + vScroller.decrement(); + return; + } + if (mouse.isMouseWheelDown()) { + vScroller.increment(); + return; + } + + if ((mouse.getX() < getWidth() - 1) + && (mouse.getY() < getHeight() - 1)) { + if (vScroller.getValue() + mouse.getY() < files.size()) { + selectedFile = vScroller.getValue() + mouse.getY(); + } + path = files.get(selectedFile); + dispatch(); + return; + } + + // Pass to children + super.onMouseDown(mouse); + } + + /** + * Handle mouse release events. + * + * @param mouse mouse button release event + */ + @Override + public void onMouseUp(final TMouseEvent mouse) { + // Pass to children + super.onMouseDown(mouse); + } + + /** + * Handle keystrokes. + * + * @param keypress keystroke event + */ + @Override + public void onKeypress(final TKeypressEvent keypress) { + if (keypress.equals(kbLeft)) { + hScroller.decrement(); + } else if (keypress.equals(kbRight)) { + hScroller.increment(); + } else if (keypress.equals(kbUp)) { + vScroller.decrement(); + } else if (keypress.equals(kbDown)) { + vScroller.increment(); + } else if (keypress.equals(kbPgUp)) { + vScroller.bigDecrement(); + } else if (keypress.equals(kbPgDn)) { + vScroller.bigIncrement(); + } else if (keypress.equals(kbHome)) { + vScroller.toTop(); + } else if (keypress.equals(kbEnd)) { + vScroller.toBottom(); + } else { + // Pass other keys (tab etc.) on + super.onKeypress(keypress); + } + } + +} diff --git a/src/jexer/TDirectoryTreeItem.java b/src/jexer/TDirectoryTreeItem.java index 25a33df..01c9b46 100644 --- a/src/jexer/TDirectoryTreeItem.java +++ b/src/jexer/TDirectoryTreeItem.java @@ -31,6 +31,7 @@ package jexer; import java.io.File; +import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.LinkedList; @@ -51,6 +52,8 @@ public class TDirectoryTreeItem extends TTreeItem { */ @Override public void onExpand() { + // System.err.printf("onExpand() %s\n", dir); + if (dir == null) { return; } @@ -70,20 +73,26 @@ public class TDirectoryTreeItem extends TTreeItem { return; } - // Refresh my child list for (File file: dir.listFiles()) { - if (file.getName().equals(".")) { + // System.err.printf(" -> file %s %s\n", file, file.getName()); + + if (file.getName().startsWith(".")) { + // Hide dot-files continue; } if (!file.isDirectory()) { continue; } - TDirectoryTreeItem item = new TDirectoryTreeItem(getTreeView(), - file.getName(), false, false); + try { + TDirectoryTreeItem item = new TDirectoryTreeItem(getTreeView(), + file.getCanonicalPath(), false, false); - item.level = this.level + 1; - getChildren().add(item); + item.level = this.level + 1; + getChildren().add(item); + } catch (IOException e) { + continue; + } } Collections.sort(getChildren()); @@ -110,7 +119,9 @@ public class TDirectoryTreeItem extends TTreeItem { * @param view root TTreeView * @param text text for this item */ - public TDirectoryTreeItem(final TTreeView view, final String text) { + public TDirectoryTreeItem(final TTreeView view, + final String text) throws IOException { + this(view, text, false, true); } @@ -122,7 +133,7 @@ public class TDirectoryTreeItem extends TTreeItem { * @param expanded if true, have it expanded immediately */ public TDirectoryTreeItem(final TTreeView view, final String text, - final boolean expanded) { + final boolean expanded) throws IOException { this(view, text, expanded, true); } @@ -137,31 +148,38 @@ public class TDirectoryTreeItem extends TTreeItem { * return the root path entry */ public TDirectoryTreeItem(final TTreeView view, final String text, - final boolean expanded, final boolean openParents) { + final boolean expanded, final boolean openParents) throws IOException { super(view, text, false); - List parentItems = new LinkedList(); List parentPaths = new LinkedList(); boolean oldExpanded = expanded; + // Convert to canonical path + File rootPath = new File(text); + rootPath = rootPath.getCanonicalFile(); + if (openParents == true) { setExpanded(true); // Go up the directory tree - File rootPath = new File(text); File parent = rootPath.getParentFile(); while (parent != null) { parentPaths.add(rootPath.getName()); rootPath = rootPath.getParentFile(); parent = rootPath.getParentFile(); } - setText(rootPath.getName()); + } + dir = rootPath; + if (rootPath.getParentFile() == null) { + // This is a filesystem root, use its full name + setText(rootPath.getCanonicalPath()); } else { - setText(text); + // This is a relative path. We got here because openParents was + // false. + assert (openParents == false); + setText(rootPath.getName()); } - - dir = new File(getText()); onExpand(); if (openParents == true) { diff --git a/src/jexer/TField.java b/src/jexer/TField.java index 07a457b..8055a38 100644 --- a/src/jexer/TField.java +++ b/src/jexer/TField.java @@ -201,7 +201,7 @@ public class TField extends TWidget { end = text.length(); } getScreen().hLineXY(0, 0, getWidth(), GraphicsChars.HATCH, fieldColor); - getScreen().putStrXY(0, 0, text.substring(windowStart, end), + getScreen().putStringXY(0, 0, text.substring(windowStart, end), fieldColor); // Fix the cursor, it will be rendered by TApplication.drawAll(). diff --git a/src/jexer/TFileOpenBox.java b/src/jexer/TFileOpenBox.java new file mode 100644 index 0000000..eb2c924 --- /dev/null +++ b/src/jexer/TFileOpenBox.java @@ -0,0 +1,243 @@ +/** + * Jexer - Java Text User Interface + * + * License: LGPLv3 or later + * + * This module is licensed under the GNU Lesser General Public License + * Version 3. Please see the file "COPYING" in this directory for more + * information about the GNU Lesser General Public License Version 3. + * + * Copyright (C) 2015 Kevin Lamonte + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * http://www.gnu.org/licenses/, or write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * @author Kevin Lamonte [kevin.lamonte@gmail.com] + * @version 1 + */ +package jexer; + +import java.io.File; +import java.io.IOException; + +import jexer.bits.GraphicsChars; +import jexer.event.TKeypressEvent; +import static jexer.TKeypress.*; + +/** + * TFileOpenBox is a system-modal dialog for selecting a file to open. Call + * it like: + * + *

+ *

+ * {@code
+ *     filename = application.fileOpenBox("/path/to/file.ext",
+ *         TFileOpenBox.Type.OPEN);
+ *     if (filename != null) {
+ *         ... the user selected a file, go open it ...
+ *     }
+ * }
+ * 
+ * + */ +public final class TFileOpenBox extends TWindow { + + /** + * TFileOpenBox can be called for either Open or Save actions. + */ + public enum Type { + OPEN, + SAVE + } + + /** + * String to return, or null if the user canceled. + */ + private String filename = null; + + /** + * Get the return string. + * + * @return the filename the user selected, or null if they canceled. + */ + public String getFilename() { + return filename; + } + + /** + * The left-side tree view pane. + */ + private TTreeView treeView; + + /** + * The data behind treeView. + */ + private TDirectoryTreeItem treeViewRoot; + + /** + * The right-side directory list pane. + */ + @SuppressWarnings("unused") + private TDirectoryList directoryList; + + /** + * The top row text field. + */ + private TField entryField; + + /** + * The Open or Save button. + */ + private TButton openButton; + + /** + * Update the fields in response to other field updates. + * + * @param enter if true, the user manually entered a filename + */ + @SuppressWarnings("unused") + private void onUpdate(boolean enter) throws IOException { + String newFilename = entryField.getText(); + 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(); + } + openButton.setEnabled(false); + } else { + if (newFile.isFile()) { + openButton.setEnabled(true); + } else { + openButton.setEnabled(false); + } + } + } else { + openButton.setEnabled(false); + } + } + + /** + * Public constructor. The file open box will be centered on screen. + * + * @param application the TApplication that manages this window + * @param path path of selected file + * @param type one of the Type constants + */ + public TFileOpenBox(final TApplication application, final String path, + final Type type) throws IOException { + + // Register with the TApplication + super(application, "", 0, 0, 76, 22, MODAL); + + // Add text field + entryField = addField(1, 1, getWidth() - 4, false, + (new File(path)).getCanonicalPath(), + new TAction() { + public void DO() {} + }, null); + + // Add directory treeView + treeView = addTreeView(1, 3, 30, getHeight() - 6, + new TAction() { + public void DO() {} + } + ); + treeViewRoot = new TDirectoryTreeItem(treeView, path, true); + + // Add directory files list + directoryList = addDirectoryList(path, 34, 3, 28, getHeight() - 6, + new TAction() { + public void DO() {} + } + ); + + String openLabel = ""; + switch (type) { + case OPEN: + openLabel = " &Open "; + setTitle("Open File..."); + break; + case SAVE: + openLabel = " &Save "; + setTitle("Save File..."); + break; + default: + throw new IllegalArgumentException("Invalid type: " + type); + } + + // Setup button actions + openButton = addButton(openLabel, this.getWidth() - 12, 3, + new TAction() { + public void DO() {} + } + ); + openButton.setEnabled(false); + + addButton("&Cancel", getWidth() - 12, 5, + new TAction() { + public void DO() { + filename = null; + getApplication().closeWindow(TFileOpenBox.this); + } + } + ); + + // Set the secondaryFiber to run me + getApplication().enableSecondaryEventReceiver(this); + + // Yield to the secondary thread. When I come back from the + // constructor response will already be set. + getApplication().yield(); + } + + /** + * Draw me on screen. + */ + @Override + public void draw() { + super.draw(); + getScreen().vLineXY(33, 4, getHeight() - 6, GraphicsChars.WINDOW_SIDE, + getBackground()); + } + + /** + * Handle keystrokes. + * + * @param keypress keystroke event + */ + @Override + public void onKeypress(final TKeypressEvent keypress) { + // Escape - behave like cancel + if (keypress.equals(kbEsc)) { + // Close window + filename = null; + getApplication().closeWindow(this); + return; + } + + // Pass to my parent + super.onKeypress(keypress); + } + +} diff --git a/src/jexer/TLabel.java b/src/jexer/TLabel.java index ad30035..801db2a 100644 --- a/src/jexer/TLabel.java +++ b/src/jexer/TLabel.java @@ -108,7 +108,7 @@ public final class TLabel extends TWidget { CellAttributes background = getWindow().getBackground(); color.setBackColor(background.getBackColor()); - getScreen().putStrXY(0, 0, label, color); + getScreen().putStringXY(0, 0, label, color); } } diff --git a/src/jexer/TPasswordField.java b/src/jexer/TPasswordField.java index 5cb9732..d68a21c 100644 --- a/src/jexer/TPasswordField.java +++ b/src/jexer/TPasswordField.java @@ -114,7 +114,7 @@ public final class TPasswordField extends TField { getScreen().hLineXY(0, 0, getWidth() - 2, '*', fieldColor); } else { - getScreen().putStrXY(0, 0, text.substring(windowStart, end), + getScreen().putStringXY(0, 0, text.substring(windowStart, end), fieldColor); } diff --git a/src/jexer/TRadioButton.java b/src/jexer/TRadioButton.java index ddeec09..4875e2b 100644 --- a/src/jexer/TRadioButton.java +++ b/src/jexer/TRadioButton.java @@ -147,7 +147,7 @@ public final class TRadioButton extends TWidget { getScreen().putCharXY(1, 0, ' ', radioButtonColor); } getScreen().putCharXY(2, 0, ')', radioButtonColor); - getScreen().putStrXY(4, 0, label, radioButtonColor); + getScreen().putStringXY(4, 0, label, radioButtonColor); } /** diff --git a/src/jexer/TRadioGroup.java b/src/jexer/TRadioGroup.java index 723148f..365c074 100644 --- a/src/jexer/TRadioGroup.java +++ b/src/jexer/TRadioGroup.java @@ -106,7 +106,7 @@ public final class TRadioGroup extends TWidget { radioGroupColor, radioGroupColor, 3, false); getScreen().hLineXY(1, 0, label.length() + 2, ' ', radioGroupColor); - getScreen().putStrXY(2, 0, label, radioGroupColor); + getScreen().putStringXY(2, 0, label, radioGroupColor); } /** diff --git a/src/jexer/TTerminalWindow.java b/src/jexer/TTerminalWindow.java index bb91a63..6d89e52 100644 --- a/src/jexer/TTerminalWindow.java +++ b/src/jexer/TTerminalWindow.java @@ -285,7 +285,7 @@ public class TTerminalWindow extends TWindow { int rc = shell.exitValue(); // The emulator exited on its own, all is fine setTitle(String.format("%s [Completed - %d]", - getTitle(), shell.exitValue())); + getTitle(), rc)); shell = null; emulator.close(); } catch (IllegalThreadStateException e) { diff --git a/src/jexer/TText.java b/src/jexer/TText.java index 64e96bb..2516a0a 100644 --- a/src/jexer/TText.java +++ b/src/jexer/TText.java @@ -294,7 +294,7 @@ public final class TText extends TWidget { line = ""; } String formatString = "%-" + Integer.toString(getWidth() - 1) + "s"; - getScreen().putStrXY(0, topY, String.format(formatString, line), + getScreen().putStringXY(0, topY, String.format(formatString, line), color); topY++; diff --git a/src/jexer/TTreeItem.java b/src/jexer/TTreeItem.java index e97ea0e..11a81a7 100644 --- a/src/jexer/TTreeItem.java +++ b/src/jexer/TTreeItem.java @@ -203,6 +203,18 @@ public class TTreeItem extends TWidget { this.selectable = selectable; } + /** + * Pointer to the previous keyboard-navigable item (kbUp). Note package + * private access. + */ + TTreeItem keyboardPrevious = null; + + /** + * Pointer to the next keyboard-navigable item (kbDown). Note package + * private access. + */ + TTreeItem keyboardNext = null; + /** * Public constructor. * @@ -323,7 +335,7 @@ public class TTreeItem extends TWidget { */ @Override public void onMouseUp(final TMouseEvent mouse) { - if ((mouse.getX() == (getExpanderX() - view.hScroller.getValue())) + if ((mouse.getX() == (getExpanderX() - view.getHScroller().getValue())) && (mouse.getY() == 0) ) { if (selectable) { @@ -356,6 +368,34 @@ public class TTreeItem extends TWidget { } } + /** + * Handle keystrokes. + * + * @param keypress keystroke event + */ + @Override + public void onKeypress(final TKeypressEvent keypress) { + if (keypress.equals(kbLeft) + || keypress.equals(kbRight) + || keypress.equals(kbSpace) + ) { + if (selectable) { + // Flip expanded flag + expanded = !expanded; + if (expanded == false) { + // Unselect children that became invisible + unselect(); + } + view.setSelected(this); + } + // Let subclasses do something with this + onExpand(); + } else { + // Pass other keys (tab etc.) on to TWidget's handler. + super.onKeypress(keypress); + } + } + /** * Draw this item to a window. */ @@ -365,7 +405,7 @@ public class TTreeItem extends TWidget { return; } - int offset = -view.hScroller.getValue(); + int offset = -view.getHScroller().getValue(); CellAttributes color = getTheme().getColor("ttreeview"); CellAttributes textColor = getTheme().getColor("ttreeview"); @@ -384,7 +424,6 @@ public class TTreeItem extends TWidget { // Blank out the background getScreen().hLineXY(0, 0, getWidth(), ' ', color); - int expandX = 0; String line = prefix; if (level > 0) { if (last) { @@ -397,12 +436,12 @@ public class TTreeItem extends TWidget { line += "[ ] "; } } - getScreen().putStrXY(offset, 0, line, color); + getScreen().putStringXY(offset, 0, line, color); if (selected) { - getScreen().putStrXY(offset + line.length(), 0, text, + getScreen().putStringXY(offset + line.length(), 0, text, selectedColor); } else { - getScreen().putStrXY(offset + line.length(), 0, text, textColor); + getScreen().putStringXY(offset + line.length(), 0, text, textColor); } if ((level > 0) && (expandable)) { if (expanded) { diff --git a/src/jexer/TTreeView.java b/src/jexer/TTreeView.java index 8c710f3..a6855ba 100644 --- a/src/jexer/TTreeView.java +++ b/src/jexer/TTreeView.java @@ -30,8 +30,6 @@ */ package jexer; -import jexer.bits.CellAttributes; -import jexer.bits.GraphicsChars; import jexer.event.TKeypressEvent; import jexer.event.TMouseEvent; import static jexer.TKeypress.*; @@ -47,9 +45,17 @@ public class TTreeView extends TWidget { private TVScroller vScroller; /** - * Horizontal scrollbar. Note package private access. + * Horizontal scrollbar. */ - THScroller hScroller; + private THScroller hScroller; + + /** + * Get the horizontal scrollbar. This is used by TTreeItem.draw(), and + * potentially subclasses. + */ + public final THScroller getHScroller() { + return hScroller; + } /** * Root of the tree. @@ -148,11 +154,11 @@ public class TTreeView extends TWidget { } /** - * Set the new selected tree view item. Note package private access. + * Set the new selected tree view item. * * @param item new item that became selected */ - void setSelected(final TTreeItem item) { + public void setSelected(final TTreeItem item) { if (item != null) { item.setSelected(true); } @@ -163,9 +169,9 @@ public class TTreeView extends TWidget { } /** - * Perform user selection action. Note package private access. + * Perform user selection action. */ - void dispatch() { + public void dispatch() { if (action != null) { action.DO(); } @@ -217,12 +223,16 @@ public class TTreeView extends TWidget { TTreeItem item = (TTreeItem) widget; item.setInvisible(true); item.setEnabled(false); + item.keyboardPrevious = null; + item.keyboardNext = null; } } // Expand the tree into a linear list getChildren().clear(); getChildren().addAll(treeRoot.expandTree("", true)); + + // Locate the selected row and maximum line width for (TWidget widget: getChildren()) { TTreeItem item = (TTreeItem) widget; @@ -239,6 +249,7 @@ public class TTreeView extends TWidget { maxLineWidth = lineWidth; } } + if ((centerWindow) && (foundSelectedRow)) { if ((selectedRow < vScroller.getValue()) || (selectedRow > vScroller.getValue() + getHeight() - 2) @@ -282,13 +293,24 @@ public class TTreeView extends TWidget { int begin = vScroller.getValue(); int topY = 0; + + // As we walk the list we also adjust next/previous pointers, + // resulting in a doubly-linked list but only of the expanded items. + TTreeItem p = null; + for (int i = 0; i < getChildren().size(); i++) { if (!(getChildren().get(i) instanceof TTreeItem)) { - // Skip + // Skip the scrollbars continue; } TTreeItem item = (TTreeItem) getChildren().get(i); + if (p != null) { + item.keyboardPrevious = p; + p.keyboardNext = item; + } + p = item; + if (i < begin) { // Render invisible item.setEnabled(false); @@ -309,6 +331,7 @@ public class TTreeView extends TWidget { item.setWidth(getWidth() - 1); topY++; } + } /** @@ -352,17 +375,35 @@ public class TTreeView extends TWidget { */ @Override public void onKeypress(final TKeypressEvent keypress) { - if (keypress.equals(kbLeft)) { + if (keypress.equals(kbShiftLeft) + || keypress.equals(kbCtrlLeft) + || keypress.equals(kbAltLeft) + ) { hScroller.decrement(); - } else if (keypress.equals(kbRight)) { + } else if (keypress.equals(kbShiftRight) + || keypress.equals(kbCtrlRight) + || keypress.equals(kbAltRight) + ) { hScroller.increment(); - } else if (keypress.equals(kbUp)) { + } else if (keypress.equals(kbShiftUp) + || keypress.equals(kbCtrlUp) + || keypress.equals(kbAltUp) + ) { vScroller.decrement(); - } else if (keypress.equals(kbDown)) { + } else if (keypress.equals(kbShiftDown) + || keypress.equals(kbCtrlDown) + || keypress.equals(kbAltDown) + ) { vScroller.increment(); - } else if (keypress.equals(kbPgUp)) { + } else if (keypress.equals(kbShiftPgUp) + || keypress.equals(kbCtrlPgUp) + || keypress.equals(kbAltPgUp) + ) { vScroller.bigDecrement(); - } else if (keypress.equals(kbPgDn)) { + } else if (keypress.equals(kbShiftPgDn) + || keypress.equals(kbCtrlPgDn) + || keypress.equals(kbAltPgDn) + ) { vScroller.bigIncrement(); } else if (keypress.equals(kbHome)) { vScroller.toTop(); @@ -372,8 +413,33 @@ public class TTreeView extends TWidget { if (selectedItem != null) { dispatch(); } + } else if (keypress.equals(kbUp)) { + // Select the previous item + if (selectedItem != null) { + TTreeItem oldItem = selectedItem; + if (selectedItem.keyboardPrevious != null) { + setSelected(selectedItem.keyboardPrevious); + if (oldItem.getY() == 0) { + vScroller.decrement(); + } + } + } + } else if (keypress.equals(kbDown)) { + // Select the next item + if (selectedItem != null) { + TTreeItem oldItem = selectedItem; + if (selectedItem.keyboardNext != null) { + setSelected(selectedItem.keyboardNext); + if (oldItem.getY() == getHeight() - 2) { + vScroller.increment(); + } + } + } + } else if (selectedItem != null) { + // Give the TTreeItem a chance to handle arrow keys + selectedItem.onKeypress(keypress); } else { - // Pass other keys (tab etc.) on + // Pass other keys (tab etc.) on to TWidget's handler. super.onKeypress(keypress); } diff --git a/src/jexer/TWidget.java b/src/jexer/TWidget.java index a32b716..29b6c72 100644 --- a/src/jexer/TWidget.java +++ b/src/jexer/TWidget.java @@ -30,6 +30,7 @@ */ package jexer; +import java.io.IOException; import java.util.List; import java.util.LinkedList; @@ -381,7 +382,6 @@ public abstract class TWidget implements Comparable { * @return difference between this.tabOrder and that.tabOrder, or * difference between this.z and that.z, or String.compareTo(text) */ - @Override public final int compareTo(final TWidget that) { if ((this instanceof TWindow) && (that instanceof TWindow) @@ -1312,5 +1312,57 @@ public abstract class TWidget implements Comparable { return new TTreeView(this, x, y, width, height, action); } + /** + * Convenience function to spawn a file open box. + * + * @param path path of selected file + * @return the result of the new file open box + */ + public final String fileOpenBox(final String path) throws IOException { + return getApplication().fileOpenBox(path); + } + + /** + * Convenience function to spawn a file open box. + * + * @param path path of selected file + * @param type one of the Type constants + * @return the result of the new file open box + */ + public final String fileOpenBox(final String path, + final TFileOpenBox.Type type) throws IOException { + + return getApplication().fileOpenBox(path, type); + } + /** + * Convenience function to add a directory list to this container/window. + * + * @param path directory path, must be a directory + * @param x column relative to parent + * @param y row relative to parent + * @param width width of text area + * @param height height of text area + */ + public final TDirectoryList addDirectoryList(final String path, final int x, + final int y, final int width, final int height) { + + return new TDirectoryList(this, path, x, y, width, height, null); + } + + /** + * Convenience function to add a directory list to this container/window. + * + * @param path directory path, must be a directory + * @param x column relative to parent + * @param y row relative to parent + * @param width width of text area + * @param height height of text area + * @param action action to perform when an item is selected + */ + public final TDirectoryList addDirectoryList(final String path, final int x, + final int y, final int width, final int height, final TAction action) { + + return new TDirectoryList(this, path, x, y, width, height, action); + } } diff --git a/src/jexer/TWindow.java b/src/jexer/TWindow.java index 82d187c..e047bc8 100644 --- a/src/jexer/TWindow.java +++ b/src/jexer/TWindow.java @@ -473,7 +473,7 @@ public class TWindow extends TWidget { // Draw the title int titleLeft = (getWidth() - title.length() - 2) / 2; putCharXY(titleLeft, 0, ' ', border); - putStrXY(titleLeft + 1, 0, title); + putStringXY(titleLeft + 1, 0, title); putCharXY(titleLeft + title.length() + 1, 0, ' ', border); if (isActive()) { @@ -776,6 +776,10 @@ public class TWindow extends TWidget { } } + // Pass a resize event to my children + onResize(new TResizeEvent(TResizeEvent.Type.WIDGET, + getWidth(), getHeight())); + return; } @@ -999,10 +1003,10 @@ public class TWindow extends TWidget { * @param str string to draw * @param attr attributes to use (bold, foreColor, backColor) */ - public final void putStrXY(final int x, final int y, final String str, + public final void putStringXY(final int x, final int y, final String str, final CellAttributes attr) { - getScreen().putStrXY(x, y, str, attr); + getScreen().putStringXY(x, y, str, attr); } /** @@ -1013,8 +1017,8 @@ public class TWindow extends TWidget { * @param y row coordinate. 0 is the top-most row. * @param str string to draw */ - public final void putStrXY(final int x, final int y, final String str) { - getScreen().putStrXY(x, y, str); + public final void putStringXY(final int x, final int y, final String str) { + getScreen().putStringXY(x, y, str); } /** diff --git a/src/jexer/bits/Color.java b/src/jexer/bits/Color.java index 54ae66a..31be310 100644 --- a/src/jexer/bits/Color.java +++ b/src/jexer/bits/Color.java @@ -66,26 +66,27 @@ public final class Color { * @return Color.RED, Color.BLUE, etc. */ static Color getColor(final String colorName) { - switch (colorName.toLowerCase()) { - case "black": + String str = colorName.toLowerCase(); + + if (str.equals("black")) { return Color.BLACK; - case "white": + } else if (str.equals("white")) { return Color.WHITE; - case "red": + } else if (str.equals("red")) { return Color.RED; - case "cyan": + } else if (str.equals("cyan")) { return Color.CYAN; - case "green": + } else if (str.equals("green")) { return Color.GREEN; - case "magenta": + } else if (str.equals("magenta")) { return Color.MAGENTA; - case "blue": + } else if (str.equals("blue")) { return Color.BLUE; - case "yellow": + } else if (str.equals("yellow")) { return Color.YELLOW; - case "brown": + } else if (str.equals("brown")) { return Color.YELLOW; - default: + } else { // Let unknown strings become white return Color.WHITE; } diff --git a/src/jexer/demos/Demo1.java b/src/jexer/demos/Demo1.java index 53c205f..d1dab90 100644 --- a/src/jexer/demos/Demo1.java +++ b/src/jexer/demos/Demo1.java @@ -30,9 +30,7 @@ */ package jexer.demos; -import jexer.*; -import jexer.event.*; -import jexer.menu.*; +import jexer.TApplication; /** * This class is the main driver for a simple demonstration of Jexer's diff --git a/src/jexer/demos/DemoApplication.java b/src/jexer/demos/DemoApplication.java index 4b31c71..95d0a54 100644 --- a/src/jexer/demos/DemoApplication.java +++ b/src/jexer/demos/DemoApplication.java @@ -33,7 +33,6 @@ package jexer.demos; import java.io.*; import jexer.*; -import jexer.event.*; import jexer.menu.*; /** diff --git a/src/jexer/demos/DemoCheckboxWindow.java b/src/jexer/demos/DemoCheckboxWindow.java index 783ad8b..fa958f0 100644 --- a/src/jexer/demos/DemoCheckboxWindow.java +++ b/src/jexer/demos/DemoCheckboxWindow.java @@ -31,8 +31,6 @@ package jexer.demos; import jexer.*; -import jexer.event.*; -import jexer.menu.*; /** * This window demonstates the TRadioGroup, TRadioButton, and TCheckbox diff --git a/src/jexer/demos/DemoMainWindow.java b/src/jexer/demos/DemoMainWindow.java index c2f77e8..9a83464 100644 --- a/src/jexer/demos/DemoMainWindow.java +++ b/src/jexer/demos/DemoMainWindow.java @@ -31,8 +31,6 @@ package jexer.demos; import jexer.*; -import jexer.event.*; -import jexer.menu.*; /** * This is the main "demo" application window. It makes use of the TTimer, @@ -158,7 +156,11 @@ public class DemoMainWindow extends TWindow { addButton("Tree&View", 35, row, new TAction() { public void DO() { - new DemoTreeViewWindow(getApplication()); + try { + new DemoTreeViewWindow(getApplication()); + } catch (Exception e) { + e.printStackTrace(); + } } } ); diff --git a/src/jexer/demos/DemoMsgBoxWindow.java b/src/jexer/demos/DemoMsgBoxWindow.java index e0c7b21..b2cef0d 100644 --- a/src/jexer/demos/DemoMsgBoxWindow.java +++ b/src/jexer/demos/DemoMsgBoxWindow.java @@ -31,8 +31,6 @@ package jexer.demos; import jexer.*; -import jexer.event.*; -import jexer.menu.*; /** * This window demonstates the TMessageBox and TInputBox widgets. diff --git a/src/jexer/demos/DemoTextWindow.java b/src/jexer/demos/DemoTextWindow.java index 81235cd..711bf3b 100644 --- a/src/jexer/demos/DemoTextWindow.java +++ b/src/jexer/demos/DemoTextWindow.java @@ -32,7 +32,6 @@ package jexer.demos; import jexer.*; import jexer.event.*; -import jexer.menu.*; /** * This window demonstates the TText, THScroller, and TVScroller widgets. diff --git a/src/jexer/demos/DemoTreeViewWindow.java b/src/jexer/demos/DemoTreeViewWindow.java index 4bd5a38..0fc5dfe 100644 --- a/src/jexer/demos/DemoTreeViewWindow.java +++ b/src/jexer/demos/DemoTreeViewWindow.java @@ -30,9 +30,10 @@ */ package jexer.demos; +import java.io.IOException; + import jexer.*; import jexer.event.*; -import jexer.menu.*; /** * This window demonstates the TTreeView widget. @@ -49,12 +50,12 @@ public class DemoTreeViewWindow extends TWindow { * * @param parent the main application */ - public DemoTreeViewWindow(TApplication parent) { + public DemoTreeViewWindow(TApplication parent) throws IOException { super(parent, "Tree View", 0, 0, 44, 16, TWindow.RESIZABLE); // Load the treeview with "stuff" treeView = addTreeView(1, 1, 40, 12); - TDirectoryTreeItem root = new TDirectoryTreeItem(treeView, ".", true); + new TDirectoryTreeItem(treeView, ".", true); } /** diff --git a/src/jexer/io/ECMA48Terminal.java b/src/jexer/io/ECMA48Terminal.java index 1aafa3c..8e1a03d 100644 --- a/src/jexer/io/ECMA48Terminal.java +++ b/src/jexer/io/ECMA48Terminal.java @@ -1165,25 +1165,6 @@ public final class ECMA48Terminal implements Runnable { return "\033[?1036l"; } - /** - * Convert a list of SGR parameters into a full escape sequence. This - * also eliminates a trailing ';' which would otherwise reset everything - * to white-on-black not-bold. - * - * @param str string of parameters, e.g. "31;1;" - * @return the string to emit to an ANSI / ECMA-style terminal, - * e.g. "\033[31;1m" - */ - private String addHeaderSGR(String str) { - if (str.length() > 0) { - // Nix any trailing ';' because that resets all attributes - while (str.endsWith(":")) { - str = str.substring(0, str.length() - 1); - } - } - return "\033[" + str + "m"; - } - /** * Create a SGR parameter sequence for a single color change. Note * package private access. @@ -1332,20 +1313,6 @@ public final class ECMA48Terminal implements Runnable { return sb.toString(); } - /** - * Create a SGR parameter sequence for enabling reverse color. - * - * @param on if true, turn on reverse - * @return the string to emit to an ANSI / ECMA-style terminal, - * e.g. "\033[7m" - */ - private String reverse(final boolean on) { - if (on) { - return "\033[7m"; - } - return "\033[27m"; - } - /** * Create a SGR parameter sequence to reset to defaults. Note package * private access. @@ -1372,87 +1339,6 @@ public final class ECMA48Terminal implements Runnable { return "0;37;40"; } - /** - * Create a SGR parameter sequence for enabling boldface. - * - * @param on if true, turn on bold - * @return the string to emit to an ANSI / ECMA-style terminal, - * e.g. "\033[1m" - */ - private String bold(final boolean on) { - return bold(on, true); - } - - /** - * Create a SGR parameter sequence for enabling boldface. - * - * @param on if true, turn on bold - * @param header if true, make the full header, otherwise just emit the - * bare parameter e.g. "1;" - * @return the string to emit to an ANSI / ECMA-style terminal, - * e.g. "\033[1m" - */ - private String bold(final boolean on, final boolean header) { - if (header) { - if (on) { - return "\033[1m"; - } - return "\033[22m"; - } - if (on) { - return "1;"; - } - return "22;"; - } - - /** - * Create a SGR parameter sequence for enabling blinking text. - * - * @param on if true, turn on blink - * @return the string to emit to an ANSI / ECMA-style terminal, - * e.g. "\033[5m" - */ - private String blink(final boolean on) { - return blink(on, true); - } - - /** - * Create a SGR parameter sequence for enabling blinking text. - * - * @param on if true, turn on blink - * @param header if true, make the full header, otherwise just emit the - * bare parameter e.g. "5;" - * @return the string to emit to an ANSI / ECMA-style terminal, - * e.g. "\033[5m" - */ - private String blink(final boolean on, final boolean header) { - if (header) { - if (on) { - return "\033[5m"; - } - return "\033[25m"; - } - if (on) { - return "5;"; - } - return "25;"; - } - - /** - * Create a SGR parameter sequence for enabling underline / underscored - * text. - * - * @param on if true, turn on underline - * @return the string to emit to an ANSI / ECMA-style terminal, - * e.g. "\033[4m" - */ - private String underline(final boolean on) { - if (on) { - return "\033[4m"; - } - return "\033[24m"; - } - /** * Create a SGR parameter sequence for enabling the visible cursor. Note * package private access. @@ -1493,35 +1379,6 @@ public final class ECMA48Terminal implements Runnable { return "\033[0;37;40m\033[K"; } - /** - * Clear the line up the cursor (inclusive). Because some terminals use - * back-color-erase, set the color to white-on-black beforehand. - * - * @return the string to emit to an ANSI / ECMA-style terminal - */ - private String clearPreceedingLine() { - return "\033[0;37;40m\033[1K"; - } - - /** - * Clear the line. Because some terminals use back-color-erase, set the - * color to white-on-black beforehand. - * - * @return the string to emit to an ANSI / ECMA-style terminal - */ - private String clearLine() { - return "\033[0;37;40m\033[2K"; - } - - /** - * Move the cursor to the top-left corner. - * - * @return the string to emit to an ANSI / ECMA-style terminal - */ - private String home() { - return "\033[H"; - } - /** * Move the cursor to (x, y). Note package private access. * diff --git a/src/jexer/io/Screen.java b/src/jexer/io/Screen.java index ec5309d..4dab0ff 100644 --- a/src/jexer/io/Screen.java +++ b/src/jexer/io/Screen.java @@ -387,7 +387,7 @@ public abstract class Screen { * @param str string to draw * @param attr attributes to use (bold, foreColor, backColor) */ - public final void putStrXY(final int x, final int y, final String str, + public final void putStringXY(final int x, final int y, final String str, final CellAttributes attr) { int i = x; @@ -409,7 +409,7 @@ public abstract class Screen { * @param y row coordinate. 0 is the top-most row. * @param str string to draw */ - public final void putStrXY(final int x, final int y, final String str) { + public final void putStringXY(final int x, final int y, final String str) { int i = x; for (int j = 0; j < str.length(); j++) { diff --git a/src/jexer/io/SwingScreen.java b/src/jexer/io/SwingScreen.java index 2c31d76..be8fb67 100644 --- a/src/jexer/io/SwingScreen.java +++ b/src/jexer/io/SwingScreen.java @@ -329,7 +329,7 @@ public final class SwingScreen extends Screen { getFontDimensions(); // Setup double-buffering - if (screen.doubleBuffer) { + if (SwingScreen.doubleBuffer) { setIgnoreRepaint(true); createBufferStrategy(2); bufferStrategy = getBufferStrategy(); @@ -582,7 +582,7 @@ public final class SwingScreen extends Screen { if (reallyCleared) { // Really refreshed, do it all - if (doubleBuffer) { + if (SwingScreen.doubleBuffer) { Graphics gr = frame.bufferStrategy.getDrawGraphics(); frame.paint(gr); gr.dispose(); @@ -649,7 +649,7 @@ public final class SwingScreen extends Screen { // Repaint the desired area // System.err.printf("REPAINT X %d %d Y %d %d\n", xMin, xMax, // yMin, yMax); - if (doubleBuffer) { + if (SwingScreen.doubleBuffer) { Graphics gr = frame.bufferStrategy.getDrawGraphics(); Rectangle bounds = new Rectangle(xMin, yMin, xMax - xMin, yMax - yMin); diff --git a/src/jexer/io/SwingTerminal.java b/src/jexer/io/SwingTerminal.java index a7a4c33..3fa07ce 100644 --- a/src/jexer/io/SwingTerminal.java +++ b/src/jexer/io/SwingTerminal.java @@ -172,7 +172,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param key keystroke received */ - @Override public void keyReleased(final KeyEvent key) { // Ignore release events } @@ -182,7 +181,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param key keystroke received */ - @Override public void keyTyped(final KeyEvent key) { // Ignore typed events } @@ -192,7 +190,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param key keystroke received */ - @Override public void keyPressed(final KeyEvent key) { boolean alt = false; boolean shift = false; @@ -397,7 +394,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param event window event received */ - @Override public void windowActivated(final WindowEvent event) { // Force a total repaint synchronized (screen) { @@ -410,7 +406,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param event window event received */ - @Override public void windowClosed(final WindowEvent event) { // Ignore } @@ -420,7 +415,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param event window event received */ - @Override public void windowClosing(final WindowEvent event) { // Drop a cmAbort and walk away synchronized (eventQueue) { @@ -436,7 +430,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param event window event received */ - @Override public void windowDeactivated(final WindowEvent event) { // Ignore } @@ -446,7 +439,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param event window event received */ - @Override public void windowDeiconified(final WindowEvent event) { // Ignore } @@ -456,7 +448,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param event window event received */ - @Override public void windowIconified(final WindowEvent event) { // Ignore } @@ -466,7 +457,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param event window event received */ - @Override public void windowOpened(final WindowEvent event) { // Ignore } @@ -476,7 +466,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param event component event received */ - @Override public void componentHidden(final ComponentEvent event) { // Ignore } @@ -486,7 +475,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param event component event received */ - @Override public void componentShown(final ComponentEvent event) { // Ignore } @@ -496,7 +484,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param event component event received */ - @Override public void componentMoved(final ComponentEvent event) { // Ignore } @@ -506,7 +493,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param event component event received */ - @Override public void componentResized(final ComponentEvent event) { // Drop a new TResizeEvent into the queue sessionInfo.queryWindowSize(); @@ -525,7 +511,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param mouse mouse event received */ - @Override public void mouseDragged(final MouseEvent mouse) { int modifiers = mouse.getModifiersEx(); boolean eventMouse1 = false; @@ -562,7 +547,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param mouse mouse event received */ - @Override public void mouseMoved(final MouseEvent mouse) { int x = screen.textColumn(mouse.getX()); int y = screen.textRow(mouse.getY()); @@ -589,7 +573,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param mouse mouse event received */ - @Override public void mouseClicked(final MouseEvent mouse) { // Ignore } @@ -599,7 +582,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param mouse mouse event received */ - @Override public void mouseEntered(final MouseEvent mouse) { // Ignore } @@ -609,7 +591,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param mouse mouse event received */ - @Override public void mouseExited(final MouseEvent mouse) { // Ignore } @@ -619,7 +600,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param mouse mouse event received */ - @Override public void mousePressed(final MouseEvent mouse) { int modifiers = mouse.getModifiersEx(); boolean eventMouse1 = false; @@ -656,7 +636,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param mouse mouse event received */ - @Override public void mouseReleased(final MouseEvent mouse) { int modifiers = mouse.getModifiersEx(); boolean eventMouse1 = false; @@ -702,7 +681,6 @@ public final class SwingTerminal implements ComponentListener, KeyListener, * * @param mouse mouse event received */ - @Override public void mouseWheelMoved(final MouseWheelEvent mouse) { int modifiers = mouse.getModifiersEx(); boolean eventMouse1 = false; diff --git a/src/jexer/menu/TMenuItem.java b/src/jexer/menu/TMenuItem.java index 43ea8f0..e60d1d4 100644 --- a/src/jexer/menu/TMenuItem.java +++ b/src/jexer/menu/TMenuItem.java @@ -218,10 +218,10 @@ public class TMenuItem extends TWidget { getScreen().vLineXY(getWidth() - 1, 0, 1, cVSide, background); getScreen().hLineXY(1, 0, getWidth() - 2, ' ', menuColor); - getScreen().putStrXY(2, 0, mnemonic.getRawLabel(), menuColor); + getScreen().putStringXY(2, 0, mnemonic.getRawLabel(), menuColor); if (hasKey) { String keyLabel = key.toString(); - getScreen().putStrXY((getWidth() - keyLabel.length() - 2), 0, + getScreen().putStringXY((getWidth() - keyLabel.length() - 2), 0, keyLabel, menuColor); } if (mnemonic.getShortcutIdx() >= 0) { diff --git a/src/jexer/net/TelnetInputStream.java b/src/jexer/net/TelnetInputStream.java index d8164a4..fc9ad5d 100644 --- a/src/jexer/net/TelnetInputStream.java +++ b/src/jexer/net/TelnetInputStream.java @@ -414,6 +414,7 @@ public final class TelnetInputStream extends InputStream * @param option the telnet option byte * @return a string describing the telnet option code */ + @SuppressWarnings("unused") private String optionString(final int option) { switch (option) { case 0: return "Binary Transmission"; @@ -871,7 +872,6 @@ public final class TelnetInputStream extends InputStream for (int i = 2; i < subnegBuffer.size(); i++) { speedString.append((char)subnegBuffer.get(i).byteValue()); } - String termSpeed = speedString.toString(); master.terminalSpeed = speedString.toString(); } break; diff --git a/src/jexer/net/TelnetOutputStream.java b/src/jexer/net/TelnetOutputStream.java index 1bc8295..ad38cdb 100644 --- a/src/jexer/net/TelnetOutputStream.java +++ b/src/jexer/net/TelnetOutputStream.java @@ -33,6 +33,8 @@ package jexer.net; import java.io.OutputStream; import java.io.IOException; +import static jexer.net.TelnetSocket.*; + /** * TelnetOutputStream works with TelnetSocket to perform the telnet protocol. */ @@ -87,8 +89,8 @@ public final class TelnetOutputStream extends OutputStream { // The last byte sent to this.write() was a CR, which was never // actually sent. So send the CR in ascii mode, then flush. // CR -> CR NULL - output.write(master.C_CR); - output.write(master.C_NUL); + output.write(C_CR); + output.write(C_NUL); writeCR = false; } output.flush(); @@ -182,10 +184,10 @@ public final class TelnetOutputStream extends OutputStream { if (master.binaryMode == true) { - if (ch == master.TELNET_IAC) { + if (ch == TELNET_IAC) { // IAC -> IAC IAC - writeBuffer[writeBufferI++] = (byte)master.TELNET_IAC; - writeBuffer[writeBufferI++] = (byte)master.TELNET_IAC; + writeBuffer[writeBufferI++] = (byte)TELNET_IAC; + writeBuffer[writeBufferI++] = (byte)TELNET_IAC; } else { // Anything else -> just send writeBuffer[writeBufferI++] = ch; @@ -197,39 +199,39 @@ public final class TelnetOutputStream extends OutputStream { // the case that the last byte of b was a CR. // Bare carriage return -> CR NUL - if (ch == master.C_CR) { + if (ch == C_CR) { if (writeCR == true) { // Flush the previous CR to the stream. // CR -> CR NULL - writeBuffer[writeBufferI++] = (byte)master.C_CR; - writeBuffer[writeBufferI++] = (byte)master.C_NUL; + writeBuffer[writeBufferI++] = (byte)C_CR; + writeBuffer[writeBufferI++] = (byte)C_NUL; } writeCR = true; - } else if (ch == master.C_LF) { + } else if (ch == C_LF) { if (writeCR == true) { // CR LF -> CR LF - writeBuffer[writeBufferI++] = (byte)master.C_CR; - writeBuffer[writeBufferI++] = (byte)master.C_LF; + writeBuffer[writeBufferI++] = (byte)C_CR; + writeBuffer[writeBufferI++] = (byte)C_LF; writeCR = false; } else { // Bare LF -> LF writeBuffer[writeBufferI++] = ch; } - } else if (ch == master.TELNET_IAC) { + } else if (ch == TELNET_IAC) { if (writeCR == true) { // CR -> CR NULL - writeBuffer[writeBufferI++] = (byte)master.C_CR; - writeBuffer[writeBufferI++] = (byte)master.C_NUL; + writeBuffer[writeBufferI++] = (byte)C_CR; + writeBuffer[writeBufferI++] = (byte)C_NUL; writeCR = false; } // IAC -> IAC IAC - writeBuffer[writeBufferI++] = (byte)master.TELNET_IAC; - writeBuffer[writeBufferI++] = (byte)master.TELNET_IAC; + writeBuffer[writeBufferI++] = (byte)TELNET_IAC; + writeBuffer[writeBufferI++] = (byte)TELNET_IAC; } else { if (writeCR == true) { // CR -> CR NULL - writeBuffer[writeBufferI++] = (byte)master.C_CR; - writeBuffer[writeBufferI++] = (byte)master.C_NUL; + writeBuffer[writeBufferI++] = (byte)C_CR; + writeBuffer[writeBufferI++] = (byte)C_NUL; writeCR = false; } else { // Normal character */ diff --git a/src/jexer/tterminal/ECMA48.java b/src/jexer/tterminal/ECMA48.java index 0918e9b..98dbcdd 100644 --- a/src/jexer/tterminal/ECMA48.java +++ b/src/jexer/tterminal/ECMA48.java @@ -683,6 +683,7 @@ public class ECMA48 implements Runnable { * Whether number pad keys send VT100 or VT52, application or numeric * sequences. */ + @SuppressWarnings("unused") private KeypadMode keypadMode; /**