/*
* ALMA - Atacama Large Millimiter Array (c) European Southern Observatory, 2011
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package alma.acs.alarm.gui.senderpanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Collection;
import java.util.Properties;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import alma.acs.alarm.gui.senderpanel.SenderPanelUtils.AlarmDescriptorType;
import alma.acs.alarm.gui.senderpanel.SenderPanelUtils.Triplet;
import alma.acs.alarm.gui.senderpanel.table.AlarmsSentTable;
import alma.acs.component.client.AdvancedComponentClient;
import alma.acs.container.ContainerServices;
import alma.acs.logging.ClientLogManager;
import cern.laser.source.alarmsysteminterface.FaultState;
/**
* A panel to send alarms.
*
* The panel allows the user to send alarms with a simple GUI,
* by triplet or selecting a file.
* <P>
* While sending by triplet the user defines the triplet, the activation mode
* and the user properties. There is a button to send the alarm.
* <BR>
* To send by file/CDB, the user select a text file with the definition of the alarms then it has 3 options
* <UL>
* <LI>activate all the alarms of the file/CDB
* <LI>terminate all the alarms of the file/CDB
* <LI>randomly activate/clear the alarms of the file/CDB
* </UL>
* <BR>
* The last option activates a thread that activates/clears the alarms defined in the the file.
* The user has to press again the button to stop sending alarms in this way.
*
* @author acaproni
*/
public class SenderPanel
extends JFrame
implements ActionListener, DocumentListener, AlarmSentListener, SlowTaskListener, TableModelListener {
/**
* ACS component client
*/
private AdvancedComponentClient acsClient;
/**
* The logger
*/
private Logger logger;
/**
* ContainerServices
*/
private final ContainerServices contSvcs;
/**
* The text file to insert the triplet
*/
private final JTextField tripletTF = new JTextField();
/**
* The text file to insert the properties
*/
private final JTextField propsTF = new JTextField();
/**
* The (active) state of the alarm to send
* <P>
* The name of the button contains the FaultState descriptor
*/
private final JRadioButton activeRB = new JRadioButton("Active");
/**
* The (change) state of the alarm to send
* <P>
* The name of the button contains the FaultState descriptor
*/
private final JRadioButton changeRB = new JRadioButton("Change");
/**
* The (terminate) state of the alarm to send
* <P>
* The name of the button contains the FaultState descriptor
*/
private final JRadioButton terminateRB = new JRadioButton("Terminate");
/**
* The (instant) state of the alarm to send
* <P>
* The name of the button contains the FaultState descriptor
*/
private final JRadioButton instantRB = new JRadioButton("Instant");
/**
* Select the sending mode by triplet
*/
private final JRadioButton sendFromTripletRB = new JRadioButton("Triplet");
/**
* Select the sending mode by file
*/
private final JRadioButton sendFromFileRB = new JRadioButton("File");
/**
* Select the sending mode by file
*/
private final JRadioButton sendFromCdbRB = new JRadioButton("TM/CDB");
/**
* It contains the radio buttons for the mode of sending alarms
*/
private final ButtonGroup sendingBG = new ButtonGroup();
/**
* The array with the buttons to facilitate getting their state
*/
private final JRadioButton[] descriptorBtns = {
activeRB,terminateRB,changeRB,instantRB
};
/**
* It contains the radio buttons for the activation
* of an alarm
*/
private final ButtonGroup activationBG = new ButtonGroup();
/**
* The button to send the alarm
*/
private final JButton sendTripletBtn = new JButton("Send");
/**
* The button to choose the file
*/
private final JButton chooseFiletBtn = new JButton("File");
/**
* The label with the name of the file
*/
private final JTextField fileNameTF = new JTextField();
/**
* The label with the number of alarms read from TM/CDB
*/
private final JTextField cdbAlarmsTF = new JTextField();
/**
* The button to activate all the alarms read from the file
*/
private final JToggleButton activateFromFileBtn = new JToggleButton("Activate all");
/**
* The button to terminate all the alarms read from the file
*/
private final JToggleButton terminateFromFileBtn = new JToggleButton("Terminate all");
/**
* The button to randomly activate/terminate the alarms contained in the file
*/
private final JToggleButton cycleFromFileBtn = new JToggleButton("Cycle");
/**
* The button to activate all the alarms read from TM/CDB
*/
private final JToggleButton activateFromCdbBtn = new JToggleButton("Activate all");
/**
* The button to terminate all the alarms read from TM/CDB
*/
private final JToggleButton terminateFromCdbBtn = new JToggleButton("Terminate all");
/**
* The button to randomly activate/terminate the alarms read from TM/CDB
*/
private final JToggleButton cycleFromCdbBtn = new JToggleButton("Cycle");
/**
* The list of the active alarms: the user can select
* and clear them
*/
private final AlarmsSentTable alarmsSent = new AlarmsSentTable();
/**
* The button to clear the alarm selected int he list
*/
private final JButton clearSelectedAlarmsBtn = new JButton("Clear selected");
/**
* The button to clear all the alarms
*/
private final JButton clearAllBtn = new JButton("Clear all");
/**
* The button to close the application
*/
private final JButton closeBtn = new JButton("Done");
/**
* The object to send alarms (ACS alarm sender)
*/
private final ParallelAlarmSender alarmSender;
/**
* The helper to send alarms read from a file
*/
private final FileSender fileSender;
/**
* The helper to send alarms read from TM/CDB
*/
private final CDBSender cdbSender;
/**
* The progress bar for long lasting operations from file
*/
private final JProgressBar fileTasksPB = new JProgressBar();
/**
* The progress bar for long lasting operations from TM/CDB
*/
private final JProgressBar cdbTasksPB = new JProgressBar();
/**
* The number of alarm read from the TM/CDB
*/
private volatile int numOfAlarmsFromCDB=0;
/**
* The number of alarm read from a file
*/
private volatile int numOfAlarmsFromFile=0;
/**
* The panel with the widgets to send larms by triplet
*/
private final JPanel tripletWdgtsPnl = new JPanel();
/**
* The panel with the widgets to send alarms by file
*/
private final JPanel fileWdgtsPnl = new JPanel();
/**
* The panel with the widgets to send alarms by TM/CDB
*/
private final JPanel cdbWdgtsPnl = new JPanel();
/**
* Constructor
*/
public SenderPanel() throws Exception {
super("Alarm sender panel");
try {
initACS();
} catch (Throwable t) {
JOptionPane.showMessageDialog(null, t.getMessage(), "Error initializing ACS", JOptionPane.ERROR_MESSAGE);
throw new Exception("Error intializing the ACS client",t);
}
contSvcs=acsClient.getContainerServices();
try {
alarmSender = new ParallelAlarmSender(contSvcs,200,0);
} catch (Throwable t) {
JOptionPane.showMessageDialog(null, t.getMessage(), "Error initializing AlarmSender", JOptionPane.ERROR_MESSAGE);
throw new Exception("Error intializing the alarm sender",t);
}
initGUI();
alarmSender.addListener(this);
alarmSender.start();
fileSender=new FileSender(this,contSvcs,alarmSender);
fileSender.addSlowTaskListener(this);
cdbSender=new CDBSender(this,contSvcs,alarmSender);
cdbSender.addSlowTaskListener(this);
}
/**
* Initialize the GUI
*/
private void initGUI() {
super.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
super.windowClosed(e);
close();
}
});
/////////////////////////////////////////////////////////
// The panel to send alarms by triplet or file
//
// This panel contains:
// * one panel to send alarms by triplet
// * one to send alarms by file
// * one to send alarms by CDB
// The user can select only one sending type by means
// of a radio button.
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
// The panel to send alarm by writing the triplet
//
// The panel has a radio button to select the sending by
// triplet and a panel that contains all the widgets
// needed by this sending mode.
/////////////////////////////////////////////////////////
JPanel tripletPnl = new JPanel(new BorderLayout());
tripletPnl.add(sendFromTripletRB,BorderLayout.WEST);
sendTripletBtn.setEnabled(false);
// The panel with all the widgets to send alarms by triplets
// It has 3 lines: triplet, descriptor and properties
tripletWdgtsPnl.setBorder(BorderFactory.createTitledBorder("Triplet sender"));
BoxLayout tripetWdgtsLayoout = new BoxLayout(tripletWdgtsPnl, BoxLayout.Y_AXIS);
tripletWdgtsPnl.setLayout(tripetWdgtsLayoout);
// Line 1: triplet text field and send button
JPanel sendTripletPnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
sendTripletPnl.add(tripletTF);
tripletTF.setColumns(40);
tripletTF.getDocument().addDocumentListener(this);
tripletTF.setToolTipText("Insert triplet: FaultFamily,FaultMember,1");
sendTripletBtn.setEnabled(false);
sendTripletBtn.addActionListener(this);
sendTripletPnl.add(sendTripletBtn);
// Line 2: the descriptor
JPanel descriptorWdgtPnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
descriptorWdgtPnl.add(new JLabel("Descriptor: "));
activeRB.setName(FaultState.ACTIVE);
terminateRB.setName(FaultState.TERMINATE);
changeRB.setName(FaultState.CHANGE);
instantRB.setName(FaultState.INSTANT);
descriptorWdgtPnl.add(activeRB);
descriptorWdgtPnl.add(terminateRB);
descriptorWdgtPnl.add(changeRB);
descriptorWdgtPnl.add(instantRB);
activeRB.setSelected(true);
// Line 3: the properties
JPanel propsWdgtsPnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
propsWdgtsPnl.add(new JLabel("Properties"));
propsWdgtsPnl.add(propsTF);
propsTF.setColumns(40);
propsTF.setToolTipText("User properties key=val, key2=val2,....");
// Add the three lines of widgets
tripletWdgtsPnl.add(sendTripletPnl);
tripletWdgtsPnl.add(descriptorWdgtPnl);
tripletWdgtsPnl.add(propsWdgtsPnl);
tripletPnl.add(tripletWdgtsPnl,BorderLayout.CENTER);
/////////////////////////////////////////////////////////
// The panel to send alarm by selecting a file
//
// The panel has a radio button to select the sending by
// file and a panel that contains all the widgets
// needed by this sending mode.
/////////////////////////////////////////////////////////
JPanel filePnl = new JPanel(new BorderLayout());
filePnl.add(sendFromFileRB,BorderLayout.WEST);
sendFromFileRB.setPreferredSize(sendFromTripletRB.getPreferredSize());
sendFromFileRB.setMinimumSize(sendFromTripletRB.getMinimumSize());
// The panel with all the widgets to send alarms by file
// It has 2 lines: one to select the file and another one with the control buttons
fileWdgtsPnl.setBorder(BorderFactory.createTitledBorder("File sender"));
BoxLayout fileWdgtsLayoout = new BoxLayout(fileWdgtsPnl, BoxLayout.Y_AXIS);
fileWdgtsPnl.setLayout(fileWdgtsLayoout);
// Line 1: widgets to select the file
JPanel selectFilePnl = new JPanel(new FlowLayout(FlowLayout.RIGHT));
fileNameTF.setColumns(40);
fileNameTF.setEditable(false);
fileNameTF.setText("");
selectFilePnl.add(fileNameTF);
selectFilePnl.add(chooseFiletBtn);
// Line 2: widgets to control the sending mode
JPanel ctrlsFilePnl = new JPanel(new BorderLayout());
JPanel ctrlsButtonsPnl = new JPanel(new FlowLayout(FlowLayout.RIGHT));
ctrlsFilePnl.add(fileTasksPB,BorderLayout.CENTER);
fileTasksPB.setValue(0);
fileTasksPB.setIndeterminate(false);
ctrlsButtonsPnl.add(activateFromFileBtn);
ctrlsButtonsPnl.add(terminateFromFileBtn);
ctrlsButtonsPnl.add(cycleFromFileBtn);
ctrlsFilePnl.add(ctrlsButtonsPnl,BorderLayout.EAST);
// Add the two lines of widgets
fileWdgtsPnl.add(selectFilePnl);
fileWdgtsPnl.add(ctrlsFilePnl);
filePnl.add(fileWdgtsPnl,BorderLayout.CENTER);
/////////////////////////////////////////////////////////
// The panel to send alarm read from TM/CDB
//
// The panel has a radio button to select the sending by
// file and a panel that contains all the widgets
// needed by this sending mode.
/////////////////////////////////////////////////////////
JPanel cdbPnl = new JPanel(new BorderLayout());
cdbPnl.add(sendFromCdbRB,BorderLayout.WEST);
sendFromCdbRB.setPreferredSize(sendFromTripletRB.getPreferredSize());
sendFromCdbRB.setMinimumSize(sendFromTripletRB.getMinimumSize());
// The panel with all the widgets to send alarms by file
// It has 2 lines: one to select the file and another one with the control buttons
cdbWdgtsPnl.setBorder(BorderFactory.createTitledBorder("TM/CDB sender"));
BoxLayout cdbWdgtsLayoout = new BoxLayout(cdbWdgtsPnl, BoxLayout.Y_AXIS);
cdbWdgtsPnl.setLayout(cdbWdgtsLayoout);
// Line 1: widgets to show the number of alarms read from TM/CDB
JPanel showCdbPnl = new JPanel(new FlowLayout(FlowLayout.RIGHT));
cdbAlarmsTF.setColumns(40);
cdbAlarmsTF.setEditable(false);
cdbAlarmsTF.setText("");
showCdbPnl.add(cdbAlarmsTF);
// Line 2: widgets to control the sending mode
JPanel ctrlsCDBPnl = new JPanel(new BorderLayout());
JPanel ctrlsCDBButtonsPnl = new JPanel(new FlowLayout(FlowLayout.RIGHT));
ctrlsCDBPnl.add(cdbTasksPB,BorderLayout.CENTER);
cdbTasksPB.setValue(0);
cdbTasksPB.setIndeterminate(false);
ctrlsCDBButtonsPnl.add(activateFromCdbBtn);
ctrlsCDBButtonsPnl.add(terminateFromCdbBtn);
ctrlsCDBButtonsPnl.add(cycleFromCdbBtn);
ctrlsCDBPnl.add(ctrlsCDBButtonsPnl,BorderLayout.EAST);
// Add the two lines of widgets
cdbWdgtsPnl.add(showCdbPnl);
cdbWdgtsPnl.add(ctrlsCDBPnl);
cdbPnl.add(cdbWdgtsPnl,BorderLayout.CENTER);
// Finally add the triplet, the file and the CDB panels to the alarm sender panel
JPanel alrmSenderPnl = new JPanel(new BorderLayout());
alrmSenderPnl.add(tripletPnl,BorderLayout.NORTH);
JPanel fileAndCDBSenderPnl = new JPanel(new BorderLayout());
fileAndCDBSenderPnl.add(filePnl,BorderLayout.NORTH);
fileAndCDBSenderPnl.add(cdbPnl,BorderLayout.SOUTH);
alrmSenderPnl.add(fileAndCDBSenderPnl,BorderLayout.SOUTH);
alrmSenderPnl.setBorder(BorderFactory.createTitledBorder("Send alarm"));
add(alrmSenderPnl,BorderLayout.NORTH);
/////////////////////////////////////////////////////////
// The panel to clear alarms
/////////////////////////////////////////////////////////
JPanel alarmClearingPnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
alarmClearingPnl.setBorder(BorderFactory.createTitledBorder("Alarm clearing"));
JScrollPane scrollPane = new JScrollPane(alarmsSent);
alarmsSent.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
alarmsSent.getModel().addTableModelListener(this);
alarmClearingPnl.add(scrollPane);
JPanel clearingBtnsPnl = new JPanel();
BoxLayout layout = new BoxLayout(clearingBtnsPnl, BoxLayout.Y_AXIS);
clearingBtnsPnl.setLayout(layout);
clearingBtnsPnl.add(clearAllBtn);
Dimension minSize = new Dimension(5, 10);
Dimension prefSize = new Dimension(5, 10);
Dimension maxSize = new Dimension(Short.MAX_VALUE, 10);
clearingBtnsPnl.add(new Box.Filler(minSize, prefSize, maxSize));
clearingBtnsPnl.add(clearSelectedAlarmsBtn);
clearAllBtn.setEnabled(false);
clearAllBtn.addActionListener(this);
clearSelectedAlarmsBtn.setEnabled(true);
clearSelectedAlarmsBtn.addActionListener(this);
alarmClearingPnl.add(clearingBtnsPnl);
add(alarmClearingPnl,BorderLayout.CENTER);
JPanel donePnl = new JPanel(new FlowLayout(FlowLayout.CENTER));
donePnl.add(closeBtn);
closeBtn.addActionListener(this);
add(donePnl,BorderLayout.SOUTH);
// Add the listeners
sendFromTripletRB.setSelected(true);
sendFromFileRB.addActionListener(this);
sendFromTripletRB.addActionListener(this);
sendFromCdbRB.addActionListener(this);
chooseFiletBtn.addActionListener(this);
activateFromFileBtn.addActionListener(this);
terminateFromFileBtn.addActionListener(this);
cycleFromFileBtn.addActionListener(this);
activateFromCdbBtn.addActionListener(this);
terminateFromCdbBtn.addActionListener(this);
cycleFromCdbBtn.addActionListener(this);
// Set the button groups
sendingBG.add(sendFromTripletRB);
sendingBG.add(sendFromFileRB);
sendingBG.add(sendFromCdbRB);
activationBG.add(activeRB);
activationBG.add(changeRB);
activationBG.add(terminateRB);
activationBG.add(instantRB);
pack();
setVisible(true);
ratioSenderModeButtons();
}
private void initACS() throws Exception {
// Connect to ACS
logger = ClientLogManager.getAcsLogManager().getLoggerForApplication("AlarmSenderPanel",true);
String managerLoc = System.getProperty("ACS.manager");
if (managerLoc == null) {
System.out.println("Java property 'ACS.manager' must be set to the corbaloc of the ACS manager!");
System.exit(-1);
}
acsClient = new AdvancedComponentClient(logger,managerLoc,"AlarmSenderPanel");
}
private void close() {
if (cdbSender!=null) {
cdbSender.close();
}
if (fileSender!=null) {
fileSender.close();
}
if (alarmSender!=null) {
alarmSender.close();
}
try {
if (acsClient!=null) {
acsClient.tearDown();
}
} catch (Throwable t) {
System.err.println("Error closing ComponentClient: "+t.getMessage());
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource()==closeBtn) {
setVisible(false);
this.dispose();
} else if (e.getSource()==sendTripletBtn) {
sendAlarm(tripletTF.getText().trim(), getDescriptor(), propsTF.getText());
} else if (e.getSource()==clearAllBtn) {
clearAllAlarms();
} else if (e.getSource()==clearSelectedAlarmsBtn) {
clearSelectedAlarms();
} else if (e.getSource()==sendFromFileRB) {
ratioSenderModeButtons();
} else if (e.getSource()==sendFromCdbRB) {
ratioSenderModeButtons();
} else if (e.getSource()==sendFromTripletRB) {
ratioSenderModeButtons();
} else if (e.getSource()==chooseFiletBtn) {
fileSender.selectFile();
cycleFromFileBtn.setEnabled(fileSender.size()>0);
terminateFromFileBtn.setEnabled(fileSender.size()>0);
activateFromFileBtn.setEnabled(fileSender.size()>0);
} else if (e.getSource()==activateFromFileBtn) {
if (activateFromFileBtn.isSelected()) {
fileSender.sendAlarms(true);
terminateFromFileBtn.setEnabled(false);
cycleFromFileBtn.setEnabled(false);
activateFromFileBtn.setEnabled(true);
} else {
fileSender.stopThread();
}
} else if (e.getSource()==terminateFromFileBtn) {
if (terminateFromFileBtn.isSelected()) {
fileSender.sendAlarms(false);
terminateFromFileBtn.setEnabled(true);
cycleFromFileBtn.setEnabled(false);
activateFromFileBtn.setEnabled(false);
} else {
fileSender.stopThread();
}
} else if (e.getSource()==cycleFromFileBtn) {
boolean selected=cycleFromFileBtn.isSelected();
if (selected) {
fileSender.startSendingRandomly();
terminateFromFileBtn.setEnabled(false);
cycleFromFileBtn.setEnabled(true);
activateFromFileBtn.setEnabled(false);
} else {
fileSender.stopThread();
}
sendFromFileRB.setEnabled(!selected);
sendFromTripletRB.setEnabled(!selected);
sendFromCdbRB.setEnabled(!selected);
} else if (e.getSource()==activateFromCdbBtn) {
if (activateFromCdbBtn.isSelected()) {
cdbSender.sendAlarms(true);
terminateFromCdbBtn.setEnabled(false);
cycleFromCdbBtn.setEnabled(false);
activateFromCdbBtn.setEnabled(true);
} else {
cdbSender.stopThread();
}
} else if (e.getSource()==terminateFromCdbBtn) {
if (terminateFromCdbBtn.isSelected()) {
cdbSender.sendAlarms(false);
terminateFromCdbBtn.setEnabled(true);
cycleFromCdbBtn.setEnabled(false);
activateFromCdbBtn.setEnabled(false);
} else {
cdbSender.stopThread();
}
} else if (e.getSource()==cycleFromCdbBtn) {
boolean selected=cycleFromCdbBtn.isSelected();
if (selected) {
cdbSender.startSendingRandomly();
terminateFromCdbBtn.setEnabled(false);
cycleFromCdbBtn.setEnabled(true);
activateFromCdbBtn.setEnabled(false);
} else {
cdbSender.stopThread();
}
sendFromCdbRB.setEnabled(!selected);
sendFromFileRB.setEnabled(!selected);
sendFromTripletRB.setEnabled(!selected);
} else {
System.out.println("Unknown event source: "+e.getSource());
}
}
public static void main(String[] args) {
try {
new SenderPanel();
} catch (Throwable t) {
System.err.println("Exception caught: "+t.getMessage());
t.printStackTrace();
}
}
@Override
public void insertUpdate(DocumentEvent e) {
sendTripletBtn.setEnabled(SenderPanelUtils.isATriplet(tripletTF.getText()) && alarmSender!=null);
}
@Override
public void removeUpdate(DocumentEvent e) {
sendTripletBtn.setEnabled(SenderPanelUtils.isATriplet(tripletTF.getText()) && alarmSender!=null);
}
@Override
public void changedUpdate(DocumentEvent e) {
sendTripletBtn.setEnabled(SenderPanelUtils.isATriplet(tripletTF.getText()) && alarmSender!=null);
}
/**
* Send an alarm by delegating to the {@link AlarmSender}.
* <P>
* This method must not be executed inside the swing thread.
*
* @param triplet The triplet in the format FF,FM,FC
* @param descriptor The {@link FaultState} descriptor
* @param props The user properties
*/
private void sendAlarm(final String triplet, final String descriptor, final String props) {
// Check if the triplet is well formed
if (!SenderPanelUtils.isATriplet(triplet)) {
JOptionPane.showMessageDialog(null, "Error building alarm triplet from "+triplet, "Syntax error", JOptionPane.ERROR_MESSAGE);
return;
}
// Check if the property string is well formed
if (props!=null && !props.trim().isEmpty() && !SenderPanelUtils.isAStringOfProperties(props)) {
JOptionPane.showMessageDialog(null, "Error building alarm props from "+props, "Syntax error", JOptionPane.ERROR_MESSAGE);
return;
}
// Get the properties and the Triplet
Triplet alarmTriplet = null;
Properties userProps=null;
try {
alarmTriplet = SenderPanelUtils.tripletFromString(triplet);
userProps=SenderPanelUtils.propertiesFromString(props);
} catch (Throwable t) {
// Should never happen!
JOptionPane.showMessageDialog(null, "Error building alarm props from "+triplet+", props="+props, "Unknown error", JOptionPane.ERROR_MESSAGE);
return;
}
AlarmDescriptorType alarmActivationType=null;
try {
alarmActivationType=AlarmDescriptorType.fromDescriptor(descriptor);
} catch (Throwable t) {
// Should never happen!
JOptionPane.showMessageDialog(null, "Error building alarm descriptor from "+descriptor, "Unknown error", JOptionPane.ERROR_MESSAGE);
return;
}
try {
alarmSender.send(alarmTriplet,alarmActivationType,userProps);
} catch (InterruptedException ie) {}
}
private void clearAllAlarms() {
Collection<Triplet> triplets= alarmsSent.getAlarms();
for (Triplet triplet: triplets) {
String tripletStr=triplet.faultFamily+","+triplet.faultMember+","+triplet.faultCode;
sendAlarm(tripletStr, FaultState.TERMINATE, null);
}
}
private void clearSelectedAlarms() {
Collection<Triplet> triplets= alarmsSent.getSelectedAlarms();
for (Triplet triplet: triplets) {
String tripletStr=triplet.faultFamily+","+triplet.faultMember+","+triplet.faultCode;
sendAlarm(tripletStr, FaultState.TERMINATE, null);
}
}
/**
* The state descriptor from the radio buttons
*
* @return The state descriptor
*/
private String getDescriptor() {
for (JRadioButton btn: descriptorBtns) {
if (btn.isSelected()) {
return btn.getName();
}
}
throw new IllegalStateException("Descriptor not found");
}
/**
* Enable/disable the widgets depending on the sending mode
*/
private void ratioSenderModeButtons() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
tripletTF.setEnabled(sendFromTripletRB.isSelected());
sendTripletBtn.setEnabled(sendFromTripletRB.isSelected() && SenderPanelUtils.isATriplet(tripletTF.getText()));
activeRB.setEnabled(sendFromTripletRB.isSelected());
changeRB.setEnabled(sendFromTripletRB.isSelected());
terminateRB.setEnabled(sendFromTripletRB.isSelected());
instantRB.setEnabled(sendFromTripletRB.isSelected());
propsTF.setEnabled(sendFromTripletRB.isSelected());
chooseFiletBtn.setEnabled(sendFromFileRB.isSelected());
fileNameTF.setEnabled(sendFromFileRB.isSelected());
activateFromFileBtn.setEnabled(sendFromFileRB.isSelected() && numOfAlarmsFromFile>0);
terminateFromFileBtn.setEnabled(sendFromFileRB.isSelected() && numOfAlarmsFromFile>0);
cycleFromFileBtn.setEnabled(sendFromFileRB.isSelected() && numOfAlarmsFromFile>0);
cdbAlarmsTF.setEnabled(sendFromCdbRB.isSelected());
activateFromCdbBtn.setEnabled(sendFromCdbRB.isSelected() && numOfAlarmsFromCDB>0);
terminateFromCdbBtn.setEnabled(sendFromCdbRB.isSelected() && numOfAlarmsFromCDB>0);
cycleFromCdbBtn.setEnabled(sendFromCdbRB.isSelected() && numOfAlarmsFromCDB>0);
}
});
}
@Override
public void alarmSent(Triplet triplet, AlarmDescriptorType descriptor, boolean success) {
if (success) {
alarmsSent.alarmSent(triplet, descriptor==AlarmDescriptorType.ACTIVE);
} else {
String msg ="Error returned sending "+triplet.toString();
JOptionPane.showMessageDialog(null, msg, "Error sending alarm alarm", JOptionPane.ERROR_MESSAGE);
}
}
/**
* Animate the passed progress bar
*
* @param bar The bar to animate
* @param nSteps The number of steps to perform.
* <code>null</code> means that the number is undefined
*/
private void animateProgressBar(final JProgressBar bar, final Integer nSteps) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (nSteps==null) {
bar.setIndeterminate(true);
bar.setMaximum(0);
bar.setMinimum(0);
} else {
bar.setIndeterminate(false);
bar.setMaximum(nSteps.intValue());
bar.setMinimum(0);
}
bar.setValue(0);
}
});
}
/**
* @see SlowTaskListener
*/
@Override
public void slowTaskStarted(Object source, Integer nSteps) {
if (source==fileSender) {
animateProgressBar(fileTasksPB, nSteps);
} else {
animateProgressBar(cdbTasksPB, nSteps);
}
}
/**
* Stop the passed progress bar
*
* @param bar The bar to stop
*/
private void stopProgressBar(final JProgressBar bar) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
bar.setIndeterminate(false);
bar.setValue(0);
}
});
}
/**
* @see SlowTaskListener
*/
@Override
public void slowTaskFinished(final Object source) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (source==fileSender) {
stopProgressBar(fileTasksPB);
terminateFromFileBtn.setEnabled(true);
cycleFromFileBtn.setEnabled(true);
activateFromFileBtn.setEnabled(true);
terminateFromFileBtn.setSelected(false);
cycleFromFileBtn.setSelected(false);
activateFromFileBtn.setSelected(false);
} else {
stopProgressBar(cdbTasksPB);
terminateFromCdbBtn.setEnabled(true);
cycleFromCdbBtn.setEnabled(true);
activateFromCdbBtn.setEnabled(true);
terminateFromCdbBtn.setSelected(false);
cycleFromCdbBtn.setSelected(false);
activateFromCdbBtn.setSelected(false);
}
}
});
}
/**
* Update the passed progress bar
*
* @param bar The bar to update
* @param step The current step
*/
private void updateProgressBar(final JProgressBar bar, final int step) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
bar.setValue(step);
}
});
}
/**
* @see SlowTaskListener
*/
@Override
public void slowTaskProgress(Object source, int progess) {
if (source==fileSender) {
updateProgressBar(fileTasksPB,progess);
} else {
updateProgressBar(cdbTasksPB,progess);
}
}
/**
* @see SlowTaskListener
*/
@Override
public void alarmsRead(Object source, int numOfAlarmsRead) {
if (source==cdbSender) {
numOfAlarmsFromCDB=numOfAlarmsRead;
cdbAlarmsTF.setText(""+numOfAlarmsFromCDB+" alarms read from TM/CDB");
} else {
numOfAlarmsFromFile=numOfAlarmsRead;
fileNameTF.setText(fileSender.getFileName()+" - "+numOfAlarmsFromFile+" alarms loaded");
}
}
/**
* The model changed so {@link #clearAllBtn} must be enabled/disabled
*/
@Override
public void tableChanged(TableModelEvent e) {
clearAllBtn.setEnabled(alarmsSent.getModel().getRowCount()>0);
}
}