Construct itemGroup within SearchableAndCategorizableComboBox
This commit is contained in:
parent
354843deb9
commit
b0feb33459
@ -28,11 +28,7 @@ import java.awt.Component;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panel for configuring a component's material and finish properties.
|
* Panel for configuring a component's material and finish properties.
|
||||||
@ -63,11 +59,6 @@ public class MaterialPanel extends JPanel implements Invalidatable, Invalidating
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mm.addCustomMaterial();
|
mm.addCustomMaterial();
|
||||||
if (MaterialPanel.this.materialCombo != null) {
|
|
||||||
MaterialComboBox.updateComboBoxItems(MaterialPanel.this.materialCombo, MaterialGroup.ALL_GROUPS,
|
|
||||||
mm.getAllMaterials());
|
|
||||||
MaterialPanel.this.materialCombo.setSelectedItem(mm.getSelectedItem());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -89,8 +80,7 @@ public class MaterialPanel extends JPanel implements Invalidatable, Invalidating
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Material selection combo box
|
// Material selection combo box
|
||||||
this.materialCombo = MaterialComboBox.createComboBox(mm, MaterialGroup.ALL_GROUPS, mm.getAllMaterials(),
|
this.materialCombo = MaterialComboBox.createComboBox(mm, customMaterialButton, editMaterialsButton);
|
||||||
customMaterialButton, editMaterialsButton);
|
|
||||||
this.materialCombo.setSelectedItem(mm.getSelectedItem());
|
this.materialCombo.setSelectedItem(mm.getSelectedItem());
|
||||||
this.materialCombo.setToolTipText(trans.get("MaterialPanel.combo.ttip.ComponentMaterialAffects"));
|
this.materialCombo.setToolTipText(trans.get("MaterialPanel.combo.ttip.ComponentMaterialAffects"));
|
||||||
this.add(this.materialCombo, "spanx 4, growx, wrap paragraph");
|
this.add(this.materialCombo, "spanx 4, growx, wrap paragraph");
|
||||||
@ -171,10 +161,8 @@ public class MaterialPanel extends JPanel implements Invalidatable, Invalidating
|
|||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
public static SearchableAndCategorizableComboBox<MaterialGroup, Material> createComboBox(
|
public static SearchableAndCategorizableComboBox<MaterialGroup, Material> createComboBox(
|
||||||
MaterialModel mm, MaterialGroup[] allGroups, Material[] materials, Component... extraCategoryWidgets) {
|
MaterialModel mm, Component... extraCategoryWidgets) {
|
||||||
final Map<MaterialGroup, List<Material>> materialGroupMap =
|
return new SearchableAndCategorizableComboBox<>(mm,
|
||||||
createMaterialGroupMap(allGroups, materials);
|
|
||||||
return new SearchableAndCategorizableComboBox<>(mm, materialGroupMap,
|
|
||||||
trans.get("MaterialPanel.MaterialComboBox.placeholder"), extraCategoryWidgets) {
|
trans.get("MaterialPanel.MaterialComboBox.placeholder"), extraCategoryWidgets) {
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayString(Material item) {
|
public String getDisplayString(Material item) {
|
||||||
@ -186,47 +174,5 @@ public class MaterialPanel extends JPanel implements Invalidatable, Invalidating
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateComboBoxItems(SearchableAndCategorizableComboBox<MaterialGroup, Material> comboBox,
|
|
||||||
MaterialGroup[] allGroups, Material[] materials) {
|
|
||||||
final Map<MaterialGroup, List<Material>> materialGroupMap = createMaterialGroupMap(allGroups, materials);
|
|
||||||
comboBox.updateItems(materialGroupMap);
|
|
||||||
comboBox.invalidate();
|
|
||||||
comboBox.repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a map of material group and corresponding material.
|
|
||||||
* @param groups the groups
|
|
||||||
* @param materials the materials
|
|
||||||
* @return the map linking the materials to their groups
|
|
||||||
*/
|
|
||||||
private static Map<MaterialGroup, List<Material>> createMaterialGroupMap(
|
|
||||||
MaterialGroup[] groups, Material[] materials) {
|
|
||||||
// Sort the groups based on priority (lower number = higher priority)
|
|
||||||
MaterialGroup[] sortedGroups = groups.clone();
|
|
||||||
Arrays.sort(sortedGroups, Comparator.comparingInt(MaterialGroup::getPriority));
|
|
||||||
|
|
||||||
Map<MaterialGroup, List<Material>> map = new LinkedHashMap<>();
|
|
||||||
MaterialGroup materialGroup;
|
|
||||||
for (MaterialGroup group : sortedGroups) {
|
|
||||||
List<Material> itemsForGroup = new ArrayList<>();
|
|
||||||
for (Material material : materials) {
|
|
||||||
materialGroup = material.getGroup();
|
|
||||||
if (materialGroup.equals(group)) {
|
|
||||||
itemsForGroup.add(material);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Sort the types within each group based on priority
|
|
||||||
itemsForGroup.sort(Comparator.comparingInt(Material::getGroupPriority));
|
|
||||||
|
|
||||||
map.put(group, itemsForGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove empty groups
|
|
||||||
map.entrySet().removeIf(entry -> entry.getValue().isEmpty());
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,8 @@ import java.util.Map;
|
|||||||
public class FlightDataComboBox extends JComboBox<FlightDataType> {
|
public class FlightDataComboBox extends JComboBox<FlightDataType> {
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
public static SearchableAndCategorizableComboBox<FlightDataTypeGroup, FlightDataType> createComboBox(FlightDataTypeGroup[] allGroups, FlightDataType[] types) {
|
public static SearchableAndCategorizableComboBox<FlightDataTypeGroup, FlightDataType> createComboBox(List<FlightDataType> types) {
|
||||||
final Map<FlightDataTypeGroup, List<FlightDataType>> typeGroupMap = createFlightDataGroupMap(allGroups, types);
|
return new SearchableAndCategorizableComboBox<>(types, trans.get("FlightDataComboBox.placeholder"));
|
||||||
return new SearchableAndCategorizableComboBox<>(typeGroupMap, trans.get("FlightDataComboBox.placeholder"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,7 +173,7 @@ public class SimulationPlotPanel extends JPanel {
|
|||||||
|
|
||||||
//// X axis type:
|
//// X axis type:
|
||||||
this.add(new JLabel(trans.get("simplotpanel.lbl.Xaxistype")), "spanx, split");
|
this.add(new JLabel(trans.get("simplotpanel.lbl.Xaxistype")), "spanx, split");
|
||||||
domainTypeSelector = FlightDataComboBox.createComboBox(FlightDataTypeGroup.ALL_GROUPS, types);
|
domainTypeSelector = FlightDataComboBox.createComboBox(Arrays.asList(types));
|
||||||
domainTypeSelector.setSelectedItem(configuration.getDomainAxisType());
|
domainTypeSelector.setSelectedItem(configuration.getDomainAxisType());
|
||||||
domainTypeSelector.addItemListener(new ItemListener() {
|
domainTypeSelector.addItemListener(new ItemListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -497,7 +497,7 @@ public class SimulationPlotPanel extends JPanel {
|
|||||||
|
|
||||||
this.index = plotIndex;
|
this.index = plotIndex;
|
||||||
|
|
||||||
typeSelector = FlightDataComboBox.createComboBox(FlightDataTypeGroup.ALL_GROUPS, types);
|
typeSelector = FlightDataComboBox.createComboBox(Arrays.asList(types));
|
||||||
typeSelector.setSelectedItem(type);
|
typeSelector.setSelectedItem(type);
|
||||||
typeSelector.addItemListener(new ItemListener() {
|
typeSelector.addItemListener(new ItemListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -28,6 +28,8 @@ import java.awt.Component;
|
|||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.FocusAdapter;
|
import java.awt.event.FocusAdapter;
|
||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.KeyAdapter;
|
import java.awt.event.KeyAdapter;
|
||||||
@ -45,8 +47,10 @@ import java.util.Iterator;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeMap;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
@ -63,12 +67,12 @@ public class SearchableAndCategorizableComboBox<G extends Group, T extends Group
|
|||||||
private static final int CHECKMARK_X_OFFSET = 5;
|
private static final int CHECKMARK_X_OFFSET = 5;
|
||||||
private static final int CHECKMARK_Y_OFFSET = 5;
|
private static final int CHECKMARK_Y_OFFSET = 5;
|
||||||
|
|
||||||
private final String placeHolderText;
|
private String placeHolderText;
|
||||||
private JPopupMenu categoryPopup;
|
private JPopupMenu categoryPopup;
|
||||||
private JPopupMenu searchPopup;
|
private JPopupMenu searchPopup;
|
||||||
private PlaceholderTextField searchFieldCategory;
|
private PlaceholderTextField searchFieldCategory;
|
||||||
private PlaceholderTextField searchFieldSearch;
|
private PlaceholderTextField searchFieldSearch;
|
||||||
private final Component[] extraCategoryWidgets;
|
private Component[] extraCategoryWidgets;
|
||||||
private JList<T> filteredList;
|
private JList<T> filteredList;
|
||||||
|
|
||||||
private Map<G, List<T>> itemGroupMap;
|
private Map<G, List<T>> itemGroupMap;
|
||||||
@ -84,19 +88,34 @@ public class SearchableAndCategorizableComboBox<G extends Group, T extends Group
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a searchable and categorizable combo box.
|
* Create a searchable and categorizable combo box.
|
||||||
* @param itemGroupMap the map of items and their corresponding groups
|
|
||||||
* @param placeHolderText the placeholder text for the search field (when no text is entered)
|
* @param placeHolderText the placeholder text for the search field (when no text is entered)
|
||||||
* @param extraCategoryWidgets extra widgets to add to the category popup. Each widget will be added as a separate menu item.
|
* @param extraCategoryWidgets extra widgets to add to the category popup. Each widget will be added as a separate menu item.
|
||||||
*/
|
*/
|
||||||
public SearchableAndCategorizableComboBox(ComboBoxModel<T> model, Map<G, List<T>> itemGroupMap, String placeHolderText,
|
public SearchableAndCategorizableComboBox(ComboBoxModel<T> model, String placeHolderText,
|
||||||
Component... extraCategoryWidgets) {
|
Component... extraCategoryWidgets) {
|
||||||
super(model != null ? model : new DefaultComboBoxModel<>());
|
super(model != null ? model : new DefaultComboBoxModel<>());
|
||||||
|
List<T> items = new ArrayList<>();
|
||||||
|
for (int i = 0; i < Objects.requireNonNull(model).getSize(); i++) {
|
||||||
|
items.add(model.getElementAt(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
init(model, constructItemGroupMapFromList(items), placeHolderText, extraCategoryWidgets);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchableAndCategorizableComboBox(List<T> allItems, String placeHolderText, Component... extraCategoryWidgets) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
init(null, constructItemGroupMapFromList(allItems), placeHolderText, extraCategoryWidgets);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(ComboBoxModel<T> model, Map<G, List<T>> itemGroupMap, String placeHolderText, Component... extraCategoryWidgets) {
|
||||||
setEditable(false);
|
setEditable(false);
|
||||||
|
|
||||||
initColors();
|
initColors();
|
||||||
|
|
||||||
this.extraCategoryWidgets = extraCategoryWidgets;
|
this.extraCategoryWidgets = extraCategoryWidgets;
|
||||||
this.placeHolderText = placeHolderText;
|
this.placeHolderText = placeHolderText;
|
||||||
|
this.itemGroupMap = itemGroupMap;
|
||||||
updateItems(itemGroupMap);
|
updateItems(itemGroupMap);
|
||||||
setupMainRenderer();
|
setupMainRenderer();
|
||||||
|
|
||||||
@ -105,10 +124,6 @@ public class SearchableAndCategorizableComboBox<G extends Group, T extends Group
|
|||||||
addMouseListeners();
|
addMouseListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchableAndCategorizableComboBox(Map<G, List<T>> itemGroupMap, String placeHolderText, Component... extraCategoryWidgets) {
|
|
||||||
this(null, itemGroupMap, placeHolderText, extraCategoryWidgets);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void initColors() {
|
private static void initColors() {
|
||||||
updateColors();
|
updateColors();
|
||||||
UITheme.Theme.addUIThemeChangeListener(SearchableAndCategorizableComboBox::updateColors);
|
UITheme.Theme.addUIThemeChangeListener(SearchableAndCategorizableComboBox::updateColors);
|
||||||
@ -118,6 +133,21 @@ public class SearchableAndCategorizableComboBox<G extends Group, T extends Group
|
|||||||
textSelectionBackground = GUIUtil.getUITheme().getTextSelectionBackgroundColor();
|
textSelectionBackground = GUIUtil.getUITheme().getTextSelectionBackgroundColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (T item : items) {
|
||||||
|
G group = item.getGroup();
|
||||||
|
itemGroupMap.computeIfAbsent(group, k -> new ArrayList<>()).add(item);
|
||||||
|
}
|
||||||
|
return itemGroupMap;
|
||||||
|
}
|
||||||
|
|
||||||
public void setupMainRenderer() {
|
public void setupMainRenderer() {
|
||||||
setRenderer(new DefaultListCellRenderer() {
|
setRenderer(new DefaultListCellRenderer() {
|
||||||
@Override
|
@Override
|
||||||
@ -173,20 +203,6 @@ public class SearchableAndCategorizableComboBox<G extends Group, T extends Group
|
|||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateItemsFromModel() {
|
|
||||||
ComboBoxModel<T> model = getModel();
|
|
||||||
Map<G, List<T>> newGroupMap = new HashMap<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < model.getSize(); i++) {
|
|
||||||
T item = model.getElementAt(i);
|
|
||||||
G group = item.getGroup();
|
|
||||||
newGroupMap.computeIfAbsent(group, k -> new ArrayList<>()).add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<G, List<T>> newItemGroupMap = new HashMap<>(newGroupMap);
|
|
||||||
updateItems(newItemGroupMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<T> extractItemsFromMap(Map<G, List<T>> itemGroupMap) {
|
private List<T> extractItemsFromMap(Map<G, List<T>> itemGroupMap) {
|
||||||
Set<T> uniqueItems = new HashSet<>(); // Use a Set to ensure uniqueness
|
Set<T> uniqueItems = new HashSet<>(); // Use a Set to ensure uniqueness
|
||||||
for (G group : itemGroupMap.keySet()) {
|
for (G group : itemGroupMap.keySet()) {
|
||||||
@ -425,6 +441,12 @@ public class SearchableAndCategorizableComboBox<G extends Group, T extends Group
|
|||||||
updateItemsFromModel();
|
updateItemsFromModel();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
model.setSelectedItem(SearchableAndCategorizableComboBox.this.getSelectedItem());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupSearchFieldListeners() {
|
private void setupSearchFieldListeners() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user