Add send_event to scripting API

This commit is contained in:
2025-08-20 15:18:55 +02:00
parent 795026b34e
commit 83a1ae739d
7 changed files with 452 additions and 8 deletions

View File

@@ -965,7 +965,34 @@ public class Controller {
try{
showingPuckLoadingDialog = (dialogPuckLoading != null) && (dialogPuckLoading.isShowing());
if ("loading".equals(Context.getSetting("puck_detection"))){
puck_detection.setEnabled(showingPuckLoadingDialog);
if (showingPuckLoadingDialog){
var werePresent = new ArrayList<String>();
Puck[] pucks = basePlate.getPucks();
for (Puck p : pucks){
if (p.getDetection() == Puck.Detection.Present){
werePresent.add(p.getName());
}
}
puck_detection.applyCache();
var present = new ArrayList<String>();
for (Puck p : pucks){
if (p.getDetection() == Puck.Detection.Present){
present.add(p.getName());
}
}
var removed = new ArrayList<>(werePresent);
removed.removeAll(present);
if (removed.size()>0){
PuckDetectionErrorDialog dlg = new PuckDetectionErrorDialog(mainFrame.getTopLevel());
dlg.initialize(removed);
dlg.setVisible(true);
}
}
puck_detection.setEnabled(showingPuckLoadingDialog);
}
} catch (Exception ex) {
Logger.getLogger(Controller.class.getName()).log(Level.WARNING, null, ex);

View File

@@ -133,9 +133,6 @@ public class PuckDetection extends DeviceBase {
setCache(contents);
if (isEnabled() || (take() == null)){
processMessage(contents);
if (Controller.getInstance() != null) {
Controller.getInstance().updateView();
}
}
setState(State.Ready);
@@ -163,6 +160,13 @@ public class PuckDetection extends DeviceBase {
setState(State.Offline);
}
}
public void applyCache(){
Object cache = take();
if (cache instanceof String contents){
processMessage(contents);
}
}
void processMessage(String str) {
try {
@@ -185,7 +189,10 @@ public class PuckDetection extends DeviceBase {
} catch (Exception ex) {
getLogger().log(Level.INFO, null, ex);
}
}
if (Controller.getInstance() != null) {
Controller.getInstance().updateView();
}
}
public PuckState getPuckState(int id) throws Exception {
if (Controller.getInstance() == null) {

View File

@@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.6" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="panelTable" alignment="0" pref="0" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="labelSuggestion" pref="470" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="buttonOk" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Component id="labelSuggestion1" pref="470" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="labelSuggestion" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="labelSuggestion1" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="panelTable" min="-2" pref="172" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="buttonOk" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="labelSuggestion">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Lucida Grande" size="24" style="0"/>
</Property>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="The following pucks were not detected "/>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="panelTable">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="table">
<Properties>
<Property name="autoCreateRowSorter" type="boolean" value="true"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Lucida Grande" size="30" style="0"/>
</Property>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="4" rowCount="0">
<Column editable="false" title="User" type="java.lang.String"/>
<Column editable="false" title="Dewar" type="java.lang.String"/>
<Column editable="false" title="Puck Id/Datamatrix" type="java.lang.String"/>
<Column editable="false" title="Puck Position" type="java.lang.String"/>
</Table>
</Property>
<Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
<TableColumnModel selectionModel="0">
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
<Title/>
<Editor/>
<Renderer/>
</Column>
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
<Title/>
<Editor/>
<Renderer/>
</Column>
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
<Title/>
<Editor/>
<Renderer/>
</Column>
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
<Title/>
<Editor/>
<Renderer/>
</Column>
</TableColumnModel>
</Property>
<Property name="rowHeight" type="int" value="40"/>
<Property name="selectionMode" type="int" value="0"/>
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
<JTableSelectionModel selectionMode="0"/>
</Property>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
<TableHeader reorderingAllowed="false" resizingAllowed="true"/>
</Property>
</Properties>
<Events>
<EventHandler event="mouseReleased" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="tableMouseReleased"/>
<EventHandler event="keyReleased" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="tableKeyReleased"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="buttonOk">
<Properties>
<Property name="text" type="java.lang.String" value="Ok"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="buttonOkActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="labelSuggestion1">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Lucida Grande" size="24" style="0"/>
</Property>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="and must be manually removed."/>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@@ -0,0 +1,244 @@
package ch.psi.mxsc;
import ch.psi.pshell.swing.StandardDialog;
import ch.psi.pshell.utils.Str;
import java.awt.Dimension;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.table.DefaultTableModel;
/**
*
*/
public class PuckDetectionErrorDialog extends StandardDialog {
final DefaultTableModel model;
final int INDEX_USER = 0;
final int INDEX_DEWAR = 1;
final int INDEX_DATAMATRIX = 2;
final int INDEX_POSITION = 3;
public PuckDetectionErrorDialog(java.awt.Frame parent) {
super(parent, true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
model = (DefaultTableModel) table.getModel();
table.getTableHeader().setFont(table.getTableHeader().getFont().deriveFont(16.0f));
panelTable.getVerticalScrollBar().setPreferredSize(new Dimension(30, 0));
initComponents();
}
public void initializePucks(List<Puck> failing) {
List<String> names = failing.stream().map(Puck::getName).toList();
initialize(names);
}
public void initialize(List<String> failing) {
Map dms = Controller.getInstance().getPuckDatamatrixInfo();
if (dms == null) {
dms = new HashMap();
}
Object[] keys = dms.keySet().toArray();
model.setRowCount(failing.size());
for (int i=0; i< failing.size(); i++) {
String pos = failing.get(i);
model.setValueAt(failing, i, INDEX_POSITION);
for (int j=0; j< keys.length; j++) {
Map info = (Map) dms.get(keys[j]);
String address = Str.toString(info.getOrDefault("address", ""));
if (pos.equals(address)){
model.setValueAt(keys[j], i, INDEX_DATAMATRIX);
model.setValueAt(info.getOrDefault("dewar", ""), i, INDEX_DEWAR);
model.setValueAt(info.getOrDefault("user", ""), i, INDEX_USER);
break;
}
}
}
}
public void updateLaser(){
try{
int sel = table.getSelectedRow();
if (sel>=0){
String pos = model.getValueAt(sel, INDEX_POSITION).toString();
Puck puck = Controller.getInstance().getPuck(pos);
if (puck!=null){
Controller.getInstance().setLaserPos(pos);
return;
}
}
Controller.getInstance().setLaserPos((Puck)null);
} catch (Exception ex){
showException(ex);
}
}
/**
* 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() {
labelSuggestion = new javax.swing.JLabel();
panelTable = new javax.swing.JScrollPane();
table = new javax.swing.JTable();
buttonOk = new javax.swing.JButton();
labelSuggestion1 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
labelSuggestion.setFont(new java.awt.Font("Lucida Grande", 0, 24)); // NOI18N
labelSuggestion.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
labelSuggestion.setText("The following pucks were not detected ");
table.setAutoCreateRowSorter(true);
table.setFont(new java.awt.Font("Lucida Grande", 0, 30)); // NOI18N
table.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"User", "Dewar", "Puck Id/Datamatrix", "Puck Position"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
};
boolean[] canEdit = new boolean [] {
false, false, false, false
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
table.setRowHeight(40);
table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
table.getTableHeader().setReorderingAllowed(false);
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);
}
});
panelTable.setViewportView(table);
buttonOk.setText("Ok");
buttonOk.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
buttonOkActionPerformed(evt);
}
});
labelSuggestion1.setFont(new java.awt.Font("Lucida Grande", 0, 24)); // NOI18N
labelSuggestion1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
labelSuggestion1.setText("and must be manually removed.");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(panelTable, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(labelSuggestion, javax.swing.GroupLayout.DEFAULT_SIZE, 470, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(buttonOk)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(labelSuggestion1, javax.swing.GroupLayout.DEFAULT_SIZE, 470, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(labelSuggestion)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(labelSuggestion1)
.addGap(18, 18, 18)
.addComponent(panelTable, javax.swing.GroupLayout.PREFERRED_SIZE, 172, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(buttonOk)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void buttonOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonOkActionPerformed
cancel();
}//GEN-LAST:event_buttonOkActionPerformed
private void tableKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tableKeyReleased
updateLaser();
}//GEN-LAST:event_tableKeyReleased
private void tableMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableMouseReleased
updateLaser();
}//GEN-LAST:event_tableMouseReleased
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(PuckDetectionErrorDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(PuckDetectionErrorDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(PuckDetectionErrorDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(PuckDetectionErrorDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the dialog */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
PuckDetectionErrorDialog dialog = new PuckDetectionErrorDialog(new javax.swing.JFrame());
dialog.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(java.awt.event.WindowEvent e) {
System.exit(0);
}
});
dialog.setVisible(true);
}
});
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton buttonOk;
private javax.swing.JLabel labelSuggestion;
private javax.swing.JLabel labelSuggestion1;
private javax.swing.JScrollPane panelTable;
javax.swing.JTable table;
// End of variables declaration//GEN-END:variables
}

View File

@@ -1,6 +1,5 @@
package ch.psi.mxsc;
import ch.psi.pshell.framework.Context;
import ch.psi.pshell.swing.DataPanel;
import ch.psi.pshell.app.MainFrame;
import ch.psi.pshell.framework.Setup;