📄 terminalwindow.java
字号:
init_layout();
// Setup the fonts
Font tafont = opser.getFontOption(GlobalOptions.textfontString);
Color[] cvec = TextColorManager.getColorVec();
mainArea.setFont(tafont);
mainArea.setColorVec(cvec);
mainArea.setEditable(false);
messageArea.setFont(tafont);
messageArea.setColorVec(cvec);
messageArea.setEditable(false);
// Splatter popup menu listeners over all the components that should
// allow a popup menu.
mainArea.addMouseListener(popupControl);
messageArea.addMouseListener(popupControl);
Image icon = Ergo.loadImage("/" + Ergo.mmdir + "back.gif");
if (icon != null)
setIconImage(icon);
} // end TerminalWindow constructor
/** Tells the optionizer which options TerminalWindow would like to "own".
* Ownership usually implies that we want to be notified via optionEvent()
* when the value of the option changes. Passing null as the 3rd arg to
* expressOwnership() says we don't want to hear about such changes.
*/
private void init_options () {
try {
// eventually Notebook.
opser.expressOwnership(GlobalOptions.saveloginString,
Optionizer.TYPE_BOOLEAN, null, new Boolean(true));
opser.expressOwnership(serverString,
Optionizer.TYPE_SERVER, this, null);
opser.expressOwnership(GlobalOptions.soundString,
Optionizer.TYPE_BOOLEAN, this, new Boolean(false));
opser.expressOwnership(exitString,
Optionizer.TYPE_BOOLEAN, this, new Boolean(true));
opser.expressOwnership(widthString,
Optionizer.TYPE_INTEGER, this, new Integer(80));
opser.expressOwnership(heightString,
Optionizer.TYPE_INTEGER, this, new Integer(25));
opser.expressOwnership(mheightString,
Optionizer.TYPE_INTEGER, this, new Integer(8));
opser.expressOwnership(GlobalOptions.textfontString,
Optionizer.TYPE_FONT, this,
new FontSpec("Monospaced", "plain", "12"));
opser.expressOwnership(GlobalOptions.infofontString,
Optionizer.TYPE_FONT, this, null);
opser.expressOwnership(GlobalOptions.debugmodeString,
Optionizer.TYPE_BOOLEAN, null,
new Boolean(Debug.getDebug()));
opser.expressOwnership(GlobalOptions.debugmenuString,
Optionizer.TYPE_BOOLEAN, null,
new Boolean(Debug.getDebug()));
Object o = new PositionListener(mainposString, this, new java.awt.Point(10,10), opser);
TextColorManager.expressAll(this, 2); // currently highlight colors not required.
// get informed when options required, since we cannot get
// dimensions out of TextArea at resize time. -AMB
// What does this mean? Do you need something from TextArea? -sigue
// No, its OK - we can't really work out what text size is in TextArea
// until its finished resizing; but _we_ only get informed when we
// begin resizing. This way is better than adding extra callback to
// TextArea, IMO.. -- AMB.
opser.expressOwnership(opser.savingString,
Optionizer.TYPE_BOOLEAN, this, null);
}
catch (Exception e) { Debug.backtrace(e); }
}
/** Create and initialize all menus and menu items. Most menu items should
* be implemented as anonymous subclasses of MenuCommand.
*/
private void init_menus () {
menuBar = new urMenuBar(this);
menuListener mListen = new menuListener();
checkboxListener cListen = new checkboxListener();
// File menu
Menu fileMenu = menuBar.generate("File");
goConnectSubmenu = mListen.generateMenu(fileMenu, "Connect");
newServerItem = mListen.generateWithSep(goConnectSubmenu, "New");
disconnectItem = new MenuCommand("Disconnect", new MenuShortcut('q'))
{
public void executeCommand (Object event) {
// The connection closes automatically after "quit" is sent.
send("quit");
}
};
fileMenu.add(disconnectItem);
saveOutputItem = mListen.generate(fileMenu, "Save Terminal Output...",
new MenuShortcut('s'));
clearOutputItem = mListen.generate(fileMenu, "Clear Terminal Output...");
loadItem = mListen.generateWithSep(fileMenu, "Open Game...", new MenuShortcut('o', true));
fileMenu.add(new MenuCommand("Exit", new MenuShortcut('q', true))
{
public void executeCommand (Object event) {
exit();
}
});
// Go menu
Menu goMenu = menuBar.generate("Play");
observeItem = mListen.generate(goMenu, "Observe Game...", new MenuShortcut('o'));
matchItem = mListen.generate(goMenu, "Request Match...", new MenuShortcut('m'));
automatchItem = mListen.generate(goMenu, "Automatch");
localGameItem = mListen.generate(goMenu, "Local Game...", new MenuShortcut('l'));
// Options menu
Menu optionsMenu = menuBar.generate("Options");
soundItem = cListen.generate(optionsMenu,"Sound");
saveOptionsItem = mListen.generate(optionsMenu, "Save Options");
// Debug menu
debugMenu = new Menu("Debug");
debugItem = cListen.generate(debugMenu,"General");
logicItem = cListen.generate(debugMenu,"Game Logic");
rawItem = cListen.generate(debugMenu,"Raw Mode");
rawMode = false;
// Windows menu
windowsMenu = registrar.registerMenu(menuBar.generate("Window"), this);
// Help menu
helpMenu = new Menu("Help");
aboutItem = mListen.generate(helpMenu, "About Ergo...");
docItem = mListen.generate(helpMenu, "Browse Documentation");
menuBar.setHelpMenu(helpMenu);
soundEnabled = opser.getBooleanOption(GlobalOptions.soundString);
soundItem.setState(soundEnabled);
// Add ourselves to the Windows menu.
registrar.registerWindowsMenuCommand(this);
// Debug menu
if (opser.getBooleanOption(GlobalOptions.debugmenuString)) {
debugMenu.add(debugItem);
debugMenu.add(logicItem);
debugMenu.add(rawItem);
debugItem.setState(Debug.getDebug());
logicItem.setState(Debug.debugGameLogicp);
rawItem.setState(rawMode);
menuBar.add(debugMenu);
}
/* Disable unimplemented items. */
automatchItem.setEnabled(false);
// Disable items that don't work in an applet. Note that I
// want these items to be visible so that people can see the
// features that are available in the non-applet version.
// +++ Might be good to leave them enabled and have them pop
// up a dialog saying you have to run it as an application
// to get that feature?
if (ergo.inApplet) {
helpMenu.add(docItem);
saveOutputItem.setEnabled(false);
loadItem.setEnabled(false);
saveOptionsItem.setEnabled(false);
}
else {
// ---*** Need to lookup how to show the web page or make sounds in an application...
docItem.setEnabled(false);
soundItem.setState(false);
soundItem.setEnabled(false);
helpMenu.add(aboutItem);
}
setMenuBar(menuBar); // Add a menuBar to this Frame.
} // end method init_menus
private void init_layout () {
MosaicPanel mPanel = new MosaicPanel();
MosaicLayout mLayout = new MosaicLayout();
mPanel.setLayout(mLayout);
// Brief (bothersome) messages are displayed in the message area.
// e.g., {soandso has disconnected}
mLayout.setPos(0, 0);
mPanel.add("", messageArea);
// Most text from the server is displayed in the echo area.
mLayout.setPos(0, 1);
mPanel.add("", mainArea);
// Slight improvement to resizing behaviour - AMB at 0.12
MosaicConstraints mc = new MosaicConstraints(MosaicConstraints.CENTER,
MosaicConstraints.BOTH,
1);
mLayout.setConstraints(messageArea, mc);
mLayout.setConstraints(mainArea, mc);
setLayout(new BorderLayout());
add("Center", mPanel);
// User input goes to the inputField.
add("South", inputField);
}
/** Implement the Runnable interface.
*/
public void run () {
updateTitle();
pack();
show();
setEnabled(true);
inputField.requestFocus();
}
class GoServerMenuItem extends MenuItem implements ActionListener {
GoServer server;
GoServerMenuItem (GoServer server1) {
super(server1.toString());
server = server1;
addActionListener(this);
}
public void actionPerformed (ActionEvent ae) {
if (conn.open(server) == false)
displayString("Unable to open connection to " + server.name);
}
}
/// Implement the PopupContributor interface
public boolean allowMoreItems (Component c) { return true; }
public void populatePopupMenu (PopupMenu p, Component comp, int x, int y) {
popupHandler.populatePopup(p, comp, x, y);
}
// This class isn't strictly necessary. It's just here to encapsulate
// some popup menu code. Notably the menu items which may have the same
// names as some in the outer class.
class PopupHandler implements ActionListener {
private MenuItem who_view = new MenuItem("Who View");
private MenuItem games_view = new MenuItem("Games View");
public PopupHandler () {}
public void populatePopup (PopupMenu popup, Component comp, int x, int y) {
// ignore(comp, x, y);
popup.add(games_view);
popup.add(who_view);
}
public void actionPerformed (ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd.equals(who_view.getLabel()))
conn.send("who", false);
else if (cmd.equals(games_view.getLabel()))
conn.send("games", false);
}
} // end inner class PopupHandler
// for the Optionizable interface.
public void optionEvent (String key, Object arg) {
// can compare this with equals, it never comes from file.
if (key == opser.savingString) {
opser.updateOption(widthString, new Integer(mainArea.getColumns()));
}
else if (opser.isSameKey(key, serverString)) {
//GoServer gs = (GoServer)arg;
//goConnectSubmenu.add(new GoServerMenuItem(gs));
}
else if (opser.isSameKey(key, GlobalOptions.soundString)) {
Boolean b = (Boolean)arg;
soundEnabled = b.booleanValue();
soundItem.setState(soundEnabled);
}
else if (opser.isSameKey(key, GlobalOptions.textfontString)) {
Font f = ((FontSpec)arg).getFont();
mainArea.setFont(f);
messageArea.setFont(f);
// invalidate(); ?? pack(); ??
}
else if (TextColorManager.isColorString(key)) {
mainArea.setColorVec(TextColorManager.getColorVec());
messageArea.setColorVec(TextColorManager.getColorVec());
}
}
private void populateServers () {
try {
int cservers = opser.getOptionSize(serverString);
int key = 1;
for (int i = 0; i < cservers; ++i) {
Object o = opser.getOption(serverString, i);
if (o == null)
// Why are servers numbered in the ini file anyway? -sigue
System.out.println("Warning: Go Server numbers are not continuous in .ini file");
else {
GoServer gs = (GoServer)o;
GoServerMenuItem mi = new GoServerMenuItem(gs);
if (i <= 9)
mi.setShortcut(new MenuShortcut(KeyEvent.VK_1 + i));
goConnectSubmenu.add(mi);
}
}
}
catch (Exception e) {
System.out.println("Error finding Go Servers: " + e);
}
}
/****************************************************************
* Manage terminal output. Terminal output can be turned on/off
* in various windows (notably the Terminal View and in game
* windows). Some output that never gets sent to the terminals
* is the junk that goes to the messageArea, and kibitzes always
* go to their respective GameWindows only.
****************************************************************/
/** Vector of objects that implement the OutputFocus interface.
* No nulls allowed. */
private Vector terminals = new Vector();
/** Add another terminal output listener. */
public void addOutputFocus (OutputFocus of) {
Debug.asser(of != null, "output focus is null");
for (int i = 0; i < terminals.size(); i++) {
if (of == terminals.elementAt(i))
return;
}
terminals.addElement(of);
}
/** Remove a terminal output listener. */
public void removeOutputFocus (OutputFocus of) {
for (int i = 0; i < terminals.size(); i++) {
OutputFocus focus = (OutputFocus) terminals.elementAt(i);
if (of == focus) {
focus.noteFocusLost();
terminals.removeElementAt(i);
}
}
}
/******************************************************************
* Implement the OutputFocus interface (inherited from GoClient). *
******************************************************************/
public void displayString (String s) {
displayStringInternal(s, mainArea, true, null);
}
public void displayString (String s, Color c) {
displayStringInternal(s, mainArea, true, c);
}
/** The Terminal View always displays terminal output, so this does nothing. */
public void noteFocusLost () { }
private void displayStringInternal (String s, TextArea area,
boolean useOutputFocus, Color color) {
if (area == null)
area = mainArea;
if (color == null)
color = area.getForeground();
if (useOutputFocus) {
for (int i = 0; i < terminals.size(); i++) {
OutputFocus terminal = (OutputFocus) terminals.elementAt(i);
terminal.displayString(s, color);
}
}
// Note that output goes to BOTH the terminal outputs and the given text area.
// That's because the given area is always a component of TerminalWindow, and
// TerminalWindow always displays all terminal output.
area.appendText(s, color);
}
/********************************************
* Code to maintain a list of Game windows *
********************************************/
public void addGameWindow (GameWindow gwin) {
gameWindows.addElement(gwin);
new Thread(gwin).start();
registrar.registerWindowsMenuCommand(gwin);
if (conn.control != null)
conn.control.sgc.inform(gwin);
}
public void removeGameWindow (GameWindow gwin) {
removeOutputFocus(gwin);
gameWindows.removeElement(gwin);
registrar.deregisterWindowsMenuCommand(gwin);
if (conn.control != null)
conn.control.sgc.uninform(gwin);
gwin.commitSuicide();
}
// Adjourn all active games. For when the user disconnects from
// the server while observing.
public void adjournAll () {
for (int i = 0; i < gameWindows.size(); i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -