Package org.openpnp.gui

Source Code of org.openpnp.gui.JobPanel

/*
   Copyright (C) 2011 Jason von Nieda <jason@vonnieda.org>
  
   This file is part of OpenPnP.
  
  OpenPnP is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    OpenPnP is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with OpenPnP.  If not, see <http://www.gnu.org/licenses/>.
  
   For more information about OpenPnP visit http://openpnp.org
*/

package org.openpnp.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FilenameFilter;
import java.util.prefs.Preferences;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultCellEditor;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.ListSelectionModel;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.openpnp.ConfigurationListener;
import org.openpnp.JobProcessorDelegate;
import org.openpnp.JobProcessorListener;
import org.openpnp.gui.components.AutoSelectTextTable;
import org.openpnp.gui.components.CameraView;
import org.openpnp.gui.components.reticle.PackageReticle;
import org.openpnp.gui.components.reticle.Reticle;
import org.openpnp.gui.importer.BoardImporter;
import org.openpnp.gui.processes.TwoPlacementBoardLocationProcess;
import org.openpnp.gui.support.ActionGroup;
import org.openpnp.gui.support.Helpers;
import org.openpnp.gui.support.IdentifiableListCellRenderer;
import org.openpnp.gui.support.IdentifiableTableCellRenderer;
import org.openpnp.gui.support.MessageBoxes;
import org.openpnp.gui.support.PartsComboBoxModel;
import org.openpnp.gui.tablemodel.BoardLocationsTableModel;
import org.openpnp.gui.tablemodel.PlacementsTableModel;
import org.openpnp.model.Board;
import org.openpnp.model.Board.Side;
import org.openpnp.model.BoardLocation;
import org.openpnp.model.Configuration;
import org.openpnp.model.Job;
import org.openpnp.model.Location;
import org.openpnp.model.Part;
import org.openpnp.model.Placement;
import org.openpnp.spi.Camera;
import org.openpnp.spi.Feeder;
import org.openpnp.spi.JobProcessor;
import org.openpnp.spi.JobProcessor.JobError;
import org.openpnp.spi.JobProcessor.JobState;
import org.openpnp.spi.JobProcessor.PickRetryAction;
import org.openpnp.spi.Machine;
import org.openpnp.spi.MachineListener;
import org.openpnp.spi.Nozzle;
import org.openpnp.util.MovableUtils;
import org.openpnp.util.Utils2D;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings("serial")
public class JobPanel extends JPanel {
  @SuppressWarnings("unused")
  private static final Logger logger = LoggerFactory
      .getLogger(JobPanel.class);

  final private Configuration configuration;
  final private MainFrame frame;
  final private MachineControlsPanel machineControlsPanel;

  private static final String PREF_DIVIDER_POSITION = "JobPanel.dividerPosition";
  private static final int PREF_DIVIDER_POSITION_DEF = -1;

  final private static String UNTITLED_JOB_FILENAME = "Untitled.job.xml";

    private JobProcessor jobProcessor;

    private BoardLocationsTableModel boardLocationsTableModel;
  private PlacementsTableModel placementsTableModel;
  private JTable boardLocationsTable;
  private JTable placementsTable;
  private JSplitPane splitPane;

  private ActionGroup jobSaveActionGroup;
  private ActionGroup boardLocationSelectionActionGroup;
  private ActionGroup placementSelectionActionGroup;

  private Preferences prefs = Preferences.userNodeForPackage(JobPanel.class);
 

  public JobPanel(Configuration configuration, MainFrame frame, MachineControlsPanel machineControlsPanel) {
    this.configuration = configuration;
    this.frame = frame;
    this.machineControlsPanel = machineControlsPanel;
   
    jobSaveActionGroup = new ActionGroup(saveJobAction, saveJobAsAction);
    jobSaveActionGroup.setEnabled(false);

    boardLocationSelectionActionGroup = new ActionGroup(removeBoardAction,
        captureCameraBoardLocationAction,
        captureToolBoardLocationAction, newPlacementAction,
        moveCameraToBoardLocationAction, moveToolToBoardLocationAction,
        twoPointLocateBoardLocationAction);
    boardLocationSelectionActionGroup.setEnabled(false);

    placementSelectionActionGroup = new ActionGroup(removePlacementAction,
        captureCameraPlacementLocation, captureToolPlacementLocation,
        moveCameraToPlacementLocation, moveToolToPlacementLocation);
    placementSelectionActionGroup.setEnabled(false);

    boardLocationsTableModel = new BoardLocationsTableModel(configuration);
    placementsTableModel = new PlacementsTableModel(configuration);

    JComboBox sidesComboBox = new JComboBox(Side.values());

    boardLocationsTable = new AutoSelectTextTable(boardLocationsTableModel);
    boardLocationsTable.setAutoCreateRowSorter(true);
    boardLocationsTable
        .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    boardLocationsTable.setDefaultEditor(Side.class, new DefaultCellEditor(
        sidesComboBox));

    boardLocationsTable.getSelectionModel().addListSelectionListener(
        new ListSelectionListener() {
          @Override
          public void valueChanged(ListSelectionEvent e) {
            if (e.getValueIsAdjusting()) {
              return;
            }
            BoardLocation boardLocation = getSelectedBoardLocation();
            boardLocationSelectionActionGroup
                .setEnabled(boardLocation != null);
            if (boardLocation == null) {
              placementsTableModel.setBoard(null);
            }
            else {
              placementsTableModel.setBoard(boardLocation
                  .getBoard());
            }
          }
        });

    JComboBox partsComboBox = new JComboBox(new PartsComboBoxModel());
    partsComboBox.setRenderer(new IdentifiableListCellRenderer<Part>());

    placementsTable = new AutoSelectTextTable(placementsTableModel);
    placementsTable.setAutoCreateRowSorter(true);
    placementsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    placementsTable.setDefaultEditor(Side.class, new DefaultCellEditor(
        sidesComboBox));
    placementsTable.setDefaultEditor(Part.class, new DefaultCellEditor(
        partsComboBox));
    placementsTable.setDefaultRenderer(Part.class,
        new IdentifiableTableCellRenderer<Part>());

    placementsTable.getSelectionModel().addListSelectionListener(
        new ListSelectionListener() {
          @Override
          public void valueChanged(ListSelectionEvent e) {
            if (e.getValueIsAdjusting()) {
              return;
            }
            placementSelectionActionGroup
                .setEnabled(getSelectedPlacement() != null);
            Placement placement = getSelectedPlacement();
            CameraView cameraView = MainFrame.cameraPanel.getSelectedCameraView();
            if (cameraView != null) {
                          if (placement != null) {
                                Reticle reticle = new PackageReticle(placement.getPart().getPackage());
                                cameraView.setReticle(JobPanel.this.getClass().getName(), reticle);
                          }
                          else {
                              cameraView.removeReticle(JobPanel.this.getClass().getName());
                          }
            }
          }
        });
   
        addComponentListener(new ComponentAdapter() {
            @Override
            public void componentHidden(ComponentEvent e) {
                CameraView cameraView = MainFrame.cameraPanel.getSelectedCameraView();
                if (cameraView != null) {
                    cameraView.removeReticle(JobPanel.this.getClass().getName());
                }
            }
        });


    setLayout(new BorderLayout(0, 0));

    splitPane = new JSplitPane();
    splitPane.setBorder(null);
    splitPane.setContinuousLayout(true);
    splitPane.setDividerLocation(prefs.getInt(PREF_DIVIDER_POSITION,
        PREF_DIVIDER_POSITION_DEF));
    splitPane.addPropertyChangeListener("dividerLocation",
        new PropertyChangeListener() {
          @Override
          public void propertyChange(PropertyChangeEvent evt) {
            prefs.putInt(PREF_DIVIDER_POSITION,
                splitPane.getDividerLocation());
          }
        });

    JPanel pnlBoards = new JPanel();
    pnlBoards.setBorder(new TitledBorder(new EtchedBorder(
        EtchedBorder.LOWERED, null, null), "Boards",
        TitledBorder.LEADING, TitledBorder.TOP, null,
        new Color(0, 0, 0)));
    pnlBoards.setLayout(new BorderLayout(0, 0));

    JToolBar toolBarBoards = new JToolBar();
    toolBarBoards.setFloatable(false);
    pnlBoards.add(toolBarBoards, BorderLayout.NORTH);

    JButton btnStartPauseResumeJob = new JButton(startPauseResumeJobAction);
    btnStartPauseResumeJob.setHideActionText(true);
    toolBarBoards.add(btnStartPauseResumeJob);
    JButton btnStepJob = new JButton(stepJobAction);
    btnStepJob.setHideActionText(true);
    toolBarBoards.add(btnStepJob);
    JButton btnStopJob = new JButton(stopJobAction);
    btnStopJob.setHideActionText(true);
    toolBarBoards.add(btnStopJob);
    toolBarBoards.addSeparator();
    JButton btnNewBoard = new JButton(newBoardAction);
    btnNewBoard.setHideActionText(true);
    toolBarBoards.add(btnNewBoard);
    JButton btnAddBoard = new JButton(addBoardAction);
    btnAddBoard.setHideActionText(true);
    toolBarBoards.add(btnAddBoard);
    JButton btnRemoveBoard = new JButton(removeBoardAction);
    btnRemoveBoard.setHideActionText(true);
    toolBarBoards.add(btnRemoveBoard);
    toolBarBoards.addSeparator();
    JButton btnCaptureCameraBoardLocation = new JButton(
        captureCameraBoardLocationAction);
    btnCaptureCameraBoardLocation.setHideActionText(true);
    toolBarBoards.add(btnCaptureCameraBoardLocation);

    JButton btnCaptureToolBoardLocation = new JButton(
        captureToolBoardLocationAction);
    btnCaptureToolBoardLocation.setHideActionText(true);
    toolBarBoards.add(btnCaptureToolBoardLocation);

    JButton btnPositionCameraBoardLocation = new JButton(
        moveCameraToBoardLocationAction);
    btnPositionCameraBoardLocation.setHideActionText(true);
    toolBarBoards.add(btnPositionCameraBoardLocation);

    JButton btnPositionToolBoardLocation = new JButton(
        moveToolToBoardLocationAction);
    btnPositionToolBoardLocation.setHideActionText(true);
    toolBarBoards.add(btnPositionToolBoardLocation);
    toolBarBoards.addSeparator();

    JButton btnTwoPointBoardLocation = new JButton(
        twoPointLocateBoardLocationAction);
    toolBarBoards.add(btnTwoPointBoardLocation);
    btnTwoPointBoardLocation.setHideActionText(true);

    pnlBoards.add(new JScrollPane(boardLocationsTable));
    JPanel pnlPlacements = new JPanel();
    pnlPlacements.setBorder(new TitledBorder(null, "Placements",
        TitledBorder.LEADING, TitledBorder.TOP, null, null));
    pnlPlacements.setLayout(new BorderLayout(0, 0));

    JToolBar toolBarPlacements = new JToolBar();
    toolBarPlacements.setFloatable(false);
    pnlPlacements.add(toolBarPlacements, BorderLayout.NORTH);
    JButton btnNewPlacement = new JButton(newPlacementAction);
    btnNewPlacement.setHideActionText(true);
    toolBarPlacements.add(btnNewPlacement);
    JButton btnRemovePlacement = new JButton(removePlacementAction);
    btnRemovePlacement.setHideActionText(true);
    toolBarPlacements.add(btnRemovePlacement);
    toolBarPlacements.addSeparator();
    JButton btnCaptureCameraPlacementLocation = new JButton(
        captureCameraPlacementLocation);
    btnCaptureCameraPlacementLocation.setToolTipText("");
    btnCaptureCameraPlacementLocation.setText("");
    btnCaptureCameraPlacementLocation.setHideActionText(true);
    toolBarPlacements.add(btnCaptureCameraPlacementLocation);

    JButton btnCaptureToolPlacementLocation = new JButton(
        captureToolPlacementLocation);
    btnCaptureToolPlacementLocation.setToolTipText("");
    btnCaptureToolPlacementLocation.setText("");
    btnCaptureToolPlacementLocation.setHideActionText(true);
    toolBarPlacements.add(btnCaptureToolPlacementLocation);
   
   
        JButton btnPositionCameraPositionLocation = new JButton(
                moveCameraToPlacementLocation);
        btnPositionCameraPositionLocation.setHideActionText(true);
        toolBarPlacements.add(btnPositionCameraPositionLocation);

        JButton btnPositionToolPositionLocation = new JButton(
                moveToolToPlacementLocation);
        btnPositionToolPositionLocation.setHideActionText(true);
        toolBarPlacements.add(btnPositionToolPositionLocation);
       

   
    pnlPlacements.add(new JScrollPane(placementsTable));

    splitPane.setLeftComponent(pnlBoards);
    splitPane.setRightComponent(pnlPlacements);

    add(splitPane);

        Configuration.get().addListener(new ConfigurationListener.Adapter() {
            public void configurationComplete(Configuration configuration) throws Exception {
                configuration.getMachine().addListener(machineListener);

                jobProcessor = configuration.getMachine().getJobProcessor();
                jobProcessor.addListener(jobProcessorListener);
                jobProcessor.setDelegate(jobProcessorDelegate);

                updateJobActions();

                // Create an empty Job if one is not loaded
                if (JobPanel.this.jobProcessor.getJob() == null) {
                    Job job = new Job();
                    JobPanel.this.jobProcessor.load(job);
                }
            }
        });
  }

  public void refreshSelectedBoardRow() {
    boardLocationsTableModel.fireTableRowsUpdated(
        boardLocationsTable.getSelectedRow(),
        boardLocationsTable.getSelectedRow());
  }

  public BoardLocation getSelectedBoardLocation() {
    int index = boardLocationsTable.getSelectedRow();
    if (index == -1) {
      return null;
    }
    else {
      index = boardLocationsTable.convertRowIndexToModel(index);
      return JobPanel.this.jobProcessor.getJob().getBoardLocations()
          .get(index);
    }
  }

  public Placement getSelectedPlacement() {
    if (getSelectedBoardLocation() == null) {
      return null;
    }
    int index = placementsTable.getSelectedRow();
    if (index == -1) {
      return null;
    }
    else {
      index = placementsTable.convertRowIndexToModel(index);
      return getSelectedBoardLocation().getBoard().getPlacements()
          .get(index);
    }
  }
 
  /**
   * Checks if there are any modifications that need to be saved. Prompts the
   * user if there are. Returns true if it's okay to exit.
   * @return
   */
  public boolean checkForModifications() {
      if (!checkForBoardModifications()) {
          return false;
      }
      if (!checkForJobModifications()) {
          return false;
      }
      return true;
  }

  private boolean checkForJobModifications() {
    if (jobProcessor.getJob().isDirty()) {
      Job job = jobProcessor.getJob();
      String name = (job.getFile() == null ? UNTITLED_JOB_FILENAME : job
          .getFile().getName());
      int result = JOptionPane.showConfirmDialog(frame,
          "Do you want to save your changes to " + name + "?" + "\n"
              + "If you don't save, your changes will be lost.",
          "Save " + name + "?", JOptionPane.YES_NO_CANCEL_OPTION);
      if (result == JOptionPane.YES_OPTION) {
        return saveJob();
      }
      else if (result == JOptionPane.CANCEL_OPTION) {
        return false;
      }
    }
    return true;
  }
 
    private boolean checkForBoardModifications() {
        for (Board board : configuration.getBoards()) {
            if (board.isDirty()) {
                int result = JOptionPane
                        .showConfirmDialog(
                                getTopLevelAncestor(),
                                "Do you want to save your changes to "
                                        + board.getFile().getName()
                                        + "?"
                                        + "\n"
                                        + "If you don't save, your changes will be lost.",
                                "Save " + board.getFile().getName() + "?",
                                JOptionPane.YES_NO_CANCEL_OPTION);
                if (result == JOptionPane.YES_OPTION) {
                    try {
                        configuration.saveBoard(board);
                    }
                    catch (Exception e) {
                        MessageBoxes.errorBox(getTopLevelAncestor(),
                                "Board Save Error", e.getMessage());
                        return false;
                    }
                }
                else if (result == JOptionPane.CANCEL_OPTION) {
                    return false;
                }
            }
        }
        return true;
    }
 
  private boolean saveJob() {
    if (jobProcessor.getJob().getFile() == null) {
      return saveJobAs();
    }
    else {
      try {
        configuration.saveJob(jobProcessor.getJob(), jobProcessor
            .getJob().getFile());
        return true;
      }
      catch (Exception e) {
        MessageBoxes.errorBox(frame, "Job Save Error", e.getMessage());
        return false;
      }
    }
  }

  private boolean saveJobAs() {
    FileDialog fileDialog = new FileDialog(frame, "Save Job As...",
        FileDialog.SAVE);
    fileDialog.setFilenameFilter(new FilenameFilter() {
      @Override
      public boolean accept(File dir, String name) {
        return name.toLowerCase().endsWith(".job.xml");
      }
    });
    fileDialog.setVisible(true);
    try {
      String filename = fileDialog.getFile();
      if (filename == null) {
        return false;
      }
      if (!filename.toLowerCase().endsWith(".job.xml")) {
        filename = filename + ".job.xml";
      }
      File file = new File(new File(fileDialog.getDirectory()), filename);
      configuration.saveJob(jobProcessor.getJob(), file);
      return true;
    }
    catch (Exception e) {
      MessageBoxes.errorBox(frame, "Job Save Error", e.getMessage());
      return false;
    }
  }

  /**
   * Updates the Job controls based on the Job state and the Machine's
   * readiness.
   */
  private void updateJobActions() {
    JobState state = jobProcessor.getState();
    if (state == JobState.Stopped) {
      startPauseResumeJobAction.setEnabled(true);
      startPauseResumeJobAction.putValue(AbstractAction.NAME, "Start");
      startPauseResumeJobAction.putValue(
          AbstractAction.SMALL_ICON,
          new ImageIcon(JobPanel.class
              .getResource("/icons/start.png")));
      startPauseResumeJobAction.putValue(
          AbstractAction.SHORT_DESCRIPTION,
          "Start processing the job.");
      stopJobAction.setEnabled(false);
      stepJobAction.setEnabled(true);
    }
    else if (state == JobState.Running) {
      startPauseResumeJobAction.setEnabled(true);
      startPauseResumeJobAction.putValue(AbstractAction.NAME, "Pause");
      startPauseResumeJobAction.putValue(
          AbstractAction.SMALL_ICON,
          new ImageIcon(JobPanel.class
              .getResource("/icons/pause.png")));
      startPauseResumeJobAction.putValue(
          AbstractAction.SHORT_DESCRIPTION,
          "Pause processing of the job.");
      stopJobAction.setEnabled(true);
      stepJobAction.setEnabled(false);
    }
    else if (state == JobState.Paused) {
      startPauseResumeJobAction.setEnabled(true);
      startPauseResumeJobAction.putValue(AbstractAction.NAME, "Resume");
      startPauseResumeJobAction.putValue(
          AbstractAction.SMALL_ICON,
          new ImageIcon(JobPanel.class
              .getResource("/icons/start.png")));
      startPauseResumeJobAction.putValue(
          AbstractAction.SHORT_DESCRIPTION,
          "Resume processing of the job.");
      stopJobAction.setEnabled(true);
      stepJobAction.setEnabled(true);
    }

    // We allow the above to run first so that all state is represented
    // correctly even if the machine is disabled.
    if (!configuration.getMachine().isEnabled()) {
      startPauseResumeJobAction.setEnabled(false);
      stopJobAction.setEnabled(false);
      stepJobAction.setEnabled(false);
    }
  }

  private void updateTitle() {
    Job job = jobProcessor.getJob();
    String title = String.format("OpenPnP - %s%s",
        job.isDirty() ? "*" : "",
        (job.getFile() == null ? UNTITLED_JOB_FILENAME : job.getFile()
            .getName()));
    frame.setTitle(title);
  }
 
  public void importBoard(Class<? extends BoardImporter> boardImporterClass) {
        if (getSelectedBoardLocation() == null) {
              MessageBoxes.errorBox(getTopLevelAncestor(), "Import Failed", "Please select a board in the Jobs tab to import into.");
            return;
        }
       
        BoardImporter boardImporter;
          try {
              boardImporter = boardImporterClass.newInstance();
          }
          catch (Exception e) {
              MessageBoxes.errorBox(getTopLevelAncestor(), "Import Failed", e);
              return;
          }
         
        try {
            Board importedBoard = boardImporter.importBoard((Frame) getTopLevelAncestor());
            Board existingBoard = getSelectedBoardLocation().getBoard();
            for (Placement placement : importedBoard.getPlacements()) {
                existingBoard.addPlacement(placement);
            }
            placementsTableModel.fireTableDataChanged();
        }
        catch (Exception e) {
            MessageBoxes.errorBox(getTopLevelAncestor(), "Import Failed", e);
        }
  }
 
  public final Action openJobAction = new AbstractAction("Open Job...") {
    @Override
    public void actionPerformed(ActionEvent arg0) {
      if (!checkForModifications()) {
        return;
      }
      FileDialog fileDialog = new FileDialog(frame);
      fileDialog.setFilenameFilter(new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
          return name.toLowerCase().endsWith(".job.xml");
        }
      });
      fileDialog.setVisible(true);
      try {
        if (fileDialog.getFile() == null) {
          return;
        }
        File file = new File(new File(fileDialog.getDirectory()),
            fileDialog.getFile());
        Job job = configuration.loadJob(file);
        jobProcessor.load(job);
      }
      catch (Exception e) {
        e.printStackTrace();
        MessageBoxes.errorBox(frame, "Job Load Error", e.getMessage());
      }
    }
  };

  public final Action newJobAction = new AbstractAction("New Job") {
    @Override
    public void actionPerformed(ActionEvent arg0) {
      if (!checkForModifications()) {
        return;
      }
      jobProcessor.load(new Job());
    }
  };

  public final Action saveJobAction = new AbstractAction("Save Job") {
    @Override
    public void actionPerformed(ActionEvent arg0) {
      saveJob();
    }
  };

  public final Action saveJobAsAction = new AbstractAction("Save Job As...") {
    @Override
    public void actionPerformed(ActionEvent arg0) {
      saveJobAs();
    }
  };

  public final Action startPauseResumeJobAction = new AbstractAction() {
    {
      putValue(
          SMALL_ICON,
          new ImageIcon(JobPanel.class
              .getResource("/icons/start.png")));
      putValue(NAME, "Start");
      putValue(SHORT_DESCRIPTION, "Start processing the job.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      JobState state = jobProcessor.getState();
      if (state == JobState.Stopped) {
        try {
          jobProcessor.start();
        }
        catch (Exception e) {
          MessageBoxes.errorBox(frame, "Job Start Error",
              e.getMessage());
        }
      }
      else if (state == JobState.Paused) {
        jobProcessor.resume();
      }
      else if (state == JobState.Running) {
        jobProcessor.pause();
      }
    }
  };

  public final Action stepJobAction = new AbstractAction() {
    {
      putValue(
          SMALL_ICON,
          new ImageIcon(JobPanel.class.getResource("/icons/step.png")));
      putValue(NAME, "Step");
      putValue(SHORT_DESCRIPTION,
          "Process one step of the job and pause.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      try {
        jobProcessor.step();
      }
      catch (Exception e) {
        MessageBoxes.errorBox(frame, "Job Step Failed", e.getMessage());
      }
    }
  };

  public final Action stopJobAction = new AbstractAction() {
    {
      putValue(
          SMALL_ICON,
          new ImageIcon(JobPanel.class.getResource("/icons/stop.png")));
      putValue(NAME, "Stop");
      putValue(SHORT_DESCRIPTION, "Stop processing the job.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      jobProcessor.stop();
    }
  };

  public final Action newBoardAction = new AbstractAction() {
    {
      putValue(SMALL_ICON,
          new ImageIcon(JobPanel.class.getResource("/icons/new.png")));
      putValue(NAME, "New Board...");
      putValue(SHORT_DESCRIPTION,
          "Create a new board and add it to the job.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      FileDialog fileDialog = new FileDialog(frame,
          "Save New Board As...", FileDialog.SAVE);
      fileDialog.setFilenameFilter(new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
          return name.toLowerCase().endsWith(".board.xml");
        }
      });
      fileDialog.setVisible(true);
      try {
        String filename = fileDialog.getFile();
        if (filename == null) {
          return;
        }
        if (!filename.toLowerCase().endsWith(".board.xml")) {
          filename = filename + ".board.xml";
        }
        File file = new File(new File(fileDialog.getDirectory()),
            filename);

        Board board = configuration.getBoard(file);
        BoardLocation boardLocation = new BoardLocation(board);
        jobProcessor.getJob().addBoardLocation(boardLocation);
        boardLocationsTableModel.fireTableDataChanged();

        Helpers.selectLastTableRow(boardLocationsTable);
      }
      catch (Exception e) {
        e.printStackTrace();
        MessageBoxes.errorBox(frame, "Unable to create new board",
            e.getMessage());
      }
    }
  };

  public final Action addBoardAction = new AbstractAction() {
    {
      putValue(SMALL_ICON,
          new ImageIcon(JobPanel.class.getResource("/icons/add.png")));
      putValue(NAME, "Add Board...");
      putValue(SHORT_DESCRIPTION, "Add an existing board to the job.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      FileDialog fileDialog = new FileDialog(frame);
      fileDialog.setFilenameFilter(new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
          return name.toLowerCase().endsWith(".board.xml");
        }
      });
      fileDialog.setVisible(true);
      try {
        if (fileDialog.getFile() == null) {
          return;
        }
        File file = new File(new File(fileDialog.getDirectory()),
            fileDialog.getFile());

        Board board = configuration.getBoard(file);
        BoardLocation boardLocation = new BoardLocation(board);
        jobProcessor.getJob().addBoardLocation(boardLocation);
        // TODO: Move to a list property listener.
        boardLocationsTableModel.fireTableDataChanged();

        Helpers.selectLastTableRow(boardLocationsTable);
      }
      catch (Exception e) {
        e.printStackTrace();
        MessageBoxes.errorBox(frame, "Board load failed",
            e.getMessage());
      }
    }
  };

  public final Action removeBoardAction = new AbstractAction("Remove Board") {
    {
      putValue(
          SMALL_ICON,
          new ImageIcon(JobPanel.class
              .getResource("/icons/delete.png")));
      putValue(NAME, "Remove Board");
      putValue(SHORT_DESCRIPTION,
          "Remove the selected board from the job.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      int index = boardLocationsTable.getSelectedRow();
      if (index != -1) {
        index = boardLocationsTable.convertRowIndexToModel(index);
        BoardLocation boardLocation = JobPanel.this.jobProcessor
            .getJob().getBoardLocations().get(index);
        JobPanel.this.jobProcessor.getJob().removeBoardLocation(
            boardLocation);
        boardLocationsTableModel.fireTableDataChanged();
      }
    }
  };

  public final Action captureCameraBoardLocationAction = new AbstractAction() {
    {
      putValue(
          SMALL_ICON,
          new ImageIcon(JobPanel.class
              .getResource("/icons/capture-camera.png")));
      putValue(NAME, "Capture Camera Location");
      putValue(SHORT_DESCRIPTION,
          "Set the board's location to the camera's current position.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      getSelectedBoardLocation().setLocation(MainFrame.cameraPanel.getSelectedCameraLocation());
      boardLocationsTableModel.fireTableRowsUpdated(
          boardLocationsTable.getSelectedRow(),
          boardLocationsTable.getSelectedRow());
    }
  };

  public final Action captureToolBoardLocationAction = new AbstractAction() {
    {
      putValue(
          SMALL_ICON,
          new ImageIcon(JobPanel.class
              .getResource("/icons/capture-tool.png")));
      putValue(NAME, "Capture Tool Location");
      putValue(SHORT_DESCRIPTION,
          "Set the board's location to the tool's current position.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      getSelectedBoardLocation().setLocation(machineControlsPanel.getSelectedNozzle().getLocation());
      boardLocationsTableModel.fireTableRowsUpdated(
          boardLocationsTable.getSelectedRow(),
          boardLocationsTable.getSelectedRow());
    }
  };

  public final Action moveCameraToBoardLocationAction = new AbstractAction(
      "Move Camera To Board Location") {
    {
      putValue(
          SMALL_ICON,
          new ImageIcon(JobPanel.class
              .getResource("/icons/center-camera.png")));
      putValue(NAME, "Move Camera To Board Location");
      putValue(SHORT_DESCRIPTION,
          "Position the camera at the board's location.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
            final Camera camera = MainFrame.cameraPanel.getSelectedCamera();
            if (camera.getHead() == null) {
                MessageBoxes.errorBox(getTopLevelAncestor(), "Move Error", "Camera is not movable.");
                return;
            }
            final Location location = getSelectedBoardLocation().getLocation();
      MainFrame.machineControlsPanel.submitMachineTask(new Runnable() {
        public void run() {
          try {
            MovableUtils.moveToLocationAtSafeZ(camera, location, 1.0);
          }
          catch (Exception e) {
            MessageBoxes.errorBox(getTopLevelAncestor(),
                "Move Error", e);
          }
        }
      });
    }
  };

  public final Action moveToolToBoardLocationAction = new AbstractAction() {
    {
      putValue(
          SMALL_ICON,
          new ImageIcon(JobPanel.class
              .getResource("/icons/center-tool.png")));
      putValue(NAME, "Move Tool To Board Location");
      putValue(SHORT_DESCRIPTION,
          "Position the tool at the board's location.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      MainFrame.machineControlsPanel.submitMachineTask(new Runnable() {
                final Nozzle nozzle = machineControlsPanel.getSelectedNozzle();
                final Location location = getSelectedBoardLocation().getLocation();
        public void run() {
          try {
            MovableUtils.moveToLocationAtSafeZ(nozzle, location, 1.0);
          }
          catch (Exception e) {
            MessageBoxes.errorBox(getTopLevelAncestor(),
                "Move Error", e);
          }
        }
      });
    }
  };

  public final Action twoPointLocateBoardLocationAction = new AbstractAction() {
    {
      putValue(
          SMALL_ICON,
          new ImageIcon(JobPanel.class
              .getResource("/icons/two-point-locate.png")));
      putValue(NAME, "Two Point Board Location");
      putValue(SHORT_DESCRIPTION,
          "Set the board's location and rotation using two placements.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      new TwoPlacementBoardLocationProcess(frame, JobPanel.this);
    }
  };

  public final Action newPlacementAction = new AbstractAction() {
    {
      putValue(SMALL_ICON,
          new ImageIcon(JobPanel.class.getResource("/icons/new.png")));
      putValue(NAME, "New Placement");
      putValue(SHORT_DESCRIPTION,
          "Create a new placement and add it to the board.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      if (Configuration.get().getParts().size() == 0) {
        MessageBoxes
            .errorBox(
                getTopLevelAncestor(),
                "Error",
                "There are currently no parts defined in the system. Please create at least one part before creating a placement.");
        return;
      }

      BoardLocation boardLocation = getSelectedBoardLocation();
      String id = JOptionPane.showInputDialog(frame,
          "Please enter an ID for the new placement.");
      if (id == null) {
        return;
      }
      // TODO: Make sure it's unique.
      Placement placement = new Placement(id);

      placement.setPart(Configuration.get().getParts().get(0));
      placement.setLocation(new Location(Configuration.get().getSystemUnits()));
     
      boardLocation.getBoard().addPlacement(placement);
      placementsTableModel.fireTableDataChanged();
      Helpers.selectLastTableRow(placementsTable);
    }
  };

  public final Action removePlacementAction = new AbstractAction() {
    {
      putValue(
          SMALL_ICON,
          new ImageIcon(JobPanel.class
              .getResource("/icons/delete.png")));
      putValue(NAME, "Remove Placement");
      putValue(SHORT_DESCRIPTION,
          "Remove the currently selected placement.");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      BoardLocation boardLocation = getSelectedBoardLocation();
      Placement placement = getSelectedPlacement();
      boardLocation.getBoard().removePlacement(placement);
      placementsTableModel.fireTableDataChanged();
    }
  };

    public final Action moveCameraToPlacementLocation = new AbstractAction() {
        {
            putValue(
                    SMALL_ICON,
                    new ImageIcon(JobPanel.class
                            .getResource("/icons/center-camera.png")));
            putValue(NAME, "Move Camera To Placement Location");
            putValue(SHORT_DESCRIPTION,
                    "Position the camera at the placement's location.");
        }

        @Override
        public void actionPerformed(ActionEvent arg0) {
            Location placementLocation =
                    Utils2D.calculateBoardPlacementLocation(
                            getSelectedBoardLocation(),
                            getSelectedPlacement());
           
            final Camera camera = MainFrame.cameraPanel.getSelectedCamera();
            if (camera.getHead() == null) {
                MessageBoxes.errorBox(getTopLevelAncestor(), "Move Error", "Camera is not movable.");
                return;
            }
            final Location location = placementLocation;
            MainFrame.machineControlsPanel.submitMachineTask(new Runnable() {
                public void run() {
                    try {
                        MovableUtils.moveToLocationAtSafeZ(camera, location, 1.0);
                    }
                    catch (Exception e) {
                        MessageBoxes.errorBox(getTopLevelAncestor(),
                                "Move Error", e);
                    }
                }
            });
        }
    };

    public final Action moveToolToPlacementLocation = new AbstractAction() {
        {
            putValue(
                    SMALL_ICON,
                    new ImageIcon(JobPanel.class
                            .getResource("/icons/center-tool.png")));
            putValue(NAME, "Move Tool To Placement Location");
            putValue(SHORT_DESCRIPTION,
                    "Position the tool at the placement's location.");
        }

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // get the selected board
            // get the selected placement
            // add the placement position to the board position
            // move there
        }
    };
   
    public final Action captureCameraPlacementLocation = new AbstractAction() {
        {
            putValue(
                    SMALL_ICON,
                    new ImageIcon(JobPanel.class
                            .getResource("/icons/capture-camera.png")));
            putValue(NAME, "Capture Camera Placement Location");
            putValue(SHORT_DESCRIPTION,
                    "Set the placement's location to the camera's current position.");
        }

        @Override
        public void actionPerformed(ActionEvent arg0) {
            MessageBoxes.notYetImplemented(getTopLevelAncestor());
        }
    };

    public final Action captureToolPlacementLocation = new AbstractAction() {
        {
            putValue(
                    SMALL_ICON,
                    new ImageIcon(JobPanel.class
                            .getResource("/icons/capture-tool.png")));
            putValue(NAME, "Capture Tool Placement Location");
            putValue(SHORT_DESCRIPTION,
                    "Set the placement's location to the tool's current position.");
        }

        @Override
        public void actionPerformed(ActionEvent arg0) {
            MessageBoxes.notYetImplemented(getTopLevelAncestor());
        }
    };
   
  private final JobProcessorListener jobProcessorListener = new JobProcessorListener.Adapter() {
    @Override
    public void jobStateChanged(JobState state) {
      updateJobActions();
    }

    @Override
    public void jobLoaded(Job job) {
      placementsTableModel.setBoard(null);
      boardLocationsTableModel.setJob(jobProcessor.getJob());
      job.addPropertyChangeListener("dirty", titlePropertyChangeListener);
      job.addPropertyChangeListener("file", titlePropertyChangeListener);
      updateTitle();
      updateJobActions();
    }

    @Override
    public void jobEncounteredError(JobError error, String description) {
      MessageBoxes.errorBox(frame, error.toString(), description
          + "\n\nThe job will be paused.");
      // TODO: Implement a way to retry, abort, etc.
      jobProcessor.pause();
    }
  };

  private final JobProcessorDelegate jobProcessorDelegate = new JobProcessorDelegate() {
    @Override
    public PickRetryAction partPickFailed(BoardLocation board, Part part,
        Feeder feeder) {
      return PickRetryAction.SkipAndContinue;
    }
  };

  private final MachineListener machineListener = new MachineListener.Adapter() {
    @Override
    public void machineEnabled(Machine machine) {
      updateJobActions();
    }

    @Override
    public void machineDisabled(Machine machine, String reason) {
      updateJobActions();
      jobProcessor.stop();
    }
  };

  private final PropertyChangeListener titlePropertyChangeListener = new PropertyChangeListener() {
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
      updateTitle();
      jobSaveActionGroup.setEnabled(jobProcessor.getJob().isDirty());
    }
  };
}
TOP

Related Classes of org.openpnp.gui.JobPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.