Batch model values to avoid too long menus

This commit is contained in:
Bane Stojkovic
2022-11-10 23:23:53 +01:00
parent d4bb4b94b9
commit f3e8509ff3
4 changed files with 277 additions and 335 deletions
@@ -41,9 +41,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.swing.AbstractAction;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
@@ -52,8 +49,6 @@ import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.IConfigListener;
import org.diylc.appframework.miscutils.IConfigurationManager;
@@ -77,6 +72,7 @@ import org.diylc.swing.gui.TranslatedMenu;
import org.diylc.swing.gui.TranslatedPopupMenu;
import org.diylc.swing.images.IconLoader;
import org.diylc.swing.plugins.file.ProjectDrawingProvider;
import org.diylc.swing.plugins.toolbox.ComponentButtonFactory;
import org.diylc.swingframework.ruler.IRulerListener;
import org.diylc.swingframework.ruler.Ruler.InchSubdivision;
import org.diylc.swingframework.ruler.RulerScrollPane;
@@ -729,88 +725,14 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
}
applyMenu.setEnabled(true);
List<Component> datasheetItems = createDatasheetItems(plugInPort, componentType, new ArrayList<String>());
List<Component> datasheetItems = ComponentButtonFactory.createDatasheetItems(plugInPort, componentType, new ArrayList<String>(), model -> {
LOG.info("Applying datasheet model " + String.join(", ", model));
plugInPort.applyModelToSelection(model);
});
for (Component item : datasheetItems) {
applyMenu.add(item);
}
}
private List<Component> createDatasheetItems(final IPlugInPort plugInPort,
final ComponentType componentType, List<String> path) {
int depth = path.size();
List<String[]> datasheet = componentType.getDatasheet();
if (datasheet == null) {
return null;
}
Stream<String[]> stream = datasheet.stream();
for (int i = 0; i < depth; i++) {
final int finalI = i;
stream = stream.filter(line -> line[finalI].equals(path.get(finalI)));
}
List<String[]> filteredDatasheet = stream.collect(Collectors.toList());
return filteredDatasheet.stream().map(x -> x[depth]).distinct().map(value -> {
if (depth < componentType.getDatasheetCreationStepCount() - 1) {
final JMenu submenu = new JMenu(value) {
private static final long serialVersionUID = 1L;
// Customize item size to fit the delete button
public java.awt.Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
return new Dimension(d.width + 32, d.height);
}
};
submenu.add(new JMenuItem("Loading..."));
submenu.addMenuListener(new MenuListener() {
@Override
public void menuSelected(MenuEvent e) {
submenu.removeAll();
List<String> newPath = new ArrayList<String>(path);
newPath.add(value);
List<Component> childItems = createDatasheetItems(plugInPort, componentType, newPath);
for (Component childItem : childItems) {
submenu.add(childItem);
}
}
@Override
public void menuDeselected(MenuEvent e) {}
@Override
public void menuCanceled(MenuEvent e) {}
});
return (Component) submenu;
}
JMenuItem item = new JMenuItem(value);
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Optional<String[]> findFirst =
filteredDatasheet.stream().filter(line -> line[depth].equals(value)).findFirst();
if (findFirst.isPresent()) {
String[] model = findFirst.get();
LOG.info("Applying datasheet model " + String.join(", ", model));
plugInPort.applyModelToSelection(model);
} else {
LOG.error("Could not find datasheet item for: " + value);
}
}
});
return (Component) item;
}).collect(Collectors.toList());
}
public ActionFactory.CutAction getCutAction() {
if (cutAction == null) {
@@ -30,6 +30,7 @@ import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -56,6 +57,7 @@ import org.diylc.core.IDIYComponent;
import org.diylc.core.Template;
import org.diylc.swing.images.IconLoader;
import org.diylc.swingframework.openide.DropDownButtonFactory;
import com.google.common.collect.Lists;
/**
* Factory that creates {@link JButton}s which display component type icons and instantiates the
@@ -65,6 +67,8 @@ import org.diylc.swingframework.openide.DropDownButtonFactory;
*/
public class ComponentButtonFactory {
private static final int MAX_MENU_ITEMS = 30;
private static final Logger LOG = Logger.getLogger(ComponentButtonFactory.class);
public static int MARGIN = 3;
@@ -208,7 +212,7 @@ public class ComponentButtonFactory {
}
public static List<Component> createDatasheetItems(final IPlugInPort plugInPort,
final ComponentType componentType, List<String> path) {
final ComponentType componentType, List<String> path, Consumer<String[]> modelConsumer) {
int depth = path.size();
List<String[]> datasheet = componentType.getDatasheet();
if (datasheet == null) {
@@ -224,16 +228,7 @@ public class ComponentButtonFactory {
return filteredDatasheet.stream().map(x -> x[depth]).distinct().map(value -> {
if (depth < componentType.getDatasheetCreationStepCount() - 1) {
final JMenu submenu = new JMenu(value) {
private static final long serialVersionUID = 1L;
// Customize item size to fit the delete button
public java.awt.Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
return new Dimension(d.width + 32, d.height);
}
};
final JMenu submenu = new JMenu(value);
submenu.add(new JMenuItem("Loading..."));
@@ -244,9 +239,33 @@ public class ComponentButtonFactory {
submenu.removeAll();
List<String> newPath = new ArrayList<String>(path);
newPath.add(value);
List<Component> childItems = createDatasheetItems(plugInPort, componentType, newPath);
for (Component childItem : childItems) {
submenu.add(childItem);
List<Component> childItems = createDatasheetItems(plugInPort, componentType, newPath, modelConsumer);
if (childItems.size() > MAX_MENU_ITEMS) {
List<List<Component>> partitions = Lists.partition(childItems, MAX_MENU_ITEMS);
for (List<Component> partition : partitions) {
String label = null;
Component first = partition.get(0);
if (first instanceof JMenu) {
label = ((JMenu) first).getText();
if (partition.size() > 1) {
label += " - " + ((JMenu) partition.get(partition.size() - 1)).getText();
}
} else if (first instanceof JMenuItem) {
label = ((JMenuItem) first).getText();
if (partition.size() > 1) {
label += " - " + ((JMenuItem) partition.get(partition.size() - 1)).getText();
}
}
JMenu partitionMenu = new JMenu(label);
for (Component childItem : partition) {
partitionMenu.add(childItem);
}
submenu.add(partitionMenu);
}
} else {
for (Component childItem : childItems) {
submenu.add(childItem);
}
}
}
@@ -267,12 +286,10 @@ public class ComponentButtonFactory {
@Override
public void actionPerformed(ActionEvent e) {
Optional<String[]> findFirst =
filteredDatasheet.stream().filter(line -> line[depth].equals(value)).findFirst();
filteredDatasheet.stream().filter(line -> line[depth].equals(value)).findFirst();
if (findFirst.isPresent()) {
LOG.info("Creating datasheet model " + String.join(", ", findFirst.get()));
plugInPort.setNewComponentTypeSlot(componentType, null, findFirst.get(),
false);
modelConsumer.accept(findFirst.get());
} else {
LOG.error("Could not find datasheet item for: " + value);
}
@@ -357,7 +357,10 @@ public class TreePanel extends JPanel {
popup.add(new JSeparator());
if (componentType.getDatasheet() != null) {
List<Component> items = ComponentButtonFactory.createDatasheetItems(plugInPort, componentType, new ArrayList<String>());
List<Component> items = ComponentButtonFactory.createDatasheetItems(plugInPort, componentType, new ArrayList<String>(), model -> {
LOG.info("Creating datasheet model " + String.join(", ", model));
plugInPort.setNewComponentTypeSlot(componentType, null, model, false);
});
for (Component item : items) {
popup.add(item);
}