Performance improvements

This commit is contained in:
SiboVG 2024-08-09 05:14:37 +02:00
parent 9cde5c9766
commit aef972699a
45 changed files with 94 additions and 98 deletions

View File

@ -48,7 +48,7 @@ public class ExpressionBuilder {
for (String name : variables.getVariableNames()) {
function.append(name).append(',');
}
expression = function.deleteCharAt(function.length() - 1).toString() + ")=" + expression;
expression = function.deleteCharAt(function.length() - 1) + ")=" + expression;
}
// create the PostfixExpression and return it as a Calculable
PostfixExpression delegate = PostfixExpression.fromInfix(expression, customFunctions);

View File

@ -218,6 +218,6 @@ class Tokenizer {
}
tokens.add(lastToken);
}
return tokens.toArray(new Token[tokens.size()]);
return tokens.toArray(new Token[0]);
}
}

View File

@ -534,9 +534,9 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
// Correct body data in map
if (forceMap != null) {
for (RocketComponent c : forceMap.keySet()) {
if (c instanceof SymmetricComponent) {
forceMap.get(c).setFrictionCD(forceMap.get(c).getFrictionCD() * correction);
for (Map.Entry<RocketComponent, AerodynamicForces> entry : forceMap.entrySet()) {
if (entry.getKey() instanceof SymmetricComponent) {
entry.getValue().setFrictionCD(entry.getValue().getFrictionCD() * correction);
}
}
}

View File

@ -134,7 +134,7 @@ public abstract class AbstractMotorLoader implements MotorLoader {
*/
protected static String[] split(String str, String delim) {
String[] pieces = str.split(delim);
if (pieces.length == 0 || !pieces[0].equals(""))
if (pieces.length == 0 || !pieces[0].isEmpty())
return pieces;
return ArrayUtils.copyOfRange(pieces, 1, pieces.length);
}

View File

@ -47,7 +47,7 @@ class ColorSetter implements Setter {
ORColor color = new ORColor(r, g, b);
setMethod.invoke(c, color);
if (!s.trim().equals("")) {
if (!s.trim().isEmpty()) {
warnings.add(Warning.FILE_INVALID_PARAMETER);
}
}

View File

@ -28,7 +28,7 @@ class MaterialSetter implements Setter {
// Check name != ""
name = name.trim();
if (name.equals("")) {
if (name.isEmpty()) {
warnings.add(Warning.fromString("Illegal material specification, ignoring."));
return;
}

View File

@ -1,6 +1,7 @@
package info.openrocket.core.file.openrocket.importt;
import java.util.HashMap;
import java.util.Map;
import org.xml.sax.SAXException;
@ -69,8 +70,8 @@ class MotorConfigurationHandler extends AbstractElementHandler {
rocket.getFlightConfiguration(fcid).setName(name);
}
for (int stageNr : stageActiveness.keySet()) {
rocket.getFlightConfiguration(fcid).preloadStageActiveness(stageNr, stageActiveness.get(stageNr));
for (Map.Entry<Integer, Boolean> entry : stageActiveness.entrySet()) {
rocket.getFlightConfiguration(fcid).preloadStageActiveness(entry.getKey(), entry.getValue());
}
if ("true".equals(attributes.remove("default"))) {

View File

@ -72,7 +72,7 @@ public class OpenRocketHandler extends AbstractElementHandler {
String str = "Unsupported document version";
if (docVersion != null)
str += " " + docVersion;
if (creator != null && !creator.trim().equals(""))
if (creator != null && !creator.trim().isEmpty())
str += " (written using '" + creator.trim() + "')";
str += ", attempting to read file anyway.";
warnings.add(str);

View File

@ -75,10 +75,10 @@ public class RecoveryHandler extends AbstractElementHandler {
// Set the values of the recovery parameters
for (int i = 1; i <= NR_OF_RECOVERY_DEVICES; i++) {
for (String e : mapParametersToVars.keySet()) {
String key = e + i;
for (Map.Entry<String, Object[]> entry : mapParametersToVars.entrySet()) {
String key = entry.getKey() + i;
if (key.equals(element)) {
Object[] vars = mapParametersToVars.get(e);
Object[] vars = entry.getValue();
if (vars.length != NR_OF_RECOVERY_DEVICES) {
throw new IllegalArgumentException("Recovery var array length is not 2");
}

View File

@ -31,7 +31,7 @@ public abstract class AbstractElementHandler implements ElementHandler {
public void closeElement(String element, HashMap<String, String> attributes,
String content, WarningSet warnings) throws SAXException {
if (!content.trim().equals("")) {
if (!content.trim().isEmpty()) {
warnings.add(Warning.fromString("Unknown text in element '" + element
+ "', ignoring."));
}

View File

@ -5,6 +5,8 @@ import info.openrocket.core.rocketcomponent.FlightConfigurableParameterSet;
import info.openrocket.core.rocketcomponent.FlightConfigurationId;
import info.openrocket.core.rocketcomponent.MotorMount;
import java.util.Map;
/**
* FlightConfigurationSet for motors.
* This is used for motors, where the default value is always no motor.
@ -49,8 +51,9 @@ public class MotorConfigurationSet extends FlightConfigurableParameterSet<MotorC
buffer.append(String.format(" ====== Dumping MotorConfigurationSet: %d motors in %s ======\n",
this.size(), mnt.getDebugName()));
for (FlightConfigurationId loopFCID : this.map.keySet()) {
MotorConfiguration curConfig = this.map.get(loopFCID);
for (Map.Entry<FlightConfigurationId, MotorConfiguration> entry : this.map.entrySet()) {
FlightConfigurationId loopFCID = entry.getKey();
MotorConfiguration curConfig = entry.getValue();
if (this.isDefault(loopFCID)) {
buffer.append(" [DEF]");
} else {

View File

@ -246,14 +246,14 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
// If I don't have a motor designation (will be the case if I read the
// thrustcurve from a file)
// use the motor code
if (motor.designation.equals("")) {
if (motor.designation.isEmpty()) {
motor.designation = motor.code;
}
// If I don't have a motor common name (will be the case if I read the
// thrustcurve from a flle)
// apply the motor code simplification heuristics to generate a common name
if (motor.commonName.equals("")) {
if (motor.commonName.isEmpty()) {
motor.commonName = simplifyDesignation(motor.designation);
}

View File

@ -1,6 +1,7 @@
package info.openrocket.core.optimization.general;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@ -21,9 +22,7 @@ public class OptimizationControllerDelegator implements OptimizationController {
* @param controllers the controllers to use.
*/
public OptimizationControllerDelegator(OptimizationController... controllers) {
for (OptimizationController c : controllers) {
this.controllers.add(c);
}
this.controllers.addAll(Arrays.asList(controllers));
}
/**

View File

@ -29,7 +29,7 @@ public class DoubleUnitColumnParser extends BaseUnitColumnParser {
Unit unit = rocksimUnits.get(unitName);
if (unit == null) {
if (unitName == null || "".equals(unitName) || "?".equals(unitName)) {
if (unitName == null || unitName.isEmpty() || "?".equals(unitName)) {
// Hmm no data... Lets assume SI
if (propKey.getUnitGroup() == UnitGroup.UNITS_LENGTH) {
unit = UnitGroup.UNITS_LENGTH.getUnit("in");

View File

@ -49,7 +49,7 @@ public class ShapeColumnParser extends BaseColumnParser {
if ("0".equals(lc)) {
shape = Shape.CONICAL;
}
if ("".equals(lc)) {
if (lc.isEmpty()) {
shape = Shape.CONICAL;
}
if ("3".equals(lc)) {

View File

@ -3,6 +3,7 @@ package info.openrocket.core.rocketcomponent;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import info.openrocket.core.util.ArrayList;
@ -38,9 +39,9 @@ public class FlightConfigurableParameterSet<E extends FlightConfigurableParamete
* @param configSet the FlightConfigurableParameterSet to copy
*/
public FlightConfigurableParameterSet(FlightConfigurableParameterSet<E> configSet) {
for (FlightConfigurationId key : configSet.map.keySet()) {
E cloneConfig = configSet.map.get(key).clone();
this.map.put(key, cloneConfig);
for (Entry<FlightConfigurationId, E> entry : configSet.map.entrySet()) {
E cloneConfig = entry.getValue().clone();
this.map.put(entry.getKey(), cloneConfig);
}
}

View File

@ -313,8 +313,8 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
if (preloadStageActiveness == null) {
return;
}
for (int stageNumber : preloadStageActiveness.keySet()) {
_setStageActive(stageNumber, preloadStageActiveness.get(stageNumber), false);
for (Map.Entry<Integer, Boolean> entry : preloadStageActiveness.entrySet()) {
_setStageActive(entry.getKey(), entry.getValue(), false);
}
preloadStageActiveness.clear();
preloadStageActiveness = null;

View File

@ -36,7 +36,7 @@ public final class FlightConfigurationId implements Comparable<FlightConfigurati
*/
public FlightConfigurationId(final String _str) {
UUID candidate;
if (_str == null || "".equals(_str)) {
if (_str == null || _str.isEmpty()) {
candidate = UUID.randomUUID();
} else {
try {

View File

@ -114,9 +114,9 @@ public class FlightDataBranch implements Monitorable {
public void addPoint() {
mutable.check();
for (FlightDataType type : values.keySet()) {
sanityCheckValues(type, Double.NaN);
values.get(type).add(Double.NaN);
for (Map.Entry<FlightDataType, ArrayList<Double>> entry : values.entrySet()) {
sanityCheckValues(entry.getKey(), Double.NaN);
entry.getValue().add(Double.NaN);
}
modID = new ModID();
}
@ -249,8 +249,8 @@ public class FlightDataBranch implements Monitorable {
* Return the number of data points in this branch.
*/
public int getLength() {
for (FlightDataType t : values.keySet()) {
return values.get(t).size();
for (ArrayList<Double> doubles : values.values()) {
return doubles.size();
}
return 0;
}
@ -449,8 +449,8 @@ public class FlightDataBranch implements Monitorable {
public FlightDataBranch clone() {
FlightDataType[] types = getTypes();
FlightDataBranch clone = new FlightDataBranch(name, types);
for (FlightDataType type : values.keySet()) {
clone.values.put(type, values.get(type).clone());
for (Map.Entry<FlightDataType, ArrayList<Double>> entry : values.entrySet()) {
clone.values.put(entry.getKey(), entry.getValue().clone());
}
clone.minValues.putAll(minValues);
clone.maxValues.putAll(maxValues);

View File

@ -23,7 +23,7 @@ public class SearchRequest {
this.manufacturer = null;
if (manufacturer != null) {
manufacturer = manufacturer.trim();
if (!"".equals(manufacturer)) {
if (!manufacturer.isEmpty()) {
this.manufacturer = manufacturer;
}
}
@ -43,7 +43,7 @@ public class SearchRequest {
return;
}
this.common_name = common_name.trim();
if ("".equals(this.common_name)) {
if (this.common_name.isEmpty()) {
this.common_name = null;
}
}
@ -52,7 +52,7 @@ public class SearchRequest {
this.impulse_class = null;
if (impulse_class != null) {
this.impulse_class = impulse_class.trim();
if ("".equals(impulse_class)) {
if (impulse_class.isEmpty()) {
this.impulse_class = null;
}
}

View File

@ -758,7 +758,7 @@ public class UnitGroup {
double value = StringUtils.convertToDouble(matcher.group(1));
String unit = matcher.group(2).trim();
if (unit.equals("")) {
if (unit.isEmpty()) {
value = this.getDefaultUnit().fromUnit(value);
} else {
int i;

View File

@ -50,7 +50,7 @@ public class QuaternionMultiply {
for (int i = 0; i < arg.length; i++) {
Value value = new Value();
if (arg[i].equals("")) {
if (arg[i].isEmpty()) {
value.sign = 0;
} else {
if (arg[i].startsWith("-")) {

View File

@ -47,7 +47,7 @@ public class StringUtils {
if (s == null) {
return true;
}
return "".equals(s.trim());
return s.trim().isEmpty();
}
/**

View File

@ -88,8 +88,7 @@ public class Transformation implements java.io.Serializable {
*/
public Transformation(double[][] rotation, Coordinate translation) {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
this.rotation[i][j] = rotation[i][j];
System.arraycopy(rotation[i], 0, this.rotation[i], 0, 3);
this.translate = translation;
}
@ -101,8 +100,7 @@ public class Transformation implements java.io.Serializable {
*/
public Transformation(double[][] rotation) {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
this.rotation[i][j] = rotation[i][j];
System.arraycopy(rotation[i], 0, this.rotation[i], 0, 3);
this.translate = Coordinate.NUL;
}

View File

@ -1222,7 +1222,7 @@ public class FreeformFinSetTest extends BaseTestCase {
final Coordinate[] actualPoints = fin.getFinPoints();
final String rawPointDescr = "\n" + fin.toDebugDetail().toString() + "\n>> axial offset: " + x_delta;
final String rawPointDescr = "\n" + fin.toDebugDetail() + "\n>> axial offset: " + x_delta;
Coordinate[] displayPoints = FinSet.translatePoints(actualPoints, x_delta, 0);
for (int index = 0; index < displayPoints.length; ++index) {

View File

@ -57,9 +57,9 @@ public class AssetHandler {
if (urls == null) return null;
for (String url : urls) {
for (String ext : mapExtensionToPlatform.keySet()) {
if (url.endsWith(ext)) {
output.put(mapExtensionToPlatform.get(ext)[0], url); // First Platform element is enough
for (Map.Entry<String, UpdatePlatform[]> entry : mapExtensionToPlatform.entrySet()) {
if (url.endsWith(entry.getKey())) {
output.put(entry.getValue()[0], url); // First Platform element is enough
}
}
}
@ -73,10 +73,10 @@ public class AssetHandler {
* @return URL to download the installer for the given platform
*/
public static String getInstallerURLForPlatform(UpdatePlatform platform, String version) {
for (UpdatePlatform[] platforms : mapPlatformToURL.keySet()) {
for (UpdatePlatform p : platforms) {
for (Map.Entry<UpdatePlatform[], String> entry : mapPlatformToURL.entrySet()) {
for (UpdatePlatform p : entry.getKey()) {
if (p == platform) {
return String.format(mapPlatformToURL.get(platforms), version);
return String.format(entry.getValue(), version);
}
}
}

View File

@ -99,9 +99,7 @@ public final class MotorLoaderHelper {
log.debug("Loading motors from file " + input.getU());
try {
List<ThrustCurveMotor.Builder> motors = load(input.getV(), input.getU().getName());
for (ThrustCurveMotor.Builder m : motors) {
list.add(m);
}
list.addAll(motors);
} finally {
try {
input.getV().close();

View File

@ -36,8 +36,8 @@ public class PhotoStudioGetter {
public PhotoSettings getPhotoSettings() {
if (parameters != null) {
for (String element : parameters.keySet()) {
processElement(element, parameters.get(element));
for (Map.Entry<String, String> entry : parameters.entrySet()) {
processElement(entry.getKey(), entry.getValue());
}
}
return p;
@ -166,7 +166,7 @@ public class PhotoStudioGetter {
}
if ("sky".equals(element)) {
if (content.equals("")) { // Case where sky is null
if (content.isEmpty()) { // Case where sky is null
p.setSky(null);
return;
}

View File

@ -1,6 +1,7 @@
package info.openrocket.swing.gui.adaptors;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EventObject;
import javax.swing.AbstractListModel;
@ -65,10 +66,8 @@ public class EnumModel<T extends Enum<T>> extends AbstractListModel<T>
this.values = values;
else
this.values = (T[]) enumClass.getEnumConstants();
for (T e : this.values){
this.displayedValues.add( e );
}
this.displayedValues.addAll(Arrays.asList(this.values));
this.nullText = nullText;
stateChanged(null); // Update current value

View File

@ -366,7 +366,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
bufferHeader.append(table.getColumnName(j));
bufferHeader.append(", ");
}
writer.write(bufferHeader.toString() + "\r\n");
writer.write(bufferHeader + "\r\n");
//write row information
for (int i = 0; i < nRow; i++) {
@ -375,7 +375,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
buffer.append(table.getValueAt(i, j));
buffer.append(", ");
}
writer.write(buffer.toString() + "\r\n");
writer.write(buffer + "\r\n");
}
writer.close();

View File

@ -1025,8 +1025,7 @@ public class GeneralOptimizationDialog extends JDialog {
list.add(m);
}
for (Object key : simulationModifiers.keySet()) {
List<SimulationModifier> list = simulationModifiers.get(key);
for (List<SimulationModifier> list : simulationModifiers.values()) {
list.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
}

View File

@ -144,8 +144,8 @@ public class OptimizationPlotDialog extends JDialog {
// Create the optimization path (with autosort)
XYSeries series = new XYSeries(trans.get("plot1d.series"), true, true);
List<String> tooltips = new ArrayList<String>();
for (Point p : evaluations.keySet()) {
FunctionEvaluationData data = evaluations.get(p);
for (Map.Entry<Point, FunctionEvaluationData> entry : evaluations.entrySet()) {
FunctionEvaluationData data = entry.getValue();
if (data != null) {
if (data.getParameterValue() != null) {
Value[] state = data.getState();
@ -153,7 +153,7 @@ public class OptimizationPlotDialog extends JDialog {
tooltips.add(getTooltip(data, parameter));
}
} else {
log.error("Could not find evaluation data for point " + p);
log.error("Could not find evaluation data for point " + entry.getKey());
}
}

View File

@ -127,9 +127,7 @@ public class RealisticRenderer extends RocketRenderer {
gl.glLightModeli(GL2.GL_LIGHT_MODEL_COLOR_CONTROL, GL2.GL_SEPARATE_SPECULAR_COLOR);
float[] convertedColor = this.convertColor(a, alpha);
for (int i=0; i < convertedColor.length; i++) {
color[i] = convertedColor[i];
}
System.arraycopy(convertedColor, 0, color, 0, convertedColor.length);
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_DIFFUSE, color, 0);
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT, color, 0);

View File

@ -13,6 +13,7 @@ import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@ -600,8 +601,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
public void setSelection(final RocketComponent[] selection) {
this.selection.clear();
if (selection != null) {
for (RocketComponent c : selection)
this.selection.add(c);
this.selection.addAll(Arrays.asList(selection));
}
internalRepaint();
}

View File

@ -89,7 +89,7 @@ public class ComponentTreeTransferHandler extends TransferHandler {
}
}
log.info("Creating transferable from component " + sb.toString());
log.info("Creating transferable from component " + sb);
return new RocketComponentTransferable(components);
}

View File

@ -21,6 +21,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -453,7 +454,7 @@ public class SimulationPlot {
private void fillEventLists(int branch, List<Double> eventTimes, List<String> eventLabels,
List<Color> eventColors, List<Image> eventImages) {
HashSet<FlightEvent.Type> typeSet = new HashSet<>();
Set<FlightEvent.Type> typeSet = new HashSet<>();
double prevTime = -100;
String text = null;
Color color = null;

View File

@ -2192,10 +2192,10 @@ public class PresetEditorDialog extends JDialog implements ItemListener {
JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
return null;
}
if (!pcLineCount.getText().equals("")) {
if (!pcLineCount.getText().isEmpty()) {
props.put(ComponentPreset.LINE_COUNT, Integer.parseInt(pcLineCount.getText()));
}
if (!pcSides.getText().equals("")) {
if (!pcSides.getText().isEmpty()) {
props.put(ComponentPreset.SIDES, Integer.parseInt(pcSides.getText()));
}
props.put(ComponentPreset.LINE_LENGTH, pcLineLength.getValue());

View File

@ -668,7 +668,7 @@ public class DesignReport {
protected void runSimulations(List<Simulation> simulations) {
if (window != null) {
log.debug("Updating " + simulations.size() + "simulations using SimulationRunDialog");
Simulation[] runMe = simulations.toArray(new Simulation[simulations.size()]);
Simulation[] runMe = simulations.toArray(new Simulation[0]);
new SimulationRunDialog(window, rocketDocument, runMe).setVisible(true);
} else {
/* This code is left for compatibility with any developers who are

View File

@ -255,10 +255,10 @@ public class FinMarkingGuide extends JPanel {
int column = 0;
for (BodyTube next : markingGuideItems.keySet()) {
double circumferenceInPoints = PrintUnit.METERS.toPoints((next.getOuterRadius() + PAPER_THICKNESS_IN_METERS) *
for (Map.Entry<BodyTube, List<ExternalComponent>> entry : markingGuideItems.entrySet()) {
double circumferenceInPoints = PrintUnit.METERS.toPoints((entry.getKey().getOuterRadius() + PAPER_THICKNESS_IN_METERS) *
TWO_PI);
List<ExternalComponent> componentList = markingGuideItems.get(next);
List<ExternalComponent> componentList = entry.getValue();
//Don't draw the lug if there are no fins.
if (hasFins(componentList)) {
length = (int) Math.ceil(circumferenceInPoints);

View File

@ -134,7 +134,7 @@ public class CheckTreeSelectionModel extends DefaultTreeSelectionModel {
toBeRemoved.add(selectionPath);
}
}
super.removeSelectionPaths(toBeRemoved.toArray(new TreePath[toBeRemoved.size()]));
super.removeSelectionPaths(toBeRemoved.toArray(new TreePath[0]));
}
// if all siblings are selected then deselect them and select parent recursively

View File

@ -185,7 +185,7 @@ public class RocketPrintTree extends JTree {
INITIAL_CHECKBOX_SELECTED));
}
}
return nodes.toArray(new CheckBoxNode[nodes.size()]);
return nodes.toArray(new CheckBoxNode[0]);
}
/**

View File

@ -254,7 +254,7 @@ public class SimulationConfigDialog extends JDialog {
private void setText() {
String name = field.getText();
if (name == null || name.equals(""))
if (name == null || name.isEmpty())
return;
simulationList[0].setName(name);

View File

@ -16,6 +16,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
@ -677,12 +678,12 @@ public class SwingPreferences extends info.openrocket.core.startup.Preferences i
public void storeDefaultUnits() {
Preferences prefs = PREFNODE.node("units");
for (String key : UnitGroup.UNITS.keySet()) {
UnitGroup group = UnitGroup.UNITS.get(key);
for (Map.Entry<String, UnitGroup> entry : UnitGroup.UNITS.entrySet()) {
UnitGroup group = entry.getValue();
if (group == null || group.getUnitCount() < 2)
continue;
prefs.put(key, group.getDefaultUnit().getUnit());
prefs.put(entry.getKey(), group.getDefaultUnit().getUnit());
}
}

View File

@ -228,9 +228,7 @@ public class MultiSlider extends JSlider {
values[0] = getMinimum();
values[num_of_values - 1] = getMaximum();
int[] def = createDefaultValues(getMinimum(), getMaximum(), num_of_values - 2, false);
for (int i = 0; i < def.length; i++) {
values[i + 1] = def[i];
}
System.arraycopy(def, 0, values, 1, def.length);
}
return values;
}

View File

@ -151,8 +151,8 @@ public class SearchableAndCategorizableComboBox<E, T> extends JComboBox<T> {
private T[] extractItemsFromMap(Map<E, T[]> itemGroupMap) {
Set<T> uniqueItems = new HashSet<>(); // Use a Set to ensure uniqueness
for (E group : itemGroupMap.keySet()) {
uniqueItems.addAll(Arrays.asList(itemGroupMap.get(group)));
for (T[] ts : itemGroupMap.values()) {
uniqueItems.addAll(Arrays.asList(ts));
}
ArrayList<T> items = new ArrayList<>(uniqueItems);
return items.toArray((T[]) new Object[0]);
@ -166,9 +166,9 @@ public class SearchableAndCategorizableComboBox<E, T> extends JComboBox<T> {
menu.addSeparator(); // Separator between search field and menu items
// Fill the menu with the groups
for (E group : itemGroupMap.keySet()) {
JMenu groupList = new JMenu(group.toString());
T[] itemsForGroup = itemGroupMap.get(group);
for (Map.Entry<E, T[]> entry : itemGroupMap.entrySet()) {
JMenu groupList = new JMenu(entry.getKey().toString());
T[] itemsForGroup = entry.getValue();
if (itemsForGroup != null) {
for (T item : itemsForGroup) {