package org.hwo.pulscounter.ui; import java.awt.EventQueue; import javax.swing.JFrame; import java.awt.GridBagLayout; import java.awt.BorderLayout; import javax.swing.JToolBar; import javax.swing.JSplitPane; import javax.swing.JTextArea; import javax.swing.JPanel; import java.awt.GridBagConstraints; import javax.swing.border.TitledBorder; import org.hwo.Smoother; import org.hwo.datetime.DateTime; import org.hwo.i18n.Messages; import org.hwo.io.NewSerialPort.NewSerialPort; import org.hwo.logging.Logging; import org.hwo.models.FlexibleObjectListModel; import org.hwo.platform.Platform; import org.hwo.pulscounter.DeviceTester; import org.hwo.pulscounter.PulsCounterApplication; import org.hwo.pulscounter.PulsCounterApplicationListener; import org.hwo.pulscounter.device.IDeviceConnector; import org.hwo.pulscounter.device.NoDeviceConnectionException; import org.hwo.pulscounter.device.ServiceLinkDeviceConnector; import org.hwo.servicelink.exceptions.*; import org.hwo.tasklet.Tasklet; import org.hwo.tasklet.TaskletListener; import org.hwo.tasklet.TaskletManager; import org.hwo.ui.JObjectSelector; import org.hwo.ui.dialog.SerialPortChooser; import org.hwo.ui.states.WindowStateManager; import org.omg.CORBA.Environment; import javax.swing.JLabel; import javax.swing.JTextField; import java.awt.Insets; import javax.swing.DefaultListModel; import javax.swing.JButton; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.awt.event.WindowStateListener; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.awt.event.ActionEvent; import java.awt.Color; import java.awt.Dialog.ModalityType; import javax.swing.JScrollPane; import javax.swing.JList; import javax.swing.JOptionPane; import java.awt.Font; import javax.swing.SwingConstants; import javax.swing.ToolTipManager; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import java.awt.Dimension; import javax.swing.BoxLayout; import javax.swing.border.EmptyBorder; import javax.swing.JCheckBox; import javax.swing.event.ChangeListener; import javax.swing.plaf.metal.MetalBorders.ToolBarBorder; import javax.swing.event.ChangeEvent; import static org.hwo.logging.Logging.log; import static org.hwo.logging.LogLevel.*; import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; public class NewMainWindow implements PulsCounterApplicationListener, TaskletListener{ private PulsCounterApplication pulsCounterApplication; private IDeviceConnector selectedDeviceInterface; private FlexibleObjectListModel> lmInterfaceClasses = new FlexibleObjectListModel<>(); private FlexibleObjectListModel lmInterfaces = new FlexibleObjectListModel<>(); private BackgroundThread backgroundThread; private JFrame frmSynolog; private JSplitPane splitter; private DefaultListModel messageListModel; private JList lMessages; private Timer timerReconnect; private JPanel pChannels; private ChannelDisplay[] channelDisplays; private JButton btnC; private JPanel panel_3; private JScrollPane scrollPane_1; private JList lTasklets; private DefaultListModel knownTasklets; private Boolean connected; private JButton btnDatenExportieren; private Integer trimTicksOnConnect; private Long trimTimeOnConnect; private Integer trimDeviceTimeSlice; private Smoother smoothTrim; private JList lInterfaces; private JScrollPane scrollPane_2; private JButton bIntfAdd; private JButton bIntfDel; private JPanel panel_4; private JTextArea tfConnectionSettings; private JButton btnSkripte; private JButton btnAufzeichnungenVerwalten; private JButton btnSelbsttest; public static void startGUI(){ try { // Set cross-platform Java L&F (also called "Metal") UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); } catch (UnsupportedLookAndFeelException e) { // handle exception } catch (ClassNotFoundException e) { // handle exception } catch (InstantiationException e) { // handle exception } catch (IllegalAccessException e) { // handle exception } ToolTipManager.sharedInstance().setDismissDelay( 20000 ); ToolTipManager.sharedInstance().setInitialDelay( 1250 ); ToolTipManager.sharedInstance().setReshowDelay( 500 ); } /** * @wbp.parser.entryPoint */ public NewMainWindow(PulsCounterApplication pulsCounterApplication) { startGUI(); this.pulsCounterApplication = pulsCounterApplication; initialize(); initializeChannelPanels(); pulsCounterApplication.addPulsCounterApplicationListener(this); frmSynolog.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { saveState(); } @Override public void windowClosed(WindowEvent e) { backgroundThread.exit(); application().notifyUiIsFinished(true); } }); //lmInterfaces.setItems(pulsCounterApplication.getInterfaces()); if (pulsCounterApplication.getInterfaces().size()>0){ interfacesChanged(pulsCounterApplication); lInterfaces.setSelectedIndex(0); } backgroundThread = new BackgroundThread(); backgroundThread.start(); restoreState(); frmSynolog.setVisible(true); } private void restoreState(){ String state = application().getApplicationConfiguration().getProperty("ui.NewMainWindow.state"); if (state != null){ WindowStateManager wsm = new WindowStateManager(); wsm.applyState(this.frmSynolog, state); log(INFO,"UI state restored"); } else { log(INFO,"UI state information not found"); } } private void saveState(){ WindowStateManager wsm = new WindowStateManager(); String state = wsm.saveState(frmSynolog); if (state != null){ application().getApplicationConfiguration().setProperty("ui.NewMainWindow.state", state); log(INFO,"UI state was saved"); } else { log(ERROR,"UI State was not saved"); } } private void initializeChannelPanels(){ channelDisplays = new ChannelDisplay[32]; for (int i=0;i<32;i++){ channelDisplays[i] = new ChannelDisplay(); channelDisplays[i].setChannelName(String.format("%02d",i)); if (i > 7){ channelDisplays[i].setAnalog(false); } GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(2, 2, 2, 2); gbc.anchor = GridBagConstraints.NORTHWEST; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1; gbc.weighty = 1; gbc.gridx = i & 0x03; gbc.gridy = i >> 2; channelDisplays[i].addChannelDisplayListener(new ChannelDisplayListener() { @Override public void set(ChannelDisplay sender, int setValue) { channelSet(sender, setValue); } @Override public void reset(ChannelDisplay sender) { channelReset(sender); } @Override public void setDescriptionText(ChannelDisplay sender, String descriptionText) { if (descriptionText.startsWith("!\"§$%")){ if (selectedDeviceInterface != null){ if (ServiceLinkDeviceConnector.class.isInstance(selectedDeviceInterface)){ ServiceLinkDeviceConnector dc = (ServiceLinkDeviceConnector)selectedDeviceInterface; if (descriptionText.startsWith("!\"§$%&")){ Integer escape = Integer.decode(descriptionText.substring(6)); dc.escape(escape, 0); } else { dc.setDeviceSerial(Integer.parseInt(descriptionText.substring(5))); } } } } } }); pChannels.add(channelDisplays[i], gbc); } } /** * Initialize the contents of the frame. */ private void initialize() { frmSynolog = new JFrame(); frmSynolog.setTitle("SYNOLO-LOG"); frmSynolog.setBounds(100, 100, 1000, 580); frmSynolog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frmSynolog.getContentPane().setLayout(new BorderLayout(0, 0)); frmSynolog.setBackground(Color.WHITE); JToolBar toolBar = new JToolBar(); toolBar.setBorder(new EmptyBorder(3, 3, 3, 3)); toolBar.setBackground(Color.WHITE); toolBar.setFloatable(false); frmSynolog.getContentPane().add(toolBar, BorderLayout.NORTH); btnC = new JButton(Messages.getString("Synololog einstellen")); btnC.setToolTipText(Messages.getString("tooltip.synololog.einstellen")); btnC.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (selectedDeviceInterface != null){ DeviceConfiguration cc = new DeviceConfiguration(selectedDeviceInterface); cc.setLocationRelativeTo(frmSynolog); cc.setVisible(true); } } }); toolBar.add(btnC); btnDatenExportieren = new JButton(Messages.getString("Daten exportieren")); btnDatenExportieren.setToolTipText(Messages.getString("tooltip.daten.exportieren")); btnDatenExportieren.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ExportFilesFrame eff = new ExportFilesFrame(); eff.setLocationRelativeTo(frmSynolog); eff.setVisible(true); } }); toolBar.add(btnDatenExportieren); btnSkripte = new JButton(Messages.getString("Skripte")); btnSkripte.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { SimpleScriptSetup sss = new SimpleScriptSetup(); sss.setLocationRelativeTo(frmSynolog); sss.setVisible(true); } }); toolBar.add(btnSkripte); btnAufzeichnungenVerwalten = new JButton(Messages.getString("Aufzeichnungen verwalten")); btnAufzeichnungenVerwalten.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { SnapshotManager.show(frmSynolog); } }); toolBar.add(btnAufzeichnungenVerwalten); btnSelbsttest = new JButton("Selbsttest"); btnSelbsttest.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { deviceTest(); } }); toolBar.add(btnSelbsttest); splitter = new JSplitPane(); splitter.setBorder(null); splitter.setOneTouchExpandable(true); splitter.setResizeWeight(0.6); frmSynolog.getContentPane().add(splitter, BorderLayout.CENTER); JPanel panel = new JPanel(); panel.setBackground(Color.WHITE); splitter.setRightComponent(panel); GridBagLayout gbl_panel = new GridBagLayout(); gbl_panel.columnWidths = new int[]{0, 0}; gbl_panel.rowHeights = new int[]{0, 0, 0, 0}; gbl_panel.columnWeights = new double[]{1.0, Double.MIN_VALUE}; gbl_panel.rowWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE}; panel.setLayout(gbl_panel); JPanel panel_1 = new JPanel(); panel_1.setBackground(Color.WHITE); panel_1.setBorder(new TitledBorder(null, Messages.getString("Verbindung"), TitledBorder.LEADING, TitledBorder.TOP, null, null)); GridBagConstraints gbc_panel_1 = new GridBagConstraints(); gbc_panel_1.insets = new Insets(0, 0, 5, 0); gbc_panel_1.fill = GridBagConstraints.BOTH; gbc_panel_1.gridx = 0; gbc_panel_1.gridy = 0; panel.add(panel_1, gbc_panel_1); GridBagLayout gbl_panel_1 = new GridBagLayout(); gbl_panel_1.columnWidths = new int[]{0, 0, 0}; gbl_panel_1.rowHeights = new int[]{0, 0, 0, 0}; gbl_panel_1.columnWeights = new double[]{1.0, 1.0, Double.MIN_VALUE}; gbl_panel_1.rowWeights = new double[]{0.0, 1.0, 1.0, Double.MIN_VALUE}; panel_1.setLayout(gbl_panel_1); bIntfAdd = new JButton("+"); bIntfAdd.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { addInterface(); } }); GridBagConstraints gbc_bIntfAdd = new GridBagConstraints(); gbc_bIntfAdd.fill = GridBagConstraints.HORIZONTAL; gbc_bIntfAdd.insets = new Insets(0, 0, 5, 5); gbc_bIntfAdd.gridx = 0; gbc_bIntfAdd.gridy = 0; panel_1.add(bIntfAdd, gbc_bIntfAdd); bIntfDel = new JButton("-"); bIntfDel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { removeInterface(); } }); GridBagConstraints gbc_bIntfDel = new GridBagConstraints(); gbc_bIntfDel.fill = GridBagConstraints.HORIZONTAL; gbc_bIntfDel.insets = new Insets(0, 0, 5, 0); gbc_bIntfDel.gridx = 1; gbc_bIntfDel.gridy = 0; panel_1.add(bIntfDel, gbc_bIntfDel); scrollPane_2 = new JScrollPane(); scrollPane_2.setMinimumSize(new Dimension(22, 80)); GridBagConstraints gbc_scrollPane_2 = new GridBagConstraints(); gbc_scrollPane_2.gridwidth = 2; gbc_scrollPane_2.fill = GridBagConstraints.BOTH; gbc_scrollPane_2.insets = new Insets(0, 0, 5, 0); gbc_scrollPane_2.gridx = 0; gbc_scrollPane_2.gridy = 1; panel_1.add(scrollPane_2, gbc_scrollPane_2); lInterfaces = new JList(lmInterfaces); lInterfaces.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if ((e.getClickCount()==2)&&(e.getButton()==e.BUTTON1)){ if (selectedDeviceInterface != null){ selectedDeviceInterface.showConnctionSetup(frmSynolog); frmSynolog.repaint(); } } } }); lInterfaces.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { selectedInterfaceChanged(); } }); scrollPane_2.setViewportView(lInterfaces); panel_4 = new JPanel(); panel_4.setBorder(new TitledBorder(null, Messages.getString("Anschlusseinstellungen"), TitledBorder.LEADING, TitledBorder.TOP, null, null)); GridBagConstraints gbc_panel_4 = new GridBagConstraints(); gbc_panel_4.gridwidth = 2; gbc_panel_4.fill = GridBagConstraints.BOTH; gbc_panel_4.gridx = 0; gbc_panel_4.gridy = 2; panel_1.add(panel_4, gbc_panel_4); GridBagLayout gbl_panel_4 = new GridBagLayout(); gbl_panel_4.columnWidths = new int[]{0, 0}; gbl_panel_4.rowHeights = new int[]{0, 0}; gbl_panel_4.columnWeights = new double[]{1.0, Double.MIN_VALUE}; gbl_panel_4.rowWeights = new double[]{1.0, Double.MIN_VALUE}; panel_4.setLayout(gbl_panel_4); tfConnectionSettings = new JTextArea(); tfConnectionSettings.setEditable(false); GridBagConstraints gbc_tfConnectionSettings = new GridBagConstraints(); gbc_tfConnectionSettings.fill = GridBagConstraints.BOTH; gbc_tfConnectionSettings.gridx = 0; gbc_tfConnectionSettings.gridy = 0; panel_4.add(tfConnectionSettings, gbc_tfConnectionSettings); tfConnectionSettings.setColumns(10); JPanel panel_2 = new JPanel(); panel_2.setBackground(Color.WHITE); panel_2.setBorder(new TitledBorder(null, Messages.getString("Meldungen"), TitledBorder.LEADING, TitledBorder.TOP, null, null)); GridBagConstraints gbc_panel_2 = new GridBagConstraints(); gbc_panel_2.insets = new Insets(0, 0, 5, 0); gbc_panel_2.fill = GridBagConstraints.BOTH; gbc_panel_2.gridx = 0; gbc_panel_2.gridy = 1; panel.add(panel_2, gbc_panel_2); GridBagLayout gbl_panel_2 = new GridBagLayout(); gbl_panel_2.columnWidths = new int[]{142, 0}; gbl_panel_2.rowHeights = new int[]{3, 0}; gbl_panel_2.columnWeights = new double[]{1.0, Double.MIN_VALUE}; gbl_panel_2.rowWeights = new double[]{1.0, Double.MIN_VALUE}; panel_2.setLayout(gbl_panel_2); JScrollPane scrollPane = new JScrollPane(); GridBagConstraints gbc_scrollPane = new GridBagConstraints(); gbc_scrollPane.fill = GridBagConstraints.BOTH; gbc_scrollPane.gridx = 0; gbc_scrollPane.gridy = 0; panel_2.add(scrollPane, gbc_scrollPane); lMessages = new JList(); lMessages.setFont(new Font("Cantarell", Font.PLAIN, 10)); scrollPane.setViewportView(lMessages); panel_3 = new JPanel(); panel_3.setBackground(Color.WHITE); panel_3.setBorder(new TitledBorder(null, "Aktive Aufgaben", TitledBorder.LEADING, TitledBorder.TOP, null, null)); GridBagConstraints gbc_panel_3 = new GridBagConstraints(); gbc_panel_3.fill = GridBagConstraints.BOTH; gbc_panel_3.gridx = 0; gbc_panel_3.gridy = 2; panel.add(panel_3, gbc_panel_3); panel_3.setLayout(new BoxLayout(panel_3, BoxLayout.X_AXIS)); scrollPane_1 = new JScrollPane(); panel_3.add(scrollPane_1); lTasklets = new JList(); scrollPane_1.setViewportView(lTasklets); pChannels = new JPanel(); pChannels.setBorder(new EmptyBorder(10, 10, 10, 10)); pChannels.setBackground(Color.WHITE); pChannels.setMinimumSize(new Dimension(600, 10)); splitter.setLeftComponent(pChannels); GridBagLayout gbl_pChannels = new GridBagLayout(); gbl_pChannels.columnWidths = new int[]{0}; gbl_pChannels.rowHeights = new int[]{0}; gbl_pChannels.columnWeights = new double[]{Double.MIN_VALUE}; gbl_pChannels.rowWeights = new double[]{Double.MIN_VALUE}; pChannels.setLayout(gbl_pChannels); messageListModel = new DefaultListModel(); lMessages.setModel(messageListModel); } private PulsCounterApplication application(){ return this.pulsCounterApplication; } private void selectedInterfaceChanged(){ selectedDeviceInterface = (IDeviceConnector)lInterfaces.getSelectedValue(); /* ToDO: GUI Update */ if (selectedDeviceInterface == null){ bIntfDel.setEnabled(false); tfConnectionSettings.setText(""); } else { bIntfDel.setEnabled(true); tfConnectionSettings.setText(selectedDeviceInterface.getConnectionSettingsText()); } } @Override public void interfaceClassesChanged(PulsCounterApplication pulsCounterApplication) { //lm.setItems(pulsCounterApplication.getInterfaceClasses()); } @Override public void interfacesChanged(PulsCounterApplication pulsCounterApplication) { lmInterfaces.setItems(pulsCounterApplication.getInterfaces()); } private void addInterface(){ Class cidc; if (pulsCounterApplication.getInterfaceClasses().size()==1){ cidc = pulsCounterApplication.getInterfaceClasses().get(0); } else { cidc = (Class)JObjectSelector.execute(pulsCounterApplication.getInterfaceClasses().toArray()); } if (cidc != null){ pulsCounterApplication.addInterface(cidc, ""); }; } private void removeInterface(){ if (selectedDeviceInterface != null){ pulsCounterApplication.removeInterface(selectedDeviceInterface); lInterfaces.clearSelection(); } } private synchronized void updateDeviceView(){ if (selectedDeviceInterface != null){ try { int[] values = selectedDeviceInterface.getCounters(); float[] analogs = selectedDeviceInterface.getAnalogs(); int inputs, outputs, pullups; inputs = selectedDeviceInterface.getInputs(); outputs = selectedDeviceInterface.getOutputs(); pullups = selectedDeviceInterface.getPullups(); for (int n=0;n<32;n++){ channelDisplays[n].setEnabled(true); channelDisplays[n].setCounter(values[n]); channelDisplays[n].setInput( ((inputs & (1<>1; // // if (device_us < 0){ // trimTicksOnConnect = null; // } else { // long elapsed_us; // long diff_us; // long trim_ns_per_slice; // // elapsed_us = (T - trimTimeOnConnect) * 1000; // diff_us = elapsed_us - device_us; // // System.err.println(String.format("Device Triming: Elapsed us: Dev: %d PC %d Diff: %d", device_us,elapsed_us,diff_us)); // // trim_ns_per_slice = (diff_us * 1000) * trimDeviceTimeSlice / elapsed_us; // // smoothTrim.cycle((int)trim_ns_per_slice); // // System.err.println(String.format("Device Triming: Trim %dns / %dus",smoothTrim.getWert(),trimDeviceTimeSlice)); // // application().getServiceLink().writeInt(13, 0, 0x1002, smoothTrim.getWert()); // // application().message(String.format("Trimmung wurde korrigiert auf %dns / %dus",smoothTrim.getWert(),trimDeviceTimeSlice)); // // } // } else { // long s1,s2,T; // // try { // trimTicksOnConnect = application().getServiceLink().getServiceRegisterCache().getCachedInteger(13, 0, 0x0027); // s1 = System.currentTimeMillis(); // application().getServiceLink().writeInt(13, 0, 0x1301, 0); // s2 = System.currentTimeMillis(); // trimTimeOnConnect = (s1+s2)>>1; // // smoothTrim = new Smoother(); // smoothTrim.setTn( 10 ); // smoothTrim.setWert( application().getServiceLink().readInt(13, 0, 0x1002) ); // // } catch (Exception e){ // System.err.println("trimDevice(): init failed"); // e.printStackTrace(); // trimTicksOnConnect = null; // } // } // // // } catch (Exception e){ // e.printStackTrace(); // } // return null; // } // // // private void checkForAssertions(){ // Integer assert_error,assert_code; // // try // { // assert_error = -1; // for (int i=0;i<8;i++){ // assert_error = application().getServiceLink().readInt(13, 0, 0x0026); // assert_code = application().getServiceLink().readInt(13, 0, 0x0025); // // if (assert_error >= 0) // break; // // application().message(String.format("Assertion: Error: 0x%08x (%d) Position: 0x%04x Mark: %d", assert_error,assert_error, assert_code & 0xffff, (assert_code >> 16) & 0xffff)); // application().getServiceLink().writeInt(13, 0, 0x0025, -1); // }; // } catch (Exception ex){ // System.err.println("Exception while checking for assertions..."); // ex.printStackTrace(); // } // } @Override public synchronized void taskletQueued(final TaskletManager manager, final Tasklet tasklet) { if (EventQueue.isDispatchThread()) knownTasklets.addElement(tasklet); else { EventQueue.invokeLater(new Runnable() { @Override public void run() { taskletQueued(manager, tasklet); } }); } } @Override public synchronized void taskletStarted(final TaskletManager manager, final Tasklet tasklet) { if (EventQueue.isDispatchThread()) lTasklets.repaint(); else EventQueue.invokeLater(new Runnable() { @Override public void run() { taskletStarted(manager, tasklet); } }); } @Override public synchronized void taskletFinished(final TaskletManager manager, final Tasklet tasklet) { if (EventQueue.isDispatchThread()) knownTasklets.removeElement(tasklet); else EventQueue.invokeLater(new Runnable() { @Override public void run() { taskletFinished(manager, tasklet); } }); } @Override public synchronized void taskletProgressChanged(final TaskletManager manager, final Tasklet tasklet) { if (EventQueue.isDispatchThread()) lTasklets.repaint(); else EventQueue.invokeLater(new Runnable() { @Override public void run() { taskletProgressChanged(manager, tasklet); } }); } private void channelReset(ChannelDisplay display){ for (int n=0;n<32;n++){ if (display == channelDisplays[n]){ channelReset(n,0); return; } } } private void channelSetDescription(ChannelDisplay display){ for (int n=0;n<32;n++){ if (display == channelDisplays[n]){ // application().setChannelDescription(n, display.getDescriptionText()); return; } } } private void channelReset(int channel,int setValue){ selectedDeviceInterface.setCounter(channel, setValue); } private void channelSet(ChannelDisplay display,int setValue){ for (int n=0;n<32;n++){ if (display == channelDisplays[n]){ channelReset(n,setValue); return; } } } class BackgroundThread extends Thread { private int timeout; private boolean exit; private boolean paused; private int checkTimeout; public BackgroundThread(){ timeout = 500; checkTimeout = 0; exit = false; } public void exit(){ synchronized (this){ this.exit = true; notify(); }; while (isAlive()){ try { sleep(50); } catch (InterruptedException e) { } } } public synchronized int getTimeout() { return timeout; } public synchronized void setTimeout(int timeout) { this.timeout = timeout; } @Override public void run() { synchronized (this) { log(INFO,"newMainWindow: backgroundThread: started"); while (!exit){ try { wait(timeout); if (!isPaused()){ updateDeviceView(); if (checkTimeout > 0){ checkTimeout--; } else { checkTimeout = 10; application().checkForSnapShots(); } } } catch (InterruptedException e){ } catch (Exception e){ log(ERROR,"Unexpected Exception in backgroundThread: %s", e.toString()); e.printStackTrace(); } } log(INFO,"newMainWindow: backgroundThread: exited"); } } public synchronized boolean isPaused() { return paused; } public synchronized void setPaused(boolean paused) { this.paused = paused; } } private void deviceTest(){ if (selectedDeviceInterface != null){ if (JOptionPane.showConfirmDialog(frmSynolog, Messages.getString("warning.title.selftest"),Messages.getString("warning.selftest"), JOptionPane.YES_NO_OPTION)== JOptionPane.YES_OPTION){ DeviceTester deviceTester = new DeviceTester(selectedDeviceInterface); backgroundThread.setPaused(true); deviceTester.start(); backgroundThread.setPaused(false); } } } }