diff --git a/core/src/main/java/info/openrocket/core/aerodynamics/AerodynamicForces.java b/core/src/main/java/info/openrocket/core/aerodynamics/AerodynamicForces.java
index 2aff94005..fd19e0f9f 100644
--- a/core/src/main/java/info/openrocket/core/aerodynamics/AerodynamicForces.java
+++ b/core/src/main/java/info/openrocket/core/aerodynamics/AerodynamicForces.java
@@ -234,6 +234,10 @@ public class AerodynamicForces implements Cloneable, Monitorable {
 		modID = new ModID();
 	}
 
+	/**
+	 * Get the drag coefficient <b>per instance</b>.
+	 * @return The drag coefficient.
+	 */
 	public double getCD() {
 		if (component == null)
 			return CD;
@@ -245,6 +249,10 @@ public class AerodynamicForces implements Cloneable, Monitorable {
 		return CD;
 	}
 
+	public double getCDTotal() {
+		return getCD() * component.getInstanceCount();
+	}
+
 	public void setPressureCD(double pressureCD) {
 		if (this.pressureCD == pressureCD)
 			return;
diff --git a/core/src/main/java/info/openrocket/core/componentanalysis/CADataType.java b/core/src/main/java/info/openrocket/core/componentanalysis/CADataType.java
index c18005a17..d6639f05e 100644
--- a/core/src/main/java/info/openrocket/core/componentanalysis/CADataType.java
+++ b/core/src/main/java/info/openrocket/core/componentanalysis/CADataType.java
@@ -39,8 +39,10 @@ public class CADataType implements Comparable<CADataType>, Groupable<CADataTypeG
 			"CD,base", UnitGroup.UNITS_NONE, CADataTypeGroup.DRAG, 21);
 	public static final CADataType FRICTION_CD = new CADataType(trans.get("ComponentAnalysisGeneralTab.dragTableModel.Col.friction"),
 			"CD,friction", UnitGroup.UNITS_NONE, CADataTypeGroup.DRAG, 22);
+	public static final CADataType PER_INSTANCE_CD = new CADataType(trans.get("ComponentAnalysisGeneralTab.dragTableModel.Col.perInstance"),
+			"CD,instance", UnitGroup.UNITS_NONE, CADataTypeGroup.DRAG, 23);
 	public static final CADataType TOTAL_CD = new CADataType(trans.get("ComponentAnalysisGeneralTab.dragTableModel.Col.total"),
-			"CD,total", UnitGroup.UNITS_NONE, CADataTypeGroup.DRAG, 23);
+			"CD,total", UnitGroup.UNITS_NONE, CADataTypeGroup.DRAG, 24);
 
 	//// Roll
 	public static final CADataType ROLL_FORCING_COEFFICIENT = new CADataType(trans.get("ComponentAnalysisGeneralTab.rollTableModel.Col.rollforc"),
@@ -53,7 +55,7 @@ public class CADataType implements Comparable<CADataType>, Groupable<CADataTypeG
 
 	public static final CADataType[] ALL_TYPES = {
 			CP_X, CNa,
-			PRESSURE_CD, BASE_CD, FRICTION_CD, TOTAL_CD,
+			PRESSURE_CD, BASE_CD, FRICTION_CD, PER_INSTANCE_CD, TOTAL_CD,
 			ROLL_FORCING_COEFFICIENT, ROLL_DAMPING_COEFFICIENT, TOTAL_ROLL_COEFFICIENT
 	};
 
@@ -124,9 +126,14 @@ public class CADataType implements Comparable<CADataType>, Groupable<CADataTypeG
 			return false;
 		}
 
+		// Doesn't make sense to calculate per-instance drag for rockets
+		if (component instanceof Rocket && type.equals(CADataType.PER_INSTANCE_CD)) {
+			return false;
+		}
+
 		if (type.equals(CADataType.CP_X) || type.equals(CADataType.CNa) ||
 				type.equals(CADataType.PRESSURE_CD) || type.equals(CADataType.BASE_CD) ||
-				type.equals(CADataType.FRICTION_CD) || type.equals(CADataType.TOTAL_CD)) {
+				type.equals(CADataType.FRICTION_CD) || type.equals(CADataType.PER_INSTANCE_CD) || type.equals(CADataType.TOTAL_CD)) {
 			return true;
 		} else if (type.equals(CADataType.ROLL_FORCING_COEFFICIENT) || type.equals(CADataType.ROLL_DAMPING_COEFFICIENT) ||
 				type.equals(CADataType.TOTAL_ROLL_COEFFICIENT)) {
diff --git a/core/src/main/java/info/openrocket/core/componentanalysis/CAParameterSweep.java b/core/src/main/java/info/openrocket/core/componentanalysis/CAParameterSweep.java
index 24ed95f18..13c956fe3 100644
--- a/core/src/main/java/info/openrocket/core/componentanalysis/CAParameterSweep.java
+++ b/core/src/main/java/info/openrocket/core/componentanalysis/CAParameterSweep.java
@@ -129,7 +129,8 @@ public class CAParameterSweep {
 				dataBranch.setValue(CADataType.PRESSURE_CD, component, forces.getPressureCD());
 				dataBranch.setValue(CADataType.BASE_CD, component, forces.getBaseCD());
 				dataBranch.setValue(CADataType.FRICTION_CD, component, forces.getFrictionCD());
-				dataBranch.setValue(CADataType.TOTAL_CD, component, forces.getCD());
+				dataBranch.setValue(CADataType.PER_INSTANCE_CD, component, forces.getCD());
+				dataBranch.setValue(CADataType.TOTAL_CD, component, forces.getCDTotal());
 			}
 
 			if (component instanceof FinSet) {
@@ -154,7 +155,8 @@ public class CAParameterSweep {
 			dataBranch.setValue(CADataType.PRESSURE_CD, rocket, totalForces.getPressureCD());
 			dataBranch.setValue(CADataType.BASE_CD, rocket, totalForces.getBaseCD());
 			dataBranch.setValue(CADataType.FRICTION_CD, rocket, totalForces.getFrictionCD());
-			dataBranch.setValue(CADataType.TOTAL_CD, rocket, totalForces.getCD());
+			dataBranch.setValue(CADataType.PER_INSTANCE_CD, rocket, totalForces.getCD());
+			dataBranch.setValue(CADataType.TOTAL_CD, rocket, totalForces.getCDTotal());
 		}
 	}
 
diff --git a/core/src/main/resources/l10n/messages.properties b/core/src/main/resources/l10n/messages.properties
index b684653bc..41229c7c3 100644
--- a/core/src/main/resources/l10n/messages.properties
+++ b/core/src/main/resources/l10n/messages.properties
@@ -940,6 +940,7 @@ ComponentAnalysisGeneralTab.dragTableModel.Col.Component = Component
 ComponentAnalysisGeneralTab.dragTableModel.Col.Pressure = <html>Pressure C<sub>D</sub>
 ComponentAnalysisGeneralTab.dragTableModel.Col.Base = <html>Base C<sub>D</sub>
 ComponentAnalysisGeneralTab.dragTableModel.Col.friction = <html>Friction C<sub>D</sub>
+ComponentAnalysisGeneralTab.dragTableModel.Col.perInstance = <html>Per instance C<sub>D</sub>
 ComponentAnalysisGeneralTab.dragTableModel.Col.total = <html>Total C<sub>D</sub>
 ComponentAnalysisGeneralTab.dragTabchar = Drag characteristics
 ComponentAnalysisGeneralTab.dragTabchar.ttip = Drag characteristics
diff --git a/swing/src/main/java/info/openrocket/swing/gui/dialogs/componentanalysis/CAPlotTypeSelector.java b/swing/src/main/java/info/openrocket/swing/gui/dialogs/componentanalysis/CAPlotTypeSelector.java
index 9eb4c1bf6..f860750e9 100644
--- a/swing/src/main/java/info/openrocket/swing/gui/dialogs/componentanalysis/CAPlotTypeSelector.java
+++ b/swing/src/main/java/info/openrocket/swing/gui/dialogs/componentanalysis/CAPlotTypeSelector.java
@@ -33,7 +33,7 @@ public class CAPlotTypeSelector extends PlotTypeSelector<CADataType, CADataTypeG
 		componentSelector = new JComboBox<>(componentsForType.toArray(new RocketComponent[0]));
 		componentSelector.setSelectedItem(selectedComponent);
 		configuration.setPlotDataComponent(plotIndex, selectedComponent);
-		this.add(componentSelector, "gapright para");
+		this.add(componentSelector, "growx, gapright para");
 
 		addRemoveButton();
 
diff --git a/swing/src/main/java/info/openrocket/swing/gui/dialogs/componentanalysis/ComponentAnalysisGeneralPanel.java b/swing/src/main/java/info/openrocket/swing/gui/dialogs/componentanalysis/ComponentAnalysisGeneralPanel.java
index 0687eeb28..0e7feb1da 100644
--- a/swing/src/main/java/info/openrocket/swing/gui/dialogs/componentanalysis/ComponentAnalysisGeneralPanel.java
+++ b/swing/src/main/java/info/openrocket/swing/gui/dialogs/componentanalysis/ComponentAnalysisGeneralPanel.java
@@ -38,6 +38,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.swing.BorderFactory;
+import javax.swing.JComponent;
 import javax.swing.JLabel;
 import javax.swing.JList;
 import javax.swing.JPanel;
@@ -50,11 +51,19 @@ import javax.swing.SwingConstants;
 import javax.swing.UIManager;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.plaf.LabelUI;
+import javax.swing.plaf.basic.BasicLabelUI;
 import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableModel;
+import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
 import java.awt.Window;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -112,8 +121,6 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 		this.theta = new DoubleModel(parameters, "Theta", UnitGroup.UNITS_ANGLE, 0, 2 * Math.PI);
 		this.roll = new DoubleModel(parameters, "RollRate", UnitGroup.UNITS_ROLL);
 
-		JTable table;
-
 		//// Wind direction:
 		this.add(new JLabel(trans.get("ComponentAnalysisGeneralTab.lbl.winddir")));
 		EditableSpinner spinner = new EditableSpinner(theta.getSpinnerModel());
@@ -200,7 +207,7 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 
 
 		// Create the Longitudinal Stability (CM vs CP) data table
-		this.longitudeStabilityTableModel = new ColumnTableModel(
+		this.longitudeStabilityTableModel = new CAColumnTableModel(
 
 				//// Component
 				new Column(trans.get("ComponentAnalysisGeneralTab.TabStability.Col.Component")) {
@@ -267,15 +274,24 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 			public int getRowCount() {
 				return stabData.size();
 			}
+
+			@Override
+			public RocketComponent getComponentForRow(int row) {
+				if (row < 0 || row >= getRowCount()) {
+					return null;
+				}
+				Object source = stabData.get(row).source;
+				return source instanceof RocketComponent ? (RocketComponent) source : null;
+			}
 		};
 
-		table = new ColumnTable(longitudeStabilityTableModel);
-		table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-		this.longitudeStabilityTableModel.setColumnWidths(table.getColumnModel());
+		final JTable stabilityTable = new ColumnTable(longitudeStabilityTableModel);
+		stabilityTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+		this.longitudeStabilityTableModel.setColumnWidths(stabilityTable.getColumnModel());
 
-		table.setDefaultRenderer(Object.class, new StabilityCellRenderer());
+		stabilityTable.setDefaultRenderer(Object.class, new StabilityCellRenderer());
 
-		JScrollPane scrollpane = new JScrollPane(table);
+		JScrollPane scrollpane = new JScrollPane(stabilityTable);
 		scrollpane.setPreferredSize(new Dimension(600, 200));
 
 		//// Stability and Stability information
@@ -285,7 +301,7 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 
 
 		// Create the drag data table
-		this.dragTableModel = new ColumnTableModel(
+		this.dragTableModel = new CAColumnTableModel(
 				//// Component
 				new Column(trans.get("ComponentAnalysisGeneralTab.dragTableModel.Col.Component")) {
 					@Override
@@ -323,11 +339,18 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 						return dragData.get(row).getFrictionCD();
 					}
 				},
+				//// <html>Per instance C<sub>D</sub>
+				new Column(trans.get("ComponentAnalysisGeneralTab.dragTableModel.Col.perInstance")) {
+					@Override
+					public Object getValueAt(int row) {
+						return dragData.get(row).getCD();
+					}
+				},
 				//// <html>Total C<sub>D</sub>
 				new Column(trans.get("ComponentAnalysisGeneralTab.dragTableModel.Col.total")) {
 					@Override
 					public Object getValueAt(int row) {
-						return dragData.get(row).getCD();
+						return dragData.get(row).getCDTotal();
 					}
 				}
 		) {
@@ -340,16 +363,24 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 			public int getRowCount() {
 				return dragData.size();
 			}
+
+			@Override
+			public RocketComponent getComponentForRow(int row) {
+				if (row < 0 || row >= getRowCount()) {
+					return null;
+				}
+				return dragData.get(row).getComponent();
+			}
 		};
 
 
-		table = new JTable(dragTableModel);
-		table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-		this.dragTableModel.setColumnWidths(table.getColumnModel());
+		final JTable dragTable = new JTable(dragTableModel);
+		dragTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+		this.dragTableModel.setColumnWidths(dragTable.getColumnModel());
 
-		table.setDefaultRenderer(Object.class, new DragCellRenderer());
+		dragTable.setDefaultRenderer(Object.class, new DragCellRenderer());
 
-		scrollpane = new JScrollPane(table);
+		scrollpane = new JScrollPane(dragTable);
 		scrollpane.setPreferredSize(new Dimension(600, 200));
 
 		//// Drag characteristics and Drag characteristics tooltip
@@ -360,7 +391,7 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 
 
 		// Create the roll data table
-		this.rollTableModel = new ColumnTableModel(
+		this.rollTableModel = new CAColumnTableModel(
 				//// Component
 				new Column(trans.get("ComponentAnalysisGeneralTab.rollTableModel.Col.component")) {
 					@Override
@@ -403,14 +434,22 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 			public int getRowCount() {
 				return rollData.size();
 			}
+
+			@Override
+			public RocketComponent getComponentForRow(int row) {
+				if (row < 0 || row >= getRowCount()) {
+					return null;
+				}
+				return rollData.get(row).getComponent();
+			}
 		};
 
 
-		table = new JTable(rollTableModel);
-		table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-		table.setDefaultRenderer(Object.class, new RollDynamicsCellRenderer());
+		final JTable rollTable = new JTable(rollTableModel);
+		rollTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+		rollTable.setDefaultRenderer(Object.class, new RollDynamicsCellRenderer());
 
-		scrollpane = new JScrollPane(table);
+		scrollpane = new JScrollPane(rollTable);
 		scrollpane.setPreferredSize(new Dimension(600, 200));
 
 		//// Roll dynamics and Roll dynamics tooltip
@@ -459,6 +498,11 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 		this.roll.addChangeListener(this);
 		this.stateChanged(null);
 
+		// Add listeners to highlight the selected component in the rocket panel
+		stabilityTable.getSelectionModel().addListSelectionListener(new CAListSelectionListener(rocketPanel, stabilityTable));
+		dragTable.getSelectionModel().addListSelectionListener(new CAListSelectionListener(rocketPanel, dragTable));
+		rollTable.getSelectionModel().addListSelectionListener(new CAListSelectionListener(rocketPanel, rollTable));
+
 		// Remove listeners when closing window
 		parent.addWindowListener(new WindowAdapter() {
 			@Override
@@ -635,7 +679,8 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 		private final List<?> data;
 		protected final int decimalPlaces;
 
-		private static Color backgroundColor;
+		protected static Color backgroundColor;
+		protected static Color foregroundColor;
 
 		static {
 			initColors();
@@ -656,6 +701,7 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 
 		private static void updateColors() {
 			backgroundColor = GUIUtil.getUITheme().getBackgroundColor();
+			foregroundColor = GUIUtil.getUITheme().getTextColor();
 		}
 
 		@Override
@@ -717,9 +763,13 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 
 	private class DragCellRenderer extends CustomCellRenderer {
 		private static final long serialVersionUID = 1L;
+		private final StripedLabelUI stripedUI;
+		private final LabelUI defaultUI;
 
 		public DragCellRenderer() {
 			super(dragData, 3);
+			this.stripedUI = new StripedLabelUI(1, 12);
+			this.defaultUI = new BasicLabelUI();
 		}
 
 		@Override
@@ -727,22 +777,53 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 													   boolean isSelected, boolean hasFocus, int row, int column) {
 			JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
 
-			if (!isSelected && (value instanceof Double)) {
-				double cd = (Double) value;
-				float r = (float) (cd / 1.5);
+			// Reset to default UI
+			label.setUI(defaultUI);
 
-				float hue = MathUtil.clamp(0.3333f * (1 - 2.0f * r), 0, 0.3333f);
-				float sat = MathUtil.clamp(0.8f * r + 0.1f * (1 - r), 0, 1);
-				float val = 1.0f;
+			// Handle selection coloring
+			if (isSelected) {
+				label.setBackground(table.getSelectionBackground());
+				label.setForeground(table.getSelectionForeground());
+				label.setOpaque(true);
+			} else {
+				// Non-selected styling
+				if (value instanceof Double) {
+					double cd = (Double) value;
+					float r = (float) (cd / 1.5);
 
-				label.setBackground(Color.getHSBColor(hue, sat, val));
-				label.setForeground(Color.BLACK);
+					float hue = MathUtil.clamp(0.3333f * (1 - 2.0f * r), 0, 0.3333f);
+					float sat = MathUtil.clamp(0.8f * r + 0.1f * (1 - r), 0, 1);
+					float val = 1.0f;
+
+					label.setBackground(Color.getHSBColor(hue, sat, val));
+					label.setForeground(Color.BLACK);
+				} else {
+					label.setBackground(table.getBackground());
+					label.setForeground(table.getForeground());
+				}
+				label.setOpaque(true);
 			}
 
-			if ((row < 0) || (row >= dragData.size()))
-				return label;
+			// Special handling for column 4
+			if (column == 4) {
+				if (row == 0) {
+					label.setText("");
+					label.setUI(stripedUI);
+					if (!isSelected) {
+						label.setBackground(table.getBackground());
+						label.setForeground(table.getForeground());
+					}
+				} else {
+					label.setText(decimalFormat(dragData.get(row).getCD()));
+				}
+			}
 
-			if ((dragData.get(row).getComponent() instanceof Rocket) || (column == 4)) {
+			// Set font
+			if ((row < 0) || (row >= dragData.size())) {
+				return label;
+			}
+
+			if ((dragData.get(row).getComponent() instanceof Rocket) || (column == 5)) {
 				label.setFont(boldFont);
 			} else {
 				label.setFont(normalFont);
@@ -755,10 +836,46 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 		protected String formatDouble(Double cd) {
 			final double totalCD = dragData.get(0).getCD();
 
-			DecimalFormat df = new DecimalFormat("0." + "#".repeat(Math.max(0, decimalPlaces)));
-			String cdFormatted = df.format(cd);
+			String cdFormatted = decimalFormat(cd);
 			return String.format(cdFormatted + "  (%.0f%%)", 100 * cd / totalCD);
 		}
+
+		private String decimalFormat(Double cd) {
+			DecimalFormat df = new DecimalFormat("0." + "#".repeat(Math.max(0, decimalPlaces)));
+			return df.format(cd);
+		}
+
+		private static class StripedLabelUI extends BasicLabelUI {
+			private final int lineWidth;
+			private final int lineSpacing;
+
+			public StripedLabelUI(int lineWidth, int lineSpacing) {
+				this.lineWidth = lineWidth;
+				this.lineSpacing = lineSpacing;
+			}
+
+			@Override
+			public void paint(Graphics g, JComponent c) {
+				Graphics2D g2d = (Graphics2D) g.create();
+				int width = c.getWidth();
+				int height = c.getHeight();
+
+				// Paint background
+				g2d.setColor(c.getBackground());
+				g2d.fillRect(0, 0, width, height);
+
+				// Paint thin lines
+				g2d.setColor(c.getForeground());
+				g2d.setStroke(new BasicStroke(lineWidth));
+				for (int x = -height; x < width; x += (lineWidth + lineSpacing)) {
+					g2d.drawLine(x, height, x + height, 0);
+				}
+
+				g2d.dispose();
+
+				super.paint(g, c);
+			}
+		}
 	}
 
 	private class RollDynamicsCellRenderer extends CustomCellRenderer {
@@ -767,8 +884,7 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 		}
 	}
 
-	private class LongitudinalStabilityRow {
-
+	private static class LongitudinalStabilityRow {
 		public String name;
 		public Object source;
 		public double eachMass;
@@ -784,6 +900,34 @@ public class ComponentAnalysisGeneralPanel extends JPanel implements StateChange
 			cpx = Double.NaN;
 			cna = Double.NaN;
 		}
+	}
 
+	private abstract static class CAColumnTableModel extends ColumnTableModel {
+		public CAColumnTableModel(Column... columns) {
+			super(columns);
+		}
+
+		public RocketComponent getComponentForRow(int row) {
+			throw new RuntimeException("Not implemented");
+		}
+	}
+
+	private static class CAListSelectionListener implements ListSelectionListener {
+		private final RocketPanel rocketPanel;
+		private final JTable table;
+
+		public CAListSelectionListener(RocketPanel rocketPanel, JTable table) {
+			this.rocketPanel = rocketPanel;
+			this.table = table;
+		}
+
+		@Override
+		public void valueChanged(ListSelectionEvent e) {
+			TableModel model = table.getModel();
+			if (model instanceof CAColumnTableModel) {
+				RocketComponent component = ((CAColumnTableModel) model).getComponentForRow(table.getSelectedRow());
+				rocketPanel.setSelectedComponent(component);
+			}
+		}
 	}
 }
diff --git a/swing/src/main/java/info/openrocket/swing/gui/scalefigure/RocketPanel.java b/swing/src/main/java/info/openrocket/swing/gui/scalefigure/RocketPanel.java
index 92a2f49db..cde27850a 100644
--- a/swing/src/main/java/info/openrocket/swing/gui/scalefigure/RocketPanel.java
+++ b/swing/src/main/java/info/openrocket/swing/gui/scalefigure/RocketPanel.java
@@ -541,6 +541,15 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
 		valueChanged((TreeSelectionEvent) null); // updates FigureParameters
 	}
 
+	public void setSelectedComponent(RocketComponent component) {
+		if (component == null) {
+			selectionModel.setSelectionPath(null);
+			return;
+		}
+		TreePath path = ComponentTreeModel.makeTreePath(component);
+		selectionModel.setSelectionPath(path);
+	}
+
 	/**
 	 * Return the angle of attack used in CP calculation.  NaN signifies the default value
 	 * of zero.
@@ -672,8 +681,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
 			if (newClick) {
 				for (RocketComponent rocketComponent : clicked) {
 					if (!selectedComponents.contains(rocketComponent)) {
-						TreePath path = ComponentTreeModel.makeTreePath(rocketComponent);
-						selectionModel.setSelectionPath(path);
+						setSelectedComponent(rocketComponent);
 					}
 				}
 			}
diff --git a/swing/src/main/java/info/openrocket/swing/gui/widgets/GroupableAndSearchableComboBox.java b/swing/src/main/java/info/openrocket/swing/gui/widgets/GroupableAndSearchableComboBox.java
index 66c74cc3f..59a5a66b0 100644
--- a/swing/src/main/java/info/openrocket/swing/gui/widgets/GroupableAndSearchableComboBox.java
+++ b/swing/src/main/java/info/openrocket/swing/gui/widgets/GroupableAndSearchableComboBox.java
@@ -130,20 +130,34 @@ public class GroupableAndSearchableComboBox<G extends Group, T extends Groupable
 	}
 
 	private Map<G, List<T>> constructItemGroupMapFromList(List<T> items) {
-		Map<G, List<T>> itemGroupMap = new TreeMap<>(new Comparator<G>() {
-			@Override
-			public int compare(G g1, G g2) {
-				return Integer.compare(g1.getPriority(), g2.getPriority());
-			}
-		});
+		Map<G, List<T>> itemGroupMap = new TreeMap<>(Comparator.comparing(Group::getPriority));
 
 		for (T item : items) {
 			G group = item.getGroup();
 			itemGroupMap.computeIfAbsent(group, k -> new ArrayList<>()).add(item);
 		}
+
+		// Sort items within each group
+		for (List<T> groupItems : itemGroupMap.values()) {
+			groupItems.sort(new ItemComparator());
+		}
+
 		return itemGroupMap;
 	}
 
+	private class ItemComparator implements Comparator<T> {
+		@Override
+		@SuppressWarnings("unchecked")
+		public int compare(T item1, T item2) {
+			if (item1 instanceof Comparable && item2 instanceof Comparable) {
+				return ((Comparable<T>) item1).compareTo(item2);
+			} else {
+				// Fall back to alphabetical sorting using the display string
+				return getDisplayString(item1).compareToIgnoreCase(getDisplayString(item2));
+			}
+		}
+	}
+
 	public void setupMainRenderer() {
 		setRenderer(new DefaultListCellRenderer() {
 			@Override