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

18
nb-configuration.xml Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-shared-configuration>
<!--
This file contains additional configuration written by modules in the NetBeans IDE.
The configuration is intended to be shared among all the users of project and
therefore it is assumed to be part of version control checkout.
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
-->
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
<!--
Properties that influence various parts of the IDE, especially code formatting and the like.
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
That way multiple projects can share the same settings (useful for formatting rules for example).
Any value defined here will override the pom.xml file value but is only applicable to the current project.
-->
<org-netbeans-modules-javascript2-requirejs.enabled>true</org-netbeans-modules-javascript2-requirejs.enabled>
</properties>
</project-shared-configuration>

View File

@@ -19,8 +19,8 @@
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<repositories>
<repository>

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;