00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 package ikayaki.gui;
00024
00025 import com.intellij.uiDesigner.core.GridConstraints;
00026 import com.intellij.uiDesigner.core.GridLayoutManager;
00027 import com.intellij.uiDesigner.core.Spacer;
00028 import ikayaki.*;
00029
00030 import javax.swing.*;
00031 import javax.swing.event.*;
00032 import javax.swing.table.TableColumnModel;
00033 import javax.swing.text.NumberFormatter;
00034 import java.awt.*;
00035 import java.awt.event.*;
00036 import java.text.DecimalFormat;
00037 import java.util.ArrayList;
00038 import java.util.List;
00039
00040 import static ikayaki.gui.SequenceColumn.*;
00041
00047 public class MeasurementSequencePanel extends ProjectComponent {
00048
00049
00050 private JTable sequenceTable;
00051 private MeasurementSequenceTableModel sequenceTableModel;
00052
00053
00054 private JFormattedTextField sequenceStartField;
00055 private JFormattedTextField sequenceStepField;
00056 private JFormattedTextField sequenceStopField;
00057 private ComponentFlasher sequenceStartFieldFlasher;
00058 private ComponentFlasher sequenceStepFieldFlasher;
00059 private ComponentFlasher sequenceStopFieldFlasher;
00060 private JButton addSequenceButton;
00061 private JComboBox loadSequenceBox;
00062
00063 private JLabel stepValueTypeLabel;
00064 private JLabel sequenceStartLabel;
00065 private JLabel sequenceStepLabel;
00066 private JLabel sequenceStopLabel;
00067 private JLabel loadSequenceLabel;
00068
00069 private JPanel controlsPane;
00070
00071
00072 private MeasurementDetailsPanel detailsPanel;
00073
00074
00078 public MeasurementSequencePanel() {
00079
00080
00081 sequenceTableModel = new MeasurementSequenceTableModel();
00082 sequenceTable = new JTable(sequenceTableModel);
00083 sequenceTable.getTableHeader().setReorderingAllowed(false);
00084 sequenceTable.getTableHeader().setResizingAllowed(false);
00085 sequenceTable.setDefaultRenderer(StyledWrapper.class, new StyledTableCellRenderer());
00086 sequenceTable.setDefaultEditor(StyledWrapper.class, new StyledCellEditor(new JTextField()));
00087
00088
00089 MyFormatterFactory factory = new MyFormatterFactory();
00090 sequenceStartField.setFormatterFactory(factory);
00091 sequenceStepField.setFormatterFactory(factory);
00092 sequenceStopField.setFormatterFactory(factory);
00093 sequenceStartFieldFlasher = new ComponentFlasher(sequenceStartField);
00094 sequenceStepFieldFlasher = new ComponentFlasher(sequenceStepField);
00095 sequenceStopFieldFlasher = new ComponentFlasher(sequenceStopField);
00096
00097
00098 controlsPane.setBorder(BorderFactory.createEmptyBorder(0, 4, 4, 4));
00099 JScrollPane scrollPane = new JScrollPane(sequenceTable);
00100 scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
00101 scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
00102 scrollPane.getViewport().setBackground(Color.WHITE);
00103
00104 setLayout(new BorderLayout());
00105 add(controlsPane, "North");
00106 add(scrollPane);
00107
00108
00109
00110
00111 sequenceTable.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
00112 public void columnAdded(TableColumnModelEvent e) {
00113 updateColumns();
00114 }
00115
00116 public void columnRemoved(TableColumnModelEvent e) {
00117 updateColumns();
00118 }
00119
00120 public void columnMoved(TableColumnModelEvent e) {
00121 updateColumns();
00122 }
00123
00124 public void columnMarginChanged(ChangeEvent e) {
00125
00126 }
00127
00128 public void columnSelectionChanged(ListSelectionEvent e) {
00129
00130 }
00131 });
00132
00133
00134 sequenceTable.getTableHeader().addMouseMotionListener(new MouseMotionAdapter() {
00135
00136 private int currentColumn;
00137
00138 @Override public void mouseMoved(MouseEvent e) {
00139 int column = sequenceTable.getColumnModel().getColumnIndexAtX(e.getX());
00140
00141 if (column != currentColumn) {
00142 sequenceTable.getTableHeader().setToolTipText(sequenceTableModel.getColumnToolTip(column));
00143 currentColumn = column;
00144 }
00145 }
00146 });
00147
00148
00149 sequenceTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
00150 public void valueChanged(ListSelectionEvent e) {
00151 if (getProject() == null) {
00152 return;
00153 }
00154
00155
00156 if (sequenceTable.getSelectedRowCount() == 1) {
00157 int index = sequenceTable.getSelectedRow();
00158 if (index < getProject().getSteps()) {
00159 getDetailsPanel().setStep(getProject().getStep(index));
00160 return;
00161 }
00162 }
00163
00164
00165 getDetailsPanel().setStep(getProject().getCurrentStep());
00166 }
00167 });
00168
00169
00170 addSequenceButton.addActionListener(new ActionListener() {
00171 public void actionPerformed(ActionEvent e) {
00172 addSequence();
00173 }
00174 });
00175 KeyListener keyListener = new KeyAdapter() {
00176 @Override public void keyTyped(KeyEvent e) {
00177 if (e.getKeyChar() == KeyEvent.VK_ENTER) {
00178 addSequence();
00179 }
00180 }
00181 };
00182 sequenceStartField.addKeyListener(keyListener);
00183 sequenceStepField.addKeyListener(keyListener);
00184 sequenceStopField.addKeyListener(keyListener);
00185
00186
00187 sequenceTableModel.addTableModelListener(new TableModelListener() {
00188 public void tableChanged(TableModelEvent e) {
00189 resetAddSequence();
00190 }
00191 });
00192
00193
00194 loadSequenceBox.addActionListener(new ActionListener() {
00195 public void actionPerformed(ActionEvent e) {
00196 if (getProject() == null || !getProject().isSequenceEditEnabled()) {
00197 return;
00198 }
00199
00200
00201 Object obj = loadSequenceBox.getSelectedItem();
00202 if (obj != null && obj instanceof MeasurementSequence) {
00203 MeasurementSequence sequence = (MeasurementSequence) obj;
00204 getProject().addSequence(sequence);
00205
00206
00207 final int addedSteps = sequence.getSteps();
00208 SwingUtilities.invokeLater(new Runnable() {
00209 public void run() {
00210 scrollToRow(getProject().getSteps());
00211 int start = getProject().getSteps() - addedSteps;
00212 int end = getProject().getSteps() - 1;
00213 sequenceTable.getSelectionModel().clearSelection();
00214 sequenceTable.getSelectionModel().setSelectionInterval(start, end);
00215 }
00216 });
00217 }
00218 }
00219 });
00220 loadSequenceBox.addPopupMenuListener(new PopupMenuListener() {
00221 public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
00222
00223
00224 if (loadSequenceBox.getSelectedItem() != null) {
00225 loadSequenceBox.setSelectedItem(null);
00226 }
00227 }
00228
00229 public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
00230
00231 }
00232
00233 public void popupMenuCanceled(PopupMenuEvent e) {
00234
00235 }
00236 });
00237
00238
00239 sequenceTable.addMouseListener(new MouseAdapter() {
00240 @Override public void mouseClicked(MouseEvent e) {
00241 if (getProject() == null) {
00242 return;
00243 }
00244 if (e.getButton() == MouseEvent.BUTTON3) {
00245 int[] rows = sequenceTable.getSelectedRows();
00246 List<MeasurementStep> steps = new ArrayList<MeasurementStep>();
00247 for (int i : rows) {
00248 if (i < getProject().getSteps()) {
00249 steps.add(getProject().getStep(i));
00250 }
00251 }
00252 JPopupMenu popup = new SequencePopupMenu(steps.toArray(new MeasurementStep[steps.size()]));
00253 popup.show(e.getComponent(), e.getX(), e.getY());
00254 }
00255 }
00256 });
00257
00258
00259 sequenceTable.getTableHeader().addMouseListener(new MouseAdapter() {
00260 @Override public void mouseClicked(MouseEvent e) {
00261 if (getProject() == null) {
00262 return;
00263 }
00264 if (e.getButton() == MouseEvent.BUTTON3) {
00265 JPopupMenu popup = new HeaderPopupMenu();
00266 popup.show(e.getComponent(), e.getX(), e.getY());
00267 }
00268 }
00269 });
00270
00271
00272 setProject(null);
00273 }
00274
00278 public MeasurementDetailsPanel getDetailsPanel() {
00279 if (detailsPanel == null) {
00280 detailsPanel = new MeasurementDetailsPanel();
00281 }
00282 return detailsPanel;
00283 }
00284
00288 public JTable getSequenceTable() {
00289 return this.sequenceTable;
00290 }
00291
00295 private void resetLoadSequenceBox() {
00296
00297 loadSequenceBox.removeAllItems();
00298 MeasurementSequence[] sequences = Settings.getSequences();
00299
00300
00301 loadSequenceBox.addItem(null);
00302 for (MeasurementSequence sequence : sequences) {
00303 loadSequenceBox.addItem(sequence);
00304 }
00305 }
00306
00310 private void updateColumns() {
00311 TableColumnModel columnModel = sequenceTable.getColumnModel();
00312 for (int col = 0; col < columnModel.getColumnCount(); col++) {
00313 if (columnModel.getColumn(col).getHeaderValue().equals(COUNT.getColumnName(null))) {
00314
00315
00316 int width = 20;
00317 Component comp;
00318 for (int row = 0; row < sequenceTable.getRowCount(); row++) {
00319 comp = sequenceTable.getCellRenderer(row, col).getTableCellRendererComponent(sequenceTable,
00320 sequenceTable.getValueAt(row, col), false, false, row, col);
00321 width = Math.max(width, comp.getPreferredSize().width);
00322 }
00323 width += 5;
00324 columnModel.getColumn(col).setMinWidth(width);
00325 columnModel.getColumn(col).setMaxWidth(width);
00326 return;
00327 }
00328 }
00329 }
00330
00334 private double getLastPositiveStepValue() {
00335 for (int i = getProject().getSteps() - 1; i >= 0; i--) {
00336 double stepValue = getProject().getStep(i).getStepValue();
00337 if (stepValue > 0.0) {
00338 return stepValue;
00339 }
00340 }
00341 return 0.0;
00342 }
00343
00347 private double getLastStepValue() {
00348 double stepValue = 0.0;
00349 if (getProject().getSteps() > 0) {
00350 stepValue = getProject().getStep(getProject().getSteps() - 1).getStepValue();
00351 }
00352 return Math.max(0.0, stepValue);
00353 }
00354
00358 private void resetAddSequence() {
00359 sequenceStartField.setValue(null);
00360 sequenceStepField.setValue(null);
00361 sequenceStopField.setValue(null);
00362 if (getProject() == null) {
00363 return;
00364 }
00365
00366
00367 double stepValue = getLastPositiveStepValue();
00368 sequenceStartField.setValue(new Double(stepValue));
00369 }
00370
00375 private void addSequence() {
00376 if (getProject() == null || !getProject().isSequenceEditEnabled()) {
00377 return;
00378 }
00379
00380
00381 double startVal;
00382 double stepVal;
00383 double stopVal;
00384 if (sequenceStartField.getValue() != null
00385 && sequenceStepField.getValue() == null
00386 && sequenceStopField.getValue() == null) {
00387
00388 startVal = Math.max(((Number) sequenceStartField.getValue()).doubleValue(), 0.0);
00389 startVal = Math.min(startVal, Settings.getDegausserMaximumField());
00390 stepVal = Settings.getDegausserMinimumFieldIncrement();
00391 stopVal = startVal;
00392
00393 } else if (sequenceStartField.getValue() != null
00394 && sequenceStepField.getValue() != null
00395 && sequenceStopField.getValue() != null) {
00396
00397 startVal = Math.max(((Number) sequenceStartField.getValue()).doubleValue(), 0.0);
00398 stepVal = Math.max(((Number) sequenceStepField.getValue()).doubleValue(),
00399 Settings.getDegausserMinimumFieldIncrement());
00400 stopVal = Math.min(((Number) sequenceStopField.getValue()).doubleValue(),
00401 Settings.getDegausserMaximumField());
00402
00403 JTextField fixThisField = null;
00404 if (startVal > stopVal) {
00405 sequenceStopFieldFlasher.flash();
00406 fixThisField = sequenceStopField;
00407 }
00408 if (stepVal < Settings.getDegausserMinimumFieldIncrement()) {
00409 sequenceStepFieldFlasher.flash();
00410 fixThisField = sequenceStepField;
00411 }
00412 if (fixThisField != null) {
00413 fixThisField.grabFocus();
00414 final JTextField f = fixThisField;
00415 SwingUtilities.invokeLater(new Runnable() {
00416 public void run() {
00417
00418 f.setSelectionStart(0);
00419 f.setSelectionEnd(f.getText().length());
00420 }
00421 });
00422 return;
00423 }
00424
00425 } else {
00426
00427 if (sequenceStopField.getValue() == null) {
00428 sequenceStopFieldFlasher.flash();
00429 sequenceStopField.grabFocus();
00430 }
00431 if (sequenceStepField.getValue() == null) {
00432 sequenceStepFieldFlasher.flash();
00433 sequenceStepField.grabFocus();
00434 }
00435 if (sequenceStartField.getValue() == null) {
00436 sequenceStartFieldFlasher.flash();
00437 sequenceStartField.grabFocus();
00438 }
00439 return;
00440 }
00441
00442
00443 final double ratio = Settings.getDegausserMinimumFieldIncrement();
00444 int istartVal = (int) Math.round(startVal / ratio);
00445 int istepVal = (int) Math.round(stepVal / ratio);
00446 int istopVal = (int) Math.round(stopVal / ratio);
00447 int imin = (int) Math.round(Settings.getDegausserMinimumField() / ratio);
00448 int imax = (int) Math.round(Settings.getDegausserMaximumField() / ratio);
00449
00450
00451 MeasurementStep step = new MeasurementStep();
00452 for (int i = istartVal; i <= istopVal; i += istepVal) {
00453 int value = i;
00454 if (value > 0 && value < imin) {
00455 value = imin;
00456 }
00457 if (getLastStepValue() > 0 && Math.abs(value - (int) Math.round(getLastStepValue() / ratio)) < 1) {
00458 continue;
00459 }
00460 step.setStepValue(value * ratio);
00461 getProject().addStep(step);
00462 }
00463
00464
00465 resetAddSequence();
00466 sequenceStartField.grabFocus();
00467 SwingUtilities.invokeLater(new Runnable() {
00468 public void run() {
00469 scrollToRow(sequenceTableModel.getRowCount() - 1);
00470 sequenceStartField.setSelectionStart(0);
00471 sequenceStartField.setSelectionEnd(sequenceStartField.getText().length());
00472 }
00473 });
00474 }
00475
00481 @Override public void setEnabled(boolean enabled) {
00482 super.setEnabled(enabled);
00483
00484 sequenceStartField.setEnabled(enabled);
00485 sequenceStepField.setEnabled(enabled);
00486 sequenceStopField.setEnabled(enabled);
00487 addSequenceButton.setEnabled(enabled);
00488 loadSequenceBox.setEnabled(enabled);
00489
00490 stepValueTypeLabel.setEnabled(enabled);
00491 sequenceStartLabel.setEnabled(enabled);
00492 sequenceStepLabel.setEnabled(enabled);
00493 sequenceStopLabel.setEnabled(enabled);
00494 loadSequenceLabel.setEnabled(enabled);
00495 }
00496
00501 public void setProject(final Project project) {
00502
00503
00504 final boolean autoSelect = getProject() != project;
00505 final int[] selectedRows = sequenceTable.getSelectedRows();
00506
00507 super.setProject(project);
00508 sequenceTableModel.setProject(project);
00509 loadSequenceBox.setSelectedItem(null);
00510 setEnabled(project != null && project.isSequenceEditEnabled());
00511 resetAddSequence();
00512 resetLoadSequenceBox();
00513
00514
00515
00516
00517
00518 SwingUtilities.invokeLater(new Runnable() {
00519 public void run() {
00520
00521
00522 scrollToRow(0);
00523 if (project != null) {
00524 scrollToRow(Math.min(project.getCompletedSteps() + 5, sequenceTableModel.getRowCount() - 1));
00525 } else {
00526 scrollToRow(sequenceTableModel.getRowCount() - 1);
00527 }
00528
00529 if (project != null) {
00530 if (autoSelect) {
00531
00532 int i = project.getCompletedSteps() - 1;
00533 if (i >= 0) {
00534 sequenceTable.getSelectionModel().clearSelection();
00535 sequenceTable.getSelectionModel().setSelectionInterval(i, i);
00536 }
00537 } else {
00538
00539 sequenceTable.getSelectionModel().clearSelection();
00540 for (int i : selectedRows) {
00541 sequenceTable.getSelectionModel().addSelectionInterval(i, i);
00542 }
00543 }
00544 }
00545 }
00546 });
00547 }
00548
00552 private void scrollToRow(int rowIndex) {
00553 sequenceTable.scrollRectToVisible(sequenceTable.getCellRect(rowIndex, rowIndex, true));
00554 }
00555
00559 public void projectUpdated(ProjectEvent event) {
00560 if (event.getType() == ProjectEvent.Type.DATA_CHANGED) {
00561
00562
00563 for (int i = 0; i < sequenceTable.getColumnCount(); i++) {
00564 sequenceTable.getColumnModel().getColumn(i).setHeaderValue(sequenceTableModel.getColumnName(i));
00565 }
00566 sequenceTable.getTableHeader().repaint();
00567
00568
00569 int[] rows = sequenceTable.getSelectedRows();
00570 sequenceTableModel.fireTableDataChanged();
00571 for (int i : rows) {
00572 sequenceTable.getSelectionModel().addSelectionInterval(i, i);
00573 }
00574 }
00575 }
00576
00577 public void measurementUpdated(MeasurementEvent event) {
00578 if (event.getType() == MeasurementEvent.Type.STEP_START) {
00579
00580
00581 for (int i = getProject().getSteps() - 1; i >= 0; i--) {
00582 if (getProject().getStep(i) == event.getStep()) {
00583 sequenceTable.getSelectionModel().setSelectionInterval(i, i);
00584 scrollToRow(i);
00585 scrollToRow(Math.min(i + 2, sequenceTableModel.getRowCount() - 1));
00586 break;
00587 }
00588 }
00589
00590
00591
00592
00593 }
00594 }
00595
00596 {
00597
00598
00599
00600 $$$setupUI$$$();
00601 }
00602
00607 private void $$$setupUI$$$() {
00608 controlsPane = new JPanel();
00609 controlsPane.setLayout(new GridLayoutManager(2, 7, new Insets(0, 0, 0, 0), 5, 0));
00610 sequenceStartField = new JFormattedTextField();
00611 sequenceStartField.setHorizontalAlignment(11);
00612 controlsPane.add(sequenceStartField,
00613 new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL,
00614 GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null,
00615 new Dimension(35, -1), null));
00616 sequenceStepField = new JFormattedTextField();
00617 sequenceStepField.setHorizontalAlignment(11);
00618 controlsPane.add(sequenceStepField,
00619 new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL,
00620 GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null,
00621 new Dimension(35, -1), null));
00622 sequenceStopField = new JFormattedTextField();
00623 sequenceStopField.setHorizontalAlignment(11);
00624 controlsPane.add(sequenceStopField,
00625 new GridConstraints(1, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL,
00626 GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null,
00627 new Dimension(35, -1), null));
00628 sequenceStartLabel = new JLabel();
00629 sequenceStartLabel.setText("Start");
00630 controlsPane.add(sequenceStartLabel,
00631 new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
00632 GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null));
00633 sequenceStepLabel = new JLabel();
00634 sequenceStepLabel.setText("Step");
00635 controlsPane.add(sequenceStepLabel,
00636 new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
00637 GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null));
00638 sequenceStopLabel = new JLabel();
00639 sequenceStopLabel.setText("Stop");
00640 controlsPane.add(sequenceStopLabel,
00641 new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
00642 GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null));
00643 addSequenceButton = new JButton();
00644 addSequenceButton.setText("Add Sequence");
00645 controlsPane.add(addSequenceButton,
00646 new GridConstraints(1, 4, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL,
00647 GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
00648 GridConstraints.SIZEPOLICY_FIXED, null, null, null));
00649 stepValueTypeLabel = new JLabel();
00650 stepValueTypeLabel.setText("mT");
00651 controlsPane.add(stepValueTypeLabel,
00652 new GridConstraints(1, 3, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
00653 GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null));
00654 final Spacer spacer1 = new Spacer();
00655 controlsPane.add(spacer1,
00656 new GridConstraints(1, 5, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL,
00657 GridConstraints.SIZEPOLICY_FIXED, 1, null, new Dimension(30, -1), null));
00658 loadSequenceBox = new JComboBox();
00659 controlsPane.add(loadSequenceBox,
00660 new GridConstraints(1, 6, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL,
00661 GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null));
00662 loadSequenceLabel = new JLabel();
00663 loadSequenceLabel.setText("Load Set");
00664 controlsPane.add(loadSequenceLabel,
00665 new GridConstraints(0, 6, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
00666 GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null));
00667 }
00668
00674 private class MyFormatterFactory extends JFormattedTextField.AbstractFormatterFactory {
00675 public JFormattedTextField.AbstractFormatter getFormatter(JFormattedTextField tf) {
00676 DecimalFormat format = new DecimalFormat();
00677 format.setGroupingUsed(false);
00678 format.setMaximumFractionDigits(1);
00679
00680 NumberFormatter formatter = new NumberFormatter(format);
00681 if (tf == sequenceStepField) {
00682 formatter.setMinimum(new Double(Settings.getDegausserMinimumFieldIncrement()));
00683 } else {
00684 formatter.setMinimum(new Double(0.0));
00685 }
00686 formatter.setMaximum(new Double(999.0));
00687 return formatter;
00688 }
00689 }
00690
00697 private class SequencePopupMenu extends JPopupMenu {
00698
00702 private MeasurementStep[] steps;
00703
00710 public SequencePopupMenu(MeasurementStep[] steps) {
00711 if (steps == null) {
00712 throw new NullPointerException();
00713 }
00714 this.steps = steps;
00715
00716 add(getInsertBeforeAction());
00717 add(getInsertAfterAction());
00718 add(getDeleteSelectedAction());
00719 add(new JSeparator());
00720 add(getSaveSelectedAsAction());
00721 add(getSaveAllAsAction());
00722 }
00723
00724
00725
00726 private Action getInsertBeforeAction() {
00727 Action action = new AbstractAction() {
00728 public void actionPerformed(ActionEvent e) {
00729 int index = getFirstIndex();
00730 for (int i = 0; i < steps.length; i++) {
00731 getProject().addStep(index, new MeasurementStep());
00732 }
00733
00734 }
00735 };
00736 action.putValue(Action.NAME, "Insert Before");
00737 action.putValue(Action.SHORT_DESCRIPTION,
00738 "Inserts the selected number of new steps " +
00739 "in front of the selected steps.");
00740 action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_I);
00741
00742 if (getProject() == null || !getProject().isSequenceEditEnabled()) {
00743 action.setEnabled(false);
00744 } else if (steps.length == 0 || getFirstIndex() < getProject().getCompletedSteps()) {
00745 action.setEnabled(false);
00746 }
00747 return action;
00748 }
00749
00750 private Action getInsertAfterAction() {
00751 Action action = new AbstractAction() {
00752 public void actionPerformed(ActionEvent e) {
00753 int index = getLastIndex() + 1;
00754 for (int i = 0; i < steps.length; i++) {
00755 getProject().addStep(index, new MeasurementStep());
00756 }
00757 sequenceTable.clearSelection();
00758 sequenceTable.getSelectionModel().addSelectionInterval(index, index + steps.length - 1);
00759 }
00760 };
00761 action.putValue(Action.NAME, "Insert After");
00762 action.putValue(Action.SHORT_DESCRIPTION,
00763 "Inserts the selected number of new steps " +
00764 "after the selected steps.");
00765 action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_N);
00766
00767 if (getProject() == null || !getProject().isSequenceEditEnabled()) {
00768 action.setEnabled(false);
00769 } else if (steps.length == 0 || getLastIndex() < getProject().getCompletedSteps() - 1) {
00770 action.setEnabled(false);
00771 }
00772 return action;
00773 }
00774
00775 private Action getDeleteSelectedAction() {
00776 Action action = new AbstractAction() {
00777 public void actionPerformed(ActionEvent e) {
00778
00779 int index;
00780 while ((index = getLastIndex()) >= 0) {
00781 getProject().removeStep(index);
00782 }
00783 sequenceTable.clearSelection();
00784 }
00785 };
00786 action.putValue(Action.NAME, "Delete Selected");
00787 action.putValue(Action.SHORT_DESCRIPTION,
00788 "Removes the selected steps from the sequence.");
00789 action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_D);
00790
00791 if (getProject() == null || !getProject().isSequenceEditEnabled()) {
00792 action.setEnabled(false);
00793 } else if (steps.length == 0 || getFirstIndex() < getProject().getCompletedSteps()) {
00794 action.setEnabled(false);
00795 }
00796 return action;
00797 }
00798
00799 private Action getSaveSelectedAsAction() {
00800 Action action = new AbstractAction() {
00801 public void actionPerformed(ActionEvent e) {
00802
00803
00804 MeasurementSequence sequence = new MeasurementSequence();
00805 for (MeasurementStep step : steps) {
00806 MeasurementStep copy = new MeasurementStep();
00807 copy.setStepValue(step.getStepValue());
00808 sequence.addStep(copy);
00809 }
00810
00811
00812 String name = showSequenceNameDialog("Enter a name for the sequence", "Save Selected As...");
00813 if (name == null) {
00814 return;
00815 }
00816
00817
00818 sequence.setName(name);
00819 Settings.addSequence(sequence);
00820 resetLoadSequenceBox();
00821 }
00822 };
00823 action.putValue(Action.NAME, "Save Selected As...");
00824 action.putValue(Action.SHORT_DESCRIPTION,
00825 "Saves the selected steps as a new preset sequence.");
00826 action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_S);
00827
00828 if (steps.length == 0) {
00829 action.setEnabled(false);
00830 }
00831 return action;
00832 }
00833
00834 private Action getSaveAllAsAction() {
00835 Action action = new AbstractAction() {
00836 public void actionPerformed(ActionEvent e) {
00837
00838
00839 MeasurementSequence sequence = getProject().copySequence(0, getProject().getSteps() - 1);
00840
00841
00842 String name = showSequenceNameDialog("Enter a name for the sequence", "Save All As...");
00843 if (name == null) {
00844 return;
00845 }
00846
00847
00848 sequence.setName(name);
00849 Settings.addSequence(sequence);
00850 resetLoadSequenceBox();
00851 }
00852 };
00853 action.putValue(Action.NAME, "Save All As...");
00854 action.putValue(Action.SHORT_DESCRIPTION,
00855 "Saves all of the steps as a new preset sequence.");
00856 action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_A);
00857
00858 if (getProject() == null || getProject().getSteps() == 0) {
00859 action.setEnabled(false);
00860 }
00861 return action;
00862 }
00863
00864 private String showSequenceNameDialog(String message, String title) {
00865 String name = null;
00866 boolean ok = false;
00867
00868 while (!ok) {
00869
00870
00871 name = (String) JOptionPane.showInputDialog(getParentFrame(),
00872 message, title, JOptionPane.PLAIN_MESSAGE, null, null, name);
00873 if (name == null) {
00874 return null;
00875 } else if (name.equals("")) {
00876 continue;
00877 }
00878
00879
00880 ok = true;
00881 MeasurementSequence[] savedSequences = Settings.getSequences();
00882 for (MeasurementSequence savedSequence : savedSequences) {
00883
00884 if (savedSequence.getName().equals(name)) {
00885
00886
00887 int response = JOptionPane.showConfirmDialog(getParentFrame(),
00888 "Another sequence with the name \"" + name + "\" exists. Do you wish to overwrite it?",
00889 "Overwrite?", JOptionPane.YES_NO_CANCEL_OPTION);
00890
00891 if (response == JOptionPane.YES_OPTION) {
00892
00893 Settings.removeSequence(savedSequence);
00894 ok = true;
00895 break;
00896
00897 } else if (response == JOptionPane.NO_OPTION) {
00898
00899 ok = false;
00900 break;
00901
00902 } else if (response == JOptionPane.CANCEL_OPTION) {
00903
00904 return null;
00905
00906 } else {
00907 throw new IllegalArgumentException("response = " + response);
00908 }
00909 }
00910 }
00911 }
00912 return name;
00913 }
00914
00918 private int getFirstIndex() {
00919 for (int i = 0; i < getProject().getSteps(); i++) {
00920 MeasurementStep current = getProject().getStep(i);
00921 for (MeasurementStep step : steps) {
00922 if (current == step) {
00923 return i;
00924 }
00925 }
00926 }
00927 return -1;
00928 }
00929
00933 private int getLastIndex() {
00934 for (int i = getProject().getSteps() - 1; i >= 0; i--) {
00935 MeasurementStep current = getProject().getStep(i);
00936 for (MeasurementStep step : steps) {
00937 if (current == step) {
00938 return i;
00939 }
00940 }
00941 }
00942 return -1;
00943 }
00944 }
00945
00952 private class HeaderPopupMenu extends JPopupMenu {
00953
00954 public HeaderPopupMenu() {
00955 JMenuItem header = new JMenuItem("Visible Columns");
00956 header.setFont(header.getFont().deriveFont(Font.BOLD));
00957 header.setEnabled(false);
00958 add(header);
00959
00960 SequenceColumn[] columns = sequenceTableModel.getPossibleColumns();
00961 for (final SequenceColumn column : columns) {
00962
00963
00964 final JCheckBox checkBox = new JCheckBox(column.getColumnName(getProject()));
00965 checkBox.addActionListener(new ActionListener() {
00966 public void actionPerformed(ActionEvent e) {
00967 sequenceTableModel.setColumnVisible(column, checkBox.isSelected());
00968 }
00969 });
00970 checkBox.setSelected(sequenceTableModel.isColumnVisible(column));
00971 checkBox.setToolTipText(column.getToolTipText(getProject()));
00972 add(checkBox);
00973 }
00974 }
00975 }
00976 }