From ddbcf597c2dae10660415852d9ec490eadac0482 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 15 Jun 2022 12:48:23 +0200 Subject: [PATCH] Extend multi-select components to different-typed components --- core/resources/l10n/messages.properties | 5 +- core/resources/l10n/messages_cs.properties | 1 - core/resources/l10n/messages_de.properties | 1 - core/resources/l10n/messages_es.properties | 3 +- core/resources/l10n/messages_fr.properties | 1 - core/resources/l10n/messages_it.properties | 1 - core/resources/l10n/messages_ja.properties | 1 - core/resources/l10n/messages_nl.properties | 1 - core/resources/l10n/messages_pl.properties | 1 - core/resources/l10n/messages_ru.properties | 1 - core/resources/l10n/messages_uk_UA.properties | 1 - .../rocketcomponent/RocketComponent.java | 20 ++++- .../gui/components/StyledLabel.java | 9 +- .../configdialog/ComponentConfigDialog.java | 84 +++++++++--------- .../gui/configdialog/FinSetConfig.java | 9 +- .../configdialog/RocketComponentConfig.java | 86 +++++++++++++++---- .../sf/openrocket/gui/main/BasicFrame.java | 13 ++- .../sf/openrocket/gui/main/RocketActions.java | 34 ++------ 18 files changed, 152 insertions(+), 120 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 0a33eaaef..9a7f539f4 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -947,7 +947,10 @@ CenteringRingCfg.tab.Generalproperties = General properties !ComponentConfigDialog ComponentCfgDlg.configuration = configuration -ComponentCfgDlg.configuration1 = +ComponentCfgDlg.MultiComponent = Multi-component +ComponentCfgDlg.MultiComponentConfig = Multi-component configuration +ComponentCfgDlg.MultiComponentEdit = Multi-component edit +ComponentCfgDlg.MultiComponentEdit.ttip = You are editing the following components:
ComponentCfgDlg.Modify = Modify !StageConfig diff --git a/core/resources/l10n/messages_cs.properties b/core/resources/l10n/messages_cs.properties index c6354d4a8..f5b5933f7 100644 --- a/core/resources/l10n/messages_cs.properties +++ b/core/resources/l10n/messages_cs.properties @@ -678,7 +678,6 @@ CenteringRingCfg.tab.Generalproperties = Obecn !ComponentConfigDialog ComponentCfgDlg.configuration = konfigurace -ComponentCfgDlg.configuration1 = ComponentCfgDlg.Modify = Uprav !StageConfig diff --git a/core/resources/l10n/messages_de.properties b/core/resources/l10n/messages_de.properties index 442081510..45f91eda5 100644 --- a/core/resources/l10n/messages_de.properties +++ b/core/resources/l10n/messages_de.properties @@ -734,7 +734,6 @@ CenteringRingCfg.tab.Generalproperties = Allgemeine Eigenschaften !ComponentConfigDialog ComponentCfgDlg.configuration = Konfiguration -ComponentCfgDlg.configuration1 = ComponentCfgDlg.Modify = Verändern !StageConfig diff --git a/core/resources/l10n/messages_es.properties b/core/resources/l10n/messages_es.properties index 9d0e5b2c3..255e26369 100644 --- a/core/resources/l10n/messages_es.properties +++ b/core/resources/l10n/messages_es.properties @@ -130,8 +130,7 @@ CompassSelectionButton.lbl.W = O ComponentCfgDlg.Modify = Modificar !ComponentConfigDialog -ComponentCfgDlg.configuration = -ComponentCfgDlg.configuration1 = Configuraci\u00f3n +ComponentCfgDlg.configuration = Configuraci\u00f3n ComponentIcons.Bodytube = Cuerpo tubular ComponentIcons.Bulkhead = Disco de enganche diff --git a/core/resources/l10n/messages_fr.properties b/core/resources/l10n/messages_fr.properties index ab7fb5544..d4cee80d0 100644 --- a/core/resources/l10n/messages_fr.properties +++ b/core/resources/l10n/messages_fr.properties @@ -121,7 +121,6 @@ CompassSelectionButton.lbl.W = O ComponentCfgDlg.Modify = Modifier !ComponentConfigDialog ComponentCfgDlg.configuration = configuration -ComponentCfgDlg.configuration1 = configuration ComponentIcons.Bodytube = Tube ComponentIcons.Bulkhead = Cloison diff --git a/core/resources/l10n/messages_it.properties b/core/resources/l10n/messages_it.properties index ef7a5d226..f99e43eb3 100644 --- a/core/resources/l10n/messages_it.properties +++ b/core/resources/l10n/messages_it.properties @@ -736,7 +736,6 @@ CenteringRingCfg.tab.Generalproperties = Proprieta' generali !ComponentConfigDialog ComponentCfgDlg.configuration = (configurazione) -ComponentCfgDlg.configuration1 = ComponentCfgDlg.Modify = Modifica !StageConfig diff --git a/core/resources/l10n/messages_ja.properties b/core/resources/l10n/messages_ja.properties index 8cf8b6b03..2417dd0c0 100644 --- a/core/resources/l10n/messages_ja.properties +++ b/core/resources/l10n/messages_ja.properties @@ -766,7 +766,6 @@ CenteringRingCfg.tab.Generalproperties = \u4E00\u822C !ComponentConfigDialog ComponentCfgDlg.configuration = \u30B3\u30F3\u30D5\u30A3\u30AE\u30E5\u30EC\u30FC\u30B7\u30E7\u30F3 -ComponentCfgDlg.configuration1 = ComponentCfgDlg.Modify = \u5909\u66F4 !StageConfig diff --git a/core/resources/l10n/messages_nl.properties b/core/resources/l10n/messages_nl.properties index 0b7e783f8..b32a8d0a5 100644 --- a/core/resources/l10n/messages_nl.properties +++ b/core/resources/l10n/messages_nl.properties @@ -889,7 +889,6 @@ CenteringRingCfg.tab.Generalproperties = Algemene eigenschappen !ComponentConfigDialog ComponentCfgDlg.configuration = configuratie -ComponentCfgDlg.configuration1 = ComponentCfgDlg.Modify = Wijzigen !StageConfig diff --git a/core/resources/l10n/messages_pl.properties b/core/resources/l10n/messages_pl.properties index 05127de1c..08bcaec77 100644 --- a/core/resources/l10n/messages_pl.properties +++ b/core/resources/l10n/messages_pl.properties @@ -680,7 +680,6 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s. !ComponentConfigDialog ComponentCfgDlg.configuration = konfiguracja - ComponentCfgDlg.configuration1 = ComponentCfgDlg.Modify = Zmodyfikuj !StageConfig diff --git a/core/resources/l10n/messages_ru.properties b/core/resources/l10n/messages_ru.properties index 5fc2e1149..6f8657f59 100644 --- a/core/resources/l10n/messages_ru.properties +++ b/core/resources/l10n/messages_ru.properties @@ -949,7 +949,6 @@ CenteringRingCfg.tab.Generalproperties = \u041E\u0441\u043D\u043E\u0432\u043D\u0 !ComponentConfigDialog ComponentCfgDlg.configuration = \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B -ComponentCfgDlg.configuration1 = ComponentCfgDlg.Modify = \u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C !StageConfig diff --git a/core/resources/l10n/messages_uk_UA.properties b/core/resources/l10n/messages_uk_UA.properties index 8a06a77ef..5d7147134 100644 --- a/core/resources/l10n/messages_uk_UA.properties +++ b/core/resources/l10n/messages_uk_UA.properties @@ -838,7 +838,6 @@ CenteringRingCfg.tab.Generalproperties = General properties !ComponentConfigDialog ComponentCfgDlg.configuration = configuration -ComponentCfgDlg.configuration1 = ComponentCfgDlg.Modify = Modify !StageConfig diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index f03862f0a..19ee93526 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -1671,6 +1671,24 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab } return false; } + + /** + * Checks whether all components in the list have the same class as this component. + * @param components list to check + * @return true if all components are of the same class, false if not + */ + public boolean checkAllClassesEqual(List components) { + if (components == null || components.size() == 0) { + return true; + } + Class myClass = this.getClass(); + for (RocketComponent c : components) { + if (!c.getClass().equals(myClass)) { + return false; + } + } + return true; + } /** * Get the root component of the component tree. @@ -1970,7 +1988,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * @return true if listener was successfully added, false if not */ public boolean addConfigListener(RocketComponent listener) { - if (listener == null || !this.getClass().equals(listener.getClass())) { + if (listener == null) { return false; } configListeners.add(listener); diff --git a/swing/src/net/sf/openrocket/gui/components/StyledLabel.java b/swing/src/net/sf/openrocket/gui/components/StyledLabel.java index 70328411b..bf2a29314 100644 --- a/swing/src/net/sf/openrocket/gui/components/StyledLabel.java +++ b/swing/src/net/sf/openrocket/gui/components/StyledLabel.java @@ -1,5 +1,6 @@ package net.sf.openrocket.gui.components; +import java.awt.Color; import java.awt.Font; import javax.swing.JLabel; @@ -87,11 +88,9 @@ public class StyledLabel extends JLabel { private void checkPreferredSize(float size, Style style) { String str = this.getText(); - if (str.startsWith("") && str.indexOf("") && !str.contains(" listeners) { + private ComponentConfigDialog(Window parent, OpenRocketDocument document, RocketComponent component) { super(parent); this.parent = parent; @@ -63,21 +64,15 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis configurator.invalidate(); document.getRocket().removeComponentChangeListener(ComponentConfigDialog.this); ComponentConfigDialog.this.dispose(); - component.clearConfigListeners(); + if (clearConfigListeners) { + component.clearConfigListeners(); + } } - - public void windowClosing(WindowEvent e){} @Override public void windowOpened(WindowEvent e) { super.windowOpened(e); - // Add config listeners - component.clearConfigListeners(); - if (listeners != null) { - for (RocketComponent listener : listeners) { - component.addConfigListener(listener); - } - } + clearConfigListeners = true; } }); } @@ -104,7 +99,17 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis configurator.updateFields(); //// configuration - setTitle(trans.get("ComponentCfgDlg.configuration1") + " " + component.getComponentName() + " " + trans.get("ComponentCfgDlg.configuration")); + List listeners = component.getConfigListeners(); + if (component.checkAllClassesEqual(listeners)) { + if (listeners != null && listeners.size() > 0) { + setTitle("(" + trans.get("ComponentCfgDlg.MultiComponent") + ") " + + component.getComponentName() + " " + trans.get("ComponentCfgDlg.configuration")); + } else { + setTitle(component.getComponentName() + " " + trans.get("ComponentCfgDlg.configuration")); + } + } else { + setTitle(trans.get("ComponentCfgDlg.MultiComponentConfig")); + } this.pack(); } @@ -118,14 +123,18 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis * Return the configurator panel of the current component. */ private RocketComponentConfig getDialogContents() { - Constructor c = + List listeners = component.getConfigListeners(); + boolean isSameClass = component.checkAllClassesEqual(listeners); + if (!isSameClass) { + return new RocketComponentConfig(document, component); + } + + Constructor constructor = findDialogContentsConstructor(component); - if (c != null) { + if (constructor != null) { try { - return c.newInstance(document, component); - } catch (InstantiationException e) { - throw new BugException("BUG in constructor reflection", e); - } catch (IllegalAccessException e) { + return constructor.newInstance(document, component); + } catch (InstantiationException | IllegalAccessException e) { throw new BugException("BUG in constructor reflection", e); } catch (InvocationTargetException e) { throw Reflection.handleWrappedException(e); @@ -196,48 +205,35 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis ////////// Static dialog ///////// - + /** * A singleton configuration dialog. Will create and show a new dialog if one has not * previously been used, or update the dialog and show it if a previous one exists. * * @param document the document to configure. * @param component the component to configure. - * @param listeners config listeners for the component */ public static void showDialog(Window parent, OpenRocketDocument document, - RocketComponent component, List listeners) { - if (dialog != null) + RocketComponent component) { + if (dialog != null) { + // If the component is the same as the ComponentConfigDialog component, and the dialog is still visible, + // that means that the user did a ctr/cmd click on a new component => don't remove the config listeners of component + if (component.equals(ComponentConfigDialog.component)) { + ComponentConfigDialog.clearConfigListeners = false; + } dialog.dispose(); + } - dialog = new ComponentConfigDialog(parent, document, component, listeners); + dialog = new ComponentConfigDialog(parent, document, component); dialog.setVisible(true); ////Modify document.addUndoPosition(trans.get("ComponentCfgDlg.Modify") + " " + component.getComponentName()); } - /** - * A singleton configuration dialog. Will create and show a new dialog if one has not - * previously been used, or update the dialog and show it if a previous one exists. - * - * @param document the document to configure. - * @param component the component to configure. - */ - public static void showDialog(Window parent, OpenRocketDocument document, - RocketComponent component) { - ComponentConfigDialog.showDialog(parent, document, component, null); - } - - - /* package */ - static void showDialog(RocketComponent component, List listeners) { - showDialog(dialog.parent, dialog.document, component, listeners); - } - /* package */ static void showDialog(RocketComponent component) { - ComponentConfigDialog.showDialog(component, null); + ComponentConfigDialog.showDialog(dialog.parent, dialog.document, component); } /** diff --git a/swing/src/net/sf/openrocket/gui/configdialog/FinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/FinSetConfig.java index 06dee6dc5..e5470185e 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/FinSetConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/FinSetConfig.java @@ -82,17 +82,10 @@ public abstract class FinSetConfig extends RocketComponentConfig { //// Convert fin set document.addUndoPosition(trans.get("FinSetConfig.Convertfinset")); - List listeners = new ArrayList<>(); - for (RocketComponent listener : component.getConfigListeners()) { - if (listener instanceof FinSet) { - listeners.add(FreeformFinSet.convertFinSet((FinSet) listener)); - } - } - RocketComponent freeform = FreeformFinSet.convertFinSet((FinSet) component); - ComponentConfigDialog.showDialog(freeform, listeners); + ComponentConfigDialog.showDialog(freeform); } }); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java index 12ce67e1f..8185cde58 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java @@ -1,6 +1,7 @@ package net.sf.openrocket.gui.configdialog; +import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.event.*; @@ -39,7 +40,6 @@ import net.sf.openrocket.gui.widgets.SelectColorButton; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.material.Material; import net.sf.openrocket.preset.ComponentPreset; -import net.sf.openrocket.rocketcomponent.ComponentAssembly; import net.sf.openrocket.rocketcomponent.*; import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish; import net.sf.openrocket.rocketcomponent.position.AxialMethod; @@ -68,20 +68,39 @@ public class RocketComponentConfig extends JPanel { private JPanel buttonPanel; private JLabel infoLabel; - - + private StyledLabel multiCompEditLabel; + + private boolean allSameType; // Checks whether all listener components are of the same type as + private boolean allMassive; // Checks whether all listener components, and this component, are massive + public RocketComponentConfig(OpenRocketDocument document, RocketComponent component) { setLayout(new MigLayout("fill, gap 4!, ins panel", "[]:5[]", "[growprio 5]5![fill, grow, growprio 500]5![growprio 5]")); this.document = document; this.component = component; - + + // Check the listeners for the same type and massive status + allSameType = true; + allMassive = component.isMassive(); + List listeners = component.getConfigListeners(); + if (listeners != null && listeners.size() > 0) { + allSameType = component.checkAllClassesEqual(listeners); + if (allMassive) { // Only check if is already massive + for (RocketComponent listener : listeners) { + if (!listener.isMassive()) { + allMassive = false; + break; + } + } + } + } + //// Component name: JLabel label = new JLabel(trans.get("RocketCompCfg.lbl.Componentname")); //// The component name. label.setToolTipText(trans.get("RocketCompCfg.ttip.Thecomponentname")); this.add(label, "spanx, height 32!, split"); - + componentNameField = new JTextField(15); textFieldListener = new TextFieldListener(); componentNameField.addActionListener(textFieldListener); @@ -89,34 +108,38 @@ public class RocketComponentConfig extends JPanel { //// The component name. componentNameField.setToolTipText(trans.get("RocketCompCfg.ttip.Thecomponentname")); this.add(componentNameField, "growx"); - - if (component.getPresetType() != null) { + + if (allSameType && component.getPresetType() != null) { // If the component supports a preset, show the preset selection box. presetModel = new PresetModel(this, document, component); presetComboBox = new JComboBox(presetModel); presetComboBox.setEditable(false); this.add(presetComboBox, ""); } - - + tabbedPane = new JTabbedPane(); this.add(tabbedPane, "newline, span, growx, growy 100, wrap"); - + //// Override and Mass and CG override options tabbedPane.addTab(trans.get("RocketCompCfg.tab.Override"), null, overrideTab(), trans.get("RocketCompCfg.tab.MassandCGoverride")); - if (component.isMassive()) { + if (allMassive) { //// Appearance options tabbedPane.addTab(trans.get("RocketCompCfg.tab.Appearance"), null, new AppearancePanel(document, component), "Appearance Tool Tip"); } - + //// Comment and Specify a comment for the component tabbedPane.addTab(trans.get("RocketCompCfg.tab.Comment"), null, commentTab(), trans.get("RocketCompCfg.tab.Specifyacomment")); - + + // Set the default tab to 'Appearance' for a different-type multi-comp dialog (this is the most prominent use case) + if (listeners != null && listeners.size() > 0 && !allSameType) { + tabbedPane.setSelectedIndex(1); + } + addButtons(); - + updateFields(); } @@ -128,6 +151,12 @@ public class RocketComponentConfig extends JPanel { buttonPanel = new JPanel(new MigLayout("fillx, ins 5")); + //// Multi-comp edit label + multiCompEditLabel = new StyledLabel(" ", 0, Style.BOLD); + //multiCompEditLabel.setFontColor(new Color(0, 0, 239)); + multiCompEditLabel.setFontColor(new Color(170, 0, 100)); + buttonPanel.add(multiCompEditLabel, "split 2"); + //// Mass: infoLabel = new StyledLabel(" ", -1); buttonPanel.add(infoLabel, "growx"); @@ -159,16 +188,17 @@ public class RocketComponentConfig extends JPanel { public void updateFields() { // Component name componentNameField.setText(component.getName()); - + // Info label StringBuilder sb = new StringBuilder(); - - if (component.getPresetComponent() != null) { + + if (allSameType && component.getPresetComponent() != null) { ComponentPreset preset = component.getPresetComponent(); sb.append(preset.getManufacturer() + " " + preset.getPartNo() + " "); } - - if (component.isMassive()) { + + List listeners = component.getConfigListeners(); + if (allMassive && (listeners == null || listeners.size() == 0)) { // TODO: support aggregate mass display for current component and listeners? sb.append(trans.get("RocketCompCfg.lbl.Componentmass") + " "); sb.append(UnitGroup.UNITS_MASS.getDefaultUnit().toStringUnit( component.getComponentMass())); @@ -193,6 +223,24 @@ public class RocketComponentConfig extends JPanel { } else { infoLabel.setText(""); } + + // Multi-comp edit label + if (listeners != null && listeners.size() > 0) { + multiCompEditLabel.setText(trans.get("ComponentCfgDlg.MultiComponentEdit")); + + StringBuilder components = new StringBuilder(trans.get("ComponentCfgDlg.MultiComponentEdit.ttip")); + components.append(component.getName()).append(", "); + for (int i = 0; i < listeners.size(); i++) { + if (i < listeners.size() - 1) { + components.append(listeners.get(i).getName()).append(", "); + } else { + components.append(listeners.get(i).getName()); + } + } + multiCompEditLabel.setToolTipText(components.toString()); + } else { + multiCompEditLabel.setText(""); + } } diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java index 880713cfa..f90605c34 100644 --- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -333,16 +333,16 @@ public class BasicFrame extends JFrame { if (!ComponentConfigDialog.isDialogVisible()) return; + else + ComponentConfigDialog.disposeDialog(); + RocketComponent c = (RocketComponent) paths[0].getLastPathComponent(); - List listeners = new ArrayList<>(); + c.clearConfigListeners(); for (int i = 1; i < paths.length; i++) { RocketComponent listener = (RocketComponent) paths[i].getLastPathComponent(); - if (listener.getClass().equals(c.getClass())) { - listeners.add((RocketComponent) paths[i].getLastPathComponent()); - } + c.addConfigListener(listener); } - ComponentConfigDialog.showDialog(BasicFrame.this, - BasicFrame.this.document, c, listeners); + ComponentConfigDialog.showDialog(BasicFrame.this, BasicFrame.this.document, c); } }); @@ -1323,7 +1323,6 @@ public class BasicFrame extends JFrame { * * @param worker the OpenFileWorker that loads the file. * @param displayName the file name to display in dialogs. - * @param file the File to set the document to (may be null). * @param parent * @param openRocketConfigDialog if true, will open the configuration dialog of the rocket. This is useful for examples. * @return diff --git a/swing/src/net/sf/openrocket/gui/main/RocketActions.java b/swing/src/net/sf/openrocket/gui/main/RocketActions.java index e966061ec..3292af843 100644 --- a/swing/src/net/sf/openrocket/gui/main/RocketActions.java +++ b/swing/src/net/sf/openrocket/gui/main/RocketActions.java @@ -5,7 +5,6 @@ import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; @@ -879,16 +878,17 @@ public class RocketActions { List components = selectionModel.getSelectedComponents(); Simulation[] sims = selectionModel.getSelectedSimulations(); - if ((components != null) && (components.size() > 0) && checkAllClassesEqual(components)) { - // Do nothing if the config dialog is already visible + if ((components != null) && (components.size() > 0)) { if (ComponentConfigDialog.isDialogVisible()) - return; + ComponentConfigDialog.disposeDialog(); - List listeners = null; + RocketComponent component = components.get(0); if (components.size() > 1) { - listeners = components.subList(1, components.size()); + for (int i = 1; i < components.size(); i++) { + component.addConfigListener(components.get(i)); + } } - ComponentConfigDialog.showDialog(parentFrame, document, components.get(0), listeners); + ComponentConfigDialog.showDialog(parentFrame, document, component); } else if (sims != null && sims.length > 0 && (simulationPanel != null)) { simulationPanel.editSimulation(); } @@ -898,25 +898,7 @@ public class RocketActions { public void clipboardChanged() { List components = selectionModel.getSelectedComponents(); - this.setEnabled(checkAllClassesEqual(components) || isSimulationSelected()); - } - - /** - * Checks whether all components in the list have the same class - * @param components list to check - * @return true if all components are of the same class, false if not - */ - private boolean checkAllClassesEqual(List components) { - if (components == null || components.size() == 0) { - return false; - } - Class myClass = components.get(0).getClass(); - for (int i = 1; i < components.size(); i++) { - if (!components.get(i).getClass().equals(myClass)) { - return false; - } - } - return true; + this.setEnabled((components != null && components.size() > 0) || isSimulationSelected()); } }