Search in sources :

Example 91 with ItemEvent

use of java.awt.event.ItemEvent in project JSettlers2 by jdmonin.

the class NewGameOptionsFrame method initInterface_Pref1.

/**
 * Set up one preference row (desc label, checkbox and/or input box)
 * for {@link #initInterface_UserPrefs(JPanel, GridBagLayout, GridBagConstraints)}.
 * @param bp  Add to this panel
 * @param gbl Use this layout
 * @param gbc Use these constraints
 * @param key Pref key name to update in {@link #localPrefs} when changed,
 *     such as {@link SOCPlayerClient#PREF_BOT_TRADE_REJECT_SEC}, or {@code null}.
 *     If {@code hasBool} but not {@code hasInt}, will store {@link Boolean#TRUE} or {@code .FALSE} as key's value.
 *     If {@code hasInt} and can't parse text field contents, stores {@link Integer} 0 as key's value.
 *     If both bool and int, will store an {@code Integer} which is negative if checkbox is unchecked.
 * @param desc  Preference description text to show. If {@code hasInt}, must contain {@code "#"} placeholder.
 * @param hasBool  True if preference has a boolean value
 * @param hasInt   True if preference has an integer value
 * @param initBoolVal  Pref's initial boolean value, for checkbox; ignored unless {@code hasBool}
 * @param initIntVal   Pref's initial integer value, for input box; ignored unless {@code hasInt}
 * @param pcl  Callback when checkbox is checked/unchecked by clicking the box or its label, or {@code null}
 * @throws IllegalArgumentException if {@code hasInt} but {@code desc} doesn't contain {@code "#"},
 *     or if both {@code key} and {@code pcl} are {@code null}
 * @since 1.2.00
 */
private void initInterface_Pref1(final JPanel bp, final GridBagLayout gbl, final GridBagConstraints gbc, final String key, final String desc, final boolean hasBool, final boolean hasInt, final boolean initBoolVal, final int initIntVal, final PrefCheckboxListener pcl) throws IllegalArgumentException {
    if ((key == null) && (pcl == null))
        throw new IllegalArgumentException("null key, pcl");
    // reminder: same gbc widths/weights are used in initInterface_Opt1
    final Checkbox cb;
    final IntTextField itf = (hasInt) ? new IntTextField(initIntVal, 3) : null;
    final MouseListener ml;
    if (hasBool) {
        cb = new Checkbox();
        cb.setState(initBoolVal);
        gbc.gridwidth = 1;
        gbc.weightx = 0;
        gbl.setConstraints(cb, gbc);
        bp.add(cb);
        ml = new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                final boolean makeChecked = !cb.getState();
                cb.setState(makeChecked);
                if (pcl != null)
                    pcl.stateChanged(makeChecked);
                if (key != null) {
                    if (hasInt) {
                        int iv = 0;
                        try {
                            iv = Integer.parseInt(itf.getText().trim());
                            if (!makeChecked)
                                iv = -iv;
                        } catch (NumberFormatException nfe) {
                        }
                        localPrefs.put(key, Integer.valueOf(iv));
                    } else {
                        localPrefs.put(key, (makeChecked) ? Boolean.TRUE : Boolean.FALSE);
                    }
                }
                e.consume();
            }
        };
    } else {
        cb = null;
        ml = null;
    }
    final int placeholderIdx;
    // null or holds label with start of desc, int input field, label with rest of desc
    final Panel prefp;
    if (hasInt) {
        placeholderIdx = desc.indexOf('#');
        if (placeholderIdx == -1)
            throw new IllegalArgumentException("missing '#'");
        // with FlowLayout
        prefp = new Panel();
        try {
            FlowLayout fl = (FlowLayout) (prefp.getLayout());
            fl.setAlignment(FlowLayout.LEFT);
            fl.setVgap(0);
            fl.setHgap(0);
        } catch (Exception fle) {
        }
    } else {
        placeholderIdx = -1;
        prefp = null;
    }
    // Any text to the left of placeholder in desc?
    if (placeholderIdx > 0) {
        Label L = new Label(desc.substring(0, placeholderIdx));
        L.setForeground(LABEL_TXT_COLOR);
        prefp.add(L);
        L.addMouseListener(ml);
    }
    if (hasInt) {
        prefp.add(itf);
        // for ESC/ENTER
        itf.addKeyListener(this);
        if ((cb != null) || (key != null))
            itf.addTextListener(new // for value store or enable/disable
            TextListener() {

                public void textValueChanged(TextEvent arg0) {
                    final String newText = itf.getText().trim();
                    final boolean notEmpty = (newText.length() > 0);
                    if (cb != null) {
                        if (notEmpty != cb.getState()) {
                            cb.setState(notEmpty);
                            if (pcl != null)
                                pcl.stateChanged(notEmpty);
                        }
                    }
                    if (key != null) {
                        int iv = 0;
                        try {
                            iv = Integer.parseInt(newText);
                            if ((cb != null) && !cb.getState())
                                iv = -iv;
                        } catch (NumberFormatException nfe) {
                        }
                        localPrefs.put(key, Integer.valueOf(iv));
                    }
                }
            });
    }
    // the text label if there is no placeholder.
    if (placeholderIdx + 1 < desc.length()) {
        Label L = new Label(desc.substring(placeholderIdx + 1));
        L.setForeground(LABEL_TXT_COLOR);
        if (prefp != null) {
            prefp.add(L);
        } else {
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            gbl.setConstraints(L, gbc);
            bp.add(L);
        }
        L.addMouseListener(ml);
    }
    if (prefp != null) {
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.weightx = 1;
        gbl.setConstraints(prefp, gbc);
        bp.add(prefp);
    }
    if (cb != null)
        cb.addItemListener(new ItemListener() {

            public void itemStateChanged(ItemEvent ie) {
                pcl.stateChanged(ie.getStateChange() == ItemEvent.SELECTED);
            }
        });
}
Also used : TextEvent(java.awt.event.TextEvent) ItemEvent(java.awt.event.ItemEvent) MouseEvent(java.awt.event.MouseEvent) FlowLayout(java.awt.FlowLayout) MouseAdapter(java.awt.event.MouseAdapter) Label(java.awt.Label) TextListener(java.awt.event.TextListener) Panel(java.awt.Panel) JPanel(javax.swing.JPanel) MouseListener(java.awt.event.MouseListener) Checkbox(java.awt.Checkbox) ItemListener(java.awt.event.ItemListener)

Example 92 with ItemEvent

use of java.awt.event.ItemEvent in project cytoscape-impl by cytoscape.

the class InstallAppsPanel method initComponents.

private void initComponents() {
    searchAppsLabel = new JLabel("Search:");
    installFromFileButton = new JButton("Install from File...");
    filterTextField = new JTextField();
    descriptionSplitPane = new JSplitPane();
    tagsSplitPane = new JSplitPane();
    tagsScrollPane = new JScrollPane();
    tagsTree = new JTree();
    resultsScrollPane = new JScrollPane();
    resultsTree = new JTree();
    descriptionPanel = new JPanel();
    descriptionScrollPane = new JScrollPane();
    descriptionTextPane = new JTextPane();
    viewOnAppStoreButton = new JButton("View on App Store");
    installButton = new JButton("Install");
    downloadSiteLabel = new JLabel("Download Site:");
    downloadSiteComboBox = new JComboBox();
    manageSitesButton = new JButton("Manage Sites...");
    searchAppsLabel.setVisible(!LookAndFeelUtil.isAquaLAF());
    // Aqua LAF only
    filterTextField.putClientProperty("JTextField.variant", "search");
    filterTextField.setToolTipText("To search, start typing");
    installFromFileButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent evt) {
            installFromFileButtonActionPerformed(evt);
        }
    });
    descriptionSplitPane.setBorder(null);
    descriptionSplitPane.setDividerLocation(390);
    tagsSplitPane.setDividerLocation(175);
    tagsSplitPane.setBorder(null);
    DefaultMutableTreeNode treeNode1 = new DefaultMutableTreeNode("root");
    DefaultMutableTreeNode treeNode2 = new DefaultMutableTreeNode("all apps (0)");
    DefaultMutableTreeNode treeNode3 = new DefaultMutableTreeNode("collections (0)");
    DefaultMutableTreeNode treeNode4 = new DefaultMutableTreeNode("apps by tag");
    treeNode1.add(treeNode2);
    treeNode1.add(treeNode3);
    treeNode1.add(treeNode4);
    tagsTree.setModel(new DefaultTreeModel(treeNode1));
    tagsTree.setFocusable(false);
    tagsTree.setRootVisible(false);
    tagsTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    tagsScrollPane.setViewportView(tagsTree);
    tagsSplitPane.setLeftComponent(tagsScrollPane);
    treeNode1 = new DefaultMutableTreeNode("root");
    resultsTree.setModel(new DefaultTreeModel(treeNode1));
    resultsTree.setFocusable(false);
    resultsTree.setRootVisible(false);
    resultsTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    resultsScrollPane.setViewportView(resultsTree);
    tagsSplitPane.setRightComponent(resultsScrollPane);
    descriptionSplitPane.setLeftComponent(tagsSplitPane);
    descriptionTextPane.setContentType("text/html");
    descriptionTextPane.setEditable(false);
    // descriptionTextPane.setText("<html>\n  <head>\n\n  </head>\n  <body>\n    <p style=\"margin-top: 0\">\n      App description is displayed here.\n    </p>\n  </body>\n</html>\n");
    descriptionTextPane.setText("");
    descriptionScrollPane.setViewportView(descriptionTextPane);
    final GroupLayout descriptionPanelLayout = new GroupLayout(descriptionPanel);
    descriptionPanel.setLayout(descriptionPanelLayout);
    descriptionPanelLayout.setHorizontalGroup(descriptionPanelLayout.createParallelGroup(Alignment.LEADING).addComponent(descriptionScrollPane, GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE));
    descriptionPanelLayout.setVerticalGroup(descriptionPanelLayout.createParallelGroup(Alignment.LEADING).addComponent(descriptionScrollPane, GroupLayout.DEFAULT_SIZE, 354, Short.MAX_VALUE));
    descriptionSplitPane.setRightComponent(descriptionPanel);
    viewOnAppStoreButton.setEnabled(false);
    viewOnAppStoreButton.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent evt) {
            viewOnAppStoreButtonActionPerformed(evt);
        }
    });
    installButton.setEnabled(false);
    installButton.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent evt) {
            installButtonActionPerformed(evt);
        }
    });
    downloadSiteComboBox.setModel(new DefaultComboBoxModel(new String[] { WebQuerier.DEFAULT_APP_STORE_URL }));
    downloadSiteComboBox.addItemListener(new ItemListener() {

        public void itemStateChanged(ItemEvent evt) {
            downloadSiteComboBoxItemStateChanged(evt);
        }
    });
    downloadSiteComboBox.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent evt) {
            downloadSiteComboBoxActionPerformed(evt);
        }
    });
    downloadSiteComboBox.addKeyListener(new KeyAdapter() {

        public void keyPressed(KeyEvent evt) {
            downloadSiteComboBoxKeyPressed(evt);
        }
    });
    manageSitesButton.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent evt) {
            manageSitesButtonActionPerformed(evt);
        }
    });
    LookAndFeelUtil.equalizeSize(installFromFileButton, viewOnAppStoreButton, installButton);
    final JSeparator sep = new JSeparator();
    final GroupLayout layout = new GroupLayout(this);
    this.setLayout(layout);
    layout.setAutoCreateContainerGaps(true);
    layout.setAutoCreateGaps(true);
    layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addComponent(downloadSiteLabel).addComponent(downloadSiteComboBox, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE).addComponent(manageSitesButton)).addComponent(sep, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE).addGroup(layout.createSequentialGroup().addComponent(searchAppsLabel).addComponent(filterTextField, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)).addComponent(descriptionSplitPane).addGroup(layout.createSequentialGroup().addComponent(installFromFileButton).addPreferredGap(ComponentPlacement.RELATED, 80, Short.MAX_VALUE).addComponent(viewOnAppStoreButton).addComponent(installButton)));
    layout.setVerticalGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(downloadSiteLabel).addComponent(downloadSiteComboBox, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE).addComponent(manageSitesButton, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE)).addComponent(sep, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE).addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(searchAppsLabel).addComponent(filterTextField, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE)).addComponent(descriptionSplitPane, DEFAULT_SIZE, 360, Short.MAX_VALUE).addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(installFromFileButton).addComponent(viewOnAppStoreButton).addComponent(installButton)));
    // Add a key listener to the download site combo box to listen for the enter key event
    final WebQuerier webQuerier = this.appManager.getWebQuerier();
    downloadSiteComboBox.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {

        @Override
        public void keyPressed(KeyEvent e) {
            final ComboBoxEditor editor = downloadSiteComboBox.getEditor();
            final Object selectedValue = editor.getItem();
            if (e.isActionKey() || e.getKeyCode() == KeyEvent.VK_ENTER) {
                if (downloadSiteComboBox.getModel() instanceof DefaultComboBoxModel && selectedValue != null) {
                    final DefaultComboBoxModel comboBoxModel = (DefaultComboBoxModel) downloadSiteComboBox.getModel();
                    SwingUtilities.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            boolean selectedAlreadyInList = false;
                            for (int i = 0; i < comboBoxModel.getSize(); i++) {
                                Object listElement = comboBoxModel.getElementAt(i);
                                if (listElement.equals(selectedValue)) {
                                    selectedAlreadyInList = true;
                                    break;
                                }
                            }
                            if (!selectedAlreadyInList) {
                                comboBoxModel.insertElementAt(selectedValue, 1);
                                editor.setItem(selectedValue);
                            }
                        }
                    });
                }
                if (webQuerier.getCurrentAppStoreUrl() != selectedValue.toString()) {
                    webQuerier.setCurrentAppStoreUrl(selectedValue.toString());
                    queryForApps();
                }
            }
        }
    });
    // Make the JTextPane render HTML using the default UI font
    Font font = UIManager.getFont("Label.font");
    String bodyRule = "body { font-family: " + font.getFamily() + "; " + "font-size: " + font.getSize() + "pt; }";
    ((HTMLDocument) descriptionTextPane.getDocument()).getStyleSheet().addRule(bodyRule);
    // Setup the TreeCellRenderer to make the app tags use the folder icon instead of the default leaf icon,
    // and have it use the opened folder icon when selected
    DefaultTreeCellRenderer tagsTreeCellRenderer = new DefaultTreeCellRenderer() {

        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
            // Make leaves use the open folder icon when selected
            if (selected && leaf)
                this.setIcon(getOpenIcon());
            return this;
        }
    };
    tagsTreeCellRenderer.setLeafIcon(tagsTreeCellRenderer.getDefaultClosedIcon());
    tagsTree.setCellRenderer(tagsTreeCellRenderer);
}
Also used : JPanel(javax.swing.JPanel) ItemEvent(java.awt.event.ItemEvent) DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode) ActionEvent(java.awt.event.ActionEvent) KeyAdapter(java.awt.event.KeyAdapter) JButton(javax.swing.JButton) JTextField(javax.swing.JTextField) ComboBoxEditor(javax.swing.ComboBoxEditor) DefaultTreeCellRenderer(javax.swing.tree.DefaultTreeCellRenderer) JSeparator(javax.swing.JSeparator) Font(java.awt.Font) KeyEvent(java.awt.event.KeyEvent) JTextPane(javax.swing.JTextPane) GroupLayout(javax.swing.GroupLayout) JScrollPane(javax.swing.JScrollPane) JComboBox(javax.swing.JComboBox) JLabel(javax.swing.JLabel) DefaultTreeModel(javax.swing.tree.DefaultTreeModel) DefaultComboBoxModel(javax.swing.DefaultComboBoxModel) JTree(javax.swing.JTree) ActionListener(java.awt.event.ActionListener) ItemListener(java.awt.event.ItemListener) JSplitPane(javax.swing.JSplitPane) WebQuerier(org.cytoscape.app.internal.net.WebQuerier)

Example 93 with ItemEvent

use of java.awt.event.ItemEvent in project cytoscape-impl by cytoscape.

the class AbstractChartEditor method getGlobalRangeCkb.

protected JCheckBox getGlobalRangeCkb() {
    if (globalRangeCkb == null) {
        globalRangeCkb = new JCheckBox("Network-Wide Axis Range");
        globalRangeCkb.setSelected(chart.get(GLOBAL_RANGE, Boolean.class, Boolean.TRUE));
        globalRangeCkb.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(final ItemEvent e) {
                final boolean selected = e.getStateChange() == ItemEvent.SELECTED;
                chart.set(GLOBAL_RANGE, selected);
                updateGlobalRange();
                if (selected)
                    updateRangeMinMax(chart.getList(RANGE, Double.class).isEmpty());
            }
        });
    }
    return globalRangeCkb;
}
Also used : JCheckBox(javax.swing.JCheckBox) ItemEvent(java.awt.event.ItemEvent) ItemListener(java.awt.event.ItemListener)

Example 94 with ItemEvent

use of java.awt.event.ItemEvent in project cytoscape-impl by cytoscape.

the class AbstractChartEditor method getAutoRangeCkb.

protected JCheckBox getAutoRangeCkb() {
    if (autoRangeCkb == null) {
        autoRangeCkb = new JCheckBox("Automatic Range");
        autoRangeCkb.setSelected(chart.get(AUTO_RANGE, Boolean.class, Boolean.TRUE));
        autoRangeCkb.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(final ItemEvent e) {
                final boolean selected = e.getStateChange() == ItemEvent.SELECTED;
                getRangeMinTxt().setEnabled(!selected);
                getRangeMaxTxt().setEnabled(!selected);
                getRangeMinTxt().requestFocus();
                chart.set(AUTO_RANGE, selected);
                if (selected)
                    updateRangeMinMax(true);
            }
        });
    }
    return autoRangeCkb;
}
Also used : JCheckBox(javax.swing.JCheckBox) ItemEvent(java.awt.event.ItemEvent) ItemListener(java.awt.event.ItemListener)

Example 95 with ItemEvent

use of java.awt.event.ItemEvent in project energy3d by concord-consortium.

the class PopupMenuForParabolicDish method getPopupMenu.

static JPopupMenu getPopupMenu() {
    if (popupMenuForParabolicDish == null) {
        final JMenuItem miMesh = new JMenuItem("Mesh...");
        miMesh.addActionListener(new ActionListener() {

            // remember the scope selection as the next action will likely be applied to the same scope
            private int selectedScopeIndex = 0;

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final ParabolicDish d = (ParabolicDish) selectedPart;
                final Foundation foundation = d.getTopContainer();
                final String partInfo = d.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
                final JPanel gui = new JPanel(new BorderLayout());
                final JPanel inputPanel = new JPanel(new GridLayout(2, 2, 5, 5));
                gui.add(inputPanel, BorderLayout.CENTER);
                inputPanel.add(new JLabel("Radial Direction: "));
                final JTextField nRadialField = new JTextField("" + d.getNRadialSections());
                inputPanel.add(nRadialField);
                inputPanel.add(new JLabel("Axial Direction: "));
                final JTextField nAxialField = new JTextField("" + d.getNAxialSections());
                inputPanel.add(nAxialField);
                inputPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
                final JPanel scopePanel = new JPanel();
                scopePanel.setLayout(new BoxLayout(scopePanel, BoxLayout.Y_AXIS));
                scopePanel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
                final JRadioButton rb1 = new JRadioButton("Only this Parabolic Dish", true);
                final JRadioButton rb2 = new JRadioButton("All Parabolic Dishes on this Foundation");
                final JRadioButton rb3 = new JRadioButton("All Parabolic Dishes");
                scopePanel.add(rb1);
                scopePanel.add(rb2);
                scopePanel.add(rb3);
                final ButtonGroup bg = new ButtonGroup();
                bg.add(rb1);
                bg.add(rb2);
                bg.add(rb3);
                switch(selectedScopeIndex) {
                    case 0:
                        rb1.setSelected(true);
                        break;
                    case 1:
                        rb2.setSelected(true);
                        break;
                    case 2:
                        rb3.setSelected(true);
                        break;
                }
                gui.add(scopePanel, BorderLayout.NORTH);
                final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
                final JOptionPane optionPane = new JOptionPane(new Object[] { "Set mesh for " + partInfo, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
                final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Parabolic Dish Mesh");
                while (true) {
                    dialog.setVisible(true);
                    final Object choice = optionPane.getValue();
                    if (choice == options[1] || choice == null) {
                        break;
                    } else {
                        int nRadialSections = 0, nAxialSections = 0;
                        boolean ok = true;
                        try {
                            nRadialSections = Integer.parseInt(nRadialField.getText());
                            nAxialSections = Integer.parseInt(nAxialField.getText());
                        } catch (final NumberFormatException nfe) {
                            JOptionPane.showMessageDialog(MainFrame.getInstance(), "Invalid input!", "Error", JOptionPane.ERROR_MESSAGE);
                            ok = false;
                        }
                        if (ok) {
                            if (nRadialSections < 4) {
                                JOptionPane.showMessageDialog(MainFrame.getInstance(), "Number of radial sections must be at least 4.", "Range Error", JOptionPane.ERROR_MESSAGE);
                            } else if (nAxialSections < 4) {
                                JOptionPane.showMessageDialog(MainFrame.getInstance(), "Number of axial sections mesh must be at least 4.", "Range Error", JOptionPane.ERROR_MESSAGE);
                            } else if (!Util.isPowerOfTwo(nRadialSections) || !Util.isPowerOfTwo(nAxialSections)) {
                                JOptionPane.showMessageDialog(MainFrame.getInstance(), "Number of parabolic dish mesh sections in x or y direction must be power of two.", "Range Error", JOptionPane.ERROR_MESSAGE);
                            } else {
                                if (rb1.isSelected()) {
                                    // final SetPartSizeCommand c = new SetPartSizeCommand(t);
                                    d.setNRadialSections(nRadialSections);
                                    d.setNAxialSections(nAxialSections);
                                    d.draw();
                                    SceneManager.getInstance().refresh();
                                    // SceneManager.getInstance().getUndoManager().addEdit(c);
                                    selectedScopeIndex = 0;
                                } else if (rb2.isSelected()) {
                                    // final SetShapeForParabolicTroughsOnFoundationCommand c = new SetShapeForParabolicTroughsOnFoundationCommand(foundation);
                                    foundation.setSectionsForParabolicDishes(nRadialSections, nAxialSections);
                                    // SceneManager.getInstance().getUndoManager().addEdit(c);
                                    selectedScopeIndex = 1;
                                } else if (rb3.isSelected()) {
                                    // final SetShapeForAllParabolicTroughsCommand c = new SetShapeForAllParabolicTroughsCommand();
                                    Scene.getInstance().setSectionsForAllParabolicDishes(nRadialSections, nAxialSections);
                                    // SceneManager.getInstance().getUndoManager().addEdit(c);
                                    selectedScopeIndex = 2;
                                }
                                updateAfterEdit();
                                if (choice == options[0]) {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        });
        final JMenuItem miRib = new JMenuItem("Ribs...");
        miRib.addActionListener(new ActionListener() {

            // remember the scope selection as the next action will likely be applied to the same scope
            private int selectedScopeIndex = 0;

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final ParabolicDish d = (ParabolicDish) selectedPart;
                final Foundation foundation = d.getTopContainer();
                final String partInfo = d.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
                final JPanel gui = new JPanel(new BorderLayout());
                final JPanel inputPanel = new JPanel(new GridLayout(2, 2, 5, 5));
                gui.add(inputPanel, BorderLayout.CENTER);
                inputPanel.add(new JLabel("Rib Lines: "));
                final JTextField nribField = new JTextField("" + d.getNumberOfRibs());
                inputPanel.add(nribField);
                inputPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
                final JPanel scopePanel = new JPanel();
                scopePanel.setLayout(new BoxLayout(scopePanel, BoxLayout.Y_AXIS));
                scopePanel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
                final JRadioButton rb1 = new JRadioButton("Only this Parabolic Dish", true);
                final JRadioButton rb2 = new JRadioButton("All Parabolic Dishes on this Foundation");
                final JRadioButton rb3 = new JRadioButton("All Parabolic Dishes");
                scopePanel.add(rb1);
                scopePanel.add(rb2);
                scopePanel.add(rb3);
                final ButtonGroup bg = new ButtonGroup();
                bg.add(rb1);
                bg.add(rb2);
                bg.add(rb3);
                switch(selectedScopeIndex) {
                    case 0:
                        rb1.setSelected(true);
                        break;
                    case 1:
                        rb2.setSelected(true);
                        break;
                    case 2:
                        rb3.setSelected(true);
                        break;
                }
                gui.add(scopePanel, BorderLayout.NORTH);
                final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
                final JOptionPane optionPane = new JOptionPane(new Object[] { "Set rib lines for " + partInfo, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
                final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Parabolic Dish Ribs");
                while (true) {
                    dialog.setVisible(true);
                    final Object choice = optionPane.getValue();
                    if (choice == options[1] || choice == null) {
                        break;
                    } else {
                        int nrib = 0;
                        boolean ok = true;
                        try {
                            nrib = Integer.parseInt(nribField.getText());
                        } catch (final NumberFormatException nfe) {
                            JOptionPane.showMessageDialog(MainFrame.getInstance(), "Invalid input!", "Error", JOptionPane.ERROR_MESSAGE);
                            ok = false;
                        }
                        if (ok) {
                            if (nrib < 0) {
                                JOptionPane.showMessageDialog(MainFrame.getInstance(), "Number of ribs cannot be negative.", "Range Error", JOptionPane.ERROR_MESSAGE);
                            } else {
                                boolean changed = nrib != d.getNumberOfRibs();
                                if (rb1.isSelected()) {
                                    if (changed) {
                                        final SetParabolicDishRibsCommand c = new SetParabolicDishRibsCommand(d);
                                        d.setNumberOfRibs(nrib);
                                        d.draw();
                                        SceneManager.getInstance().refresh();
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 0;
                                } else if (rb2.isSelected()) {
                                    if (!changed) {
                                        for (final ParabolicDish x : foundation.getParabolicDishes()) {
                                            if (x.getNumberOfRibs() != nrib) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final SetRibsForParabolicDishesOnFoundationCommand c = new SetRibsForParabolicDishesOnFoundationCommand(foundation);
                                        foundation.setNumberOfRibsForParabolicDishes(nrib);
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 1;
                                } else if (rb3.isSelected()) {
                                    if (!changed) {
                                        for (final ParabolicDish x : Scene.getInstance().getAllParabolicDishes()) {
                                            if (x.getNumberOfRibs() != nrib) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final SetRibsForAllParabolicDishesCommand c = new SetRibsForAllParabolicDishesCommand();
                                        Scene.getInstance().setNumberOfRibsForAllParabolicDishes(nrib);
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 2;
                                }
                                if (changed) {
                                    updateAfterEdit();
                                }
                                if (choice == options[0]) {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        });
        final JCheckBoxMenuItem cbmiDisableEditPoint = new JCheckBoxMenuItem("Disable Edit Point");
        cbmiDisableEditPoint.addItemListener(new ItemListener() {

            // remember the scope selection as the next action will likely be applied to the same scope
            private int selectedScopeIndex = 0;

            @Override
            public void itemStateChanged(final ItemEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final boolean disabled = cbmiDisableEditPoint.isSelected();
                final ParabolicDish dish = (ParabolicDish) selectedPart;
                final String partInfo = dish.toString().substring(0, dish.toString().indexOf(')') + 1);
                final JPanel gui = new JPanel(new BorderLayout(0, 20));
                final JPanel panel = new JPanel();
                gui.add(panel, BorderLayout.SOUTH);
                panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
                panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
                final JRadioButton rb1 = new JRadioButton("Only this Parabolic Dish", true);
                final JRadioButton rb2 = new JRadioButton("All Parabolic Dishes on this Foundation");
                final JRadioButton rb3 = new JRadioButton("All Parabolic Dishes");
                panel.add(rb1);
                panel.add(rb2);
                panel.add(rb3);
                final ButtonGroup bg = new ButtonGroup();
                bg.add(rb1);
                bg.add(rb2);
                bg.add(rb3);
                switch(selectedScopeIndex) {
                    case 0:
                        rb1.setSelected(true);
                        break;
                    case 1:
                        rb2.setSelected(true);
                        break;
                    case 2:
                        rb3.setSelected(true);
                        break;
                }
                final String title = "<html>" + (disabled ? "Disable" : "Enable") + " edit point for " + partInfo + "</html>";
                final String footnote = "<html><hr><font size=2>Disable the edit point of a parabolic dish prevents it<br>from being unintentionally moved.<hr></html>";
                final Object[] options = new Object[] { "OK", "Cancel" };
                final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[0]);
                final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), (disabled ? "Disable" : "Enable") + " Edit Point");
                dialog.setVisible(true);
                if (optionPane.getValue() == options[0]) {
                    if (rb1.isSelected()) {
                        final LockEditPointsCommand c = new LockEditPointsCommand(dish);
                        dish.setLockEdit(disabled);
                        SceneManager.getInstance().getUndoManager().addEdit(c);
                        selectedScopeIndex = 0;
                    } else if (rb2.isSelected()) {
                        final Foundation foundation = dish.getTopContainer();
                        final LockEditPointsOnFoundationCommand c = new LockEditPointsOnFoundationCommand(foundation, dish.getClass());
                        foundation.setLockEditForClass(disabled, dish.getClass());
                        SceneManager.getInstance().getUndoManager().addEdit(c);
                        selectedScopeIndex = 1;
                    } else if (rb3.isSelected()) {
                        final LockEditPointsForClassCommand c = new LockEditPointsForClassCommand(dish);
                        Scene.getInstance().setLockEditForClass(disabled, dish.getClass());
                        SceneManager.getInstance().getUndoManager().addEdit(c);
                        selectedScopeIndex = 2;
                    }
                    SceneManager.getInstance().refresh();
                    Scene.getInstance().setEdited(true);
                }
            }
        });
        final JCheckBoxMenuItem cbmiDrawSunBeams = new JCheckBoxMenuItem("Draw Sun Beams");
        cbmiDrawSunBeams.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(final ItemEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final ParabolicDish d = (ParabolicDish) selectedPart;
                final ShowSunBeamCommand c = new ShowSunBeamCommand(d);
                d.setSunBeamVisible(cbmiDrawSunBeams.isSelected());
                d.drawSunBeam();
                d.draw();
                SceneManager.getInstance().refresh();
                SceneManager.getInstance().getUndoManager().addEdit(c);
                Scene.getInstance().setEdited(true);
            }
        });
        final JMenuItem miRimRadius = new JMenuItem("Rim Radius...");
        miRimRadius.addActionListener(new ActionListener() {

            // remember the scope selection as the next action will likely be applied to the same scope
            private int selectedScopeIndex = 0;

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final ParabolicDish d = (ParabolicDish) selectedPart;
                final Foundation foundation = d.getTopContainer();
                final String partInfo = d.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
                final JPanel gui = new JPanel(new BorderLayout());
                final JPanel inputPanel = new JPanel(new GridLayout(1, 2, 5, 5));
                gui.add(inputPanel, BorderLayout.CENTER);
                inputPanel.add(new JLabel("Rim Radius (m): "));
                final JTextField apertureRadiusField = new JTextField(threeDecimalsFormat.format(d.getRimRadius()));
                inputPanel.add(apertureRadiusField);
                inputPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
                final JPanel scopePanel = new JPanel();
                scopePanel.setLayout(new BoxLayout(scopePanel, BoxLayout.Y_AXIS));
                scopePanel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
                final JRadioButton rb1 = new JRadioButton("Only this Parabolic Dish", true);
                final JRadioButton rb2 = new JRadioButton("All Parabolic Dishes on this Foundation");
                final JRadioButton rb3 = new JRadioButton("All Parabolic Dishes");
                scopePanel.add(rb1);
                scopePanel.add(rb2);
                scopePanel.add(rb3);
                final ButtonGroup bg = new ButtonGroup();
                bg.add(rb1);
                bg.add(rb2);
                bg.add(rb3);
                switch(selectedScopeIndex) {
                    case 0:
                        rb1.setSelected(true);
                        break;
                    case 1:
                        rb2.setSelected(true);
                        break;
                    case 2:
                        rb3.setSelected(true);
                        break;
                }
                gui.add(scopePanel, BorderLayout.NORTH);
                final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
                final JOptionPane optionPane = new JOptionPane(new Object[] { "Set rim radius for " + partInfo, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
                final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Parabolic Dish Rim Radius");
                while (true) {
                    dialog.setVisible(true);
                    final Object choice = optionPane.getValue();
                    if (choice == options[1] || choice == null) {
                        break;
                    } else {
                        double r = 0;
                        boolean ok = true;
                        try {
                            r = Double.parseDouble(apertureRadiusField.getText());
                        } catch (final NumberFormatException x) {
                            JOptionPane.showMessageDialog(MainFrame.getInstance(), "Invalid input!", "Error", JOptionPane.ERROR_MESSAGE);
                            ok = false;
                        }
                        if (ok) {
                            if (r < 1 || r > 10) {
                                JOptionPane.showMessageDialog(MainFrame.getInstance(), "Parabolic dish rim radius must be between 1 and 10 m.", "Range Error", JOptionPane.ERROR_MESSAGE);
                            } else {
                                boolean changed = Math.abs(r - d.getRimRadius()) > 0.000001;
                                if (rb1.isSelected()) {
                                    if (changed) {
                                        final SetPartSizeCommand c = new SetPartSizeCommand(d);
                                        d.setRimRadius(r);
                                        d.draw();
                                        SceneManager.getInstance().refresh();
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 0;
                                } else if (rb2.isSelected()) {
                                    if (!changed) {
                                        for (final ParabolicDish x : foundation.getParabolicDishes()) {
                                            if (Math.abs(r - x.getRimRadius()) > 0.000001) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final SetRimRadiusForParabolicDishesOnFoundationCommand c = new SetRimRadiusForParabolicDishesOnFoundationCommand(foundation);
                                        foundation.setRimRadiusForParabolicDishes(r);
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 1;
                                } else if (rb3.isSelected()) {
                                    if (!changed) {
                                        for (final ParabolicDish x : Scene.getInstance().getAllParabolicDishes()) {
                                            if (Math.abs(r - x.getRimRadius()) > 0.000001) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final SetRimRadiusForAllParabolicDishesCommand c = new SetRimRadiusForAllParabolicDishesCommand();
                                        Scene.getInstance().setRimRadiusForAllParabolicDishes(r);
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 2;
                                }
                                if (changed) {
                                    updateAfterEdit();
                                }
                                if (choice == options[0]) {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        });
        final JMenuItem miFocalLength = new JMenuItem("Focal Length...");
        miFocalLength.addActionListener(new ActionListener() {

            // remember the scope selection as the next action will likely be applied to the same scope
            private int selectedScopeIndex = 0;

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final ParabolicDish d = (ParabolicDish) selectedPart;
                final Foundation foundation = d.getTopContainer();
                final String partInfo = d.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
                final JPanel gui = new JPanel(new BorderLayout());
                final JPanel inputPanel = new JPanel(new GridLayout(1, 2, 5, 5));
                gui.add(inputPanel, BorderLayout.CENTER);
                inputPanel.add(new JLabel("Focal Length (m): "));
                final JTextField focalLengthField = new JTextField(threeDecimalsFormat.format(d.getFocalLength()));
                inputPanel.add(focalLengthField);
                inputPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
                final JPanel scopePanel = new JPanel();
                scopePanel.setLayout(new BoxLayout(scopePanel, BoxLayout.Y_AXIS));
                scopePanel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
                final JRadioButton rb1 = new JRadioButton("Only this Parabolic Dish", true);
                final JRadioButton rb2 = new JRadioButton("All Parabolic Dishes on this Foundation");
                final JRadioButton rb3 = new JRadioButton("All Parabolic Dishes");
                scopePanel.add(rb1);
                scopePanel.add(rb2);
                scopePanel.add(rb3);
                final ButtonGroup bg = new ButtonGroup();
                bg.add(rb1);
                bg.add(rb2);
                bg.add(rb3);
                switch(selectedScopeIndex) {
                    case 0:
                        rb1.setSelected(true);
                        break;
                    case 1:
                        rb2.setSelected(true);
                        break;
                    case 2:
                        rb3.setSelected(true);
                        break;
                }
                gui.add(scopePanel, BorderLayout.NORTH);
                final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
                final JOptionPane optionPane = new JOptionPane(new Object[] { "Set focal length for " + partInfo, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
                final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Focal Length");
                while (true) {
                    dialog.setVisible(true);
                    final Object choice = optionPane.getValue();
                    if (choice == options[1] || choice == null) {
                        break;
                    } else {
                        double fl = 0;
                        boolean ok = true;
                        try {
                            fl = Double.parseDouble(focalLengthField.getText());
                        } catch (final NumberFormatException nfe) {
                            JOptionPane.showMessageDialog(MainFrame.getInstance(), "Invalid input!", "Error", JOptionPane.ERROR_MESSAGE);
                            ok = false;
                        }
                        if (ok) {
                            if (fl < 0.5 || fl > 10) {
                                JOptionPane.showMessageDialog(MainFrame.getInstance(), "Focal length must be between 0.5 and 10 m.", "Range Error", JOptionPane.ERROR_MESSAGE);
                            } else {
                                boolean changed = Math.abs(fl - d.getFocalLength()) > 0.000001;
                                if (rb1.isSelected()) {
                                    if (changed) {
                                        final SetParabolicDishFocalLengthCommand c = new SetParabolicDishFocalLengthCommand(d);
                                        d.setFocalLength(fl);
                                        d.draw();
                                        SceneManager.getInstance().refresh();
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 0;
                                } else if (rb2.isSelected()) {
                                    if (!changed) {
                                        for (final ParabolicDish x : foundation.getParabolicDishes()) {
                                            if (Math.abs(fl - x.getFocalLength()) > 0.000001) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final SetFocalLengthForParabolicDishesOnFoundationCommand c = new SetFocalLengthForParabolicDishesOnFoundationCommand(foundation);
                                        foundation.setFocalLengthForParabolicDishes(fl);
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 1;
                                } else if (rb3.isSelected()) {
                                    if (!changed) {
                                        for (final ParabolicDish x : Scene.getInstance().getAllParabolicDishes()) {
                                            if (Math.abs(fl - x.getFocalLength()) > 0.000001) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final SetFocalLengthForAllParabolicDishesCommand c = new SetFocalLengthForAllParabolicDishesCommand();
                                        Scene.getInstance().setFocalLengthForAllParabolicDishes(fl);
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 2;
                                }
                                if (changed) {
                                    updateAfterEdit();
                                }
                                if (choice == options[0]) {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        });
        final JMenuItem miBaseHeight = new JMenuItem("Base Height...");
        miBaseHeight.addActionListener(new ActionListener() {

            // remember the scope selection as the next action will likely be applied to the same scope
            private int selectedScopeIndex = 0;

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
                final ParabolicDish d = (ParabolicDish) selectedPart;
                final Foundation foundation = d.getTopContainer();
                final String title = "<html>Base Height (m) of " + partInfo + "</html>";
                final String footnote = "<html><hr><font size=2></html>";
                final JPanel gui = new JPanel(new BorderLayout());
                final JPanel panel = new JPanel();
                gui.add(panel, BorderLayout.CENTER);
                panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
                panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
                final JRadioButton rb1 = new JRadioButton("Only this Parabolic Dish", true);
                final JRadioButton rb2 = new JRadioButton("All Parabolic Dishes on this Foundation");
                final JRadioButton rb3 = new JRadioButton("All Parabolic Dishes");
                panel.add(rb1);
                panel.add(rb2);
                panel.add(rb3);
                final ButtonGroup bg = new ButtonGroup();
                bg.add(rb1);
                bg.add(rb2);
                bg.add(rb3);
                switch(selectedScopeIndex) {
                    case 0:
                        rb1.setSelected(true);
                        break;
                    case 1:
                        rb2.setSelected(true);
                        break;
                    case 2:
                        rb3.setSelected(true);
                        break;
                }
                final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(d.getBaseHeight() * Scene.getInstance().getAnnotationScale()));
                gui.add(inputField, BorderLayout.SOUTH);
                final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
                final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
                final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Parabolic Dish Base Height");
                while (true) {
                    inputField.selectAll();
                    inputField.requestFocusInWindow();
                    dialog.setVisible(true);
                    final Object choice = optionPane.getValue();
                    if (choice == options[1] || choice == null) {
                        break;
                    } else {
                        double val = 0;
                        boolean ok = true;
                        try {
                            val = Double.parseDouble(inputField.getText()) / Scene.getInstance().getAnnotationScale();
                        } catch (final NumberFormatException exception) {
                            JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
                            ok = false;
                        }
                        if (ok) {
                            boolean changed = Math.abs(val - d.getBaseHeight()) > 0.000001;
                            if (rb1.isSelected()) {
                                if (changed) {
                                    final ChangeBaseHeightCommand c = new ChangeBaseHeightCommand(d);
                                    d.setBaseHeight(val);
                                    d.draw();
                                    SceneManager.getInstance().refresh();
                                    SceneManager.getInstance().getUndoManager().addEdit(c);
                                }
                                selectedScopeIndex = 0;
                            } else if (rb2.isSelected()) {
                                if (!changed) {
                                    for (final ParabolicDish x : foundation.getParabolicDishes()) {
                                        if (Math.abs(val - x.getBaseHeight()) > 0.000001) {
                                            changed = true;
                                            break;
                                        }
                                    }
                                }
                                if (changed) {
                                    final ChangeFoundationSolarCollectorBaseHeightCommand c = new ChangeFoundationSolarCollectorBaseHeightCommand(foundation, d.getClass());
                                    foundation.setBaseHeightForParabolicDishes(val);
                                    SceneManager.getInstance().getUndoManager().addEdit(c);
                                }
                                selectedScopeIndex = 1;
                            } else if (rb3.isSelected()) {
                                if (!changed) {
                                    for (final ParabolicDish x : Scene.getInstance().getAllParabolicDishes()) {
                                        if (Math.abs(val - x.getBaseHeight()) > 0.000001) {
                                            changed = true;
                                            break;
                                        }
                                    }
                                }
                                if (changed) {
                                    final ChangeBaseHeightForAllSolarCollectorsCommand c = new ChangeBaseHeightForAllSolarCollectorsCommand(d.getClass());
                                    Scene.getInstance().setBaseHeightForAllParabolicDishes(val);
                                    SceneManager.getInstance().getUndoManager().addEdit(c);
                                }
                                selectedScopeIndex = 2;
                            }
                            if (changed) {
                                updateAfterEdit();
                            }
                            if (choice == options[0]) {
                                break;
                            }
                        }
                    }
                }
            }
        });
        final JMenuItem miStructureType = new JMenuItem("Structure Type...");
        miStructureType.addActionListener(new ActionListener() {

            // remember the scope selection as the next action will likely be applied to the same scope
            private int selectedScopeIndex = 0;

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
                final ParabolicDish d = (ParabolicDish) selectedPart;
                final Foundation foundation = d.getTopContainer();
                final String title = "<html>Structure Type of " + partInfo + "</html>";
                final String footnote = "<html><hr><font size=2></html>";
                final JPanel gui = new JPanel(new BorderLayout());
                final JPanel panel = new JPanel();
                gui.add(panel, BorderLayout.CENTER);
                panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
                panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
                final JRadioButton rb1 = new JRadioButton("Only this Parabolic Dish", true);
                final JRadioButton rb2 = new JRadioButton("All Parabolic Dishes on this Foundation");
                final JRadioButton rb3 = new JRadioButton("All Parabolic Dishes");
                panel.add(rb1);
                panel.add(rb2);
                panel.add(rb3);
                final ButtonGroup bg = new ButtonGroup();
                bg.add(rb1);
                bg.add(rb2);
                bg.add(rb3);
                switch(selectedScopeIndex) {
                    case 0:
                        rb1.setSelected(true);
                        break;
                    case 1:
                        rb2.setSelected(true);
                        break;
                    case 2:
                        rb3.setSelected(true);
                        break;
                }
                final JComboBox<String> comboBox = new JComboBox<String>(new String[] { "Central Pole", "Tripod" });
                comboBox.setSelectedIndex(d.getStructureType());
                gui.add(comboBox, BorderLayout.SOUTH);
                final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
                final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
                final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Structure Type");
                while (true) {
                    dialog.setVisible(true);
                    final Object choice = optionPane.getValue();
                    if (choice == options[1] || choice == null) {
                        break;
                    } else {
                        final int structureType = comboBox.getSelectedIndex();
                        boolean changed = structureType != d.getStructureType();
                        if (rb1.isSelected()) {
                            if (changed) {
                                final SetParabolicDishStructureTypeCommand c = new SetParabolicDishStructureTypeCommand(d);
                                d.setStructureType(structureType);
                                d.draw();
                                SceneManager.getInstance().refresh();
                                SceneManager.getInstance().getUndoManager().addEdit(c);
                            }
                            selectedScopeIndex = 0;
                        } else if (rb2.isSelected()) {
                            if (!changed) {
                                for (final ParabolicDish x : foundation.getParabolicDishes()) {
                                    if (structureType != x.getStructureType()) {
                                        changed = true;
                                        break;
                                    }
                                }
                            }
                            if (changed) {
                                final ChangeFoundationParabolicDishStructureTypeCommand c = new ChangeFoundationParabolicDishStructureTypeCommand(foundation);
                                foundation.setStructureTypeForParabolicDishes(structureType);
                                SceneManager.getInstance().getUndoManager().addEdit(c);
                            }
                            selectedScopeIndex = 1;
                        } else if (rb3.isSelected()) {
                            if (!changed) {
                                for (final ParabolicDish x : Scene.getInstance().getAllParabolicDishes()) {
                                    if (structureType != x.getStructureType()) {
                                        changed = true;
                                        break;
                                    }
                                }
                            }
                            if (changed) {
                                final ChangeStructureTypeForAllParabolicDishesCommand c = new ChangeStructureTypeForAllParabolicDishesCommand();
                                Scene.getInstance().setStructureTypeForAllParabolicDishes(structureType);
                                SceneManager.getInstance().getUndoManager().addEdit(c);
                            }
                            selectedScopeIndex = 2;
                        }
                        if (changed) {
                            updateAfterEdit();
                        }
                        if (choice == options[0]) {
                            break;
                        }
                    }
                }
            }
        });
        final JMenu labelMenu = new JMenu("Label");
        final JCheckBoxMenuItem miLabelNone = new JCheckBoxMenuItem("None", true);
        miLabelNone.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {
                if (miLabelNone.isSelected()) {
                    final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                    if (selectedPart instanceof ParabolicDish) {
                        final ParabolicDish d = (ParabolicDish) selectedPart;
                        final SetParabolicDishLabelCommand c = new SetParabolicDishLabelCommand(d);
                        d.clearLabels();
                        d.draw();
                        SceneManager.getInstance().getUndoManager().addEdit(c);
                        Scene.getInstance().setEdited(true);
                        SceneManager.getInstance().refresh();
                    }
                }
            }
        });
        labelMenu.add(miLabelNone);
        final JCheckBoxMenuItem miLabelCustom = new JCheckBoxMenuItem("Custom");
        miLabelCustom.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (selectedPart instanceof ParabolicDish) {
                    final ParabolicDish d = (ParabolicDish) selectedPart;
                    final SetParabolicDishLabelCommand c = new SetParabolicDishLabelCommand(d);
                    d.setLabelCustom(miLabelCustom.isSelected());
                    if (d.getLabelCustom()) {
                        d.setLabelCustomText(JOptionPane.showInputDialog(MainFrame.getInstance(), "Custom Text", d.getLabelCustomText()));
                    }
                    d.draw();
                    SceneManager.getInstance().getUndoManager().addEdit(c);
                    Scene.getInstance().setEdited(true);
                    SceneManager.getInstance().refresh();
                }
            }
        });
        labelMenu.add(miLabelCustom);
        final JCheckBoxMenuItem miLabelId = new JCheckBoxMenuItem("ID");
        miLabelId.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (selectedPart instanceof ParabolicDish) {
                    final ParabolicDish d = (ParabolicDish) selectedPart;
                    final SetParabolicDishLabelCommand c = new SetParabolicDishLabelCommand(d);
                    d.setLabelId(miLabelId.isSelected());
                    d.draw();
                    SceneManager.getInstance().getUndoManager().addEdit(c);
                    Scene.getInstance().setEdited(true);
                    SceneManager.getInstance().refresh();
                }
            }
        });
        labelMenu.add(miLabelId);
        final JCheckBoxMenuItem miLabelEnergyOutput = new JCheckBoxMenuItem("Energy Output");
        miLabelEnergyOutput.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (selectedPart instanceof ParabolicDish) {
                    final ParabolicDish d = (ParabolicDish) selectedPart;
                    final SetParabolicDishLabelCommand c = new SetParabolicDishLabelCommand(d);
                    d.setLabelEnergyOutput(miLabelEnergyOutput.isSelected());
                    d.draw();
                    SceneManager.getInstance().getUndoManager().addEdit(c);
                    Scene.getInstance().setEdited(true);
                    SceneManager.getInstance().refresh();
                }
            }
        });
        labelMenu.add(miLabelEnergyOutput);
        popupMenuForParabolicDish = createPopupMenu(true, true, new Runnable() {

            @Override
            public void run() {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final ParabolicDish d = (ParabolicDish) selectedPart;
                Util.selectSilently(miLabelNone, !d.isLabelVisible());
                Util.selectSilently(miLabelCustom, d.getLabelCustom());
                Util.selectSilently(miLabelId, d.getLabelId());
                Util.selectSilently(miLabelEnergyOutput, d.getLabelEnergyOutput());
                Util.selectSilently(cbmiDrawSunBeams, d.isSunBeamVisible());
                Util.selectSilently(cbmiDisableEditPoint, d.getLockEdit());
            }
        });
        final JMenuItem miReflectance = new JMenuItem("Mirror Reflectance...");
        miReflectance.addActionListener(new ActionListener() {

            // remember the scope selection as the next action will likely be applied to the same scope
            private int selectedScopeIndex = 0;

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
                final ParabolicDish d = (ParabolicDish) selectedPart;
                final String title = "<html>Reflectance (%) of " + partInfo + "</html>";
                final String footnote = "<html><hr><font size=2>Reflectance can be affected by pollen and dust.<hr></html>";
                final JPanel gui = new JPanel(new BorderLayout());
                final JPanel panel = new JPanel();
                gui.add(panel, BorderLayout.CENTER);
                panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
                panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
                final JRadioButton rb1 = new JRadioButton("Only this Parabolic Dish", true);
                final JRadioButton rb2 = new JRadioButton("All Parabolic Dishes on this Foundation");
                final JRadioButton rb3 = new JRadioButton("All Parabolic Dishes");
                panel.add(rb1);
                panel.add(rb2);
                panel.add(rb3);
                final ButtonGroup bg = new ButtonGroup();
                bg.add(rb1);
                bg.add(rb2);
                bg.add(rb3);
                switch(selectedScopeIndex) {
                    case 0:
                        rb1.setSelected(true);
                        break;
                    case 1:
                        rb2.setSelected(true);
                        break;
                    case 2:
                        rb3.setSelected(true);
                        break;
                }
                final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(d.getReflectance() * 100));
                gui.add(inputField, BorderLayout.SOUTH);
                final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
                final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
                final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Parabolic Dish Mirror Reflectance");
                while (true) {
                    inputField.selectAll();
                    inputField.requestFocusInWindow();
                    dialog.setVisible(true);
                    final Object choice = optionPane.getValue();
                    if (choice == options[1] || choice == null) {
                        break;
                    } else {
                        double val = 0;
                        boolean ok = true;
                        try {
                            val = Double.parseDouble(inputField.getText());
                        } catch (final NumberFormatException exception) {
                            JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
                            ok = false;
                        }
                        if (ok) {
                            if (val < 50 || val > 99) {
                                JOptionPane.showMessageDialog(MainFrame.getInstance(), "Parabolic dish reflectance must be between 50% and 99%.", "Range Error", JOptionPane.ERROR_MESSAGE);
                            } else {
                                boolean changed = Math.abs(val * 0.01 - d.getReflectance()) > 0.000001;
                                if (rb1.isSelected()) {
                                    if (changed) {
                                        final ChangeSolarReflectorReflectanceCommand c = new ChangeSolarReflectorReflectanceCommand(d);
                                        d.setReflectance(val * 0.01);
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 0;
                                } else if (rb2.isSelected()) {
                                    final Foundation foundation = d.getTopContainer();
                                    if (!changed) {
                                        for (final ParabolicDish x : foundation.getParabolicDishes()) {
                                            if (Math.abs(val * 0.01 - x.getReflectance()) > 0.000001) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final ChangeFoundationSolarReflectorReflectanceCommand c = new ChangeFoundationSolarReflectorReflectanceCommand(foundation, d.getClass());
                                        foundation.setReflectanceForSolarReflectors(val * 0.01, d.getClass());
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 1;
                                } else if (rb3.isSelected()) {
                                    if (!changed) {
                                        for (final ParabolicDish x : Scene.getInstance().getAllParabolicDishes()) {
                                            if (Math.abs(val * 0.01 - x.getReflectance()) > 0.000001) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final ChangeReflectanceForAllSolarReflectorsCommand c = new ChangeReflectanceForAllSolarReflectorsCommand(d.getClass());
                                        Scene.getInstance().setReflectanceForAllSolarReflectors(val * 0.01, d.getClass());
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 2;
                                }
                                if (changed) {
                                    updateAfterEdit();
                                }
                                if (choice == options[0]) {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        });
        final JMenuItem miAbsorptance = new JMenuItem("Receiver Absorptance...");
        miAbsorptance.addActionListener(new ActionListener() {

            // remember the scope selection as the next action will likely be applied to the same scope
            private int selectedScopeIndex = 0;

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
                final ParabolicDish d = (ParabolicDish) selectedPart;
                final String title = "<html>Absorptance (%) of " + partInfo + "</html>";
                final String footnote = "<html><hr><font size=2><hr></html>";
                final JPanel gui = new JPanel(new BorderLayout());
                final JPanel panel = new JPanel();
                gui.add(panel, BorderLayout.CENTER);
                panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
                panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
                final JRadioButton rb1 = new JRadioButton("Only this Parabolic Dish", true);
                final JRadioButton rb2 = new JRadioButton("All Parabolic Dishes on this Foundation");
                final JRadioButton rb3 = new JRadioButton("All Parabolic Dishes");
                panel.add(rb1);
                panel.add(rb2);
                panel.add(rb3);
                final ButtonGroup bg = new ButtonGroup();
                bg.add(rb1);
                bg.add(rb2);
                bg.add(rb3);
                switch(selectedScopeIndex) {
                    case 0:
                        rb1.setSelected(true);
                        break;
                    case 1:
                        rb2.setSelected(true);
                        break;
                    case 2:
                        rb3.setSelected(true);
                        break;
                }
                final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(d.getAbsorptance() * 100));
                gui.add(inputField, BorderLayout.SOUTH);
                final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
                final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
                final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Parabolic Dish Receiver Absorptance");
                while (true) {
                    inputField.selectAll();
                    inputField.requestFocusInWindow();
                    dialog.setVisible(true);
                    final Object choice = optionPane.getValue();
                    if (choice == options[1] || choice == null) {
                        break;
                    } else {
                        double val = 0;
                        boolean ok = true;
                        try {
                            val = Double.parseDouble(inputField.getText());
                        } catch (final NumberFormatException exception) {
                            JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
                            ok = false;
                        }
                        if (ok) {
                            if (val < 50 || val > 99) {
                                JOptionPane.showMessageDialog(MainFrame.getInstance(), "Parabolic dish absorptance must be between 50% and 99%.", "Range Error", JOptionPane.ERROR_MESSAGE);
                            } else {
                                boolean changed = Math.abs(val * 0.01 - d.getAbsorptance()) > 0.000001;
                                if (rb1.isSelected()) {
                                    if (changed) {
                                        final ChangeSolarReflectorAbsorptanceCommand c = new ChangeSolarReflectorAbsorptanceCommand(d);
                                        d.setAbsorptance(val * 0.01);
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 0;
                                } else if (rb2.isSelected()) {
                                    final Foundation foundation = d.getTopContainer();
                                    if (!changed) {
                                        for (final ParabolicDish x : foundation.getParabolicDishes()) {
                                            if (Math.abs(val * 0.01 - x.getAbsorptance()) > 0.000001) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final ChangeFoundationSolarReflectorAbsorptanceCommand c = new ChangeFoundationSolarReflectorAbsorptanceCommand(foundation, d.getClass());
                                        foundation.setAbsorptanceForSolarReflectors(val * 0.01, d.getClass());
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 1;
                                } else if (rb3.isSelected()) {
                                    if (!changed) {
                                        for (final ParabolicDish x : Scene.getInstance().getAllParabolicDishes()) {
                                            if (Math.abs(val * 0.01 - x.getAbsorptance()) > 0.000001) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final ChangeAbsorptanceForAllSolarReflectorsCommand c = new ChangeAbsorptanceForAllSolarReflectorsCommand(d.getClass());
                                        Scene.getInstance().setAbsorptanceForAllSolarReflectors(val * 0.01, d.getClass());
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 2;
                                }
                                if (changed) {
                                    updateAfterEdit();
                                }
                                if (choice == options[0]) {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        });
        final JMenuItem miOpticalEfficiency = new JMenuItem("Optical Efficiency...");
        miOpticalEfficiency.addActionListener(new ActionListener() {

            // remember the scope selection as the next action will likely be applied to the same scope
            private int selectedScopeIndex = 0;

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
                final ParabolicDish d = (ParabolicDish) selectedPart;
                final String title = "<html>Opitical efficiency (%) of " + partInfo + "</html>";
                final String footnote = "<html><hr><font size=2>For example, the percentage of the effective area for reflection after deducting<br>the area of facet gaps, module frames, absorber shadow, etc.<hr></html>";
                final JPanel gui = new JPanel(new BorderLayout());
                final JPanel panel = new JPanel();
                gui.add(panel, BorderLayout.CENTER);
                panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
                panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
                final JRadioButton rb1 = new JRadioButton("Only this Parabolic Dish", true);
                final JRadioButton rb2 = new JRadioButton("All Parabolic Dishes on this Foundation");
                final JRadioButton rb3 = new JRadioButton("All Parabolic Dishes");
                panel.add(rb1);
                panel.add(rb2);
                panel.add(rb3);
                final ButtonGroup bg = new ButtonGroup();
                bg.add(rb1);
                bg.add(rb2);
                bg.add(rb3);
                switch(selectedScopeIndex) {
                    case 0:
                        rb1.setSelected(true);
                        break;
                    case 1:
                        rb2.setSelected(true);
                        break;
                    case 2:
                        rb3.setSelected(true);
                        break;
                }
                final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(d.getOpticalEfficiency() * 100));
                gui.add(inputField, BorderLayout.SOUTH);
                final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
                final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
                final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Parabolic Dish Optical Efficiency");
                while (true) {
                    inputField.selectAll();
                    inputField.requestFocusInWindow();
                    dialog.setVisible(true);
                    final Object choice = optionPane.getValue();
                    if (choice == options[1] || choice == null) {
                        break;
                    } else {
                        double val = 0;
                        boolean ok = true;
                        try {
                            val = Double.parseDouble(inputField.getText());
                        } catch (final NumberFormatException exception) {
                            JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
                            ok = false;
                        }
                        if (ok) {
                            if (val < 50 || val > 100) {
                                JOptionPane.showMessageDialog(MainFrame.getInstance(), "Parabolic dish optical efficiency must be between 50% and 100%.", "Range Error", JOptionPane.ERROR_MESSAGE);
                            } else {
                                boolean changed = Math.abs(val * 0.01 - d.getOpticalEfficiency()) > 0.000001;
                                if (rb1.isSelected()) {
                                    if (changed) {
                                        final ChangeSolarReflectorOpticalEfficiencyCommand c = new ChangeSolarReflectorOpticalEfficiencyCommand(d);
                                        d.setOpticalEfficiency(val * 0.01);
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 0;
                                } else if (rb2.isSelected()) {
                                    final Foundation foundation = d.getTopContainer();
                                    if (!changed) {
                                        for (final ParabolicDish x : foundation.getParabolicDishes()) {
                                            if (Math.abs(val * 0.01 - x.getOpticalEfficiency()) > 0.000001) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final ChangeFoundationSolarReflectorOpticalEfficiencyCommand c = new ChangeFoundationSolarReflectorOpticalEfficiencyCommand(foundation, d.getClass());
                                        foundation.setOpticalEfficiencyForSolarReflectors(val * 0.01, d.getClass());
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 1;
                                } else if (rb3.isSelected()) {
                                    if (!changed) {
                                        for (final ParabolicDish x : Scene.getInstance().getAllParabolicDishes()) {
                                            if (Math.abs(val * 0.01 - x.getOpticalEfficiency()) > 0.000001) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final ChangeOpticalEfficiencyForAllSolarReflectorsCommand c = new ChangeOpticalEfficiencyForAllSolarReflectorsCommand(d.getClass());
                                        Scene.getInstance().setOpticalEfficiencyForAllSolarReflectors(val * 0.01, d.getClass());
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 2;
                                }
                                if (changed) {
                                    updateAfterEdit();
                                }
                                if (choice == options[0]) {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        });
        final JMenuItem miThermalEfficiency = new JMenuItem("Thermal Efficiency...");
        miThermalEfficiency.addActionListener(new ActionListener() {

            // remember the scope selection as the next action will likely be applied to the same scope
            private int selectedScopeIndex = 0;

            @Override
            public void actionPerformed(final ActionEvent e) {
                final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
                if (!(selectedPart instanceof ParabolicDish)) {
                    return;
                }
                final String partInfo = selectedPart.toString().substring(0, selectedPart.toString().indexOf(')') + 1);
                final ParabolicDish d = (ParabolicDish) selectedPart;
                final String title = "<html>Thermal efficiency (%) of " + partInfo + "</html>";
                final String footnote = "<html><hr><font size=2><hr></html>";
                final JPanel gui = new JPanel(new BorderLayout());
                final JPanel panel = new JPanel();
                gui.add(panel, BorderLayout.CENTER);
                panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
                panel.setBorder(BorderFactory.createTitledBorder("Apply to:"));
                final JRadioButton rb1 = new JRadioButton("Only this Parabolic Dish", true);
                final JRadioButton rb2 = new JRadioButton("All Parabolic Dishes on this Foundation");
                final JRadioButton rb3 = new JRadioButton("All Parabolic Dishes");
                panel.add(rb1);
                panel.add(rb2);
                panel.add(rb3);
                final ButtonGroup bg = new ButtonGroup();
                bg.add(rb1);
                bg.add(rb2);
                bg.add(rb3);
                switch(selectedScopeIndex) {
                    case 0:
                        rb1.setSelected(true);
                        break;
                    case 1:
                        rb2.setSelected(true);
                        break;
                    case 2:
                        rb3.setSelected(true);
                        break;
                }
                final JTextField inputField = new JTextField(EnergyPanel.TWO_DECIMALS.format(d.getThermalEfficiency() * 100));
                gui.add(inputField, BorderLayout.SOUTH);
                final Object[] options = new Object[] { "OK", "Cancel", "Apply" };
                final JOptionPane optionPane = new JOptionPane(new Object[] { title, footnote, gui }, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[2]);
                final JDialog dialog = optionPane.createDialog(MainFrame.getInstance(), "Parabolic Dish Thermal Efficiency");
                while (true) {
                    inputField.selectAll();
                    inputField.requestFocusInWindow();
                    dialog.setVisible(true);
                    final Object choice = optionPane.getValue();
                    if (choice == options[1] || choice == null) {
                        break;
                    } else {
                        double val = 0;
                        boolean ok = true;
                        try {
                            val = Double.parseDouble(inputField.getText());
                        } catch (final NumberFormatException exception) {
                            JOptionPane.showMessageDialog(MainFrame.getInstance(), inputField.getText() + " is an invalid value!", "Error", JOptionPane.ERROR_MESSAGE);
                            ok = false;
                        }
                        if (ok) {
                            if (val < 5 || val > 80) {
                                JOptionPane.showMessageDialog(MainFrame.getInstance(), "Parabolic dish thermal efficiency must be between 5% and 80%.", "Range Error", JOptionPane.ERROR_MESSAGE);
                            } else {
                                boolean changed = Math.abs(val * 0.01 - d.getThermalEfficiency()) > 0.000001;
                                if (rb1.isSelected()) {
                                    if (changed) {
                                        final ChangeSolarReflectorThermalEfficiencyCommand c = new ChangeSolarReflectorThermalEfficiencyCommand(d);
                                        d.setThermalEfficiency(val * 0.01);
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 0;
                                } else if (rb2.isSelected()) {
                                    final Foundation foundation = d.getTopContainer();
                                    if (!changed) {
                                        for (final ParabolicDish x : foundation.getParabolicDishes()) {
                                            if (Math.abs(val * 0.01 - x.getThermalEfficiency()) > 0.000001) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final ChangeFoundationSolarReflectorThermalEfficiencyCommand c = new ChangeFoundationSolarReflectorThermalEfficiencyCommand(foundation, d.getClass());
                                        foundation.setThermalEfficiencyForSolarReflectors(val * 0.01, d.getClass());
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 1;
                                } else if (rb3.isSelected()) {
                                    if (!changed) {
                                        for (final ParabolicDish x : Scene.getInstance().getAllParabolicDishes()) {
                                            if (Math.abs(val * 0.01 - x.getThermalEfficiency()) > 0.000001) {
                                                changed = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (changed) {
                                        final ChangeThermalEfficiencyForAllSolarReflectorsCommand c = new ChangeThermalEfficiencyForAllSolarReflectorsCommand(d.getClass());
                                        Scene.getInstance().setThermalEfficiencyForAllSolarReflectors(val * 0.01, d.getClass());
                                        SceneManager.getInstance().getUndoManager().addEdit(c);
                                    }
                                    selectedScopeIndex = 2;
                                }
                                if (changed) {
                                    updateAfterEdit();
                                }
                                if (choice == options[0]) {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        });
        popupMenuForParabolicDish.addSeparator();
        popupMenuForParabolicDish.add(cbmiDisableEditPoint);
        popupMenuForParabolicDish.add(cbmiDrawSunBeams);
        popupMenuForParabolicDish.add(labelMenu);
        popupMenuForParabolicDish.addSeparator();
        popupMenuForParabolicDish.add(miRimRadius);
        popupMenuForParabolicDish.add(miFocalLength);
        popupMenuForParabolicDish.add(miBaseHeight);
        popupMenuForParabolicDish.add(miStructureType);
        popupMenuForParabolicDish.addSeparator();
        popupMenuForParabolicDish.add(miReflectance);
        popupMenuForParabolicDish.add(miAbsorptance);
        popupMenuForParabolicDish.add(miOpticalEfficiency);
        popupMenuForParabolicDish.add(miThermalEfficiency);
        popupMenuForParabolicDish.addSeparator();
        popupMenuForParabolicDish.add(miMesh);
        popupMenuForParabolicDish.add(miRib);
        popupMenuForParabolicDish.addSeparator();
        JMenuItem mi = new JMenuItem("Daily Yield Analysis...");
        mi.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {
                if (EnergyPanel.getInstance().adjustCellSize()) {
                    return;
                }
                if (SceneManager.getInstance().getSelectedPart() instanceof ParabolicDish) {
                    new ParabolicDishDailyAnalysis().show();
                }
            }
        });
        popupMenuForParabolicDish.add(mi);
        mi = new JMenuItem("Annual Yield Analysis...");
        mi.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {
                if (EnergyPanel.getInstance().adjustCellSize()) {
                    return;
                }
                if (SceneManager.getInstance().getSelectedPart() instanceof ParabolicDish) {
                    new ParabolicDishAnnualAnalysis().show();
                }
            }
        });
        popupMenuForParabolicDish.add(mi);
    }
    return popupMenuForParabolicDish;
}
Also used : JPanel(javax.swing.JPanel) ActionEvent(java.awt.event.ActionEvent) SetPartSizeCommand(org.concord.energy3d.undo.SetPartSizeCommand) ChangeSolarReflectorOpticalEfficiencyCommand(org.concord.energy3d.undo.ChangeSolarReflectorOpticalEfficiencyCommand) SetRibsForParabolicDishesOnFoundationCommand(org.concord.energy3d.undo.SetRibsForParabolicDishesOnFoundationCommand) ChangeBaseHeightForAllSolarCollectorsCommand(org.concord.energy3d.undo.ChangeBaseHeightForAllSolarCollectorsCommand) SetFocalLengthForParabolicDishesOnFoundationCommand(org.concord.energy3d.undo.SetFocalLengthForParabolicDishesOnFoundationCommand) BorderLayout(java.awt.BorderLayout) ChangeAbsorptanceForAllSolarReflectorsCommand(org.concord.energy3d.undo.ChangeAbsorptanceForAllSolarReflectorsCommand) ParabolicDishAnnualAnalysis(org.concord.energy3d.simulation.ParabolicDishAnnualAnalysis) Foundation(org.concord.energy3d.model.Foundation) LockEditPointsOnFoundationCommand(org.concord.energy3d.undo.LockEditPointsOnFoundationCommand) ChangeFoundationSolarReflectorThermalEfficiencyCommand(org.concord.energy3d.undo.ChangeFoundationSolarReflectorThermalEfficiencyCommand) SetParabolicDishStructureTypeCommand(org.concord.energy3d.undo.SetParabolicDishStructureTypeCommand) ChangeReflectanceForAllSolarReflectorsCommand(org.concord.energy3d.undo.ChangeReflectanceForAllSolarReflectorsCommand) HousePart(org.concord.energy3d.model.HousePart) JOptionPane(javax.swing.JOptionPane) JCheckBoxMenuItem(javax.swing.JCheckBoxMenuItem) ChangeSolarReflectorAbsorptanceCommand(org.concord.energy3d.undo.ChangeSolarReflectorAbsorptanceCommand) ChangeFoundationParabolicDishStructureTypeCommand(org.concord.energy3d.undo.ChangeFoundationParabolicDishStructureTypeCommand) ActionListener(java.awt.event.ActionListener) ChangeFoundationSolarCollectorBaseHeightCommand(org.concord.energy3d.undo.ChangeFoundationSolarCollectorBaseHeightCommand) JDialog(javax.swing.JDialog) SetRimRadiusForAllParabolicDishesCommand(org.concord.energy3d.undo.SetRimRadiusForAllParabolicDishesCommand) ChangeStructureTypeForAllParabolicDishesCommand(org.concord.energy3d.undo.ChangeStructureTypeForAllParabolicDishesCommand) ItemEvent(java.awt.event.ItemEvent) JRadioButton(javax.swing.JRadioButton) ChangeSolarReflectorReflectanceCommand(org.concord.energy3d.undo.ChangeSolarReflectorReflectanceCommand) BoxLayout(javax.swing.BoxLayout) JTextField(javax.swing.JTextField) ChangeFoundationSolarReflectorAbsorptanceCommand(org.concord.energy3d.undo.ChangeFoundationSolarReflectorAbsorptanceCommand) GridLayout(java.awt.GridLayout) SetParabolicDishRibsCommand(org.concord.energy3d.undo.SetParabolicDishRibsCommand) JMenuItem(javax.swing.JMenuItem) SetRimRadiusForParabolicDishesOnFoundationCommand(org.concord.energy3d.undo.SetRimRadiusForParabolicDishesOnFoundationCommand) LockEditPointsCommand(org.concord.energy3d.undo.LockEditPointsCommand) JComboBox(javax.swing.JComboBox) JLabel(javax.swing.JLabel) ShowSunBeamCommand(org.concord.energy3d.undo.ShowSunBeamCommand) ChangeBaseHeightCommand(org.concord.energy3d.undo.ChangeBaseHeightCommand) ChangeOpticalEfficiencyForAllSolarReflectorsCommand(org.concord.energy3d.undo.ChangeOpticalEfficiencyForAllSolarReflectorsCommand) SetParabolicDishLabelCommand(org.concord.energy3d.undo.SetParabolicDishLabelCommand) ParabolicDish(org.concord.energy3d.model.ParabolicDish) LockEditPointsForClassCommand(org.concord.energy3d.undo.LockEditPointsForClassCommand) ChangeFoundationSolarReflectorReflectanceCommand(org.concord.energy3d.undo.ChangeFoundationSolarReflectorReflectanceCommand) ChangeSolarReflectorThermalEfficiencyCommand(org.concord.energy3d.undo.ChangeSolarReflectorThermalEfficiencyCommand) ChangeFoundationSolarReflectorOpticalEfficiencyCommand(org.concord.energy3d.undo.ChangeFoundationSolarReflectorOpticalEfficiencyCommand) ParabolicDishDailyAnalysis(org.concord.energy3d.simulation.ParabolicDishDailyAnalysis) SetRibsForAllParabolicDishesCommand(org.concord.energy3d.undo.SetRibsForAllParabolicDishesCommand) ButtonGroup(javax.swing.ButtonGroup) ChangeThermalEfficiencyForAllSolarReflectorsCommand(org.concord.energy3d.undo.ChangeThermalEfficiencyForAllSolarReflectorsCommand) SetFocalLengthForAllParabolicDishesCommand(org.concord.energy3d.undo.SetFocalLengthForAllParabolicDishesCommand) ItemListener(java.awt.event.ItemListener) SetParabolicDishFocalLengthCommand(org.concord.energy3d.undo.SetParabolicDishFocalLengthCommand) JMenu(javax.swing.JMenu)

Aggregations

ItemEvent (java.awt.event.ItemEvent)339 ItemListener (java.awt.event.ItemListener)313 ActionEvent (java.awt.event.ActionEvent)120 ActionListener (java.awt.event.ActionListener)110 JPanel (javax.swing.JPanel)106 JLabel (javax.swing.JLabel)84 JCheckBox (javax.swing.JCheckBox)72 JComboBox (javax.swing.JComboBox)65 Dimension (java.awt.Dimension)59 JButton (javax.swing.JButton)53 BorderLayout (java.awt.BorderLayout)48 JTextField (javax.swing.JTextField)46 ButtonGroup (javax.swing.ButtonGroup)35 JCheckBoxMenuItem (javax.swing.JCheckBoxMenuItem)33 GridLayout (java.awt.GridLayout)30 ChangeEvent (javax.swing.event.ChangeEvent)30 GridBagConstraints (java.awt.GridBagConstraints)29 JMenu (javax.swing.JMenu)29 ChangeListener (javax.swing.event.ChangeListener)29 GridBagLayout (java.awt.GridBagLayout)28