/*
* CardReaderManagerView.java
*/
/**
*
* @author Sebastien Riou
*/
package uk.co.nimp.scardterminalmanager;
import java.util.EventObject;
import javax.smartcardio.CardNotPresentException;
import org.jdesktop.application.Application;
import uk.co.nimp.scard.log.StarScriptLogHandler;
import uk.co.nimp.scard.log.ScardPrintStreamLogHandler;
import uk.co.nimp.scard.log.MpScopeSequenceLogHandler;
import com.atolsystems.atolutilities.InputFileFormatException;
import code.from.internet.CloseableTabbedPaneListener;
import code.from.internet.JListUtility;
import code.from.internet.JarClassLoader;
import com.atolsystems.atolutilities.*;
import com.atolsystems.atolutilities.ACommandLineUtilities.Arg;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.FocusTraversalPolicy;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.smartcardio.CardException;
import javax.swing.event.DocumentEvent;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.Task;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.InputMap;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.jdesktop.application.Application.ExitListener;
import uk.co.nimp.scard.*;
import uk.co.nimp.scard.Main.StdParams;
import uk.co.nimp.scard.log.MpManagerScriptLogHandler;
import uk.co.nimp.scard.log.VerilogStimuliLogHandler;
import uk.co.nimp.smartcard.Apdu;
/**
* The application's main frame.
*/
public final class CardReaderManagerView extends FrameView implements SmartCardTaskProcessor {
public static final String LAST_TASK_PATH_KEY = "CardReaderManagerViewLastTaskPath";
public static final String LAST_LOG_PATH_KEY = "CardReaderManagerViewLastLogPath";
LoggingWindow appLoggingWindow;
private ActiveTerminalPropertyListener activeTerminalPropertyListener;
private boolean initCompleted;
private List<GenericTerminalManager> terminalManagers;
//needed for RMI scheme
public boolean exist() throws Exception {
return true;
}
protected HashMap<String, TerminalInfo> terminals;//this contain all terminals seen since startup. terminals are never removed from it
protected class ConnectReaderAction extends javax.swing.AbstractAction {
public void actionPerformed(ActionEvent e) {
try {
if (terminalsListSelection != LIST_AVAILABLE_TERMINALS) {
return;//terminal already connected
}
JList list = (JList) e.getSource();
if (false == list.isSelectionEmpty()) {
String name = list.getSelectedValue().toString();
TerminalInfo tI = terminals.get(name);
StatusDisplayerLabel sdl = new StatusDisplayerLabel();
sdl.setText(name);
tI.setStatusDisplayer(sdl);
int index = loggingTabbedPane.getTabCount();
TerminalLoggingWindow logWindow = new TerminalLoggingWindow(tI);
loggingTabbedPane.addTab(name, logWindow);
tI.setTopComponentInTab(loggingTabbedPane.getComponentAt(index));
/*must be done before changing the list because the list update will trigger
update of status label, which is based on the selected tab in this case*/
loggingTabbedPane.setSelectedIndex(index);
DefaultListModel model = (DefaultListModel) list.getModel();
model.remove(list.getSelectedIndex());
if (0 == model.getSize()) {
terminalsListButtonGroup.setSelected(openedRadioButton.getModel(), true);
openedAction().run();
}
controlTabbedPane.add(logControlPanel);
enableConnectedTerminalsLists(true);
}
} catch (IOException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
protected TerminalInfo[] getSelectedTerminalInfo(boolean throwExceptionIfNoSelection) {
int selected[] = readersList.getSelectedIndices();
TerminalInfo out[] = null;
TerminalLoggingWindow tLog = loggingTabbedPane.getSelectedTerminalLoggingWindow();
if (selected.length > 0) {
out = new TerminalInfo[selected.length];
for (int i = 0; i < selected.length; i++) {
NamedObject o = (NamedObject) readersList.getModel().getElementAt(selected[i]);
out[i] = (TerminalInfo) o.getObject();
}
} else {
if (null == tLog) {
if (throwExceptionIfNoSelection) {
throw new RuntimeException("No terminal selected");
}
} else {
out = new TerminalInfo[1];
out[0] = tLog.gettI();
}
}
return out;
}
protected void selectTerminalInReadersList(TerminalInfo tI) {
NamedObject o = getNamedObjectInReadersList(tI);
if (null != o) {
readersList.setSelectedValue(o, true);
}
}
protected NamedObject getNamedObjectInReadersList(TerminalInfo tI) {
NamedObject out = null;
for (int i = 0; i < readersList.getModel().getSize(); i++) {
NamedObject trial = (NamedObject) readersList.getModel().getElementAt(i);
if (trial.getObject() == tI) {
out = trial;
break;
}
}
return out;
}
class ActiveLogHandler {
final ScardLogHandler logHandler;
final GenericTerminal terminal;
public ActiveLogHandler(ScardLogHandler logHandler, GenericTerminal terminal) {
this.logHandler = logHandler;
this.terminal = terminal;
}
public ScardLogHandler getLogHandler() {
return logHandler;
}
public GenericTerminal getTerminal() {
return terminal;
}
}
protected void addLogHandler() {
try {
DefaultListModel model = (DefaultListModel) availableLoggersList.getModel();
int selectedIndexes[] = availableLoggersList.getSelectedIndices();
if (selectedIndexes.length < 1) {
return;//nothing to do
}
Class loggerClass = (Class) ((NamedObject) availableLoggersList.getSelectedValue()).getObject();
Class[] args = new Class[1];
args[0] = File.class;
Constructor c = loggerClass.getConstructor(args);
AFileChooser fileChooser;
fileChooser = new AFileChooser((java.awt.Frame) null, true, LAST_LOG_PATH_KEY);
fileChooser.setDialogTitle("Output file for " + loggerClass.getSimpleName());
fileChooser.setAcceptAllFileFilterUsed(true);
int option = fileChooser.showOpenDialog(null);
if (option != JFileChooser.APPROVE_OPTION) {
return;
}
fileChooser.saveCurrentPath();
File out = fileChooser.getSelectedFile();
fileChooser.dispose();
TerminalInfo[] selectedTerminalInfo = getSelectedTerminalInfo(true);
File targetFile = out;
String extension = AFileUtilities.extractFileExtension(out.getCanonicalPath());
String path = out.getCanonicalPath();
String baseName;
if (extension.isEmpty()) {
baseName = path;
} else {
baseName = path.substring(0, path.length() - extension.length() - 1);
}
model = (DefaultListModel) registeredLoggersList.getModel();
for (int i = 0; i < selectedTerminalInfo.length; i++) {
if (selectedTerminalInfo.length > 1) {
targetFile = new File(baseName + " - " + selectedTerminalInfo[i].getTerminal().getName() + "." + extension);
}
ScardLogHandler logger = (ScardLogHandler) c.newInstance(targetFile);
selectedTerminalInfo[i].getTerminal().addLogHandler(logger);
String name = logger.getClass().getSimpleName() + " - " + selectedTerminalInfo[i].getTerminal().getName();
name += " - " + targetFile.getName() + " (" + targetFile.getParent() + ")";
NamedObject o = new NamedObject(name, new ActiveLogHandler(logger, selectedTerminalInfo[i].getTerminal()));
model.addElement(o);
}
} catch (Exception ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
}
protected void removeLogHandler() {
try {
DefaultListModel model = (DefaultListModel) registeredLoggersList.getModel();
int selectedIndexes[] = registeredLoggersList.getSelectedIndices();
if (selectedIndexes.length < 1) {
return;//nothing to do
}
NamedObject o = (NamedObject) model.getElementAt(registeredLoggersList.getSelectedIndex());
model.removeElementAt(registeredLoggersList.getSelectedIndex());
ActiveLogHandler alh = (ActiveLogHandler) o.getObject();
alh.getTerminal().closeLog(alh.getLogHandler());
alh.getTerminal().removeLog(alh.getLogHandler());
} catch (Exception ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
}
protected class AddLogAction extends javax.swing.AbstractAction {
public void actionPerformed(ActionEvent e) {
addLogHandler();
}
}
protected class RemoveLogAction extends javax.swing.AbstractAction {
public void actionPerformed(ActionEvent e) {
removeLogHandler();
}
}
Apdu manualApdu;
protected Apdu makeManualApdu(boolean includeLc, boolean includeLe, boolean showErrorMessages) {
//try to make an apdu
Apdu out = null;
try {
String header = (String) apduHeaderTextField.getText();
header = header.replaceAll("\\s", "");
header = header.replaceAll("-", "");
Apdu apdu = new Apdu();
apdu.setHeader(header);
apdu.setLcData(CardReaderManagerView.this.lcDataEditor.getText().replaceAll("\\s", "").replaceAll("-", ""));
String le = CardReaderManagerView.this.leTextField.getText().replaceAll("\\s", "").replaceAll("-", "");
if (!le.isEmpty()) {
apdu.setExpectedLe(Integer.parseInt(le, 16));
}
out = apdu;
} catch (Throwable ex) {
if (showErrorMessages) {
String msg = "Cannot parse the APDU, action cancelled:\n" + ex;
JOptionPane.showMessageDialog(null, msg, "Incorrect input", JOptionPane.INFORMATION_MESSAGE);
}
}
manualApdu = out;
if (null == out) {
if (this.isActiveTerminalReady()) {
enableSendApduButtons(false);
}
this.sendApduButton.setToolTipText("APDU not recognized");
this.sendApduNoLeButton.setToolTipText("APDU not recognized");
this.sendApduNoLcButton.setToolTipText("APDU not recognized");
return out;
}
String toolTip = out.toString().replace("\n", "<br>");
toolTip = "<html>" + toolTip + "</html>";
this.sendApduButton.setToolTipText(toolTip);
Apdu outNoLe = out.clone();
outNoLe.setExpectedLe(0);
toolTip = outNoLe.toString().replace("\n", "<br>");
toolTip = "<html>" + toolTip + "</html>";
this.sendApduNoLeButton.setToolTipText(toolTip);
Apdu outNoLc = out.clone();
outNoLc.setLcData(new byte[0]);
toolTip = outNoLc.toString().replace("\n", "<br>");
toolTip = "<html>" + toolTip + "</html>";
this.sendApduNoLcButton.setToolTipText(toolTip);
if (this.isActiveTerminalReady()) {
enableSendApduButtons(true);
}
if (!includeLc) {
out = outNoLc;
}
if (!includeLe) {
out = outNoLe;
}
return out;
}
void enableSendApduButtons(boolean enable) {
this.sendApduButton.setEnabled(enable);
this.sendApduNoLeButton.setEnabled(enable);
this.sendApduNoLcButton.setEnabled(enable);
}
class ApduHeaderActionListener extends javax.swing.AbstractAction {
public void actionPerformed(ActionEvent e) {
//comboBoxChanged: fired selection changed or string has been edited
//comboBoxEdited: fired when press enter, or when loosing focus and string has been edited
if (false == e.getActionCommand().equals("comboBoxChanged")) {
return;
}
loadApduFromApduComboBoxToTextFields();
}
}
void loadApduFromApduComboBoxToTextFields(){
String apduString = (String) CardReaderManagerView.this.apduComboBox.getSelectedItem();
if ((null == apduString) || apduString.isEmpty()) {
return;
}
Apdu apdu = new Apdu(apduString);
CardReaderManagerView.this.lcDataEditor.setText(apdu.getLcDataAsString());
String header = apdu.getClaAsString() + " ";
header += apdu.getInsAsString() + " ";
header += apdu.getP1AsString() + " ";
header += apdu.getP2AsString();
CardReaderManagerView.this.apduHeaderTextField.setText(header);
CardReaderManagerView.this.leTextField.setText(apdu.getExpectedLeAsHexString());
}
class LcDataDocumentListener implements DocumentListener {
void refreshLc() {
String lcData = CardReaderManagerView.this.lcDataEditor.getText();
lcData = lcData.replaceAll("\\s", "").replaceAll("-", "");
int len = lcData.length();
if ((1 == (len & 1)) || ((len / 2) > 255)) {
CardReaderManagerView.this.lcTextField.setText("xx");
} else {
CardReaderManagerView.this.lcTextField.setText(AStringUtilities.byteToHex(len / 2));
}
CardReaderManagerView.this.makeManualApdu(true, true, false);
}
public void insertUpdate(DocumentEvent e) {
refreshLc();
}
public void removeUpdate(DocumentEvent e) {
refreshLc();
}
public void changedUpdate(DocumentEvent e) {
refreshLc();
}
}
class ApduPartDocumentListener implements DocumentListener {
public void insertUpdate(DocumentEvent e) {
CardReaderManagerView.this.makeManualApdu(true, true, false);
}
public void removeUpdate(DocumentEvent e) {
CardReaderManagerView.this.makeManualApdu(true, true, false);
}
public void changedUpdate(DocumentEvent e) {
CardReaderManagerView.this.makeManualApdu(true, true, false);
}
}
protected class CloseTabListener implements CloseableTabbedPaneListener {
/**
* Informs all <code>CloseableTabbedPaneListener</code>s when a tab should be
* closed
* @param tabIndexToClose the index of the tab which should be closed
* @return true if the tab can be closed, false otherwise
*/
public boolean closeTab(int tabIndexToClose) {
TerminalLoggingWindow log = (TerminalLoggingWindow) loggingTabbedPane.getTerminalLoggingWindowAt(tabIndexToClose);
if (null == log) {
return false;//never close the default log window
}
TerminalInfo tI = log.gettI();
if (null != tI) {
tI.setTopComponentInTab(null);
tI.getStatusDisplayer().setText("");
}
if (2 == loggingTabbedPane.getTabCount())//if no terminal connected, (compare to 2 because the terminal tab is not removed yet)
{
terminalsListButtonGroup.setSelected(availableRadioButton.getModel(), true);
availableAction().run();//force terminal list to show available terminals
controlTabbedPane.remove(logControlPanel);//remove the logging tab
enableConnectedTerminalsLists(false);//disable buttons to show coldConnect terminals
}
return true;//always close terminal logging windows
}
}
class ActiveTerminalPropertyListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent evt) {
TerminalInfo tI = (TerminalInfo) evt.getNewValue();
setStatusLabel(tI);
if (null != tI) {
Object selected[] = readersList.getSelectedValues();
NamedObject toSelect = getNamedObjectInReadersList(tI);
boolean found = false;
for (int i = 0; i < selected.length; i++) {
if (selected[i] == toSelect) {
found = true;
break;
}
}
if (!found) {
selectTerminalInReadersList(tI);
}
}
enableCardRelatedComponents();
}
}
boolean isActiveTerminalReady() {
boolean enable = false;
if (null != this.loggingTabbedPane.activeTerminal) {
enable = this.loggingTabbedPane.activeTerminal.isPresent() & !this.loggingTabbedPane.activeTerminal.isBusy();
}
return enable;
}
void enableCardRelatedComponents() {
boolean enable = isActiveTerminalReady();
Component[] comps;
comps = terminalConnectedPanel.getComponents();
for (int i = 0; i < comps.length; i++) {
comps[i].setEnabled(enable);
}
comps = this.scriptPanel.getComponents();
for (int i = 0; i < comps.length; i++) {
if (!comps[i].equals(this.startScriptButton)) {
comps[i].setEnabled(enable);
}
}
if (enable) {
if (null != script) {
startScriptButton.setEnabled(true);
}
} else {
startScriptButton.setEnabled(false);
}
comps = this.taskPanel.getComponents();
for (int i = 0; i < comps.length; i++) {
comps[i].setEnabled(enable);
}
if (enable) {
if (null != manualApdu) {
this.enableSendApduButtons(true);
}
} else {
this.enableSendApduButtons(false);
}
}
void enableConnectedTerminalsLists(boolean enable) {
this.openedRadioButton.setEnabled(enable);
this.noCardRadioButton.setEnabled(enable);
this.idleRadioButton.setEnabled(enable);
this.busyRadioButton.setEnabled(enable);
}
protected void initLogControlPanel() {
DefaultListModel model = new DefaultListModel();
//Constructor c=new Constructor();
model.addElement(new NamedObject(ScardPrintStreamLogHandler.class.getSimpleName(), ScardPrintStreamLogHandler.class));
model.addElement(new NamedObject(StarScriptLogHandler.class.getSimpleName(), StarScriptLogHandler.class));
model.addElement(new NamedObject(MpManagerScriptLogHandler.class.getSimpleName(), MpManagerScriptLogHandler.class));
model.addElement(new NamedObject(MpScopeSequenceLogHandler.class.getSimpleName(), MpScopeSequenceLogHandler.class));
model.addElement(new NamedObject(VerilogStimuliLogHandler.class.getSimpleName(), VerilogStimuliLogHandler.class));
availableLoggersList.setModel(model);
JListUtility.addAction(availableLoggersList, new AddLogAction());//add double click action
model = new DefaultListModel();
registeredLoggersList.setModel(model);
JListUtility.addAction(registeredLoggersList, new RemoveLogAction());//add double click action
}
private static final KeyStroke DELETE = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
public static void addAction(JComboBox source, javax.swing.Action action) {
// Handle enter key
InputMap im = source.getInputMap();
im.put(DELETE, DELETE);
source.getActionMap().put(DELETE, action);
}
void deleteApdu() {
DefaultComboBoxModel model = (DefaultComboBoxModel) this.apduComboBox.getModel();
int sel = this.apduComboBox.getSelectedIndex();
model.removeElementAt(sel);
}
class deleteAction implements javax.swing.Action {
public Object getValue(String key) {
return this;
}
public void putValue(String key, Object value) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void setEnabled(boolean b) {
throw new UnsupportedOperationException("Not supported yet.");
}
public boolean isEnabled() {
return true;
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void actionPerformed(ActionEvent e) {
deleteApdu();
}
}
public static class MyOwnFocusTraversalPolicy
extends FocusTraversalPolicy {
Vector<Component> order;
public MyOwnFocusTraversalPolicy(Vector<Component> order) {
this.order = new Vector<Component>(order.size());
this.order.addAll(order);
}
public Component getComponentAfter(Container focusCycleRoot,
Component aComponent) {
int idx = (order.indexOf(aComponent) + 1) % order.size();
return order.get(idx);
}
public Component getComponentBefore(Container focusCycleRoot,
Component aComponent) {
int idx = order.indexOf(aComponent) - 1;
if (idx < 0) {
idx = order.size() - 1;
}
return order.get(idx);
}
public Component getDefaultComponent(Container focusCycleRoot) {
return order.get(0);
}
public Component getLastComponent(Container focusCycleRoot) {
return order.lastElement();
}
public Component getFirstComponent(Container focusCycleRoot) {
return order.get(0);
}
}
protected void initManualControlPanel() {
this.enableSendApduButtons(false);
apduComboBox.addActionListener(new ApduHeaderActionListener());
addAction(apduComboBox, new deleteAction());
ApduPartDocumentListener apduPartDocumentListener = new ApduPartDocumentListener();
this.apduHeaderTextField.getDocument().addDocumentListener(apduPartDocumentListener);
this.lcDataEditor.getDocument().addDocumentListener(new LcDataDocumentListener());
this.leTextField.getDocument().addDocumentListener(apduPartDocumentListener);
MyOwnFocusTraversalPolicy newPolicy;
Vector<Component> order = new Vector<Component>(5);
order.add(this.apduHeaderTextField);
order.add(this.lcDataEditor);
order.add(this.leTextField);
order.add(this.sendApduButton);
order.add(this.sendApduNoLeButton);
order.add(this.sendApduNoLcButton);
order.add(this.apduComboBox);
newPolicy = new MyOwnFocusTraversalPolicy(order);
manualControlPanel.setFocusTraversalPolicyProvider(true);
manualControlPanel.setFocusTraversalPolicy(newPolicy);
loadApduFromApduComboBoxToTextFields();
}
static final String ARG_HELP = "-help";
static final int ARG_HELP_ID = 0;
static final String ARG_SET_CONF_FOLDER = "-confFolder:";
static final int ARG_SET_CONF_FOLDER_ID = 1;
static final String ARG_ADD_JAR_FILE = "-addJarFile:";
static final int ARG_ADD_JAR_FILE_ID = 2;
static final String ARG_ADD_TERMINAL_MANAGER = "-addTerminalManager:";
static final int ARG_ADD_TERMINAL_MANAGER_ID = 3;
protected void initClass(SingleFrameApplication app) {
debugMenu.setVisible(false);
sharedPanelPlaceHolder = new JPanel();
taskLastSharedPanelPlaceHolder = dummySharedPanel;
manualLastSharedPanelPlaceHolder = manualSharedPanel;
scriptLastSharedPanelPlaceHolder = sharedPanel;
visibleStatusLabel = statusMessageLabel;
enableCardRelatedComponents();
appLoggingWindow = new LoggingWindow();
appLoggingWindow.putClientProperty("isClosable", false);
loggingTabbedPane.addTab("App log", appLoggingWindow);
loggingTabbedPane.enableHighlightOnChange(0, Color.orange, true, false, false);
initLogControlPanel();
initManualControlPanel();
PipedOutputStream pos = new PipedOutputStream();
PrintStream outStream = new PrintStream(pos);
try {
appLoggingWindow.monitorStream(pos);
System.setOut(outStream);
System.setErr(outStream);
} catch (IOException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
terminals = new HashMap<String, TerminalInfo>();
loggingTabbedPane.addCloseableTabbedPaneListener(new CloseTabListener());
readersList.setModel(new DefaultListModel());
JListUtility.addAction(readersList, new ConnectReaderAction());//add double click action
activeTerminalPropertyListener = new ActiveTerminalPropertyListener();
loggingTabbedPane.addPropertyChangeListener(LogTabbedPane.SELECTED_TERMINAL_PROPERTY, activeTerminalPropertyListener);
loadTerminalManagers();
terminalListRefreshTimer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
org.jdesktop.application.Task refreshTask = new RefreshReadersListTask(getApplication());
refreshTask.run();
}
});
if (null != terminalManagers) {
LinkedList<GenericTerminal> availableTerminals = new LinkedList<GenericTerminal>();
try {
Main.getAvailableTerminals(terminalManagers, availableTerminals);
} catch (ScardException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
if (availableTerminals.isEmpty()) {
Main.printNoTerminalMessage(terminalManagers);
}
terminalListRefreshTimer.setInitialDelay(0);
terminalListRefreshTimer.start();
} else {
System.out.println("No terminal manager succesfully loaded: please check command line and \".conf\" files\n");
}
this.getFrame().addWindowFocusListener(new java.awt.event.WindowFocusListener() {
public void windowGainedFocus(WindowEvent e) {
if (null != terminalManagers) {
terminalListRefreshTimer.start();
}
}
public void windowLostFocus(WindowEvent e) {
terminalListRefreshTimer.stop();
}
});
this.controlTabbedPane.remove(logControlPanel);
}
protected void loadTerminalManagers() {
try {
ArgSpec[] argSpecs = {};
StdParams p = Main.processStdArgs(ScardTerminalManagerApp.args, argSpecs, this.getClass(), "ScardTerminalManager");
terminalManagers = p.getTerminalManagers();
} catch (Throwable ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
}
public CardReaderManagerView(SingleFrameApplication app) {
super(app);
initComponents();
// status bar initialization - message timeout, idle icon and busy animation, etc
ResourceMap resourceMap = getResourceMap();
int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
messageTimer = new Timer(messageTimeout, new ActionListener() {
public void actionPerformed(ActionEvent e) {
statusMessageLabel.setText("");
}
});
messageTimer.setRepeats(false);
int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
for (int i = 0; i < busyIcons.length; i++) {
busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
}
busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
public void actionPerformed(ActionEvent e) {
busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
}
});
idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
statusAnimationLabel.setIcon(idleIcon);
progressBar.setVisible(false);
// connecting action actionStarters to status bar via TaskMonitor
TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
public void propertyChange(java.beans.PropertyChangeEvent evt) {
String propertyName = evt.getPropertyName();
if ("started".equals(propertyName)) {
if (!busyIconTimer.isRunning()) {
statusAnimationLabel.setIcon(busyIcons[0]);
busyIconIndex = 0;
busyIconTimer.start();
}
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
} else if ("done".equals(propertyName)) {
busyIconTimer.stop();
statusAnimationLabel.setIcon(idleIcon);
progressBar.setVisible(false);
progressBar.setValue(0);
} else if ("message".equals(propertyName)) {
String text = (String) (evt.getNewValue());
statusMessageLabel.setText((text == null) ? "" : text);
messageTimer.restart();
} else if ("progress".equals(propertyName)) {
int value = (Integer) (evt.getNewValue());
progressBar.setVisible(true);
progressBar.setIndeterminate(false);
progressBar.setValue(value);
}
}
});
initClass(app);
}
public class ViewExitListener implements ExitListener {
public boolean canExit(EventObject event) {
return true;
}
public void willExit(EventObject event) {
//we restore the original state of tabs to avoid a warning from
CardReaderManagerView.this.controlTabbedPane.setSelectedComponent(scriptPanel);
CardReaderManagerView.this.controlTabbedPaneStateChanged(null);
//JOptionPane.showConfirmDialog(null, "bye", "Bye", JOptionPane.OK_OPTION);
}
}
public void endOfStartupHook() {
this.controlTabbedPane.setSelectedComponent(scriptPanel);
this.getApplication().addExitListener(new ViewExitListener());
statusMessageLabel.setText("Ready");
initCompleted = true;
}
@Action
public void showAboutBox() {
if (aboutBox == null) {
JFrame mainFrame = ScardTerminalManagerApp.getApplication().getMainFrame();
aboutBox = new ScardTerminalManagerAboutBox(mainFrame);
aboutBox.setLocationRelativeTo(mainFrame);
}
ScardTerminalManagerApp.getApplication().show(aboutBox);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
mainPanel = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
readersList = new javax.swing.JList();
availableRadioButton = new javax.swing.JRadioButton();
openedRadioButton = new javax.swing.JRadioButton();
noCardRadioButton = new javax.swing.JRadioButton();
idleRadioButton = new javax.swing.JRadioButton();
busyRadioButton = new javax.swing.JRadioButton();
jLabel1 = new javax.swing.JLabel();
controlTabbedPane = new javax.swing.JTabbedPane();
manualControlPanel = new javax.swing.JPanel();
apduComboBox = new javax.swing.JComboBox();
sendApduButton = new javax.swing.JButton();
manualSharedPanel = new javax.swing.JPanel();
jScrollPane4 = new javax.swing.JScrollPane();
lcDataEditor = new javax.swing.JEditorPane();
lcTextField = new javax.swing.JTextField();
jLabel5 = new javax.swing.JLabel();
jLabel6 = new javax.swing.JLabel();
leTextField = new javax.swing.JTextField();
apduHeaderTextField = new javax.swing.JTextField();
clearApduButton = new javax.swing.JButton();
sendApduNoLcButton = new javax.swing.JButton();
sendApduNoLeButton = new javax.swing.JButton();
scriptPanel = new javax.swing.JPanel();
browseScriptButton = new javax.swing.JButton();
jLabel2 = new javax.swing.JLabel();
nRunTextField = new javax.swing.JTextField();
sharedPanel = new javax.swing.JPanel();
terminalConnectedPanel = new javax.swing.JPanel();
cardConnectButton = new javax.swing.JButton();
cardConnectButton1 = new javax.swing.JButton();
cardDisconnectButton = new javax.swing.JButton();
jSeparator1 = new javax.swing.JSeparator();
loggingTabbedPane = new uk.co.nimp.scardterminalmanager.LogTabbedPane();
clearLogButton = new javax.swing.JButton();
scriptFileTextField = new javax.swing.JTextField();
startScriptButton = new javax.swing.JButton();
taskPanel = new javax.swing.JPanel();
startTaskButton = new javax.swing.JButton();
dummySharedPanel = new javax.swing.JPanel();
logControlPanel = new javax.swing.JPanel();
jScrollPane2 = new javax.swing.JScrollPane();
availableLoggersList = new javax.swing.JList();
jLabel3 = new javax.swing.JLabel();
jScrollPane3 = new javax.swing.JScrollPane();
registeredLoggersList = new javax.swing.JList();
moveLoggersButton = new javax.swing.JButton();
jLabel4 = new javax.swing.JLabel();
openAllTerminalsButton = new javax.swing.JButton();
openAllTerminalsWithCardButton = new javax.swing.JButton();
menuBar = new javax.swing.JMenuBar();
javax.swing.JMenu fileMenu = new javax.swing.JMenu();
javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
javax.swing.JMenu helpMenu = new javax.swing.JMenu();
javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
debugModeMenuItem = new javax.swing.JMenuItem();
debugMenu = new javax.swing.JMenu();
debugMenuItem = new javax.swing.JMenuItem();
debugBackGroundMenuItem = new javax.swing.JMenuItem();
garbageCollectorMenuItem = new javax.swing.JMenuItem();
statusPanel = new javax.swing.JPanel();
javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
statusMessageLabel = new javax.swing.JLabel();
statusAnimationLabel = new javax.swing.JLabel();
progressBar = new javax.swing.JProgressBar();
terminalsListButtonGroup = new javax.swing.ButtonGroup();
mainPanel.setName("mainPanel"); // NOI18N
jScrollPane1.setEnabled(false);
jScrollPane1.setName("jScrollPane1"); // NOI18N
jScrollPane1.setPreferredSize(new java.awt.Dimension(23, 23));
readersList.setDoubleBuffered(true);
readersList.setName("readersList"); // NOI18N
readersList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
readersListValueChanged(evt);
}
});
jScrollPane1.setViewportView(readersList);
javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(uk.co.nimp.scardterminalmanager.ScardTerminalManagerApp.class).getContext().getActionMap(CardReaderManagerView.class, this);
availableRadioButton.setAction(actionMap.get("availableAction")); // NOI18N
terminalsListButtonGroup.add(availableRadioButton);
availableRadioButton.setSelected(true);
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(uk.co.nimp.scardterminalmanager.ScardTerminalManagerApp.class).getContext().getResourceMap(CardReaderManagerView.class);
availableRadioButton.setText(resourceMap.getString("availableRadioButton.text")); // NOI18N
availableRadioButton.setName("availableRadioButton"); // NOI18N
openedRadioButton.setAction(actionMap.get("openedAction")); // NOI18N
terminalsListButtonGroup.add(openedRadioButton);
openedRadioButton.setText(resourceMap.getString("openedRadioButton.text")); // NOI18N
openedRadioButton.setName("openedRadioButton"); // NOI18N
noCardRadioButton.setAction(actionMap.get("noCardAction")); // NOI18N
terminalsListButtonGroup.add(noCardRadioButton);
noCardRadioButton.setText(resourceMap.getString("noCardRadioButton.text")); // NOI18N
noCardRadioButton.setName("noCardRadioButton"); // NOI18N
idleRadioButton.setAction(actionMap.get("idleAction")); // NOI18N
terminalsListButtonGroup.add(idleRadioButton);
idleRadioButton.setText(resourceMap.getString("idleRadioButton.text")); // NOI18N
idleRadioButton.setName("idleRadioButton"); // NOI18N
busyRadioButton.setAction(actionMap.get("busyAction")); // NOI18N
terminalsListButtonGroup.add(busyRadioButton);
busyRadioButton.setText(resourceMap.getString("busyRadioButton.text")); // NOI18N
busyRadioButton.setName("busyRadioButton"); // NOI18N
jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
jLabel1.setName("jLabel1"); // NOI18N
controlTabbedPane.setName("controlTabbedPane"); // NOI18N
controlTabbedPane.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
controlTabbedPaneStateChanged(evt);
}
});
manualControlPanel.setName("manualControlPanel"); // NOI18N
apduComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0084000010" }));
apduComboBox.setToolTipText(resourceMap.getString("apduComboBox.toolTipText")); // NOI18N
apduComboBox.setName("apduComboBox"); // NOI18N
sendApduButton.setAction(actionMap.get("sendApduAction")); // NOI18N
sendApduButton.setText(resourceMap.getString("sendApduButton.text")); // NOI18N
sendApduButton.setName("sendApduButton"); // NOI18N
manualSharedPanel.setName("manualSharedPanel"); // NOI18N
javax.swing.GroupLayout manualSharedPanelLayout = new javax.swing.GroupLayout(manualSharedPanel);
manualSharedPanel.setLayout(manualSharedPanelLayout);
manualSharedPanelLayout.setHorizontalGroup(
manualSharedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 546, Short.MAX_VALUE)
);
manualSharedPanelLayout.setVerticalGroup(
manualSharedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 144, Short.MAX_VALUE)
);
jScrollPane4.setName("jScrollPane4"); // NOI18N
lcDataEditor.setToolTipText(resourceMap.getString("lcDataEditor.toolTipText")); // NOI18N
lcDataEditor.setName("lcDataEditor"); // NOI18N
jScrollPane4.setViewportView(lcDataEditor);
lcTextField.setEditable(false);
lcTextField.setText(resourceMap.getString("lcTextField.text")); // NOI18N
lcTextField.setFocusable(false);
lcTextField.setName("lcTextField"); // NOI18N
jLabel5.setText(resourceMap.getString("jLabel5.text")); // NOI18N
jLabel5.setName("jLabel5"); // NOI18N
jLabel6.setText(resourceMap.getString("jLabel6.text")); // NOI18N
jLabel6.setName("jLabel6"); // NOI18N
leTextField.setText(resourceMap.getString("leTextField.text")); // NOI18N
leTextField.setName("leTextField"); // NOI18N
apduHeaderTextField.setText(resourceMap.getString("apduHeaderTextField.text")); // NOI18N
apduHeaderTextField.setToolTipText(resourceMap.getString("apduHeaderTextField.toolTipText")); // NOI18N
apduHeaderTextField.setName("apduHeaderTextField"); // NOI18N
clearApduButton.setAction(actionMap.get("clearApduButton")); // NOI18N
clearApduButton.setText(resourceMap.getString("clearApduButton.text")); // NOI18N
clearApduButton.setName("clearApduButton"); // NOI18N
sendApduNoLcButton.setAction(actionMap.get("sendApduNoLcAction")); // NOI18N
sendApduNoLcButton.setText(resourceMap.getString("sendApduNoLcButton.text")); // NOI18N
sendApduNoLcButton.setName("sendApduNoLcButton"); // NOI18N
sendApduNoLeButton.setAction(actionMap.get("sendApduNoLe")); // NOI18N
sendApduNoLeButton.setText(resourceMap.getString("sendApduNoLeButton.text")); // NOI18N
sendApduNoLeButton.setName("sendApduNoLeButton"); // NOI18N
javax.swing.GroupLayout manualControlPanelLayout = new javax.swing.GroupLayout(manualControlPanel);
manualControlPanel.setLayout(manualControlPanelLayout);
manualControlPanelLayout.setHorizontalGroup(
manualControlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, manualControlPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(manualControlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(manualSharedPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, manualControlPanelLayout.createSequentialGroup()
.addComponent(apduHeaderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(jLabel5)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lcTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jLabel6)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(leTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(sendApduButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sendApduNoLeButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sendApduNoLcButton))
.addComponent(jScrollPane4, javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(manualControlPanelLayout.createSequentialGroup()
.addComponent(apduComboBox, 0, 462, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(clearApduButton)))
.addContainerGap())
);
manualControlPanelLayout.setVerticalGroup(
manualControlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(manualControlPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(manualControlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel5)
.addComponent(lcTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel6)
.addComponent(leTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(sendApduButton)
.addComponent(apduHeaderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(sendApduNoLeButton)
.addComponent(sendApduNoLcButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(manualControlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(apduComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(clearApduButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(manualSharedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
controlTabbedPane.addTab(resourceMap.getString("manualControlPanel.TabConstraints.tabTitle"), manualControlPanel); // NOI18N
scriptPanel.setName("scriptPanel"); // NOI18N
browseScriptButton.setAction(actionMap.get("browseScriptAction")); // NOI18N
browseScriptButton.setText(resourceMap.getString("browseScriptButton.text")); // NOI18N
browseScriptButton.setFocusable(false);
browseScriptButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
browseScriptButton.setName("browseScriptButton"); // NOI18N
browseScriptButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jLabel2.setText(resourceMap.getString("jLabel2.text")); // NOI18N
jLabel2.setName("jLabel2"); // NOI18N
nRunTextField.setText(resourceMap.getString("nRunTextField.text")); // NOI18N
nRunTextField.setAutoscrolls(false);
nRunTextField.setMaximumSize(new java.awt.Dimension(100, 20));
nRunTextField.setName("nRunTextField"); // NOI18N
sharedPanel.setMaximumSize(new java.awt.Dimension(0, 0));
sharedPanel.setName("sharedPanel"); // NOI18N
sharedPanel.setPreferredSize(new java.awt.Dimension(0, 0));
terminalConnectedPanel.setName("terminalConnectedPanel"); // NOI18N
cardConnectButton.setAction(actionMap.get("cardConnectAction")); // NOI18N
cardConnectButton.setText(resourceMap.getString("cardConnectButton.text")); // NOI18N
cardConnectButton.setFocusable(false);
cardConnectButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
cardConnectButton.setName("cardConnectButton"); // NOI18N
cardConnectButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
cardConnectButton1.setAction(actionMap.get("cardWarmConnectAction")); // NOI18N
cardConnectButton1.setText(resourceMap.getString("cardConnectButton1.text")); // NOI18N
cardConnectButton1.setFocusable(false);
cardConnectButton1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
cardConnectButton1.setName("cardConnectButton1"); // NOI18N
cardConnectButton1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
cardDisconnectButton.setAction(actionMap.get("powerOffCardAction")); // NOI18N
cardDisconnectButton.setText(resourceMap.getString("cardDisconnectButton.text")); // NOI18N
cardDisconnectButton.setFocusable(false);
cardDisconnectButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
cardDisconnectButton.setName("cardDisconnectButton"); // NOI18N
cardDisconnectButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);
jSeparator1.setName("jSeparator1"); // NOI18N
javax.swing.GroupLayout terminalConnectedPanelLayout = new javax.swing.GroupLayout(terminalConnectedPanel);
terminalConnectedPanel.setLayout(terminalConnectedPanelLayout);
terminalConnectedPanelLayout.setHorizontalGroup(
terminalConnectedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(terminalConnectedPanelLayout.createSequentialGroup()
.addComponent(cardConnectButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cardConnectButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cardDisconnectButton, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE))
);
terminalConnectedPanelLayout.setVerticalGroup(
terminalConnectedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(terminalConnectedPanelLayout.createSequentialGroup()
.addGroup(terminalConnectedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(cardConnectButton)
.addComponent(cardConnectButton1)
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(cardDisconnectButton))
.addContainerGap())
);
terminalConnectedPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {cardConnectButton1, jSeparator1});
loggingTabbedPane.setName("loggingTabbedPane"); // NOI18N
loggingTabbedPane.setPreferredSize(new java.awt.Dimension(32767, 32767));
clearLogButton.setAction(actionMap.get("clearLogAction")); // NOI18N
clearLogButton.setText(resourceMap.getString("clearLogButton.text")); // NOI18N
clearLogButton.setFocusable(false);
clearLogButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
clearLogButton.setName("clearLogButton"); // NOI18N
clearLogButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
javax.swing.GroupLayout sharedPanelLayout = new javax.swing.GroupLayout(sharedPanel);
sharedPanel.setLayout(sharedPanelLayout);
sharedPanelLayout.setHorizontalGroup(
sharedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(sharedPanelLayout.createSequentialGroup()
.addComponent(terminalConnectedPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(clearLogButton))
.addComponent(loggingTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 568, Short.MAX_VALUE)
);
sharedPanelLayout.setVerticalGroup(
sharedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(sharedPanelLayout.createSequentialGroup()
.addGroup(sharedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(terminalConnectedPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(clearLogButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(loggingTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE))
);
scriptFileTextField.setEditable(false);
scriptFileTextField.setText(resourceMap.getString("scriptFileTextField.text")); // NOI18N
scriptFileTextField.setName("scriptFileTextField"); // NOI18N
startScriptButton.setAction(actionMap.get("startScriptAction")); // NOI18N
startScriptButton.setText(resourceMap.getString("startScriptButton.text")); // NOI18N
startScriptButton.setName("startScriptButton"); // NOI18N
javax.swing.GroupLayout scriptPanelLayout = new javax.swing.GroupLayout(scriptPanel);
scriptPanel.setLayout(scriptPanelLayout);
scriptPanelLayout.setHorizontalGroup(
scriptPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(scriptPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(scriptPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(sharedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 546, Short.MAX_VALUE)
.addGroup(scriptPanelLayout.createSequentialGroup()
.addComponent(browseScriptButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(scriptFileTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(startScriptButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(nRunTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
);
scriptPanelLayout.setVerticalGroup(
scriptPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(scriptPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(scriptPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(browseScriptButton)
.addGroup(scriptPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(nRunTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel2)
.addComponent(scriptFileTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(startScriptButton)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(sharedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 275, Short.MAX_VALUE))
);
controlTabbedPane.addTab(resourceMap.getString("scriptPanel.TabConstraints.tabTitle"), scriptPanel); // NOI18N
taskPanel.setName("taskPanel"); // NOI18N
startTaskButton.setAction(actionMap.get("addTaskAction")); // NOI18N
startTaskButton.setText(resourceMap.getString("startTaskButton.text")); // NOI18N
startTaskButton.setFocusable(false);
startTaskButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
startTaskButton.setName("startTaskButton"); // NOI18N
startTaskButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
dummySharedPanel.setMaximumSize(new java.awt.Dimension(0, 0));
dummySharedPanel.setName("dummySharedPanel"); // NOI18N
javax.swing.GroupLayout dummySharedPanelLayout = new javax.swing.GroupLayout(dummySharedPanel);
dummySharedPanel.setLayout(dummySharedPanelLayout);
dummySharedPanelLayout.setHorizontalGroup(
dummySharedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 546, Short.MAX_VALUE)
);
dummySharedPanelLayout.setVerticalGroup(
dummySharedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 275, Short.MAX_VALUE)
);
javax.swing.GroupLayout taskPanelLayout = new javax.swing.GroupLayout(taskPanel);
taskPanel.setLayout(taskPanelLayout);
taskPanelLayout.setHorizontalGroup(
taskPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(taskPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(taskPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(dummySharedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(startTaskButton))
.addContainerGap())
);
taskPanelLayout.setVerticalGroup(
taskPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(taskPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(startTaskButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(dummySharedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
controlTabbedPane.addTab(resourceMap.getString("taskPanel.TabConstraints.tabTitle"), taskPanel); // NOI18N
logControlPanel.setEnabled(false);
logControlPanel.setName("logControlPanel"); // NOI18N
jScrollPane2.setName("jScrollPane2"); // NOI18N
availableLoggersList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
availableLoggersList.setName("availableLoggersList"); // NOI18N
availableLoggersList.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
availableLoggersListMouseClicked(evt);
}
});
jScrollPane2.setViewportView(availableLoggersList);
jLabel3.setText(resourceMap.getString("jLabel3.text")); // NOI18N
jLabel3.setName("jLabel3"); // NOI18N
jScrollPane3.setName("jScrollPane3"); // NOI18N
registeredLoggersList.setName("registeredLoggersList"); // NOI18N
registeredLoggersList.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
registeredLoggersListMouseClicked(evt);
}
});
jScrollPane3.setViewportView(registeredLoggersList);
moveLoggersButton.setAction(actionMap.get("moveLoggers")); // NOI18N
moveLoggersButton.setText(resourceMap.getString("moveLoggersButton.text")); // NOI18N
moveLoggersButton.setName("moveLoggersButton"); // NOI18N
jLabel4.setText(resourceMap.getString("jLabel4.text")); // NOI18N
jLabel4.setName("jLabel4"); // NOI18N
javax.swing.GroupLayout logControlPanelLayout = new javax.swing.GroupLayout(logControlPanel);
logControlPanel.setLayout(logControlPanelLayout);
logControlPanelLayout.setHorizontalGroup(
logControlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(logControlPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(logControlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel3)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 238, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(moveLoggersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(logControlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jLabel4)
.addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 239, Short.MAX_VALUE))
.addContainerGap())
);
logControlPanelLayout.setVerticalGroup(
logControlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(logControlPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(logControlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel3)
.addComponent(jLabel4))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(logControlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 277, Short.MAX_VALUE)
.addComponent(jScrollPane3, 0, 0, Short.MAX_VALUE)
.addComponent(moveLoggersButton))
.addContainerGap())
);
controlTabbedPane.addTab(resourceMap.getString("logControlPanel.TabConstraints.tabTitle"), logControlPanel); // NOI18N
openAllTerminalsButton.setAction(actionMap.get("openAllTerminalsAction")); // NOI18N
openAllTerminalsButton.setText(resourceMap.getString("openAllTerminalsButton.text")); // NOI18N
openAllTerminalsButton.setName("openAllTerminalsButton"); // NOI18N
openAllTerminalsWithCardButton.setAction(actionMap.get("openAllTerminalsWithCardAction")); // NOI18N
openAllTerminalsWithCardButton.setText(resourceMap.getString("openAllTerminalsWithCardButton.text")); // NOI18N
openAllTerminalsWithCardButton.setName("openAllTerminalsWithCardButton"); // NOI18N
javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
mainPanel.setLayout(mainPanelLayout);
mainPanelLayout.setHorizontalGroup(
mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, mainPanelLayout.createSequentialGroup()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(availableRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(openedRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(noCardRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(idleRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(busyRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(openAllTerminalsButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(openAllTerminalsWithCardButton))
.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addComponent(controlTabbedPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 575, Short.MAX_VALUE))
.addContainerGap())
);
mainPanelLayout.setVerticalGroup(
mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(mainPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(availableRadioButton)
.addComponent(openedRadioButton)
.addComponent(noCardRadioButton)
.addComponent(idleRadioButton)
.addComponent(busyRadioButton)
.addComponent(openAllTerminalsButton)
.addComponent(openAllTerminalsWithCardButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(controlTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 347, Short.MAX_VALUE)
.addContainerGap())
);
menuBar.setName("menuBar"); // NOI18N
fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
fileMenu.setName("fileMenu"); // NOI18N
exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
exitMenuItem.setName("exitMenuItem"); // NOI18N
fileMenu.add(exitMenuItem);
menuBar.add(fileMenu);
helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
helpMenu.setName("helpMenu"); // NOI18N
aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
aboutMenuItem.setName("aboutMenuItem"); // NOI18N
helpMenu.add(aboutMenuItem);
debugModeMenuItem.setAction(actionMap.get("debugModeAction")); // NOI18N
debugModeMenuItem.setText(resourceMap.getString("debugModeMenuItem.text")); // NOI18N
debugModeMenuItem.setName("debugModeMenuItem"); // NOI18N
helpMenu.add(debugModeMenuItem);
menuBar.add(helpMenu);
debugMenu.setText(resourceMap.getString("debugMenu.text")); // NOI18N
debugMenu.setName("debugMenu"); // NOI18N
debugMenuItem.setAction(actionMap.get("debugButtonAction")); // NOI18N
debugMenuItem.setText(resourceMap.getString("debugMenuItem.text")); // NOI18N
debugMenuItem.setName("debugMenuItem"); // NOI18N
debugMenu.add(debugMenuItem);
debugBackGroundMenuItem.setAction(actionMap.get("debugBackgroundAction")); // NOI18N
debugBackGroundMenuItem.setText(resourceMap.getString("debugBackGroundMenuItem.text")); // NOI18N
debugBackGroundMenuItem.setName("debugBackGroundMenuItem"); // NOI18N
debugMenu.add(debugBackGroundMenuItem);
garbageCollectorMenuItem.setAction(actionMap.get("garbageCollectorAction")); // NOI18N
garbageCollectorMenuItem.setText(resourceMap.getString("garbageCollectorMenuItem.text")); // NOI18N
garbageCollectorMenuItem.setName("garbageCollectorMenuItem"); // NOI18N
debugMenu.add(garbageCollectorMenuItem);
menuBar.add(debugMenu);
statusPanel.setName("statusPanel"); // NOI18N
statusPanel.setPreferredSize(new java.awt.Dimension(521, 35));
statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N
statusMessageLabel.setName("statusMessageLabel"); // NOI18N
statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N
progressBar.setName("progressBar"); // NOI18N
javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
statusPanel.setLayout(statusPanelLayout);
statusPanelLayout.setHorizontalGroup(
statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE, 599, Short.MAX_VALUE)
.addGroup(statusPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(statusMessageLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 424, Short.MAX_VALUE)
.addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(statusAnimationLabel)
.addContainerGap())
);
statusPanelLayout.setVerticalGroup(
statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(statusPanelLayout.createSequentialGroup()
.addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 16, Short.MAX_VALUE)
.addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(statusMessageLabel)
.addComponent(statusAnimationLabel)
.addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(3, 3, 3))
);
setComponent(mainPanel);
setMenuBar(menuBar);
setStatusBar(statusPanel);
}// </editor-fold>//GEN-END:initComponents
JPanel sharedPanelPlaceHolder;
JPanel taskLastSharedPanelPlaceHolder;
JPanel manualLastSharedPanelPlaceHolder;
JPanel scriptLastSharedPanelPlaceHolder;
private void controlTabbedPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_controlTabbedPaneStateChanged
if (!initCompleted) {
return;//we just return if this happen during tab construction
}
JPanel p = (JPanel) controlTabbedPane.getSelectedComponent();
if ((logControlPanel == p)) {
this.terminalsListButtonGroup.setSelected(openedRadioButton.getModel(), true);
openedAction().run();
//();
} else {
if (sharedPanel.getParent() != p) {
/*here we should move the sharedPanel from its current container to the new one (p)
problem is, it is not as simple as calling "p.add(sharedPanel);"
that would basically works but it loose the resizing property
so what is needed is a clean code which play with the layout manager
well, not in the mood today, so here is my quick and dirty trick:
- have a fake panel in other tabs
- have a spare panel not placed anywhere
- use the replace method of GroupManager to move the sharedPanel
probably not very efficient, but that does the trick !*/
JPanel toReplace = null;
if ((taskPanel == p)) {
toReplace = taskLastSharedPanelPlaceHolder;
} else if ((manualControlPanel == p)) {
toReplace = manualLastSharedPanelPlaceHolder;
} else if ((scriptPanel == p)) {
toReplace = scriptLastSharedPanelPlaceHolder;
} else {
throw new RuntimeException("Unknown target JPanel");
}
GroupLayout oldLayout = (GroupLayout) sharedPanel.getParent().getLayout();
oldLayout.replace(sharedPanel, sharedPanelPlaceHolder);
GroupLayout newLayout = (GroupLayout) p.getLayout();
newLayout.replace(toReplace, sharedPanel);
oldLayout.replace(sharedPanelPlaceHolder, toReplace);
if ((toReplace.getParent() == taskPanel)) {
taskLastSharedPanelPlaceHolder = toReplace;
} else if ((toReplace.getParent() == manualControlPanel)) {
manualLastSharedPanelPlaceHolder = toReplace;
} else if ((toReplace.getParent() == scriptPanel)) {
scriptLastSharedPanelPlaceHolder = toReplace;
} else {
throw new RuntimeException("Unknown parent JPanel");
}
}
if (1 == loggingTabbedPane.getTabCount()) {//if no terminal connected, don't change terminal list
return;
}
this.terminalsListButtonGroup.setSelected(openedRadioButton.getModel(), true);
openedAction().run();
}
}//GEN-LAST:event_controlTabbedPaneStateChanged
JLabel visibleStatusLabel;
protected void updateVisibleStatusLabel() {
JPanel p = (JPanel) controlTabbedPane.getSelectedComponent();
if (logControlPanel == p) {
return;
}
if ((LIST_AVAILABLE_TERMINALS != terminalsListSelection) && (1 == readersList.getSelectedValues().length)) {
//update according to readersList
NamedObject o = (NamedObject) readersList.getSelectedValue();
TerminalInfo tI = (TerminalInfo) o.getObject();
loggingTabbedPane.setSelectedComponent(tI.getTopComponentInTab());
setStatusLabel(tI);
} else if ((LIST_AVAILABLE_TERMINALS == terminalsListSelection) || (0 == readersList.getSelectedValues().length)) {
//update according to loggingTabbedPane
setStatusLabel(loggingTabbedPane.getSelectedTerminalLoggingWindow());
}
}
protected void setStatusLabel(TerminalLoggingWindow terminalLoggingWindow) {
if (null == terminalLoggingWindow) {
setStatusLabel((TerminalInfo) null);
} else {
setStatusLabel(terminalLoggingWindow.gettI());
}
}
protected void setStatusLabel(TerminalInfo tI) {
JLabel label;
if (null == tI) {
label = statusMessageLabel;
} else {
label = tI.getStatusDisplayer();
}
GroupLayout layout = (GroupLayout) visibleStatusLabel.getParent().getLayout();
layout.replace(visibleStatusLabel, label);
visibleStatusLabel = label;
}
private void readersListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_readersListValueChanged
if (terminalsListRefreshing) {
return;
}
if (!initCompleted) {
return;
}
JPanel p = (JPanel) controlTabbedPane.getSelectedComponent();
if (logControlPanel == p) {
manageLogControlPanelGui();
} else {
updateVisibleStatusLabel();
}
}//GEN-LAST:event_readersListValueChanged
private void registeredLoggersListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_registeredLoggersListMouseClicked
this.availableLoggersList.clearSelection();
this.moveLoggersButton.setText("<");
}//GEN-LAST:event_registeredLoggersListMouseClicked
private void availableLoggersListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_availableLoggersListMouseClicked
this.registeredLoggersList.clearSelection();
this.moveLoggersButton.setText(">");
}//GEN-LAST:event_availableLoggersListMouseClicked
void manageLogControlPanelGuiWithGuards() {
if (terminalsListRefreshing) {
return;
}
if (!initCompleted) {
return;
}
JPanel p = (JPanel) controlTabbedPane.getSelectedComponent();
if (logControlPanel != p) {
return;
}
manageLogControlPanelGui();
}
void manageLogControlPanelGui() {
if ((LIST_AVAILABLE_TERMINALS != terminalsListSelection) && (1 == readersList.getModel().getSize())) {
readersList.setSelectedIndex(0);//if only one terminal, select it
}
int selected[] = readersList.getSelectedIndices();
if ((0 == selected.length) || (LIST_AVAILABLE_TERMINALS == terminalsListSelection)) {
this.availableLoggersList.setEnabled(false);
this.availableLoggersList.clearSelection();
this.registeredLoggersList.setVisible(false);
this.registeredLoggersList.clearSelection();
} else {
this.availableLoggersList.setEnabled(true);
this.registeredLoggersList.setVisible(true);
}
//this.logControlPanel.invalidate();
}
List<TerminalInfo> getListOfTerminalsToUpdate() throws ScardException {
// Your Task's code here. This method runs
// on a background thread, so don't reference
// the Swing GUI from here.
List<GenericTerminal> allTerminals = new LinkedList<GenericTerminal>();
List<TerminalInfo> terminalsToUpdate = new LinkedList<TerminalInfo>();
HashMap<String, TerminalInfo> newTerminals = new HashMap<String, TerminalInfo>();
for (GenericTerminalManager terminalManager : terminalManagers) {
List<GenericTerminal> trial = terminalManager.list();
if (null != trial) {
allTerminals.addAll(trial);
}
}
for (GenericTerminal t : allTerminals) {
String name = t.getName();
TerminalInfo tI = terminals.get(name);
if (null == tI) {
//add to general list
tI = new TerminalInfo(t, null, null);
newTerminals.put(name, tI);
}
terminalsToUpdate.add(tI);//add to the list
}
for (Map.Entry<String, TerminalInfo> e : terminals.entrySet()) {
if (allTerminals.contains(e.getValue().getTerminal())) {
//terminal is present, update its state if necessary
if (false == e.getValue().isPresent()) {
//was in "absent" state, update it
e.getValue().setPresent(true);
//terminalsToUpdate.add(e.getValue());
}
} else {//terminal not present anymore
if (e.getValue().isPresent()) {
//was in "present" state, update it
e.getValue().setPresent(false);
terminalsToUpdate.add(e.getValue());
}
}
}
terminals.putAll(newTerminals);
return terminalsToUpdate;
}
protected int terminalsListSelection = LIST_AVAILABLE_TERMINALS;
protected static final int LIST_AVAILABLE_TERMINALS = 0;
protected static final int LIST_OPENED_TERMINALS = 1;
protected static final int LIST_NOCARD_TERMINALS = 2;
protected static final int LIST_IDLE_TERMINALS = 3;
protected static final int LIST_BUSY_TERMINALS = 4;
protected boolean terminalsListRefreshing;
void updateTerminalListAndTabs(List<TerminalInfo> terminals) {
// Runs on the EDT. Update the GUI based on
// the result computed by doInBackground().
terminalsListRefreshing = true;
try {
DefaultListModel model = (DefaultListModel) readersList.getModel();
Object selection[] = readersList.getSelectedValues();
model.clear();
for (TerminalInfo tI : terminals) {
if (tI.isInTab()) {
//update tab title
loggingTabbedPane.updateTab(tI);
}
switch (terminalsListSelection) {
case CardReaderManagerView.LIST_AVAILABLE_TERMINALS: {
if (false == tI.isInTab()) {
//update available terminals list
if (tI.isPresent()) {
model.addElement(new NamedObject(tI.getTerminal().getName(), tI));
}
}
break;
}
case CardReaderManagerView.LIST_OPENED_TERMINALS: {
if (tI.isInTab()) {
//update opened terminals list
model.addElement(new NamedObject(tI.getTerminal().getName(), tI));
}
break;
}
case CardReaderManagerView.LIST_NOCARD_TERMINALS: {
if (tI.isInTab()) {
//update opened terminals list without card
if (false == tI.getTerminal().isCardPresent()) {
model.addElement(new NamedObject(tI.getTerminal().getName(), tI));
}
}
break;
}
case CardReaderManagerView.LIST_IDLE_TERMINALS: {
if (tI.isInTab()) {
if (tI.getTerminal().isCardPresent()) {
if (!tI.isBusy()) {
model.addElement(new NamedObject(tI.getTerminal().getName(), tI));
}
}
}
break;
}
case CardReaderManagerView.LIST_BUSY_TERMINALS: {
if (tI.isInTab()) {
if (tI.isBusy()) {
model.addElement(new NamedObject(tI.getTerminal().getName(), tI));
}
}
break;
}
default:
throw new RuntimeException("terminalsListSelection as an invalid value:" + terminalsListSelection);
}
}
if (null != selection) {
for (int i = 0; i < selection.length; i++) {
int j = model.indexOf(selection[i]);
if (-1 != j) {
readersList.addSelectionInterval(j, j);
}
}
}
} catch (Exception ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
} finally {
terminalsListRefreshing = false;
manageLogControlPanelGuiWithGuards();
enableCardRelatedComponents();
}
}
private class RefreshReadersListTask extends org.jdesktop.application.Task<Object, Void> {
RefreshReadersListTask(org.jdesktop.application.Application app) {
// Runs on the EDT. Copy GUI state that
// doInBackground() depends on from parameters
// to RefreshReadersListTask fields, here.
super(app);
}
@Override
protected Object doInBackground() {
// Your Task's code here. This method runs
// on a background thread, so don't reference
// the Swing GUI from here.
List<TerminalInfo> terminalsToUpdate;
try {
terminalsToUpdate = getListOfTerminalsToUpdate();
} catch (ScardException ex) {
return ex;
}
return terminalsToUpdate; // return your result
}
@Override
protected void succeeded(Object result) {
// Runs on the EDT. Update the GUI based on
// the result computed by doInBackground().
if (result instanceof ScardException) {
ScardException ex = (ScardException) result;
System.out.println(ex.getMessage() + " " + ex.getCode());
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
return;
}
updateTerminalListAndTabs((List<TerminalInfo>) result);
}
}
@Action
public Task refreshReadersListAction() {
return new RefreshReadersListTask(getApplication());
}
@Action
public Task availableAction() {
terminalsListSelection = CardReaderManagerView.LIST_AVAILABLE_TERMINALS;
return new RefreshReadersListTask(getApplication());
}
@Action
public Task openedAction() {
terminalsListSelection = CardReaderManagerView.LIST_OPENED_TERMINALS;
return new RefreshReadersListTask(getApplication());
}
@Action
public Task noCardAction() {
terminalsListSelection = CardReaderManagerView.LIST_NOCARD_TERMINALS;
return new RefreshReadersListTask(getApplication());
}
@Action
public Task idleAction() {
terminalsListSelection = CardReaderManagerView.LIST_IDLE_TERMINALS;
return new RefreshReadersListTask(getApplication());
}
@Action
public Task busyAction() {
terminalsListSelection = CardReaderManagerView.LIST_BUSY_TERMINALS;
return new RefreshReadersListTask(getApplication());
}
@Action
public Task cardConnectAction() {
return new CardConnectActionStarterTask(getApplication());
}
class CardConnectActionTask extends MultiTerminalActionTask {
CardConnectActionTask(TerminalLoggingWindow log) {
super(log);
}
@Override
void doAction() throws InterruptedException, StopRequestFromUserException, ScardException, CardNotPresentException {
log.getTerminal().coldConnect();
}
}
class CardConnectActionStarterTask extends MultiTerminalActionStarterTask {
CardConnectActionStarterTask(Application application) {
super(application);
}
@Override
void commonInit() {
//nothing to do
}
@Override
MultiTerminalActionTask getNewActionTask(TerminalLoggingWindow log) {
return new CardConnectActionTask(log);
}
}
/* private class CardConnectActionStarterTask extends org.jdesktop.application.Task<Object, Void> {
TerminalLoggingWindow log;
CardConnectActionStarterTask(org.jdesktop.application.Application app) {
// Runs on the EDT. Copy GUI state that
// doInBackground() depends on from parameters
// to CardConnectActionStarterTask fields, here.
super(app);
log = loggingTabbedPane.getSelectedTerminalLoggingWindow();
}
@Override
protected Object doInBackground() {
// Your Task's code here. This method runs
// on a background thread, so don't reference
// the Swing GUI from here.
if (null == log) {
System.out.println("no terminal selected");
return new Boolean(false);
}
GenericTerminal terminal = log.getTerminal();
try {
terminal.coldConnect();
return new Boolean(true); // return your result
} catch (CardException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
return new Boolean(false);
}
}
@Override
protected void succeeded(Object result) {
}
}*/
@Action
public Task cardWarmConnectAction() {
return new CardWarmConnectActionStarterTask(getApplication());
}
class CardWarmConnectActionTask extends MultiTerminalActionTask {
CardWarmConnectActionTask(TerminalLoggingWindow log) {
super(log);
}
@Override
void doAction() throws InterruptedException, StopRequestFromUserException, ScardException, CardNotPresentException {
GenericTerminal terminal=log.getTerminal();
if(false==terminal.isConnected())
terminal.coldConnect();
terminal.warmConnect();
}
}
class CardWarmConnectActionStarterTask extends MultiTerminalActionStarterTask {
CardWarmConnectActionStarterTask(Application application) {
super(application);
}
@Override
void commonInit() {
//nothing to do
}
@Override
MultiTerminalActionTask getNewActionTask(TerminalLoggingWindow log) {
return new CardWarmConnectActionTask(log);
}
}
@Action
public Task powerOffCardAction() {
return new PowerOffCardActionStarterTask(getApplication());
}
class PowerOffActionTask extends MultiTerminalActionTask {
PowerOffActionTask(TerminalLoggingWindow log) {
super(log);
}
@Override
void doAction() throws InterruptedException, StopRequestFromUserException, ScardException, CardNotPresentException {
log.getTerminal().disconnect();
}
}
class PowerOffCardActionStarterTask extends MultiTerminalActionStarterTask {
PowerOffCardActionStarterTask(Application application) {
super(application);
}
@Override
void commonInit() {
//nothing to do
}
@Override
MultiTerminalActionTask getNewActionTask(TerminalLoggingWindow log) {
return new PowerOffActionTask(log);
}
}
@Action
public Task sendApduAction() {
return sendApduAction(true, true);
}
@Action
public Task sendApduNoLe() {
return sendApduAction(true, false);
}
@Action
public Task sendApduNoLcAction() {
return sendApduAction(false, true);
}
Task sendApduAction(boolean sendLc, boolean sendLe) {
TerminalLoggingWindow log = loggingTabbedPane.getSelectedTerminalLoggingWindow();
if (null == log) {
throw new RuntimeException("sendApduAction invoked but loggingTabbedPane.getSelectedTerminalLoggingWindow() return null");
}
if (log.gettI().isBusy()) {
throw new RuntimeException("sendApduAction invoked but log.gettI().isBusy() return true");
}
log.gettI().setReserved(true);
this.enableCardRelatedComponents();
Apdu apdu = makeManualApdu(sendLc, sendLe, true);
if (null == apdu) {
log.gettI().setReserved(false);
this.enableCardRelatedComponents();
return null;
}
DefaultComboBoxModel model = (DefaultComboBoxModel) this.apduComboBox.getModel();
String header = AStringUtilities.bytesToHex(apdu.getCommandAPDU().getBytes());
boolean present = false;
for (int i = 0; i < model.getSize(); i++) {
if (header.equals((String) model.getElementAt(i))) {
present = true;
}
}
if (false == present) {
model.addElement(header);
}
return new SendApduActionStarterTask(getApplication(), log, apdu);
}
class SendApduActionTask extends MultiTerminalActionTask {
Apdu apdu;
SendApduActionTask(TerminalLoggingWindow log) {
super(log);
}
public void setApdu(Apdu apdu) {
this.apdu = apdu;
}
@Override
void doAction() throws InterruptedException, StopRequestFromUserException, ScardException, CardNotPresentException {
log.getTerminal().checkConnection();
log.getTerminal().sendApdu(apdu);
}
}
class SendApduActionStarterTask extends MultiTerminalActionStarterTask {
LinkedList<SendApduActionTask> actionTasks;
SendApduActionStarterTask(Application application, TerminalLoggingWindow log, Apdu apdu) {
super(application);
if(null!=actionTasks){
for(SendApduActionTask actionTask:actionTasks)
actionTask.setApdu(apdu);
}
}
@Override
void commonInit() {
actionTasks=new LinkedList<SendApduActionTask>();
}
@Override
MultiTerminalActionTask getNewActionTask(TerminalLoggingWindow log) {
/*if(null==actionTasks)
actionTasks=new LinkedList<SendApduActionTask>();*/
actionTasks.add( new SendApduActionTask(log));
return actionTasks.getLast();
}
}
/*private class SendApduActionTask extends org.jdesktop.application.Task<Object, Void> {
TerminalLoggingWindow log;
Apdu apdu;
SendApduActionTask(org.jdesktop.application.Application app, TerminalLoggingWindow log, Apdu apdu) {
// Runs on the EDT. Copy GUI state that
// doInBackground() depends on from parameters
// to SendApduActionTask fields, here.
super(app);
this.log = log;
this.apdu = apdu;
}
@Override
protected Object doInBackground() {
// Your Task's code here. This method runs
// on a background thread, so don't reference
// the Swing GUI from here.
if (null == log) {
System.out.println("no terminal selected");
return null;
}
GenericTerminal terminal = log.getTerminal();
try {
terminal.checkConnection();
terminal.sendApdu(apdu);
} catch (CardException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
} catch (StopRequestFromUserException e) {
//nothing to do
}
return null; // return your result
}
@Override
protected void succeeded(Object result) {
// Runs on the EDT. Update the GUI based on
// the result computed by doInBackground().
//CardReaderManagerView.this.sendApduButton.setEnabled(true);
//CardReaderManagerView.this.enableCardRelatedComponents(true);
log.gettI().setReserved(false);
CardReaderManagerView.this.enableCardRelatedComponents();
}
}*/
@Action
public void debugButtonAction() {
RmiServerThread rmiServer = new RmiServerThread(this);
Thread rmiServerThread = new Thread(rmiServer);
rmiServerThread.setName("RmiServerThread");
rmiServerThread.setDaemon(true);
rmiServerThread.start();
}
@Action
public void clearLogAction() {
//check if user wanted to clear the app log pane
if (loggingTabbedPane.getSelectedLoggingWindow() == appLoggingWindow) {
loggingTabbedPane.clearHighlightOfSelectedTab();
appLoggingWindow.clear();
} else {
TerminalInfo tIs[] = getSelectedTerminalInfo(false);
if (null != tIs) {
for (int i = 0; i < tIs.length; i++) {
int index = loggingTabbedPane.indexOfComponent(tIs[i].getTopComponentInTab());
loggingTabbedPane.getTerminalLoggingWindowAt(index).clear();
}
} else {
throw new RuntimeException("Could not determine the log to clear");
}
}
}
public int executeTask(SmartCardTask t) throws Exception {
int out = SmartCardTask.SYSTEM_ERROR;
this.getFrame().requestFocusInWindow();
this.getApplication().show(this);
TerminalLoggingWindow log = loggingTabbedPane.getSelectedTerminalLoggingWindow();
if (null == log) {
System.out.println("No connected terminal selected");
return out;
}
TerminalInfo tI = log.gettI();
tI.setWorkingThread(Thread.currentThread());
GenericTerminal terminal = log.getTerminal();
PipedOutputStream pos = log.getStream();
BasicCardReaderTaskExecutor executor = new BasicCardReaderTaskExecutor(false, false, new PrintStream(pos), terminal, log);
try {
out = executor.executeTask(t);
} catch (InterruptedException e) {
//nothing to do
} catch (StopRequestFromUserException e) {
//nothing to do
} catch (Throwable ex) {
PrintStream ps = new PrintStream(pos);
ps.println();
ex.printStackTrace(ps);
System.err.println("ERROR: " + log.getTerminalName());
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
} finally {
//executor.closeMonitoringWindow(false);
executor = null;
log = null;
terminal = null;
pos = null;
tI.setWorkingThread(null);
}
return out;
}
public int executeScript(List<? extends Object> cmds, long nRun, TerminalLoggingWindow log) throws Exception {
int out = SmartCardTask.SYSTEM_ERROR;
TerminalInfo tI = log.gettI();
tI.setWorkingThread(Thread.currentThread());
GenericTerminal terminal = log.getTerminal();
PipedOutputStream pos = log.getStream();
ScriptPlayer player = new ScriptPlayer(tI.getStatusDisplayer());
player.setnRun(nRun);
try {
player.play(terminal, cmds);
} catch (StopRequestFromUserException e) {
//nothing to do
} catch (Throwable ex) {
PrintStream ps = new PrintStream(pos);
ps.println();
ex.printStackTrace(ps);
System.err.println("ERROR: " + log.getTerminalName());
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
} finally {
player = null;
log = null;
terminal = null;
pos = null;
tI.setWorkingThread(null);
}
return out;
}
public class TaskStarter implements Runnable {
File out;
TaskStarter() {
AFileChooser fileChooser;
fileChooser = new AFileChooser((java.awt.Frame) null, true, LAST_TASK_PATH_KEY);
fileChooser.setDialogTitle("Start task");
FileNameExtensionFilter filter = new FileNameExtensionFilter("all jar files", "jar");
fileChooser.addChoosableFileFilter(filter);
filter = new FileNameExtensionFilter("smart card task files", "scardtask");
fileChooser.addChoosableFileFilter(filter);
fileChooser.setAcceptAllFileFilterUsed(true);
int option = fileChooser.showOpenDialog(null);
if (option != JFileChooser.APPROVE_OPTION) {
return;
}
fileChooser.saveCurrentPath();
out = fileChooser.getSelectedFile();
fileChooser.dispose();
}
public void run() {
try {
SmartCardTask task = null;
JarClassLoader cl = null;
try {
if (null == out) {
return;
}
cl = new JarClassLoader(out.toURI().toURL());
InputStream reg = cl.getResourceAsStream("SmartCardTaskRegistrator");
InputStreamReader isr = new InputStreamReader(reg);
BufferedReader in = new BufferedReader(isr);
String className = in.readLine();
String methodName = in.readLine();
in.close();
task = (SmartCardTask) cl.invokeClassStaticMethod(className, methodName);
} catch (ClassNotFoundException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchMethodException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
try {
executeTask(task);
} catch (InterruptedException ex) {
//do nothing
} catch (StopRequestFromUserException ex) {
//do nothing
} catch (Exception ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
} finally {
cl = null;
task = null;
System.gc();
System.gc();//attempt to unload the task to allow replacement of the jar file when debugging
//does not really work :-S
}
} catch (MalformedURLException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
File scriptFile=null;
protected File getScriptFile() {
return scriptFile;
}
protected void browseScriptFile() {
AFileChooser fileChooser;
fileChooser = new AFileChooser((java.awt.Frame) null, true, LAST_TASK_PATH_KEY);
fileChooser.setDialogTitle("Start script");
FileNameExtensionFilter filter = new FileNameExtensionFilter("starScript files", "starScript");
fileChooser.addChoosableFileFilter(filter);
filter = new FileNameExtensionFilter("text files", "txt");
fileChooser.setAcceptAllFileFilterUsed(true);
int option = fileChooser.showOpenDialog(null);
if (option != JFileChooser.APPROVE_OPTION) {
//scriptFile = null;//keep previous file
}
fileChooser.saveCurrentPath();
scriptFile = fileChooser.getSelectedFile();
fileChooser.dispose();
}
public class ScriptStarter implements Runnable {
final File in;
final long nRun;
final TerminalLoggingWindow log;
ScriptStarter(long nRun, TerminalLoggingWindow log) {
in = getScriptFile();
if (null == in) {
this.nRun = 0;
this.log = null;
return;
}
this.nRun = nRun;
this.log = log;
}
ScriptStarter(long nRun, TerminalLoggingWindow log, File in) {
this.log = log;
this.in = in;
this.nRun = nRun;
}
public void run() {
try {
List<? extends Object> cmds;
StarScriptReader script = new StarScriptReader(in);
cmds = script.getCmds();
try {
executeScript(cmds, nRun, log);
} catch (InterruptedException ex) {
//do nothing
} catch (StopRequestFromUserException ex) {
//do nothing
} catch (Throwable ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (IOException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
@Action
public Task addTaskAction() {
return new AddTaskActionTask(getApplication());
}
private class AddTaskActionTask extends org.jdesktop.application.Task<Object, Void> {
TaskStarter startTask;
AddTaskActionTask(org.jdesktop.application.Application app) {
// Runs on the EDT. Copy GUI state that
// doInBackground() depends on from parameters
// to AddTaskActionTask fields, here.
super(app);
startTask = new TaskStarter();
}
@Override
protected Object doInBackground() {
// Your Task's code here. This method runs
// on a background thread, so don't reference
// the Swing GUI from here.
Thread startTaskThread = new Thread(startTask);
startTaskThread.setName("startTaskThread");
startTaskThread.start();
return null; // return your result
}
@Override
protected void succeeded(Object result) {
// Runs on the EDT. Update the GUI based on
// the result computed by doInBackground().
}
}
protected long getNRun() {
long out = -2;
try {
out = Long.decode(nRunTextField.getText());
if (-1 > out) {
String msg = "Number of iteration must be >= -1 and <= " + Long.MAX_VALUE + ".\n(-1 means infinte number of iterations)\n\n";
JOptionPane.showMessageDialog(null, msg, "Incorrect input", JOptionPane.INFORMATION_MESSAGE);
out = -2;
}
} catch (RuntimeException e) {
String msg = "Cannot decode the number of iteration, action cancelled.\n\n";
JOptionPane.showMessageDialog(null, msg, "Incorrect input", JOptionPane.INFORMATION_MESSAGE);
}
return out;
}
@Action
public Task startScriptAction() {
if (this.START_SCRIPT_BUTTON_TEXT.equals(this.startScriptButton.getText())) {
return new StartScriptActionTask(getApplication());
}
TerminalLoggingWindow log = loggingTabbedPane.getSelectedTerminalLoggingWindow();
if (null == log) {
throw new RuntimeException("sendApduAction invoked but loggingTabbedPane.getSelectedTerminalLoggingWindow() return null");
}
if (log.gettI().isBusy()) {
throw new RuntimeException("sendApduAction invoked but log.gettI().isBusy() return true");
}
log.gettI().setReserved(true);
this.enableCardRelatedComponents();
return new CheckScriptActionTask(getApplication(), log, false);
}
StarScriptReader script = null;
private class StartScriptActionTask extends org.jdesktop.application.Task<Object, Void> {
ScriptStarter startScript[];
long nRun;
StartScriptActionTask(org.jdesktop.application.Application app) {
// Runs on the EDT. Copy GUI state that
// doInBackground() depends on from parameters
// to StartScriptActionTask fields, here.
super(app);
nRun = getNRun();
if (-2 != nRun) {
int selected[] = readersList.getSelectedIndices();
TerminalLoggingWindow logs[] = null;
if (0 == selected.length) {//CardReaderManagerView.LIST_IDLE_TERMINALS!=terminalsListSelection){
//in this case, only single terminal is possible
//the terminal is the current one in the log tabs
TerminalLoggingWindow log = loggingTabbedPane.getSelectedTerminalLoggingWindow();
if (null != log) {
logs = new TerminalLoggingWindow[1];
logs[0] = log;
selected = new int[1];
}
} else {
logs = new TerminalLoggingWindow[selected.length];
for (int i = 0; i < selected.length; i++) {
NamedObject o = (NamedObject) readersList.getModel().getElementAt(selected[i]);
TerminalInfo tI = (TerminalInfo) o.getObject();
logs[i] = loggingTabbedPane.getTerminalTab(tI.getTerminal().getName());
}
}
if ((null != logs) && (0 < logs.length)) {
startScript = new ScriptStarter[logs.length];
File in = getScriptFile();
if (null == in) {
nRun = -2;
return;
}
for (int i = 0; i < logs.length; i++) {
logs[i].gettI().setReserved(true);
startScript[i] = new ScriptStarter(nRun, logs[i], in);
}
} else {
System.out.println("No connected terminal selected");
this.nRun = -2;
return;
}
CardReaderManagerView.this.enableCardRelatedComponents();
}
}
@Override
protected Object doInBackground() {
// Your Task's code here. This method runs
// on a background thread, so don't reference
// the Swing GUI from here.
if (-2 != nRun) {
Thread startScriptThread[] = new Thread[startScript.length];
for (int i = 0; i < startScript.length; i++) {
startScriptThread[i] = new Thread(startScript[i]);
startScriptThread[i].setName("startScriptThread" + i);
startScriptThread[i].start();
}
for (int i = 0; i < startScript.length; i++) {
try {
startScriptThread[i].join();
} catch (InterruptedException ex) {
}
}
}
return null; // return your result
}
@Override
protected void succeeded(Object result) {
// Runs on the EDT. Update the GUI based on
// the result computed by doInBackground().
if (null != startScript) {
for (int i = 0; i < startScript.length; i++) {
startScript[i].log.gettI().setReserved(false);
}
}
CardReaderManagerView.this.enableCardRelatedComponents();
}
}
public abstract class MultiTerminalActionTask implements Runnable {
final TerminalLoggingWindow log;
MultiTerminalActionTask(TerminalLoggingWindow log) {
this.log = log;
}
abstract void doAction() throws InterruptedException, StopRequestFromUserException, ScardException, CardNotPresentException;
public void run() {
try {
doAction();
} catch (InterruptedException ex) {
//do nothing
} catch (StopRequestFromUserException ex) {
//do nothing
} catch (Throwable ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private abstract class MultiTerminalActionStarterTask extends org.jdesktop.application.Task<Object, Void> {
MultiTerminalActionTask actionStarters[];
abstract void commonInit();
abstract MultiTerminalActionTask getNewActionTask(TerminalLoggingWindow log);
MultiTerminalActionStarterTask(org.jdesktop.application.Application app) {
// Runs on the EDT. Copy GUI state that
// doInBackground() depends on from parameters
// to MultiTerminalActionStarterTask fields, here.
super(app);
int selected[] = readersList.getSelectedIndices();
TerminalLoggingWindow logs[] = null;
if (0 == selected.length) {//CardReaderManagerView.LIST_IDLE_TERMINALS!=terminalsListSelection){
//in this case, only single terminal is possible
//the terminal is the current one in the log tabs
TerminalLoggingWindow log = loggingTabbedPane.getSelectedTerminalLoggingWindow();
if (null != log) {
logs = new TerminalLoggingWindow[1];
logs[0] = log;
selected = new int[1];
}
} else {
logs = new TerminalLoggingWindow[selected.length];
for (int i = 0; i < selected.length; i++) {
NamedObject o = (NamedObject) readersList.getModel().getElementAt(selected[i]);
TerminalInfo tI = (TerminalInfo) o.getObject();
logs[i] = loggingTabbedPane.getTerminalTab(tI.getTerminal().getName());
if(null==logs[i])
throw new RuntimeException("null==logs["+i+"] ! (tI.getTerminal().getName()="+tI.getTerminal().getName()+")");
}
}
if ((null != logs) && (0 < logs.length)) {
actionStarters = new MultiTerminalActionTask[logs.length];
commonInit();
for (int i = 0; i < logs.length; i++) {
TerminalInfo tI=logs[i].gettI();
tI.setReserved(true);
actionStarters[i] = getNewActionTask(logs[i]);
}
} else {
System.out.println("No connected terminal selected");
return;
}
CardReaderManagerView.this.enableCardRelatedComponents();
}
@Override
protected Object doInBackground() {
// Your Task's code here. This method runs
// on a background thread, so don't reference
// the Swing GUI from here.
Thread actionThread[] = new Thread[actionStarters.length];
for (int i = 0; i < actionStarters.length; i++) {
actionThread[i] = new Thread(actionStarters[i]);
actionThread[i].setName("scardAction" + i);
actionThread[i].start();
}
for (int i = 0; i < actionStarters.length; i++) {
try {
actionThread[i].join();
} catch (InterruptedException ex) {
}
}
return null; // return your result
}
@Override
protected void succeeded(Object result) {
// Runs on the EDT. Update the GUI based on
// the result computed by doInBackground().
if (null != actionStarters) {
for (int i = 0; i < actionStarters.length; i++) {
actionStarters[i].log.gettI().setReserved(false);
}
}
CardReaderManagerView.this.enableCardRelatedComponents();
}
}
@Action
public Task browseScriptAction() {
TerminalLoggingWindow log = loggingTabbedPane.getSelectedTerminalLoggingWindow();
if (null == log) {
throw new RuntimeException("sendApduAction invoked but loggingTabbedPane.getSelectedTerminalLoggingWindow() return null");
}
if (log.gettI().isBusy()) {
throw new RuntimeException("sendApduAction invoked but log.gettI().isBusy() return true");
}
return new CheckScriptActionTask(getApplication(), log, true);
}
private class CheckScriptActionTask extends org.jdesktop.application.Task<Object, Void> {
boolean browse;
TerminalLoggingWindow log;
CheckScriptActionTask(org.jdesktop.application.Application app, TerminalLoggingWindow log, boolean browse) {
// Runs on the EDT. Copy GUI state that
// doInBackground() depends on from parameters
// to BrowseScriptActionTask fields, here.
super(app);
this.browse = browse;
this.log = log;
}
@Override
protected Object doInBackground() {
script = null;
try {
// Your Task's code here. This method runs
// on a background thread, so don't reference
// the Swing GUI from here.
if (browse) {
browseScriptFile();
}
if (null != scriptFile) {
try {
script = new StarScriptReader(scriptFile);
} catch (InputFileFormatException e) {
String msg = "Failed to open input file \"" + scriptFile.getName() + "\"\n\n" + e.getMessage() + "\n";
JOptionPane.showMessageDialog(null, msg);
return null;
}
}
// return your result
} catch (FileNotFoundException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
scriptFile = null;
} catch (IOException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
scriptFile = null;
}
return script; // return your result
}
@Override
protected void succeeded(Object result) {
// Runs on the EDT. Update the GUI based on
// the result computed by doInBackground().
if (null != result) {
CardReaderManagerView.this.scriptFileTextField.setText(scriptFile.getName());
CardReaderManagerView.this.scriptFileTextField.setToolTipText(scriptFile.getAbsolutePath());
CardReaderManagerView.this.startScriptButton.setText(START_SCRIPT_BUTTON_TEXT);
CardReaderManagerView.this.startScriptButton.setEnabled(true);
} else {
if (null != scriptFile) {
CardReaderManagerView.this.scriptFileTextField.setText(scriptFile.getName());
CardReaderManagerView.this.scriptFileTextField.setToolTipText(scriptFile.getAbsolutePath());
CardReaderManagerView.this.startScriptButton.setText(CHECK_SCRIPT_BUTTON_TEXT);
CardReaderManagerView.this.startScriptButton.setEnabled(true);
} else {
CardReaderManagerView.this.scriptFileTextField.setText("");
CardReaderManagerView.this.scriptFileTextField.setToolTipText("Please use the browse button to select a file");
CardReaderManagerView.this.startScriptButton.setEnabled(false);
}
}
log.gettI().setReserved(false);
CardReaderManagerView.this.enableCardRelatedComponents();
}
}
final public String START_SCRIPT_BUTTON_TEXT = "Start";
final public String CHECK_SCRIPT_BUTTON_TEXT = "Check";
@Action
public void moveLoggers() {
if (this.moveLoggersButton.getText().equals(">")) {
addLogHandler();
} else {
removeLogHandler();
}
}
@Action
public void clearApduButton() {
this.apduComboBox.setModel(new DefaultComboBoxModel());
}
@Action
public Task garbageCollectorAction() {
return new GarbageCollectorActionTask(getApplication());
}
private class GarbageCollectorActionTask extends org.jdesktop.application.Task<Object, Void> {
GarbageCollectorActionTask(org.jdesktop.application.Application app) {
// Runs on the EDT. Copy GUI state that
// doInBackground() depends on from parameters
// to GarbageCollectorActionTask fields, here.
super(app);
}
@Override
protected Object doInBackground() {
// Your Task's code here. This method runs
// on a background thread, so don't reference
// the Swing GUI from here.
System.gc();
return null; // return your result
}
@Override
protected void succeeded(Object result) {
// Runs on the EDT. Update the GUI based on
// the result computed by doInBackground().
}
}
@Action
public Task debugBackgroundAction() {
return new DebugBackgroundActionTask(getApplication());
}
private class DebugBackgroundActionTask extends org.jdesktop.application.Task<Object, Void> {
SmartCardTaskProcessor engine;
DebugBackgroundActionTask(org.jdesktop.application.Application app) {
// Runs on the EDT. Copy GUI state that
// doInBackground() depends on from parameters
// to DebugBackgroundActionTask fields, here.
super(app);
engine = CardReaderManagerView.this;
}
@Override
protected Object doInBackground() {
// Your Task's code here. This method runs
// on a background thread, so don't reference
// the Swing GUI from here.
RmiServerThread rmiServer = new RmiServerThread(engine);
Thread rmiServerThread = new Thread(rmiServer);
rmiServerThread.setName("RmiServerThread");
rmiServerThread.setDaemon(true);
rmiServerThread.start();
return null; // return your result
}
@Override
protected void succeeded(Object result) {
// Runs on the EDT. Update the GUI based on
// the result computed by doInBackground().
}
}
String debugPass = "";
final static String DEBUG_PASS = "babba";
@Action
public void debugModeAction() {
String inputValue = JOptionPane.showInputDialog("Please enter password");
if (inputValue.equals(DEBUG_PASS)) {
debugMenu.setVisible(!debugMenu.isVisible());
}
}
@Action
public void openAllTerminalsAction() {
openAllTerminalsAction(false);
}
@Action
public void openAllTerminalsWithCardAction() {
openAllTerminalsAction(true);
}
void openAllTerminalsAction(boolean requireCardPresent) {
int added=0;
int lastIndex=0;
for(TerminalInfo tI:terminals.values()){
try {
if (tI.isInTab()) {
continue;
}
if (requireCardPresent & !tI.getTerminal().isCardPresent()) {
continue;
}
String name = tI.getTerminal().getName();
StatusDisplayerLabel sdl = new StatusDisplayerLabel();
sdl.setText(name);
tI.setStatusDisplayer(sdl);
int index = loggingTabbedPane.getTabCount();
lastIndex=index;
TerminalLoggingWindow logWindow;
try {
logWindow = new TerminalLoggingWindow(tI);
loggingTabbedPane.addTab(name, logWindow);
tI.setTopComponentInTab(loggingTabbedPane.getComponentAt(index));
added++;
} catch (IOException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (ScardException ex) {
Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
}
}
if(added>0){
controlTabbedPane.add(logControlPanel);
terminalsListButtonGroup.setSelected(openedRadioButton.getModel(), true);
openedAction().run();
DefaultListModel model = (DefaultListModel) readersList.getModel();
readersList.setSelectionInterval(0, model.size()-1);
enableConnectedTerminalsLists(true);
loggingTabbedPane.setSelectedIndex(lastIndex);
}else{
JOptionPane.showMessageDialog(null, "Could not find any terminal to connect");
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JComboBox apduComboBox;
private javax.swing.JTextField apduHeaderTextField;
private javax.swing.JList availableLoggersList;
private javax.swing.JRadioButton availableRadioButton;
private javax.swing.JButton browseScriptButton;
private javax.swing.JRadioButton busyRadioButton;
private javax.swing.JButton cardConnectButton;
private javax.swing.JButton cardConnectButton1;
private javax.swing.JButton cardDisconnectButton;
private javax.swing.JButton clearApduButton;
private javax.swing.JButton clearLogButton;
private javax.swing.JTabbedPane controlTabbedPane;
private javax.swing.JMenuItem debugBackGroundMenuItem;
private javax.swing.JMenu debugMenu;
private javax.swing.JMenuItem debugMenuItem;
private javax.swing.JMenuItem debugModeMenuItem;
private javax.swing.JPanel dummySharedPanel;
private javax.swing.JMenuItem garbageCollectorMenuItem;
private javax.swing.JRadioButton idleRadioButton;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JScrollPane jScrollPane4;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JEditorPane lcDataEditor;
private javax.swing.JTextField lcTextField;
private javax.swing.JTextField leTextField;
private javax.swing.JPanel logControlPanel;
private uk.co.nimp.scardterminalmanager.LogTabbedPane loggingTabbedPane;
private javax.swing.JPanel mainPanel;
private javax.swing.JPanel manualControlPanel;
private javax.swing.JPanel manualSharedPanel;
private javax.swing.JMenuBar menuBar;
private javax.swing.JButton moveLoggersButton;
private javax.swing.JTextField nRunTextField;
private javax.swing.JRadioButton noCardRadioButton;
private javax.swing.JButton openAllTerminalsButton;
private javax.swing.JButton openAllTerminalsWithCardButton;
private javax.swing.JRadioButton openedRadioButton;
private javax.swing.JProgressBar progressBar;
private javax.swing.JList readersList;
private javax.swing.JList registeredLoggersList;
private javax.swing.JTextField scriptFileTextField;
private javax.swing.JPanel scriptPanel;
private javax.swing.JButton sendApduButton;
private javax.swing.JButton sendApduNoLcButton;
private javax.swing.JButton sendApduNoLeButton;
private javax.swing.JPanel sharedPanel;
private javax.swing.JButton startScriptButton;
private javax.swing.JButton startTaskButton;
private javax.swing.JLabel statusAnimationLabel;
private javax.swing.JLabel statusMessageLabel;
private javax.swing.JPanel statusPanel;
private javax.swing.JPanel taskPanel;
private javax.swing.JPanel terminalConnectedPanel;
private javax.swing.ButtonGroup terminalsListButtonGroup;
// End of variables declaration//GEN-END:variables
private final Timer messageTimer;
private final Timer busyIconTimer;
private final Icon idleIcon;
private final Icon[] busyIcons = new Icon[15];
private int busyIconIndex = 0;
private JDialog aboutBox;
Timer terminalListRefreshTimer;
}