Rename AWT to Swing

This commit is contained in:
Kevin Lamonte 2015-03-21 19:14:34 -04:00
parent 091d8a06c7
commit a4406f4ed7
9 changed files with 188 additions and 117 deletions

View file

@ -1,7 +1,8 @@
Jexer - Java Text User Interface library
========================================
WARNING: THIS IS ALPHA CODE!
WARNING: THIS IS ALPHA CODE! PLEASE CONSIDER FILING BUGS AS YOU
ENCOUNTER THEM.
This library is intended to implement a text-based windowing system
loosely reminiscient of Borland's [Turbo
@ -16,16 +17,20 @@ Two backends are available:
(tested on Linux + xterm). I/O is handled through terminal escape
sequences generated by the library itself: ncurses is not required
or linked to. xterm mouse tracking using UTF8 coordinates is
supported. This is the default backend on non-Windows platforms.
supported. For the demo application, this is the default backend on
non-Windows platforms.
* Java AWT UI. This backend can be selected by setting
jexer.AWT=true. This is the default backend on Windows platforms.
AWT is experimental, please consider filing bugs when you encounter
them. The default window size for AWT is 132x40, which is set in
jexer.session.AWTSession.
* Java Swing UI. This backend can be selected by setting
jexer.Swing=true. The default window size for Swing is 132x40,
which is set in jexer.session.SwingSession. For the demo
application, this is the default backend on Windows platforms.
A demo application showing the existing UI controls is available via
'java -jar jexer.jar' or 'java -Djexer.AWT=true -jar jexer.jar' .
The demo application showing the existing UI controls is available via
'java -jar jexer.jar' or 'java -Djexer.Swing=true -jar jexer.jar' .
Additional backends can be created by subclassing
jexer.backend.Backend and passing it into the TApplication
constructor.
@ -55,7 +60,7 @@ Usage
-----
Usage patterns are still being worked on, but in general the goal will
be to build applications somewhat as follows:
be to build applications as follows:
```Java
import jexer.*;
@ -63,7 +68,7 @@ import jexer.*;
public class MyApplication extends TApplication {
public MyApplication() {
super();
super(BackendType.SWING); // Could also use BackendType.XTERM
// Create standard menus for File and Window
addFileMenu();
@ -72,7 +77,7 @@ public class MyApplication extends TApplication {
public static void main(String [] args) {
MyApplication app = new MyApplication();
app.run();
(new Thread(app)).start();
}
}
```
@ -100,6 +105,10 @@ ambiguous. This section describes such issues.
- See jexer.tterminal.ECMA48 for more specifics of terminal
emulation limitations.
- TTerminalWindow uses cmd.exe on Windows. Output will not be seen
until enter is pressed, due to cmd.exe's use of line-oriented
input (see the ENABLE_LINE_INPUT flag for GetConsoleMode() and
SetConsoleMode()).
@ -108,15 +117,14 @@ Roadmap
Many tasks remain before calling this version 1.0:
0.0.2:
0.0.2: STABILIZE EXISTING
- Making TMenu keyboard accelerators active/inactive
- AWT:
- TTerminalWindow
- Expose shell commands as properties
- Swing:
- Blinking cursor
- Block cursor
- ECMA48Backend running on socket
- TTreeView
- TDirectoryList
- TFileOpen
- Decide on naming convention: getText, getValue, getLabel: one or all
of them?
@ -125,36 +133,42 @@ Many tasks remain before calling this version 1.0:
- getCh() --> getChar()
- getAlt/getCtrl/getShift --> isAltDown / isCtrlDown / isShiftDown
- Other boolean getters --> isSomething
- Document any properties used
- Expose use of 'stty'
0.0.3:
0.0.3: FINISH PORTING
- TTreeView
- Also add keyboard navigation
- TDirectoryList
- Also add keyboard navigation
0.0.4: NEW STUFF
- Making TMenu keyboard accelerators active/inactive
- TStatusBar
- TEditor
0.0.4:
- Bugs
- TSubMenu keyboard mnemonic not working
- TDirectoryList cannot be navigated only with keyboard
- TTreeView cannot be navigated only with keyboard
- RangeViolation after dragging scrollbar up/down
0.1.0:
- TWindow
- "Smart placement" for new windows
0.0.5: BUG HUNT
- TSubMenu keyboard mnemonic not working
0.1.0: BETA RELEASE
- TSpinner
- TComboBox
- TListBox
- TCalendar
- TColorPicker
Wishlist features (2.0):
- TTerminal
- Handle resize events (pass to child process)
- Screen
- Allow complex characters in putCharXY() and detect them in putStrXY().
- TComboBox
- TListBox
- TSpinner
- TCalendar widget
- TColorPicker widget
- Drag and drop
- TEditor
- TField

View file

@ -35,9 +35,11 @@
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="jar.dir" value="${build.dir}/jar"/>
<property name="apidocs.dir" value="docs/api"/>
<target name="clean">
<delete dir="${build.dir}"/>
<delete dir="${apidocs.dir}"/>
</target>
<target name="compile">
@ -62,7 +64,7 @@
<target name="run" depends="jar">
<java jar="${jar.dir}/${ant.project.name}.jar" fork="true">
<arg value="-Djexer.AWT=true"/>
<arg value="-Djexer.Swing=true"/>
</java>
</target>
@ -74,7 +76,7 @@
<target name="docs" depends="jar">
<javadoc
destdir="docs/api"
destdir="${apidocs.dir}"
author="true"
version="true"
use="true"

View file

@ -51,7 +51,7 @@ import jexer.event.TMenuEvent;
import jexer.event.TMouseEvent;
import jexer.event.TResizeEvent;
import jexer.backend.Backend;
import jexer.backend.AWTBackend;
import jexer.backend.SwingBackend;
import jexer.backend.ECMA48Backend;
import jexer.io.Screen;
import jexer.menu.TMenu;
@ -61,7 +61,7 @@ import static jexer.TCommand.*;
/**
* TApplication sets up a full Text User Interface application.
*/
public class TApplication {
public class TApplication implements Runnable {
/**
* If true, emit thread stuff to System.err.
@ -73,6 +73,26 @@ public class TApplication {
*/
private static final boolean debugEvents = false;
/**
* Two backend types are available.
*/
public static enum BackendType {
/**
* A Swing JFrame.
*/
SWING,
/**
* An ECMA48 / ANSI X3.64 / XTERM style terminal.
*/
ECMA48,
/**
* Synonym for ECMA48
*/
XTERM
}
/**
* WidgetEventHandler is the main event consumer loop. There are at most
* two such threads in existence: the primary for normal case and a
@ -461,6 +481,29 @@ public class TApplication {
/**
* Public constructor.
*
* @param backendType BackendType.XTERM, BackendType.ECMA48 or
* BackendType.SWING
* @throws UnsupportedEncodingException if an exception is thrown when
* creating the InputStreamReader
*/
public TApplication(final BackendType backendType)
throws UnsupportedEncodingException {
switch (backendType) {
case SWING:
backend = new SwingBackend(this);
break;
case XTERM:
// Fall through...
case ECMA48:
backend = new ECMA48Backend(this, null, null);
}
TApplicationImpl();
}
/**
* Public constructor. The backend type will be BackendType.ECMA48.
*
* @param input an InputStream connected to the remote user, or null for
* System.in. If System.in is used, then on non-Windows systems it will
* be put in raw mode; shutdown() will (blindly!) put System.in in cooked
@ -474,26 +517,25 @@ public class TApplication {
public TApplication(final InputStream input,
final OutputStream output) throws UnsupportedEncodingException {
// AWT is the default backend on Windows unless explicitly overridden
// by jexer.AWT.
boolean useAWT = false;
if (System.getProperty("os.name").startsWith("Windows")) {
useAWT = true;
}
if (System.getProperty("jexer.AWT") != null) {
if (System.getProperty("jexer.AWT", "false").equals("true")) {
useAWT = true;
} else {
useAWT = false;
}
}
if (useAWT) {
backend = new AWTBackend(this);
} else {
backend = new ECMA48Backend(this, input, output);
TApplicationImpl();
}
/**
* Public constructor. This hook enables use with new non-Jexer
* backends.
*
* @param backend a Backend that is already ready to go.
*/
public TApplication(final Backend backend) {
this.backend = backend;
TApplicationImpl();
}
/**
* Finish construction once the backend is set.
*/
private void TApplicationImpl() {
theme = new ColorTheme();
desktopBottom = getScreen().getHeight() - 1;
fillEventQueue = new ArrayList<TInputEvent>();
@ -638,7 +680,7 @@ public class TApplication {
/**
* Run this application until it exits.
*/
public final void run() {
public void run() {
while (!quit) {
// Timeout is in milliseconds, so default timeout after 1 second
// of inactivity.

View file

@ -33,19 +33,19 @@ package jexer.backend;
import java.util.List;
import jexer.event.TInputEvent;
import jexer.io.AWTScreen;
import jexer.io.AWTTerminal;
import jexer.io.SwingScreen;
import jexer.io.SwingTerminal;
/**
* This class uses standard AWT calls to handle screen, keyboard, and mouse
* This class uses standard Swing calls to handle screen, keyboard, and mouse
* I/O.
*/
public final class AWTBackend extends Backend {
public final class SwingBackend extends Backend {
/**
* Input events are processed by this Terminal.
*/
private AWTTerminal terminal;
private SwingTerminal terminal;
/**
* Public constructor.
@ -53,13 +53,13 @@ public final class AWTBackend extends Backend {
* @param listener the object this backend needs to wake up when new
* input comes in
*/
public AWTBackend(final Object listener) {
public SwingBackend(final Object listener) {
// Create a screen
AWTScreen screen = new AWTScreen();
SwingScreen screen = new SwingScreen();
this.screen = screen;
// Create the AWT event listeners
terminal = new AWTTerminal(listener, screen);
// Create the Swing event listeners
terminal = new SwingTerminal(listener, screen);
// Hang onto the session info
this.sessionInfo = terminal.getSessionInfo();

View file

@ -446,10 +446,11 @@ class DemoApplication extends TApplication {
/**
* Public constructor.
*
* @param backendType one of the TApplication.BackendType values
* @throws Exception if TApplication can't instantiate the Backend.
*/
public DemoApplication() throws Exception {
super(null, null);
public DemoApplication(BackendType backendType) throws Exception {
super(backendType);
new DemoMainWindow(this);
// Add the menus
@ -494,8 +495,21 @@ public class Demo1 {
*/
public static void main(final String [] args) {
try {
DemoApplication app = new DemoApplication();
app.run();
// Swing is the default backend on Windows unless explicitly
// overridden by jexer.Swing.
TApplication.BackendType backendType = TApplication.BackendType.XTERM;
if (System.getProperty("os.name").startsWith("Windows")) {
backendType = TApplication.BackendType.SWING;
}
if (System.getProperty("jexer.Swing") != null) {
if (System.getProperty("jexer.Swing", "false").equals("true")) {
backendType = TApplication.BackendType.SWING;
} else {
backendType = TApplication.BackendType.XTERM;
}
}
DemoApplication app = new DemoApplication(backendType);
(new Thread(app)).start();
} catch (Exception e) {
e.printStackTrace();
}

View file

@ -32,7 +32,7 @@ package jexer.io;
import jexer.bits.Cell;
import jexer.bits.CellAttributes;
import jexer.session.AWTSessionInfo;
import jexer.session.SwingSessionInfo;
import java.awt.Color;
import java.awt.Cursor;
@ -50,9 +50,9 @@ import javax.swing.JFrame;
import javax.swing.SwingUtilities;
/**
* This Screen implementation draws to a Java AWT Frame.
* This Screen implementation draws to a Java Swing JFrame.
*/
public final class AWTScreen extends Screen {
public final class SwingScreen extends Screen {
private static Color MYBLACK;
private static Color MYRED;
@ -75,7 +75,7 @@ public final class AWTScreen extends Screen {
private static boolean dosColors = false;
/**
* Setup AWT colors to match DOS color palette.
* Setup Swing colors to match DOS color palette.
*/
private static void setDOSColors() {
if (dosColors) {
@ -102,9 +102,9 @@ public final class AWTScreen extends Screen {
}
/**
* AWTFrame is our top-level hook into the AWT system.
* SwingFrame is our top-level hook into the Swing system.
*/
class AWTFrame extends JFrame {
class SwingFrame extends JFrame {
/**
* Serializable version.
@ -119,7 +119,7 @@ public final class AWTScreen extends Screen {
/**
* The TUI Screen data.
*/
AWTScreen screen;
SwingScreen screen;
/**
* Width of a character cell.
@ -147,10 +147,10 @@ public final class AWTScreen extends Screen {
private int left = 30;
/**
* Convert a CellAttributes foreground color to an AWT Color.
* Convert a CellAttributes foreground color to an Swing Color.
*
* @param attr the text attributes
* @return the AWT Color
* @return the Swing Color
*/
private Color attrToForegroundColor(final CellAttributes attr) {
/*
@ -200,10 +200,10 @@ public final class AWTScreen extends Screen {
}
/**
* Convert a CellAttributes background color to an AWT Color.
* Convert a CellAttributes background color to an Swing Color.
*
* @param attr the text attributes
* @return the AWT Color
* @return the Swing Color
*/
private Color attrToBackgroundColor(final CellAttributes attr) {
/*
@ -237,7 +237,7 @@ public final class AWTScreen extends Screen {
*
* @param screen the Screen that Backend talks to
*/
public AWTFrame(final AWTScreen screen) {
public SwingFrame(final SwingScreen screen) {
this.screen = screen;
setDOSColors();
@ -310,7 +310,7 @@ public final class AWTScreen extends Screen {
/**
* Update redraws the whole screen.
*
* @param gr the AWT Graphics context
* @param gr the Swing Graphics context
*/
@Override
public void update(final Graphics gr) {
@ -322,7 +322,7 @@ public final class AWTScreen extends Screen {
/**
* Paint redraws the whole screen.
*
* @param gr the AWT Graphics context
* @param gr the Swing Graphics context
*/
@Override
public void paint(final Graphics gr) {
@ -420,31 +420,31 @@ public final class AWTScreen extends Screen {
} // synchronized (screen)
}
} // class AWTFrame
} // class SwingFrame
/**
* The raw AWT Frame. Note package private access.
* The raw Swing JFrame. Note package private access.
*/
AWTFrame frame;
SwingFrame frame;
/**
* Public constructor.
*/
public AWTScreen() {
public SwingScreen() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
AWTScreen.this.frame = new AWTFrame(AWTScreen.this);
AWTScreen.this.sessionInfo =
new AWTSessionInfo(AWTScreen.this.frame,
SwingScreen.this.frame = new SwingFrame(SwingScreen.this);
SwingScreen.this.sessionInfo =
new SwingSessionInfo(SwingScreen.this.frame,
frame.textWidth,
frame.textHeight);
AWTScreen.this.setDimensions(sessionInfo.getWindowWidth(),
SwingScreen.this.setDimensions(sessionInfo.getWindowWidth(),
sessionInfo.getWindowHeight());
AWTScreen.this.frame.resizeToScreen();
AWTScreen.this.frame.setVisible(true);
SwingScreen.this.frame.resizeToScreen();
SwingScreen.this.frame.setVisible(true);
}
} );
} catch (Exception e) {
@ -455,14 +455,14 @@ public final class AWTScreen extends Screen {
/**
* The sessionInfo.
*/
private AWTSessionInfo sessionInfo;
private SwingSessionInfo sessionInfo;
/**
* Create the AWTSessionInfo. Note package private access.
* Create the SwingSessionInfo. Note package private access.
*
* @return the sessionInfo
*/
AWTSessionInfo getSessionInfo() {
SwingSessionInfo getSessionInfo() {
return sessionInfo;
}

View file

@ -51,26 +51,26 @@ import jexer.event.TKeypressEvent;
import jexer.event.TMouseEvent;
import jexer.event.TResizeEvent;
import jexer.session.SessionInfo;
import jexer.session.AWTSessionInfo;
import jexer.session.SwingSessionInfo;
import static jexer.TCommand.*;
import static jexer.TKeypress.*;
/**
* This class reads keystrokes and mouse events from an AWT Frame.
* This class reads keystrokes and mouse events from an Swing JFrame.
*/
public final class AWTTerminal implements ComponentListener, KeyListener,
public final class SwingTerminal implements ComponentListener, KeyListener,
MouseListener, MouseMotionListener,
MouseWheelListener, WindowListener {
/**
* The backend Screen.
*/
private AWTScreen screen;
private SwingScreen screen;
/**
* The session information.
*/
private AWTSessionInfo sessionInfo;
private SwingSessionInfo sessionInfo;
/**
* Getter for sessionInfo.
@ -132,9 +132,9 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
*
* @param listener the object this backend needs to wake up when new
* input comes in
* @param screen the top-level AWT frame
* @param screen the top-level Swing frame
*/
public AWTTerminal(final Object listener, final AWTScreen screen) {
public SwingTerminal(final Object listener, final SwingScreen screen) {
this.listener = listener;
this.screen = screen;
mouse1 = false;
@ -176,7 +176,7 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
}
/**
* Pass AWT keystrokes into the event queue.
* Pass Swing keystrokes into the event queue.
*
* @param key keystroke received
*/
@ -186,7 +186,7 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
}
/**
* Pass AWT keystrokes into the event queue.
* Pass Swing keystrokes into the event queue.
*
* @param key keystroke received
*/
@ -196,7 +196,7 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
}
/**
* Pass AWT keystrokes into the event queue.
* Pass Swing keystrokes into the event queue.
*
* @param key keystroke received
*/
@ -217,7 +217,7 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
shift = key.isShiftDown();
/*
System.err.printf("AWT Key: %s\n", key);
System.err.printf("Swing Key: %s\n", key);
System.err.printf(" isKey: %s\n", isKey);
System.err.printf(" alt: %s\n", alt);
System.err.printf(" ctrl: %s\n", ctrl);

View file

@ -34,14 +34,14 @@ import java.awt.Frame;
import java.awt.Insets;
/**
* AWTSessionInfo provides a session implementation with a callback into an
* AWT Frame to support queryWindowSize(). The username is blank, language
* SwingSessionInfo provides a session implementation with a callback into an
* Swing Frame to support queryWindowSize(). The username is blank, language
* is "en_US", with a 132x40 text window.
*/
public final class AWTSessionInfo implements SessionInfo {
public final class SwingSessionInfo implements SessionInfo {
/**
* The AWT Frame.
* The Swing Frame.
*/
private Frame frame;
@ -132,11 +132,11 @@ public final class AWTSessionInfo implements SessionInfo {
/**
* Public constructor.
*
* @param frame the AWT Frame
* @param frame the Swing Frame
* @param textWidth the width of a cell in pixels
* @param textHeight the height of a cell in pixels
*/
public AWTSessionInfo(final Frame frame, final int textWidth,
public SwingSessionInfo(final Frame frame, final int textWidth,
final int textHeight) {
this.frame = frame;

View file

@ -38,9 +38,8 @@ import java.util.StringTokenizer;
/**
* TTYSessionInfo queries environment variables and the tty window size for
* the session information. The username is taken from
* getpwuid(geteuid()).pw_name, language is taken from LANG, and text window
* size from ioctl(TIOCGWINSIZ).
* the session information. The username is taken from user.name, language
* is taken from user.language, and text window size from 'stty size'.
*/
public final class TTYSessionInfo implements SessionInfo {