import ch.psi.pshell.epics.Positioner; import ch.psi.pshell.framework.Context; import ch.psi.pshell.framework.ScriptProcessor; import ch.psi.pshell.framework.Setup; import ch.psi.pshell.utils.EncoderJson; import ch.psi.pshell.utils.IO; import ch.psi.pshell.utils.State; import ch.psi.pshell.swing.SwingUtils; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JFileChooser; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.table.DefaultTableModel; /** * */ public class EnergyScan extends ScriptProcessor { final DefaultTableModel model; Positioner energy; File currentFile; public static final String FILE_EXTENSION = "ens"; public EnergyScan() { initComponents(); model = (DefaultTableModel) table.getModel(); updateButtons(); } @Override public String getType() { return "Energy Scan"; } @Override public boolean canSave() { return true; } @Override public boolean createMenuNew() { return true; } @Override public boolean createFilePanel() { return true; } @Override public String getDescription() { return "Energy scan definition file (*." + FILE_EXTENSION + ")"; } @Override public String[] getExtensions() { return new String[]{FILE_EXTENSION}; } @Override public String getHomePath() { return "{home}/parameters"; } //Overridable callbacks @Override public void onInitialize(int runCount) { energy = (Positioner) getDevice("energy"); } @Override public void onStateChange(State state, State former) { buttonStart.setEnabled(state == State.Ready); buttonAbort.setEnabled((state == State.Busy) && isRunning()); buttonScienta.setEnabled(state.isInitialized()); buttonAddToQueue.setEnabled(buttonStart.isEnabled()); updateButtons(); updateSeq(); } void updateSeq() { try { textFileId.setText(String.valueOf(Context.getFileSequentialNumber())); } catch (Exception ex) { textFileId.setText(""); } } @Override public void onExecutedFile(String fileName, Object result) { } //Callback to perform update - in event thread @Override protected void doUpdate() { } void checkValues() { if (model.getRowCount() == 0) { throw new IllegalArgumentException(); } Positioner energy = (Positioner) getDevice("energy"); for (int i = 0; i < model.getRowCount(); i++) { Double start = (Double) model.getValueAt(i, 0); Double stop = (Double) model.getValueAt(i, 1); Double step = (Double) model.getValueAt(i, 2); if (Double.isNaN(start) || Double.isNaN(stop) || Double.isNaN(step) || (step < 0) || (start < energy.getMinValue()) || (stop > energy.getMaxValue()) || (start > energy.getMaxValue()) || (stop < energy.getMinValue())) { throw new IllegalArgumentException(); } } } String getScanName() { String name = textName.getText().trim(); return name.isEmpty() ? null : name; } @Override public void saveAs(String fileName) throws IOException { currentFile = new File(fileName); ArrayList data = new ArrayList(); data.add(new Object[][]{new Object[]{textName.getText()}}); data.add(model.getDataVector()); data.add(new Object[][]{new Object[]{spinnerPasses.getValue()}}); String json = EncoderJson.encode(data, true); Files.write(currentFile.toPath(), json.getBytes()); updateButtons(); } @Override public void open(String fileName) throws IOException { if (fileName==null){ currentFile = null; textName.setText(""); model.setRowCount(0); spinnerPasses.setValue(1); } else { Path path = Paths.get(fileName); String json = new String(Files.readAllBytes(path)); currentFile = path.toFile(); Object[][][] vector = (Object[][][]) EncoderJson.decode(json, Object[][][].class); textName.setText(String.valueOf(vector[0][0][0])); model.setDataVector(vector[1], SwingUtils.getTableColumnNames(table)); spinnerPasses.setValue((vector.length>2) ? (Integer)vector[2][0][0] : 1); } updateButtons(); } String lastOutput; @Override protected void onStartingExecution(Map args){ getLogger().warning(this.getFileName()); lastOutput = Context.getDataManager().getLastOutput(); } @Override protected void onFinishedExecution(Map args, Object ret, Throwable t){ if (checkAutoSaveArgs.isSelected()) { //Save scan attributes String output = Context.getDataManager().getLastOutput(); if ((output != null) && !output.isEmpty() && !output.equals(lastOutput)) { try { saveAs(output + "." + FILE_EXTENSION); } catch (IOException e) { Logger.getLogger(EnergyScan.class.getName()).log(Level.WARNING, null, e); } } } } @Override public String getScript() { return "templates/EnergyScan"; } @Override public Map getArgs() { HashMap args = new HashMap<>(); checkValues(); ArrayList regions = new ArrayList(); for (int i = 0; i < model.getRowCount(); i++) { ArrayList region = new ArrayList(); region.add(model.getValueAt(i, 0)); region.add(model.getValueAt(i, 1)); region.add(model.getValueAt(i, 2)); regions.add(region); } args.put("FILE", null); args.put("NAME", getScanName()); args.put("REGIONS", regions); args.put("PASSES", spinnerPasses.getValue()); return args; } protected void updateButtons() { boolean editing = !isExecuting(); int rows = model.getRowCount(); int cur = table.getSelectedRow(); buttonDelete.setEnabled((rows > 0) && (cur >= 0) && editing); buttonInsert.setEnabled(editing); buttonClear.setEnabled(editing); buttonOpen.setEnabled(editing); buttonSave.setEnabled(getState().isInitialized()); table.setEnabled(editing); textName.setEnabled(editing); } @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { jScrollPane2 = new javax.swing.JScrollPane(); jEditorPane1 = new javax.swing.JEditorPane(); buttonStart = new javax.swing.JButton(); buttonAbort = new javax.swing.JButton(); checkAutoSaveArgs = new javax.swing.JCheckBox(); buttonScienta = new javax.swing.JButton(); jPanel2 = new javax.swing.JPanel(); textName = new javax.swing.JTextField(); jPanel1 = new javax.swing.JPanel(); jScrollPane1 = new javax.swing.JScrollPane(); table = new javax.swing.JTable(); buttonInsert = new javax.swing.JButton(); buttonDelete = new javax.swing.JButton(); jLabel1 = new javax.swing.JLabel(); buttonOpen = new javax.swing.JButton(); buttonSave = new javax.swing.JButton(); buttonAddToQueue = new javax.swing.JButton(); jLabel3 = new javax.swing.JLabel(); spinnerPasses = new javax.swing.JSpinner(); buttonClear = new javax.swing.JButton(); jLabel2 = new javax.swing.JLabel(); textFileId = new javax.swing.JTextField(); buttonResetId = new javax.swing.JButton(); jScrollPane2.setViewportView(jEditorPane1); buttonStart.setText("Start"); buttonStart.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonStartActionPerformed(evt); } }); buttonAbort.setText("Abort"); buttonAbort.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonAbortActionPerformed(evt); } }); checkAutoSaveArgs.setText("Auto save parameters"); buttonScienta.setText("Scienta Panel"); buttonScienta.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonScientaActionPerformed(evt); } }); jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Parameters")); jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Regions")); table.setModel(new javax.swing.table.DefaultTableModel( new Object [][] { }, new String [] { "Start", "End", "Step" } ) { Class[] types = new Class [] { java.lang.Double.class, java.lang.Double.class, java.lang.Double.class }; public Class getColumnClass(int columnIndex) { return types [columnIndex]; } }); table.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseReleased(java.awt.event.MouseEvent evt) { tableMouseReleased(evt); } }); table.addKeyListener(new java.awt.event.KeyAdapter() { public void keyReleased(java.awt.event.KeyEvent evt) { tableKeyReleased(evt); } }); jScrollPane1.setViewportView(table); buttonInsert.setText("Insert"); buttonInsert.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonInsertActionPerformed(evt); } }); buttonDelete.setText("Delete"); buttonDelete.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonDeleteActionPerformed(evt); } }); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 307, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE) .addComponent(buttonInsert) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(buttonDelete))) .addContainerGap()) ); jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonDelete, buttonInsert}); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 82, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(buttonInsert) .addComponent(buttonDelete)) .addContainerGap()) ); jLabel1.setText("Name:"); buttonOpen.setText("Open"); buttonOpen.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonOpenActionPerformed(evt); } }); buttonSave.setText("Save"); buttonSave.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonSaveActionPerformed(evt); } }); buttonAddToQueue.setText("Add To Queue"); buttonAddToQueue.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonAddToQueueActionPerformed(evt); } }); jLabel3.setText("Passes:"); spinnerPasses.setModel(new javax.swing.SpinnerNumberModel(1, 1, 100, 1)); buttonClear.setText("Clear"); buttonClear.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonClearActionPerformed(evt); } }); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(textName, javax.swing.GroupLayout.DEFAULT_SIZE, 108, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(buttonClear) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(buttonOpen) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(buttonSave)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(spinnerPasses, 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(buttonAddToQueue))) .addContainerGap()) ); jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonClear, buttonOpen, buttonSave}); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(textName) .addComponent(buttonOpen) .addComponent(buttonSave) .addComponent(jLabel1) .addComponent(buttonClear)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(buttonAddToQueue) .addComponent(jLabel3) .addComponent(spinnerPasses, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap()) ); jLabel2.setText("File ID:"); textFileId.setEditable(false); textFileId.setHorizontalAlignment(javax.swing.JTextField.CENTER); buttonResetId.setText("Reset"); buttonResetId.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonResetIdActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(0, 9, Short.MAX_VALUE) .addComponent(buttonStart, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(33, 33, 33) .addComponent(buttonAbort) .addContainerGap(19, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(checkAutoSaveArgs) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(textFileId, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() .addComponent(buttonScienta) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(buttonResetId))) .addContainerGap()))) ); layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonAbort, buttonStart}); layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonResetId, textFileId}); layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonScienta, checkAutoSaveArgs}); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(7, 7, 7) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAutoSaveArgs) .addComponent(jLabel2) .addComponent(textFileId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(buttonScienta) .addComponent(buttonResetId)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, 32, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(buttonStart) .addComponent(buttonAbort)) .addContainerGap()) ); }// //GEN-END:initComponents private void buttonStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonStartActionPerformed try { execute(); } catch (Exception ex) { showException(ex); } }//GEN-LAST:event_buttonStartActionPerformed private void buttonAbortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonAbortActionPerformed try { abort(); } catch (Exception ex) { showException(ex); } }//GEN-LAST:event_buttonAbortActionPerformed private void buttonInsertActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonInsertActionPerformed try { //model.addRow(new Object[]{energy.getMinValue(), energy.getMaxValue(), 10.0}); model.addRow(new Object[]{500.0, 1000.0, 100.0}); updateButtons(); } catch (Exception ex) { showException(ex); } }//GEN-LAST:event_buttonInsertActionPerformed private void buttonDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDeleteActionPerformed try { if ((model.getRowCount() > 0) && (table.getSelectedRow() >= 0)) { model.removeRow(table.getSelectedRow()); updateButtons(); } } catch (Exception ex) { showException(ex); } }//GEN-LAST:event_buttonDeleteActionPerformed private void buttonOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonOpenActionPerformed try { open(); } catch (Exception ex) { showException(ex); } }//GEN-LAST:event_buttonOpenActionPerformed private void buttonSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSaveActionPerformed try { JFileChooser chooser = new JFileChooser(Setup.expandPath(getHomePath())); FileNameExtensionFilter filter = new FileNameExtensionFilter(getDescription(), getExtensions()); chooser.setFileFilter(filter); try { if (currentFile != null) { chooser.setSelectedFile(currentFile); } else if (getScanName() != null) { File file = Paths.get(chooser.getCurrentDirectory().getAbsolutePath(), getScanName()).toFile(); chooser.setSelectedFile(file); } } catch (Exception ex) { this.showException(ex); } int rVal = chooser.showSaveDialog(this); if (rVal == JFileChooser.APPROVE_OPTION) { String fileName = chooser.getSelectedFile().getAbsolutePath(); if (IO.getExtension(chooser.getSelectedFile().getAbsolutePath()).isEmpty()) { fileName += "." + FILE_EXTENSION; } saveAs(fileName); } } catch (Exception ex) { showException(ex); } }//GEN-LAST:event_buttonSaveActionPerformed private void buttonScientaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonScientaActionPerformed try { this.showDevicePanel("scienta"); } catch (Exception ex) { showException(ex); } }//GEN-LAST:event_buttonScientaActionPerformed private void buttonResetIdActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonResetIdActionPerformed try { Context.setFileSequentialNumber(0); updateSeq(); } catch (Exception ex) { showException(ex); } }//GEN-LAST:event_buttonResetIdActionPerformed private void buttonAddToQueueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonAddToQueueActionPerformed try { queue(); //TODO: Data/file } catch (Exception ex) { showException( ex); } }//GEN-LAST:event_buttonAddToQueueActionPerformed private void buttonClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonClearActionPerformed try { open(null); } catch (Exception ex) { showException( ex); } }//GEN-LAST:event_buttonClearActionPerformed private void tableMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableMouseReleased updateButtons(); }//GEN-LAST:event_tableMouseReleased private void tableKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tableKeyReleased updateButtons(); }//GEN-LAST:event_tableKeyReleased // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton buttonAbort; private javax.swing.JButton buttonAddToQueue; private javax.swing.JButton buttonClear; private javax.swing.JButton buttonDelete; private javax.swing.JButton buttonInsert; private javax.swing.JButton buttonOpen; private javax.swing.JButton buttonResetId; private javax.swing.JButton buttonSave; private javax.swing.JButton buttonScienta; private javax.swing.JButton buttonStart; private javax.swing.JCheckBox checkAutoSaveArgs; private javax.swing.JEditorPane jEditorPane1; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JSpinner spinnerPasses; private javax.swing.JTable table; private javax.swing.JTextField textFileId; private javax.swing.JTextField textName; // End of variables declaration//GEN-END:variables }