package ch.psi.mxsc; import ch.psi.pshell.swing.DataPanel; import ch.psi.pshell.app.MainFrame; import ch.psi.pshell.framework.Setup; import ch.psi.pshell.swing.SwingUtils; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JDialog; import javax.swing.Timer; import javax.swing.table.DefaultTableModel; /** * */ public class PuckLoadingDialog extends JDialog { final Path dialogPersistPath; final DefaultTableModel model; final boolean persist; final boolean showBasePlate; final int INDEX_USER = 0; final int INDEX_DEWAR = 1; final int INDEX_DATAMATRIX = 2; final int INDEX_POSITION = 3; /** * Creates new form PuckLoadingDialog */ public PuckLoadingDialog(java.awt.Frame parent, boolean modal, boolean persist, boolean showBasePlate ) { super(parent, "Puck Loading", modal); initComponents(); this.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE); this.setName("PuckLoadingDialog"); dialogPersistPath = Paths.get(Setup.getContextPath(), getClass().getSimpleName()); this.persist=persist; this.showBasePlate=showBasePlate; setStatusLabel(null,-1); setSugestionLabel(null,-1); model = (DefaultTableModel) table.getModel(); table.getTableHeader().setFont(table.getTableHeader().getFont().deriveFont(16.0f)); panelTable.getVerticalScrollBar().setPreferredSize(new Dimension(30, 0)); basePlatePanel.setMode(BasePlatePanel.Mode.pucks); basePlatePanel.setSelectionMode(BasePlatePanel.SelectionMode.Pucks); basePlatePanel.setDevice(Controller.getInstance().basePlate); if (!showBasePlate){ splitPanel.setDividerLocation(0); } setLocationRelativeTo(parent); } public BasePlatePanel getBasePlatePanel(){ return showBasePlate ? basePlatePanel : null; } @Override public void setVisible(boolean visible){ if (visible != isVisible()){ if (!visible){ if (persist) { try { MainFrame.save(PuckLoadingDialog.this, dialogPersistPath); } catch (Exception ex) { Logger.getLogger(DataPanel.class.getName()).log(Level.WARNING, null, ex); } } } super.setVisible(visible); if ( visible){ restore(); update(); } } } public void restore(){ if (persist){ try { MainFrame.restore(PuckLoadingDialog.this, dialogPersistPath); } catch (Exception ex) { Logger.getLogger(DataPanel.class.getName()).log(Level.WARNING, null, ex); } } else { Rectangle bounds = getParent().getBounds(); if(showBasePlate){ //setSize(new Dimension(bounds.width * 3 / 4, bounds.height * 3 / 4)); //setLocationRelativeTo(getParent()); setBounds(bounds); } else { int width = bounds.width / 3; int height = bounds.height; int x = bounds.x + bounds.width - width; int y = bounds.y; setBounds(x, y, width, height); } } } void update() { Map dms = Controller.getInstance().getPuckDatamatrixInfo(); if (dms == null) { dms = new HashMap(); } Object[] keys = dms.keySet().toArray(); Arrays.sort(keys); if (keys.length != model.getRowCount()){ model.setRowCount(keys.length); } for (int i=0; i< keys.length; i++) { model.setValueAt(keys[i], i, INDEX_DATAMATRIX); try{ Map info = (Map) dms.get(keys[i]); model.setValueAt(info.get("address"), i, INDEX_POSITION); model.setValueAt(info.get("dewar"), i, INDEX_DEWAR); model.setValueAt(info.get("user"), i, INDEX_USER); } catch (Exception ex){ model.setValueAt("Unknown", i, INDEX_POSITION); model.setValueAt("Unknown", i, INDEX_DEWAR); model.setValueAt("Unknown", i, INDEX_USER); } } } void onPuckScanned(String datamatrix){ textScannedDatamatrix.setText((datamatrix == null) ? "" : datamatrix.trim()); if ((datamatrix != null) && (!datamatrix.isEmpty())){ setStatusLabel("Scanned puck " + datamatrix, 5000); makeVisible(datamatrix); String loadedPuck = Controller.getInstance().getPuckFromDatamatrix(datamatrix); if ((loadedPuck!=null) && !loadedPuck.isBlank()){ Controller.getInstance().setLaserPos(loadedPuck); } else { Puck puck = Controller.getInstance().getFreePuck(); Controller.getInstance().setLaserPos(puck.getName()); } } else { setStatusLabel(null, -1); Controller.getInstance().setLaserPos((Puck)null); } setSugestionLabel(null, -1); buttonSet.setEnabled(false); detectedPuck = null; textDetectedPuck.setText(""); } Puck detectedPuck; String detectedDatamatrix; void onPuckMounted(Puck puck, String datamatrix){ Controller.getInstance().setLaserPos((Puck)null); if ((datamatrix != null) && (!datamatrix.isEmpty())) { setStatusLabel("Mounted puck " + datamatrix + " at " + puck.getName(), 5000); setSugestionLabel(null, -1); buttonSet.setEnabled(false); textDetectedPuck.setText(""); detectedPuck = null; } else { setStatusLabel("Detected puck at " + puck.getName(), -1); setSugestionLabel("Select the datamatrix and press 'Set'", -1); detectedPuck = puck; textDetectedPuck.setText(puck.getName()); buttonSet.setEnabled(true); table.clearSelection(); } update(); } Timer timerClear; void onPuckUnmounted(Puck puck){ if (puck == detectedPuck){ } setStatusLabel("Unmounted puck from "+ puck.getName(), 5000); if (puck == detectedPuck){ buttonSet.setEnabled(false); detectedPuck = null; } makeVisible(puck); update(); } void onManualSetPuckLocation(String datamatrix){ if (detectedPuck!=null){ Controller.getInstance().linkPuckDatamatrix(detectedPuck, datamatrix, false); setStatusLabel("Set puck " + datamatrix + " at " + detectedPuck.getName(), 5000); setSugestionLabel(null, -1); buttonSet.setEnabled(false); detectedPuck = null; textDetectedPuck.setText(""); } update(); } Timer timerLabelStatus; void setStatusLabel(String message, int delay){ final String defaultStatus = " "; //Waiting for Puck Detection"; if (timerLabelStatus!=null){ timerLabelStatus.stop(); timerLabelStatus = null; } labelStatus.setText(message==null ? defaultStatus : message); if (delay>0){ timerLabelStatus = new Timer(delay, (e)->{ labelStatus.setText(defaultStatus); }); timerLabelStatus.start(); } } Timer timerLabelSuggestion; void setSugestionLabel(String message, int delay){ final String defaultSuggestion = "Scan, Insert or Remove Pucks"; //Waiting for Puck Detection"; if (timerLabelSuggestion!=null){ timerLabelSuggestion.stop(); timerLabelSuggestion = null; } labelSuggestion.setText(message==null ? defaultSuggestion : message); if (delay>0){ timerLabelSuggestion = new Timer(delay, (e)->{ labelSuggestion.setText(defaultSuggestion); }); timerLabelSuggestion.start(); } } void makeVisible(String datamatrix){ if (datamatrix!=null){ for (int i=0; i//GEN-BEGIN:initComponents private void initComponents() { splitPanel = new javax.swing.JSplitPane(); jPanel1 = new javax.swing.JPanel(); buttonSet = new javax.swing.JButton(); textDetectedPuck = new javax.swing.JTextField(); buttonClearDatamatrix = new javax.swing.JButton(); textScannedDatamatrix = new javax.swing.JTextField(); panelTable = new javax.swing.JScrollPane(); table = new javax.swing.JTable(); labelStatus = new javax.swing.JLabel(); jLabel1 = new javax.swing.JLabel(); labelSuggestion = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel(); basePlatePanel = new ch.psi.mxsc.BasePlatePanel(){ void onPuckPressed(MouseEvent e, Puck puck){ onSelected(puck); } }; setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); splitPanel.setDividerLocation(600); splitPanel.setDividerSize(0); buttonSet.setFont(new java.awt.Font("Lucida Grande", 0, 30)); // NOI18N buttonSet.setText("Set"); buttonSet.setEnabled(false); buttonSet.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonSetActionPerformed(evt); } }); textDetectedPuck.setEditable(false); textDetectedPuck.setFont(new java.awt.Font("Lucida Grande", 0, 30)); // NOI18N textDetectedPuck.setHorizontalAlignment(javax.swing.JTextField.CENTER); buttonClearDatamatrix.setFont(new java.awt.Font("Tahoma", 0, 24)); // NOI18N buttonClearDatamatrix.setText("Clear"); buttonClearDatamatrix.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonClearDatamatrixActionPerformed(evt); } }); textScannedDatamatrix.setEditable(false); textScannedDatamatrix.setFont(new java.awt.Font("Lucida Grande", 0, 30)); // NOI18N textScannedDatamatrix.setHorizontalAlignment(javax.swing.JTextField.CENTER); 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.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); labelStatus.setFont(new java.awt.Font("Lucida Grande", 0, 24)); // NOI18N labelStatus.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); labelStatus.setText("Waiting for Puck Detection"); labelStatus.setBorder(javax.swing.BorderFactory.createEtchedBorder()); jLabel1.setFont(new java.awt.Font("Lucida Grande", 0, 24)); // NOI18N jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); jLabel1.setText("Scanned Datamatrix:"); labelSuggestion.setFont(new java.awt.Font("Lucida Grande", 0, 30)); // NOI18N labelSuggestion.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); labelSuggestion.setText("Scan, Insert or Remove Pucks"); jLabel2.setFont(new java.awt.Font("Lucida Grande", 0, 24)); // NOI18N jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); jLabel2.setText("Detected Puck:"); 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) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE) .addComponent(buttonSet, javax.swing.GroupLayout.PREFERRED_SIZE, 201, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, Short.MAX_VALUE)) .addComponent(labelSuggestion, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(panelTable, javax.swing.GroupLayout.DEFAULT_SIZE, 474, Short.MAX_VALUE) .addGap(14, 14, 14)) .addComponent(labelStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(textDetectedPuck)) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(textScannedDatamatrix))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(buttonClearDatamatrix))) .addContainerGap()) ); jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel1, jLabel2}); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(labelSuggestion) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(textScannedDatamatrix, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel2) .addComponent(textDetectedPuck, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(buttonClearDatamatrix, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(panelTable, javax.swing.GroupLayout.DEFAULT_SIZE, 336, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(buttonSet) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(labelStatus) .addContainerGap()) ); splitPanel.setRightComponent(jPanel1); javax.swing.GroupLayout basePlatePanelLayout = new javax.swing.GroupLayout(basePlatePanel); basePlatePanel.setLayout(basePlatePanelLayout); basePlatePanelLayout.setHorizontalGroup( basePlatePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 600, Short.MAX_VALUE) ); basePlatePanelLayout.setVerticalGroup( basePlatePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 600, Short.MAX_VALUE) ); splitPanel.setLeftComponent(basePlatePanel); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(splitPanel) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(splitPanel) ); pack(); }// //GEN-END:initComponents private void buttonSetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSetActionPerformed try { int row = table.getSelectedRow(); String datamatrix = (row >= 0) ? String.valueOf(table.getValueAt(row, INDEX_DATAMATRIX)) : null; if (datamatrix != null) { onManualSetPuckLocation(datamatrix); } } catch (Exception ex) { SwingUtils.showException(this, ex); } }//GEN-LAST:event_buttonSetActionPerformed private void buttonClearDatamatrixActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonClearDatamatrixActionPerformed try { Controller.getInstance().onPuckScanned(null); } catch (Exception ex) { SwingUtils.showException(this, ex); } }//GEN-LAST:event_buttonClearDatamatrixActionPerformed private void tableMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableMouseReleased try { int row = table.getSelectedRow(); String position = (row >= 0) ? String.valueOf(table.getValueAt(row, INDEX_POSITION)) : null; if ((position!=null) && (!position.isBlank())){ Puck puck = Controller.getInstance().getPuck(position); pointPuck(puck); } } catch (Exception ex) { SwingUtils.showException(this, ex); } }//GEN-LAST:event_tableMouseReleased private void tableKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tableKeyReleased tableMouseReleased(null); }//GEN-LAST:event_tableKeyReleased /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ // /* 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(PuckLoadingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(PuckLoadingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(PuckLoadingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(PuckLoadingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } // /* Create and display the dialog */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { PuckLoadingDialog dialog = new PuckLoadingDialog(new javax.swing.JFrame(), true, false, true); 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 ch.psi.mxsc.BasePlatePanel basePlatePanel; private javax.swing.JButton buttonClearDatamatrix; javax.swing.JButton buttonSet; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JPanel jPanel1; private javax.swing.JLabel labelStatus; private javax.swing.JLabel labelSuggestion; private javax.swing.JScrollPane panelTable; private javax.swing.JSplitPane splitPanel; javax.swing.JTable table; javax.swing.JTextField textDetectedPuck; javax.swing.JTextField textScannedDatamatrix; // End of variables declaration//GEN-END:variables }