Cleaning and some optimizations
This commit is contained in:
@@ -9,6 +9,7 @@ import haus.nightmare.lib3270j.screen.ScreenBuffer;
|
||||
import haus.nightmare.j3270.ui.*;
|
||||
import haus.nightmare.j3270.ft.FileTransfer;
|
||||
import haus.nightmare.j3270.ft.FileTransferDialog;
|
||||
import haus.nightmare.j3270.config.Settings;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -182,7 +183,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
terminalPanel.setStatusBarToggleCallback(this::toggleStatusBar);
|
||||
terminalPanel.addModeChangeListener(this::syncModeMenuItems);
|
||||
|
||||
statusBar.setVisible(haus.nightmare.j3270.config.Settings.getStatusBarVisible());
|
||||
statusBar.setVisible(Settings.getStatusBarVisible());
|
||||
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
getContentPane().setBackground(Color.BLACK);
|
||||
@@ -195,10 +196,10 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
if (wordWrapItem != null) wordWrapItem.setSelected(terminalPanel.isWordWrap());
|
||||
if (aplModeItem != null) aplModeItem.setSelected(terminalPanel.isAplMode());
|
||||
if (insertModeItem != null) insertModeItem.setSelected(terminalPanel.isInsertMode());
|
||||
if (fourColorItem != null) fourColorItem.setSelected(haus.nightmare.j3270.config.Settings.getFourColorOverride());
|
||||
if (numLockItem != null) numLockItem.setSelected(haus.nightmare.j3270.config.Settings.getNumericFieldLock());
|
||||
if (autoSkipItem != null) autoSkipItem.setSelected(haus.nightmare.j3270.config.Settings.getAutoSkipEnabled());
|
||||
if (insertOffAidItem != null) insertOffAidItem.setSelected(haus.nightmare.j3270.config.Settings.getInsertOffOnAid());
|
||||
if (fourColorItem != null) fourColorItem.setSelected(Settings.getFourColorOverride());
|
||||
if (numLockItem != null) numLockItem.setSelected(Settings.getNumericFieldLock());
|
||||
if (autoSkipItem != null) autoSkipItem.setSelected(Settings.getAutoSkipEnabled());
|
||||
if (insertOffAidItem != null) insertOffAidItem.setSelected(Settings.getInsertOffOnAid());
|
||||
}
|
||||
|
||||
private void onThemeChanged(UITheme theme) {
|
||||
@@ -302,7 +303,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
JRadioButtonMenuItem darkThemeItem = new JRadioButtonMenuItem("Dark Mode", ThemeManager.isDark());
|
||||
ThemeManager.styleMenuItem(darkThemeItem);
|
||||
darkThemeItem.addActionListener(e -> {
|
||||
haus.nightmare.j3270.config.Settings.setJavaUiTheme(UITheme.DARK);
|
||||
Settings.setJavaUiTheme(UITheme.DARK);
|
||||
ThemeManager.setTheme(UITheme.DARK);
|
||||
});
|
||||
themeGroup.add(darkThemeItem);
|
||||
@@ -311,7 +312,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
JRadioButtonMenuItem lightThemeItem = new JRadioButtonMenuItem("Light Mode", ThemeManager.isLight());
|
||||
ThemeManager.styleMenuItem(lightThemeItem);
|
||||
lightThemeItem.addActionListener(e -> {
|
||||
haus.nightmare.j3270.config.Settings.setJavaUiTheme(UITheme.LIGHT);
|
||||
Settings.setJavaUiTheme(UITheme.LIGHT);
|
||||
ThemeManager.setTheme(UITheme.LIGHT);
|
||||
});
|
||||
themeGroup.add(lightThemeItem);
|
||||
@@ -320,7 +321,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
viewMenu.add(themeMenu);
|
||||
viewMenu.addSeparator();
|
||||
|
||||
statusBarItem = new JCheckBoxMenuItem("Status Bar", statusBar != null ? statusBar.isVisible() : haus.nightmare.j3270.config.Settings.getStatusBarVisible());
|
||||
statusBarItem = new JCheckBoxMenuItem("Status Bar", statusBar != null ? statusBar.isVisible() : Settings.getStatusBarVisible());
|
||||
ThemeManager.styleMenuItem(statusBarItem);
|
||||
statusBarItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.ALT_DOWN_MASK));
|
||||
statusBarItem.addActionListener(e -> setStatusBarVisible(statusBarItem.isSelected()));
|
||||
@@ -332,7 +333,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
rulerItem.addActionListener(e -> {
|
||||
boolean en = rulerItem.isSelected();
|
||||
terminalPanel.setCrosshairRulerEnabled(en);
|
||||
haus.nightmare.j3270.config.Settings.setCrosshairRuler(en);
|
||||
Settings.setCrosshairRuler(en);
|
||||
});
|
||||
viewMenu.add(rulerItem);
|
||||
|
||||
@@ -342,7 +343,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
ThemeManager.styleMenuItem(blockCursorItem);
|
||||
blockCursorItem.addActionListener(e -> {
|
||||
terminalPanel.setCursorStyle(TerminalPanel.CursorStyle.BLOCK);
|
||||
haus.nightmare.j3270.config.Settings.setCursorStyle("BLOCK");
|
||||
Settings.setCursorStyle("BLOCK");
|
||||
});
|
||||
cursorGroup.add(blockCursorItem);
|
||||
cursorMenu.add(blockCursorItem);
|
||||
@@ -351,7 +352,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
ThemeManager.styleMenuItem(underlineCursorItem);
|
||||
underlineCursorItem.addActionListener(e -> {
|
||||
terminalPanel.setCursorStyle(TerminalPanel.CursorStyle.UNDERLINE);
|
||||
haus.nightmare.j3270.config.Settings.setCursorStyle("UNDERLINE");
|
||||
Settings.setCursorStyle("UNDERLINE");
|
||||
});
|
||||
cursorGroup.add(underlineCursorItem);
|
||||
cursorMenu.add(underlineCursorItem);
|
||||
@@ -436,34 +437,34 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
|
||||
modesMenu.addSeparator();
|
||||
|
||||
fourColorItem = new JCheckBoxMenuItem("Base 4-Color Override", haus.nightmare.j3270.config.Settings.getFourColorOverride());
|
||||
fourColorItem = new JCheckBoxMenuItem("Base 4-Color Override", Settings.getFourColorOverride());
|
||||
ThemeManager.styleMenuItem(fourColorItem);
|
||||
fourColorItem.addActionListener(e -> {
|
||||
haus.nightmare.j3270.config.Settings.setFourColorOverride(fourColorItem.isSelected());
|
||||
Settings.setFourColorOverride(fourColorItem.isSelected());
|
||||
terminalPanel.repaint();
|
||||
});
|
||||
modesMenu.add(fourColorItem);
|
||||
|
||||
numLockItem = new JCheckBoxMenuItem("Numeric Field Lock", haus.nightmare.j3270.config.Settings.getNumericFieldLock());
|
||||
numLockItem = new JCheckBoxMenuItem("Numeric Field Lock", Settings.getNumericFieldLock());
|
||||
ThemeManager.styleMenuItem(numLockItem);
|
||||
numLockItem.addActionListener(e -> {
|
||||
haus.nightmare.j3270.config.Settings.setNumericFieldLock(numLockItem.isSelected());
|
||||
Settings.setNumericFieldLock(numLockItem.isSelected());
|
||||
terminalPanel.applyModeSettings();
|
||||
});
|
||||
modesMenu.add(numLockItem);
|
||||
|
||||
autoSkipItem = new JCheckBoxMenuItem("Auto-Skip Across Fields", haus.nightmare.j3270.config.Settings.getAutoSkipEnabled());
|
||||
autoSkipItem = new JCheckBoxMenuItem("Auto-Skip Across Fields", Settings.getAutoSkipEnabled());
|
||||
ThemeManager.styleMenuItem(autoSkipItem);
|
||||
autoSkipItem.addActionListener(e -> {
|
||||
haus.nightmare.j3270.config.Settings.setAutoSkipEnabled(autoSkipItem.isSelected());
|
||||
Settings.setAutoSkipEnabled(autoSkipItem.isSelected());
|
||||
terminalPanel.applyModeSettings();
|
||||
});
|
||||
modesMenu.add(autoSkipItem);
|
||||
|
||||
insertOffAidItem = new JCheckBoxMenuItem("Reset Insert on AID Key", haus.nightmare.j3270.config.Settings.getInsertOffOnAid());
|
||||
insertOffAidItem = new JCheckBoxMenuItem("Reset Insert on AID Key", Settings.getInsertOffOnAid());
|
||||
ThemeManager.styleMenuItem(insertOffAidItem);
|
||||
insertOffAidItem.addActionListener(e -> {
|
||||
haus.nightmare.j3270.config.Settings.setInsertOffOnAid(insertOffAidItem.isSelected());
|
||||
Settings.setInsertOffOnAid(insertOffAidItem.isSelected());
|
||||
terminalPanel.applyModeSettings();
|
||||
});
|
||||
modesMenu.add(insertOffAidItem);
|
||||
@@ -561,13 +562,15 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
|
||||
// ========== Dialog Openers ==========
|
||||
|
||||
private void showFindDialog() {
|
||||
public void showFindDialog() {
|
||||
if (client == null) {
|
||||
JOptionPane.showMessageDialog(this, "Connect to a host before using Find.", "Not Connected", JOptionPane.WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
if (findDialog == null) {
|
||||
findDialog = new FindDialog(this, client, terminalPanel);
|
||||
} else {
|
||||
findDialog.setClient(client);
|
||||
}
|
||||
findDialog.setVisible(true);
|
||||
}
|
||||
@@ -620,13 +623,15 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
}
|
||||
}
|
||||
|
||||
private void showScriptDialog() {
|
||||
public void showScriptDialog() {
|
||||
if (client == null) {
|
||||
JOptionPane.showMessageDialog(this, "Connect to a host before running scripts.", "Not Connected", JOptionPane.WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
if (scriptDialog == null) {
|
||||
scriptDialog = new ScriptDialog(this, client, terminalPanel);
|
||||
} else {
|
||||
scriptDialog.setClient(client);
|
||||
}
|
||||
scriptDialog.setVisible(true);
|
||||
}
|
||||
@@ -707,7 +712,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
terminalPanel.refreshScreen();
|
||||
statusBar.updateStatus();
|
||||
}
|
||||
haus.nightmare.j3270.config.Settings.setCodePage(cpId);
|
||||
Settings.setCodePage(cpId);
|
||||
}
|
||||
|
||||
private void changeGraphicsMode(GraphicsMode mode) {
|
||||
@@ -715,7 +720,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
client.getDataStreamProcessor().getQueryReplyBuilder().setGraphicsMode(mode);
|
||||
terminalPanel.repaint();
|
||||
}
|
||||
haus.nightmare.j3270.config.Settings.setGraphicsMode(mode);
|
||||
Settings.setGraphicsMode(mode);
|
||||
}
|
||||
|
||||
private void printScreen() {
|
||||
@@ -814,15 +819,15 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
}
|
||||
|
||||
ConnectDialog dialog = new ConnectDialog(this);
|
||||
String initialHost = lastHost != null && !lastHost.isEmpty() ? lastHost : haus.nightmare.j3270.config.Settings.getAutoConnectHost();
|
||||
int initialPort = lastPort > 0 ? lastPort : haus.nightmare.j3270.config.Settings.getAutoConnectPort();
|
||||
String initialHost = lastHost != null && !lastHost.isEmpty() ? lastHost : Settings.getAutoConnectHost();
|
||||
int initialPort = lastPort > 0 ? lastPort : Settings.getAutoConnectPort();
|
||||
dialog.setInitialHost(initialHost);
|
||||
dialog.setInitialPort(initialPort);
|
||||
dialog.setInitialTls(haus.nightmare.j3270.config.Settings.getAutoConnectTls());
|
||||
dialog.setInitialVerifyCert(haus.nightmare.j3270.config.Settings.getAutoConnectVerifyCert());
|
||||
dialog.setInitialCodePage(haus.nightmare.j3270.config.Settings.getCodePage());
|
||||
dialog.setInitialGraphicsMode(haus.nightmare.j3270.config.Settings.getGraphicsMode());
|
||||
dialog.setInitialHostType(haus.nightmare.j3270.config.Settings.getDefaultHostType());
|
||||
dialog.setInitialTls(Settings.getAutoConnectTls());
|
||||
dialog.setInitialVerifyCert(Settings.getAutoConnectVerifyCert());
|
||||
dialog.setInitialCodePage(Settings.getCodePage());
|
||||
dialog.setInitialGraphicsMode(Settings.getGraphicsMode());
|
||||
dialog.setInitialHostType(Settings.getDefaultHostType());
|
||||
dialog.setVisible(true);
|
||||
|
||||
if (dialog.isConfirmed()) {
|
||||
@@ -835,7 +840,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
|
||||
public void setConnectionHostType(haus.nightmare.lib3270j.ft.FTConfig.HostType ht) {
|
||||
if (ht == null) return;
|
||||
haus.nightmare.j3270.config.Settings.setDefaultHostType(ht.name());
|
||||
Settings.setDefaultHostType(ht.name());
|
||||
if (client != null && client.getConfig() != null) {
|
||||
client.getConfig().setFtHostType(ht);
|
||||
String profileId = client.getConfig().getSavedProfileId();
|
||||
@@ -857,7 +862,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
if (client != null && client.getConfig() != null) {
|
||||
currentHt = client.getConfig().getFtHostType();
|
||||
} else {
|
||||
String def = haus.nightmare.j3270.config.Settings.getDefaultHostType();
|
||||
String def = Settings.getDefaultHostType();
|
||||
try {
|
||||
if (def != null) currentHt = haus.nightmare.lib3270j.ft.FTConfig.HostType.valueOf(def.trim().toUpperCase());
|
||||
} catch (Exception ignored) {}
|
||||
@@ -905,6 +910,18 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
if (refreshTimer != null) {
|
||||
refreshTimer.stop();
|
||||
}
|
||||
if (findDialog != null) {
|
||||
findDialog.dispose();
|
||||
findDialog = null;
|
||||
}
|
||||
if (scriptDialog != null) {
|
||||
scriptDialog.dispose();
|
||||
scriptDialog = null;
|
||||
}
|
||||
if (fieldInspectorDialog != null) {
|
||||
fieldInspectorDialog.dispose();
|
||||
fieldInspectorDialog = null;
|
||||
}
|
||||
if (printerSessionDialog != null) {
|
||||
printerSessionDialog.dispose();
|
||||
}
|
||||
@@ -985,6 +1002,18 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
return statusBar;
|
||||
}
|
||||
|
||||
public FindDialog getFindDialog() {
|
||||
return findDialog;
|
||||
}
|
||||
|
||||
public ScriptDialog getScriptDialog() {
|
||||
return scriptDialog;
|
||||
}
|
||||
|
||||
public FieldInspectorDialog getFieldInspectorDialog() {
|
||||
return fieldInspectorDialog;
|
||||
}
|
||||
|
||||
public void connect(ConnectionConfig config) {
|
||||
connect(config, true);
|
||||
}
|
||||
@@ -1004,19 +1033,19 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
lastHost = config.getHost();
|
||||
lastPort = config.getPort();
|
||||
|
||||
haus.nightmare.j3270.config.Settings.setAutoConnectHost(config.getHost());
|
||||
haus.nightmare.j3270.config.Settings.setAutoConnectPort(config.getPort());
|
||||
haus.nightmare.j3270.config.Settings.setAutoConnectTls(config.isUseTls());
|
||||
haus.nightmare.j3270.config.Settings.setAutoConnectVerifyCert(config.isTlsVerifyCert());
|
||||
haus.nightmare.j3270.config.Settings.setCodePage(config.getCodePage());
|
||||
Settings.setAutoConnectHost(config.getHost());
|
||||
Settings.setAutoConnectPort(config.getPort());
|
||||
Settings.setAutoConnectTls(config.isUseTls());
|
||||
Settings.setAutoConnectVerifyCert(config.isTlsVerifyCert());
|
||||
Settings.setCodePage(config.getCodePage());
|
||||
if (config.getHostType() != null) {
|
||||
haus.nightmare.j3270.config.Settings.setDefaultHostType(config.getHostType());
|
||||
Settings.setDefaultHostType(config.getHostType());
|
||||
}
|
||||
if (FileTransferDialog.getLastTransferState() != null && config.isSavedConnection()) {
|
||||
FileTransferDialog.getLastTransferState().hostType = config.getFtHostType();
|
||||
}
|
||||
if (config.getGraphicsMode() != null) {
|
||||
haus.nightmare.j3270.config.Settings.setGraphicsMode(config.getGraphicsMode());
|
||||
Settings.setGraphicsMode(config.getGraphicsMode());
|
||||
}
|
||||
|
||||
Telnet3270Client oldClient = client;
|
||||
@@ -1045,6 +1074,15 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
|
||||
terminalPanel.setClient(client);
|
||||
statusBar.setClient(client, terminalPanel);
|
||||
if (findDialog != null) {
|
||||
findDialog.setClient(client);
|
||||
}
|
||||
if (scriptDialog != null) {
|
||||
scriptDialog.setClient(client);
|
||||
}
|
||||
if (fieldInspectorDialog != null) {
|
||||
fieldInspectorDialog.setClient(client);
|
||||
}
|
||||
|
||||
String tlsIndicator = config.isUseTls() ? (config.isTlsVerifyCert() ? " [TLS]" : " [TLS/Unverified]") : "";
|
||||
setTitle("j3270 — " + config.getHost() + ":" + config.getPort() + tlsIndicator);
|
||||
@@ -1101,6 +1139,15 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
client = null;
|
||||
c.removeConnectionListener(this);
|
||||
c.removeScreenUpdateListener(this);
|
||||
if (findDialog != null) {
|
||||
findDialog.setClient(null);
|
||||
}
|
||||
if (scriptDialog != null) {
|
||||
scriptDialog.setClient(null);
|
||||
}
|
||||
if (fieldInspectorDialog != null) {
|
||||
fieldInspectorDialog.setClient(null);
|
||||
}
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
@@ -1142,7 +1189,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
if (statusBar != null) {
|
||||
statusBar.setVisible(visible);
|
||||
}
|
||||
haus.nightmare.j3270.config.Settings.setStatusBarVisible(visible);
|
||||
Settings.setStatusBarVisible(visible);
|
||||
if (statusBarItem != null) {
|
||||
statusBarItem.setSelected(visible);
|
||||
}
|
||||
@@ -1203,6 +1250,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
if (screenUpdatePending.compareAndSet(false, true)) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
screenUpdatePending.set(false);
|
||||
terminalPanel.onScreenUpdated();
|
||||
if (fileTransfer != null) {
|
||||
fileTransfer.onScreenUpdated();
|
||||
}
|
||||
@@ -1224,6 +1272,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
@Override
|
||||
public void onScreenSizeChanged(int rows, int cols) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
terminalPanel.onScreenSizeChanged(rows, cols);
|
||||
terminalPanel.revalidate();
|
||||
terminalPanel.repaint();
|
||||
statusBar.updateStatus();
|
||||
@@ -1504,7 +1553,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
|
||||
if (configFile != null) {
|
||||
try {
|
||||
haus.nightmare.j3270.config.Settings.loadFromIniFile(configFile);
|
||||
Settings.loadFromIniFile(configFile);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to load config file: " + configFile);
|
||||
System.err.println(e.getMessage());
|
||||
@@ -1517,8 +1566,8 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
} catch (Exception e) {
|
||||
log.fine("Could not set system look and feel");
|
||||
}
|
||||
ThemeManager.applyUIManagerDefaults(haus.nightmare.j3270.config.Settings.getJavaUiTheme());
|
||||
ThemeManager.setTheme(haus.nightmare.j3270.config.Settings.getJavaUiTheme());
|
||||
ThemeManager.applyUIManagerDefaults(Settings.getJavaUiTheme());
|
||||
ThemeManager.setTheme(Settings.getJavaUiTheme());
|
||||
|
||||
System.setProperty("apple.laf.useScreenMenuBar", "true");
|
||||
System.setProperty("apple.awt.application.name", "j3270");
|
||||
@@ -1590,12 +1639,12 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
if (finalAutoSysUnlock != null) {
|
||||
config.setAutoSysUnlock(finalAutoSysUnlock);
|
||||
} else {
|
||||
config.setAutoSysUnlock(haus.nightmare.j3270.config.Settings.getAutoSysUnlock());
|
||||
config.setAutoSysUnlock(Settings.getAutoSysUnlock());
|
||||
}
|
||||
if (finalGraphicsMode != null) {
|
||||
config.setGraphicsMode(finalGraphicsMode);
|
||||
} else {
|
||||
config.setGraphicsMode(haus.nightmare.j3270.config.Settings.getGraphicsMode());
|
||||
config.setGraphicsMode(Settings.getGraphicsMode());
|
||||
}
|
||||
if (finalProxyUrl != null) {
|
||||
applyProxyUrl(config, finalProxyUrl);
|
||||
@@ -1603,11 +1652,11 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
if (finalHostType != null) {
|
||||
config.setHostType(finalHostType);
|
||||
} else {
|
||||
config.setHostType(haus.nightmare.j3270.config.Settings.getDefaultHostType());
|
||||
config.setHostType(Settings.getDefaultHostType());
|
||||
}
|
||||
app.connect(config);
|
||||
} else {
|
||||
haus.nightmare.j3270.config.Settings.StartupBehavior behavior = haus.nightmare.j3270.config.Settings
|
||||
Settings.StartupBehavior behavior = Settings
|
||||
.getStartupBehavior();
|
||||
switch (behavior) {
|
||||
case SHOW_CONNECT:
|
||||
@@ -1626,22 +1675,22 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
if (finalProxyUrl != null) applyProxyUrl(config, finalProxyUrl);
|
||||
app.connect(config);
|
||||
} else {
|
||||
String host = haus.nightmare.j3270.config.Settings.getAutoConnectHost();
|
||||
int port = haus.nightmare.j3270.config.Settings.getAutoConnectPort();
|
||||
boolean tls = haus.nightmare.j3270.config.Settings.getAutoConnectTls();
|
||||
boolean verify = haus.nightmare.j3270.config.Settings.getAutoConnectVerifyCert();
|
||||
boolean tn3270e = haus.nightmare.j3270.config.Settings.getAutoConnectTn3270e();
|
||||
String host = Settings.getAutoConnectHost();
|
||||
int port = Settings.getAutoConnectPort();
|
||||
boolean tls = Settings.getAutoConnectTls();
|
||||
boolean verify = Settings.getAutoConnectVerifyCert();
|
||||
boolean tn3270e = Settings.getAutoConnectTn3270e();
|
||||
if (host != null && !host.isEmpty()) {
|
||||
ConnectionConfig config = new ConnectionConfig(host, port, TerminalModel.IBM_3279_4, tls);
|
||||
config.setTlsVerifyCert(verify);
|
||||
config.setTn3270eEnabled(finalTn3270e != null ? finalTn3270e : tn3270e);
|
||||
config.setAutoReconnect(haus.nightmare.j3270.config.Settings.getAutoConnectAutoReconnect());
|
||||
config.setReconnectMaxRetries(haus.nightmare.j3270.config.Settings.getAutoConnectReconnectMaxRetries());
|
||||
config.setAutoSysUnlock(finalAutoSysUnlock != null ? finalAutoSysUnlock : haus.nightmare.j3270.config.Settings.getAutoSysUnlock());
|
||||
config.setAutoReconnect(Settings.getAutoConnectAutoReconnect());
|
||||
config.setReconnectMaxRetries(Settings.getAutoConnectReconnectMaxRetries());
|
||||
config.setAutoSysUnlock(finalAutoSysUnlock != null ? finalAutoSysUnlock : Settings.getAutoSysUnlock());
|
||||
if (finalGraphicsMode != null) {
|
||||
config.setGraphicsMode(finalGraphicsMode);
|
||||
} else {
|
||||
config.setGraphicsMode(haus.nightmare.j3270.config.Settings.getGraphicsMode());
|
||||
config.setGraphicsMode(Settings.getGraphicsMode());
|
||||
}
|
||||
if (finalProxyUrl != null) {
|
||||
applyProxyUrl(config, finalProxyUrl);
|
||||
@@ -1649,7 +1698,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate
|
||||
if (finalHostType != null) {
|
||||
config.setHostType(finalHostType);
|
||||
} else {
|
||||
config.setHostType(haus.nightmare.j3270.config.Settings.getDefaultHostType());
|
||||
config.setHostType(Settings.getDefaultHostType());
|
||||
}
|
||||
app.connect(config);
|
||||
} else {
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.List;
|
||||
*/
|
||||
public class FieldInspectorDialog extends JDialog implements ScreenUpdateListener {
|
||||
|
||||
private final Telnet3270Client client;
|
||||
private Telnet3270Client client;
|
||||
private final TerminalPanel terminalPanel;
|
||||
|
||||
private DefaultTableModel tableModel;
|
||||
@@ -46,13 +46,39 @@ public class FieldInspectorDialog extends JDialog implements ScreenUpdateListene
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
if (client != null) {
|
||||
// Screen update listener removed on close
|
||||
if (FieldInspectorDialog.this.client != null) {
|
||||
FieldInspectorDialog.this.client.removeScreenUpdateListener(FieldInspectorDialog.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setClient(Telnet3270Client newClient) {
|
||||
if (this.client != null) {
|
||||
this.client.removeScreenUpdateListener(this);
|
||||
}
|
||||
this.client = newClient;
|
||||
if (this.client != null) {
|
||||
this.client.addScreenUpdateListener(this);
|
||||
refreshFields();
|
||||
} else if (tableModel != null && countLabel != null) {
|
||||
tableModel.setRowCount(0);
|
||||
countLabel.setText("Not connected");
|
||||
}
|
||||
}
|
||||
|
||||
public Telnet3270Client getClient() {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (client != null) {
|
||||
client.removeScreenUpdateListener(this);
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private void buildUI() {
|
||||
JPanel mainPanel = new JPanel(new BorderLayout(8, 8));
|
||||
mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.awt.event.KeyEvent;
|
||||
*/
|
||||
public class FindDialog extends JDialog {
|
||||
|
||||
private final Telnet3270Client client;
|
||||
private Telnet3270Client client;
|
||||
private final TerminalPanel terminalPanel;
|
||||
|
||||
private JTextField searchField;
|
||||
@@ -40,6 +40,24 @@ public class FindDialog extends JDialog {
|
||||
setResizable(false);
|
||||
}
|
||||
|
||||
public void setClient(Telnet3270Client client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public Telnet3270Client getClient() {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
public void setSearchText(String text) {
|
||||
if (searchField != null) {
|
||||
searchField.setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
public String getSearchText() {
|
||||
return searchField != null ? searchField.getText() : "";
|
||||
}
|
||||
|
||||
private void buildUI() {
|
||||
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
|
||||
mainPanel.setBorder(new EmptyBorder(12, 14, 12, 14));
|
||||
|
||||
@@ -143,6 +143,9 @@ public class HotspotEngine {
|
||||
private int cachedRows = 0;
|
||||
private int cachedCols = 0;
|
||||
private List<Hotspot> cachedHotspots = Collections.emptyList();
|
||||
private ScreenBuffer lastScreenBuffer;
|
||||
private long lastSnapshotVersion = -1;
|
||||
private long scanCount = 0;
|
||||
|
||||
public HotspotEngine() {
|
||||
}
|
||||
@@ -174,9 +177,19 @@ public class HotspotEngine {
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
public void invalidateCache() {
|
||||
public synchronized void invalidateCache() {
|
||||
cachedScreenText = "";
|
||||
cachedHotspots = Collections.emptyList();
|
||||
lastScreenBuffer = null;
|
||||
lastSnapshotVersion = -1;
|
||||
}
|
||||
|
||||
public synchronized void markDirty() {
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
public synchronized long getScanCount() {
|
||||
return scanCount;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,6 +199,13 @@ public class HotspotEngine {
|
||||
if (sb == null) return Collections.emptyList();
|
||||
int rows = sb.getDisplayRows();
|
||||
int cols = sb.getDisplayCols();
|
||||
long version = sb.getSnapshotVersion();
|
||||
|
||||
if (sb == lastScreenBuffer && version == lastSnapshotVersion && rows == cachedRows && cols == cachedCols) {
|
||||
return cachedHotspots;
|
||||
}
|
||||
|
||||
scanCount++;
|
||||
|
||||
// Build plain text representation
|
||||
StringBuilder fullText = new StringBuilder(rows * (cols + 1));
|
||||
@@ -204,7 +224,10 @@ public class HotspotEngine {
|
||||
}
|
||||
}
|
||||
|
||||
return scanText(fullText.toString(), rows, cols);
|
||||
List<Hotspot> results = scanText(fullText.toString(), rows, cols);
|
||||
lastScreenBuffer = sb;
|
||||
lastSnapshotVersion = version;
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.nio.charset.StandardCharsets;
|
||||
*/
|
||||
public class ScriptDialog extends JDialog {
|
||||
|
||||
private final Telnet3270Client client;
|
||||
private Telnet3270Client client;
|
||||
private final TerminalPanel terminalPanel;
|
||||
|
||||
private JTextArea scriptArea;
|
||||
@@ -32,6 +32,24 @@ public class ScriptDialog extends JDialog {
|
||||
setLocationRelativeTo(parent);
|
||||
}
|
||||
|
||||
public void setClient(Telnet3270Client client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public Telnet3270Client getClient() {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
public void setScriptText(String text) {
|
||||
if (scriptArea != null) {
|
||||
scriptArea.setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
public String getScriptText() {
|
||||
return scriptArea != null ? scriptArea.getText() : "";
|
||||
}
|
||||
|
||||
private void buildUI() {
|
||||
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
|
||||
mainPanel.setBorder(new EmptyBorder(12, 14, 12, 14));
|
||||
|
||||
@@ -64,6 +64,8 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
CHAR_STRINGS[i] = String.valueOf((char) i);
|
||||
}
|
||||
}
|
||||
// Reusable single-character buffer for drawing non-ASCII cells (Phase 27.4 / T1-A)
|
||||
private final char[] charScratch = new char[1];
|
||||
public enum CursorStyle {
|
||||
BLOCK,
|
||||
UNDERLINE
|
||||
@@ -110,10 +112,14 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
// ========== Phase 25: Hotspots & Mouse Wheel ==========
|
||||
private final HotspotEngine hotspotEngine = new HotspotEngine();
|
||||
private HotspotEngine.Hotspot hoveredHotspot = null;
|
||||
private static final Color HOTSPOT_HOVER_COLOR = new Color(0, 220, 255);
|
||||
private static final Stroke HOTSPOT_HOVER_STROKE = new BasicStroke(2.0f);
|
||||
private boolean hotspotsEnabled = haus.nightmare.j3270.config.Settings.getHotspotsEnabled();
|
||||
private boolean mouseWheelEnabled = haus.nightmare.j3270.config.Settings.getMouseWheelEnabled();
|
||||
private String mouseWheelUpAction = haus.nightmare.j3270.config.Settings.getMouseWheelUpKey();
|
||||
private String mouseWheelDownAction = haus.nightmare.j3270.config.Settings.getMouseWheelDownKey();
|
||||
private boolean hotspotsDirty = true;
|
||||
private boolean[] selectedCellsScratch = new boolean[0];
|
||||
|
||||
// ========== Mode and Listener State ==========
|
||||
private boolean insertMode = false;
|
||||
@@ -400,7 +406,10 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
int col = (e.getX() - ox) / cellWidth;
|
||||
int row = (e.getY() - oy) / cellHeight;
|
||||
if (row >= 0 && row < rows && col >= 0 && col < cols) {
|
||||
hotspotEngine.scan(sb);
|
||||
if (hotspotsDirty) {
|
||||
hotspotEngine.scan(sb);
|
||||
hotspotsDirty = false;
|
||||
}
|
||||
HotspotEngine.Hotspot h = hotspotEngine.findHotspot(row, col);
|
||||
if (h != null) {
|
||||
if (hoveredHotspot != h) {
|
||||
@@ -515,6 +524,10 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
|
||||
// Phase 25.2: Interactive Hotspot click execution (URLs, PF keys, choices)
|
||||
if (hotspotsEnabled && client.getConnectionState().isFullSession()) {
|
||||
if (hotspotsDirty) {
|
||||
hotspotEngine.scan(sb);
|
||||
hotspotsDirty = false;
|
||||
}
|
||||
HotspotEngine.Hotspot h = hotspotEngine.findHotspot(row, col);
|
||||
if (h != null) {
|
||||
if (h.getType() == HotspotEngine.HotspotType.URL) {
|
||||
@@ -1054,7 +1067,7 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
popup.show(this, e.getX(), e.getY());
|
||||
}
|
||||
|
||||
private boolean isCellSelected(int row, int col) {
|
||||
public boolean isCellSelected(int row, int col) {
|
||||
if (!hasSelection()) return false;
|
||||
|
||||
int r1 = Math.min(selectionStartRow, selectionEndRow);
|
||||
@@ -1066,7 +1079,7 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
return row >= r1 && row <= r2 && col >= c1 && col <= c2;
|
||||
} else {
|
||||
int cols = 80;
|
||||
if (client != null) cols = client.getScreenBuffer().getCols();
|
||||
if (client != null && client.getScreenBuffer() != null) cols = client.getScreenBuffer().getDisplayCols();
|
||||
int addr = row * cols + col;
|
||||
int startAddr, endAddr;
|
||||
if (selectionStartRow < selectionEndRow ||
|
||||
@@ -1081,6 +1094,51 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
}
|
||||
}
|
||||
|
||||
public void precomputeSelectionScratch(int rows, int cols) {
|
||||
int totalCells = rows * cols;
|
||||
if (selectedCellsScratch == null || selectedCellsScratch.length < totalCells) {
|
||||
selectedCellsScratch = new boolean[totalCells];
|
||||
}
|
||||
java.util.Arrays.fill(selectedCellsScratch, 0, totalCells, false);
|
||||
if (hasSelection()) {
|
||||
int r1 = Math.min(selectionStartRow, selectionEndRow);
|
||||
int r2 = Math.max(selectionStartRow, selectionEndRow);
|
||||
if (blockSelectMode || trimRectSizingHandles) {
|
||||
int c1 = Math.min(selectionStartCol, selectionEndCol);
|
||||
int c2 = Math.max(selectionStartCol, selectionEndCol);
|
||||
int minR = Math.max(0, r1);
|
||||
int maxR = Math.min(rows - 1, r2);
|
||||
int minC = Math.max(0, c1);
|
||||
int maxC = Math.min(cols - 1, c2);
|
||||
if (minC <= maxC) {
|
||||
for (int r = minR; r <= maxR; r++) {
|
||||
int rowBase = r * cols;
|
||||
java.util.Arrays.fill(selectedCellsScratch, rowBase + minC, rowBase + maxC + 1, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int startAddr, endAddr;
|
||||
if (selectionStartRow < selectionEndRow ||
|
||||
(selectionStartRow == selectionEndRow && selectionStartCol <= selectionEndCol)) {
|
||||
startAddr = selectionStartRow * cols + selectionStartCol;
|
||||
endAddr = selectionEndRow * cols + selectionEndCol;
|
||||
} else {
|
||||
startAddr = selectionEndRow * cols + selectionEndCol;
|
||||
endAddr = selectionStartRow * cols + selectionStartCol;
|
||||
}
|
||||
int s = Math.max(0, startAddr);
|
||||
int e = Math.min(totalCells - 1, endAddr);
|
||||
if (s <= e) {
|
||||
java.util.Arrays.fill(selectedCellsScratch, s, e + 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean[] getSelectedCellsScratch() {
|
||||
return selectedCellsScratch;
|
||||
}
|
||||
|
||||
|
||||
public void packForModel(int modelRows, int modelCols) {
|
||||
if (isDisplayable() && !SwingUtilities.isEventDispatchThread()) {
|
||||
@@ -1687,6 +1745,7 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
}
|
||||
|
||||
public void applyModeSettings() {
|
||||
hotspotsDirty = true;
|
||||
if (client != null) {
|
||||
ScreenBuffer sb = client.getScreenBuffer();
|
||||
if (sb != null) {
|
||||
@@ -1723,6 +1782,7 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
}
|
||||
|
||||
public void refreshScreen() {
|
||||
hotspotsDirty = true;
|
||||
if (client != null) {
|
||||
client.getScreenBuffer().updateDisplaySnapshot();
|
||||
}
|
||||
@@ -1740,6 +1800,26 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
}
|
||||
}
|
||||
|
||||
public void onScreenUpdated() {
|
||||
hotspotsDirty = true;
|
||||
}
|
||||
|
||||
public void onScreenSizeChanged() {
|
||||
hotspotsDirty = true;
|
||||
}
|
||||
|
||||
public void onScreenSizeChanged(int rows, int cols) {
|
||||
hotspotsDirty = true;
|
||||
}
|
||||
|
||||
public boolean isHotspotsDirty() {
|
||||
return hotspotsDirty;
|
||||
}
|
||||
|
||||
public void setHotspotsDirty(boolean hotspotsDirty) {
|
||||
this.hotspotsDirty = hotspotsDirty;
|
||||
}
|
||||
|
||||
private void setupFont() {
|
||||
currentFontSize = haus.nightmare.j3270.config.Settings.getFontSize();
|
||||
String fontFamily = haus.nightmare.j3270.config.Settings.getFontFamily();
|
||||
@@ -1880,6 +1960,7 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
|
||||
public void setClient(Telnet3270Client client) {
|
||||
this.client = client;
|
||||
hotspotsDirty = true;
|
||||
if (client != null) {
|
||||
setupGraphicsPlaneRenderer();
|
||||
updateCellSize();
|
||||
@@ -2076,6 +2157,9 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
g2.fillRect(cx, oy, cellWidth, gridH);
|
||||
}
|
||||
|
||||
// Phase 28.2 / T2-B: Precompute selection scratch lookup once per frame
|
||||
precomputeSelectionScratch(rows, cols);
|
||||
|
||||
// Layer 3: Character / Text Plane
|
||||
byte currentFA = 0;
|
||||
ExtendedAttribute currentFieldEa = null;
|
||||
@@ -2097,7 +2181,7 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
if (ea.isFieldAttribute()) {
|
||||
currentFA = ea.fa;
|
||||
currentFieldEa = ea;
|
||||
if (isCellSelected(row, col)) {
|
||||
if (selectedCellsScratch[baddr]) {
|
||||
g2.setColor(SELECTION_COLOR);
|
||||
g2.fillRect(x, y, cellWidth, cellHeight);
|
||||
}
|
||||
@@ -2142,7 +2226,7 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
// Field Outlining (0xC2 / TY_FOUTLINE)
|
||||
drawOutlining(g2, ea, currentFieldEa, baddr, row, col, x, y, cellWidth, cellHeight, rows, cols, sb, fgColor);
|
||||
|
||||
if (isCellSelected(row, col)) {
|
||||
if (selectedCellsScratch[baddr]) {
|
||||
g2.setColor(SELECTION_COLOR);
|
||||
g2.fillRect(x, y, cellWidth, cellHeight);
|
||||
}
|
||||
@@ -2194,7 +2278,8 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
if (ch < 128) {
|
||||
g2.drawString(CHAR_STRINGS[ch], x, textY);
|
||||
} else {
|
||||
g2.drawString(String.valueOf(ch), x, textY);
|
||||
charScratch[0] = ch;
|
||||
g2.drawChars(charScratch, 0, 1, x, textY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2215,7 +2300,7 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
}
|
||||
|
||||
// Draw selection highlight (40% alpha blend over cell)
|
||||
if (isCellSelected(row, col)) {
|
||||
if (selectedCellsScratch[baddr]) {
|
||||
g2.setColor(SELECTION_COLOR);
|
||||
g2.fillRect(x, y, cellWidth, cellHeight);
|
||||
}
|
||||
@@ -2261,8 +2346,8 @@ public class TerminalPanel extends JPanel implements java.awt.print.Printable, I
|
||||
if (hotspotsEnabled && hoveredHotspot != null) {
|
||||
Color oldColor = g2.getColor();
|
||||
Stroke oldStroke = g2.getStroke();
|
||||
g2.setColor(new Color(0, 220, 255)); // Bright cyan hotspot underline
|
||||
g2.setStroke(new BasicStroke(2.0f));
|
||||
g2.setColor(HOTSPOT_HOVER_COLOR); // Bright cyan hotspot underline
|
||||
g2.setStroke(HOTSPOT_HOVER_STROKE);
|
||||
|
||||
int hr0 = hoveredHotspot.getStartRow();
|
||||
int hr1 = hoveredHotspot.getEndRow();
|
||||
|
||||
Reference in New Issue
Block a user