/* * Copyright (c) 2014 Paul Scherrer Institute. All rights reserved. */ import java.io.File; import java.io.IOException; import java.nio.file.Paths; import javax.swing.DefaultComboBoxModel; import ch.psi.pshell.ui.Panel; import ch.psi.pshell.imaging.ImageListener; import ch.psi.utils.State; import ch.psi.utils.IO; import ch.psi.utils.swing.SwingUtils; import ch.psi.utils.swing.ConfigDialog; import ch.psi.utils.swing.StandardDialog; import ch.psi.pshell.epics.PsiCamera; import ch.psi.pshell.core.JsonSerializer; import ch.psi.pshell.imaging.Data; import java.awt.Dimension; import java.awt.Frame; import java.awt.image.BufferedImage; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE; /** * */ public class Cameras extends Panel { public Cameras() { initComponents(); renderer.setPersistenceFile(Paths.get(getController().getSetup().getContextPath(), "Renderer_Cameras.bin")); } final String configFolder= "/afs/psi.ch/intranet/SF/Applications/config/camtool"; File[] cameraConfigFiles = new File[0]; PsiCamera camera; String cameraName; CameraConfig config; //Overridable callbacks @Override public void onInitialize(int runCount) { cameraConfigFiles = IO.listFiles(configFolder, new String[]{"json"}); DefaultComboBoxModel model = new DefaultComboBoxModel(); for (File file:cameraConfigFiles) { String prefix = IO.getPrefix(file); if (!prefix.startsWith("#")){ model.addElement(prefix); } } comboCameras.setModel(model); if (model.getSize()>0){ try { setCamera((String)comboCameras.getSelectedItem()); } catch (Exception ex) { } } startTimer(1000); } @Override public void onStateChange(State state, State former) { } @Override public void onExecutedFile(String fileName, Object result) { } //Callback to perform update - in event thread @Override protected void doUpdate() { } public static class CameraConfig{ public HashMap kwargs; public ArrayList args; public ArrayList links; public String type; public HashMap state; public CameraConfig image_source; public HashMap subcomponents; public ArrayList getCalibration(){ return (ArrayList) state.get("calibration"); } public Double getCalibrationHeight(){ return (Double) state.get("calibration_height"); } public Double getCalibrationWidth(){ return (Double) state.get("calibration_width"); } public Double getCalibrationHorizontalAngle(){ return (Double) state.get("calibration_horizontal_angle"); } public Double getCalibrationVerticalAngle(){ return (Double) state.get("calibration_vertical_angle"); } public Boolean getMirrorX(){ return (Boolean) state.get("mirror_x"); } public Boolean getMirrorY(){ return (Boolean) state.get("mirror_y"); } public Integer getRotate(){ return (Integer) state.get("rotate"); } public ArrayList getOrigin(){ return (ArrayList) state.get("origin"); } public ArrayList getRoi(){ return (ArrayList) state.get("roi"); } public Boolean getRoiEnable(){ if ((state.get("roi_enable")==null) ||(state.get("roi")==null)){ return false; } return (Boolean) state.get("roi_enable"); } public ArrayList getUnitSize(){ return (ArrayList) state.get("unit_size"); } public Integer getRun(){ return (Integer) state.get("run"); } } void setCamera(String cameraName) throws IOException, InterruptedException{ if (camera!=null){ camera.close(); camera = null; } try{ Path configFile= Paths.get(configFolder, cameraName + ".json"); String json = new String(Files.readAllBytes(configFile)); this.cameraName=cameraName; //SwingUtils.showMessage(null, "", json); camera = new PsiCamera("CurrentCamera", cameraName); try{ config = (CameraConfig) JsonSerializer.decode(json, CameraConfig.class); camera.getConfig().flipHorizontally = config.getMirrorX(); camera.getConfig().flipVertically = config.getMirrorY(); camera.getConfig().rotation = config.getRotate(); camera.getConfig().rotationCrop = true; camera.getConfig().roiX = config.getRoiEnable() ? config.getRoi().get(0) : 0; camera.getConfig().roiY = config.getRoiEnable() ?config.getRoi().get(1) : 0; camera.getConfig().roiWidth = config.getRoiEnable() ?config.getRoi().get(2) : -1; camera.getConfig().roiHeight = config.getRoiEnable() ?config.getRoi().get(3): -1; camera.getConfig().spatialCalOffsetX = (config.getOrigin()!=null) ? config.getOrigin().get(0) : Double.NaN; camera.getConfig().spatialCalOffsetY = (config.getOrigin()!=null) ? config.getOrigin().get(1) : Double.NaN; camera.getConfig().spatialCalScaleX = (config.getUnitSize()!=null) && (config.getOrigin().get(0)!=0) ? 1.0/(config.getOrigin().get(0)*1000) : Double.NaN; camera.getConfig().spatialCalScaleY= (config.getUnitSize()!=null) && (config.getOrigin().get(1)!=0) ? 1.0/(config.getOrigin().get(1)*1000) : Double.NaN; } catch (Exception ex){ config = null; showException(ex); } camera.getConfig().save(); camera.initialize(); camera.setMonitored(true); renderer.setDevice(camera); renderer.setShowReticle(true); renderer.setAutoScroll(true); camera.addListener(new ImageListener() { @Override public void onImage(Object o, BufferedImage bi, Data data) { if ((renderer.getReticle()!=null) && (bi!=null)){ renderer.getReticle().setSize(new Dimension(bi.getWidth(), bi.getHeight())); } camera.removeListener(this); } @Override public void onError(Object o, Exception excptn) { } }); } finally{ onTimer(); } } @Override protected void onTimer() { textState.setText((camera==null) ? "" : camera.getState().toString()); buttonConfig.setEnabled(camera!=null); } @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { renderer = new ch.psi.pshell.imaging.Renderer(); jLabel1 = new javax.swing.JLabel(); comboCameras = new javax.swing.JComboBox(); jLabel2 = new javax.swing.JLabel(); textState = new javax.swing.JTextField(); buttonConfig = new javax.swing.JButton(); jLabel1.setText("Camera:"); comboCameras.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { comboCamerasActionPerformed(evt); } }); jLabel2.setText("State:"); textState.setEditable(false); textState.setHorizontalAlignment(javax.swing.JTextField.CENTER); textState.setDisabledTextColor(new java.awt.Color(0, 0, 0)); textState.setEnabled(false); buttonConfig.setText("Config"); buttonConfig.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonConfigActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(renderer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(comboCameras, 0, 290, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(buttonConfig) .addGap(10, 10, 10) .addComponent(jLabel2) .addGap(4, 4, 4) .addComponent(textState, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(comboCameras, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel2) .addComponent(textState, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(buttonConfig)) .addGap(18, 18, 18) .addComponent(renderer, javax.swing.GroupLayout.DEFAULT_SIZE, 342, Short.MAX_VALUE) .addGap(6, 6, 6)) ); layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {comboCameras, textState}); }// //GEN-END:initComponents private void comboCamerasActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboCamerasActionPerformed try{ setCamera((String) comboCameras.getSelectedItem()); } catch(Exception ex){ showException(ex); } }//GEN-LAST:event_comboCamerasActionPerformed private void buttonConfigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonConfigActionPerformed try{ final ConfigDialog dlg = new ConfigDialog((Frame) getTopLevelAncestor(), false); dlg.setTitle("Device Configuration: " + cameraName); dlg.setConfig(camera.getConfig()); dlg.setDefaultCloseOperation(DISPOSE_ON_CLOSE); dlg.setListener((StandardDialog sd, boolean accepted) -> { if (sd.getResult()) { try { camera.getConfig().save(); } catch (IOException ex) { showException(ex); } } }); dlg.setVisible(true); SwingUtils.centerComponent(getTopLevelAncestor(), dlg); dlg.requestFocus(); } catch(Exception ex){ showException(ex); } }//GEN-LAST:event_buttonConfigActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton buttonConfig; private javax.swing.JComboBox comboCameras; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private ch.psi.pshell.imaging.Renderer renderer; private javax.swing.JTextField textState; // End of variables declaration//GEN-END:variables }