From b227668fc478acd0596435c98931843a383e9658 Mon Sep 17 00:00:00 2001 From: Karl Duderstadt Date: Tue, 3 Aug 2021 16:43:23 +0200 Subject: [PATCH 1/2] SwingInputPanel: support input widget groups with collapsible labels Updates the SwingInputPanel to recognize ItemVisibility.GROUP and group annotations and organize input widgets accordingly with group labels and the ability to expand or collapse groups. Addresses scijava-common issue 310. Depends on scijava-common additions of GROUP visibility and group annotations --- .../ui/swing/widget/SwingInputPanel.java | 118 +++++++++++++++++- 1 file changed, 113 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/scijava/ui/swing/widget/SwingInputPanel.java b/src/main/java/org/scijava/ui/swing/widget/SwingInputPanel.java index 3b7542b..08f7fdb 100644 --- a/src/main/java/org/scijava/ui/swing/widget/SwingInputPanel.java +++ b/src/main/java/org/scijava/ui/swing/widget/SwingInputPanel.java @@ -29,16 +29,26 @@ package org.scijava.ui.swing.widget; +import java.awt.Component; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import javax.swing.JLabel; import javax.swing.JPanel; import net.miginfocom.swing.MigLayout; +import org.scijava.ItemVisibility; import org.scijava.widget.AbstractInputPanel; import org.scijava.widget.InputPanel; import org.scijava.widget.InputWidget; import org.scijava.widget.WidgetModel; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + /** * Swing implementation of {@link InputPanel}. * @@ -47,6 +57,9 @@ public class SwingInputPanel extends AbstractInputPanel { private JPanel uiComponent; + + private Map> widgetGroups; + private Map widgetGroupVisible; // -- InputPanel methods -- @@ -55,20 +68,115 @@ public void addWidget(final InputWidget widget) { super.addWidget(widget); final JPanel widgetPane = widget.getComponent(); final WidgetModel model = widget.get(); - + final String group = (model.getItem().getVisibility() == ItemVisibility.GROUP) ? (String) model.getValue() : model.getGroup(); + + if (widgetGroups == null) + widgetGroups = new HashMap>(); + + if (widgetGroupVisible == null) + widgetGroupVisible = new HashMap(); + + if (!widgetGroups.containsKey(group)) + widgetGroups.put(group, new ArrayList()); + // add widget to panel - if (widget.isLabeled()) { + if (model.getItem().getVisibility() == ItemVisibility.GROUP) { + JPanel labelPanel = new JPanel(new MigLayout("fillx,insets 5 15 5 15, gapy 0")); + JLabel label = (model.getItem().isExpanded()) ? new JLabel("▼ " + group + "") : + new JLabel("▶ " + group + ""); + + widgetGroupVisible.put(group, model.getItem().isExpanded()); + + label.addMouseListener(new MouseAdapter() { + /** + * Invoked when the mouse button has been clicked (pressed + * and released) on a component. + * @param e the event to be processed + */ + @Override + public void mouseClicked(MouseEvent e) { + } + + /** + * Invoked when a mouse button has been pressed on a component. + * @param e the event to be processed + */ + @Override + public void mousePressed(MouseEvent e) { + if (widgetGroups.get(group).size() == 0) + return; + + final boolean visible = label.getText().startsWith("▼"); + + widgetGroups.get(group).forEach( comp -> { + if (visible) + comp.setVisible(false); + else + comp.setVisible(true); + }); + + if(visible) + label.setText("▶ " + group + ""); + else + label.setText("▼ " + group + ""); + + getComponent().revalidate(); + } + + /** + * Invoked when a mouse button has been released on a component. + * @param e the event to be processed + */ + @Override + public void mouseReleased(MouseEvent e) { + } + + /** + * Invoked when the mouse enters a component. + * @param e the event to be processed + */ + @Override + public void mouseEntered(MouseEvent e) { + } + + /** + * Invoked when the mouse exits a component. + * @param e the event to be processed + */ + @Override + public void mouseExited(MouseEvent e) { + } + + }); + + labelPanel.add(label); + getComponent().add(labelPanel, "align left, wrap"); + } + else if (widget.isLabeled()) { // widget is prefixed by a label final JLabel l = new JLabel(model.getWidgetLabel()); final String desc = model.getItem().getDescription(); if (desc != null && !desc.isEmpty()) l.setToolTipText(desc); - getComponent().add(l); - getComponent().add(widgetPane); + getComponent().add(l, "hidemode 3"); + widgetGroups.get(group).add(l); + + getComponent().add(widgetPane, "hidemode 3"); + widgetGroups.get(group).add(widgetPane); } else { // widget occupies entire row - getComponent().add(widgetPane, "span"); + getComponent().add(widgetPane, "span, hidemode 3"); + widgetGroups.get(group).add(widgetPane); } + + //Make sure components have correct starting visibility + if (widgetGroups.containsKey(group) && widgetGroupVisible.containsKey(group)) + widgetGroups.get(group).forEach( comp -> { + if (widgetGroupVisible.get(group)) + comp.setVisible(true); + else + comp.setVisible(false); + }); } @Override From d435f5ca2b3f024074364d7b479a3160a91f3254 Mon Sep 17 00:00:00 2001 From: Karl Duderstadt Date: Tue, 3 Aug 2021 23:24:27 +0200 Subject: [PATCH 2/2] SwingInputPanel: simply group visibility logic --- .../ui/swing/widget/SwingInputPanel.java | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/scijava/ui/swing/widget/SwingInputPanel.java b/src/main/java/org/scijava/ui/swing/widget/SwingInputPanel.java index 08f7fdb..1d6491f 100644 --- a/src/main/java/org/scijava/ui/swing/widget/SwingInputPanel.java +++ b/src/main/java/org/scijava/ui/swing/widget/SwingInputPanel.java @@ -53,6 +53,7 @@ * Swing implementation of {@link InputPanel}. * * @author Curtis Rueden + * @author Karl Duderstadt */ public class SwingInputPanel extends AbstractInputPanel { @@ -103,22 +104,13 @@ public void mouseClicked(MouseEvent e) { */ @Override public void mousePressed(MouseEvent e) { - if (widgetGroups.get(group).size() == 0) - return; - - final boolean visible = label.getText().startsWith("▼"); - - widgetGroups.get(group).forEach( comp -> { - if (visible) - comp.setVisible(false); - else - comp.setVisible(true); - }); - - if(visible) - label.setText("▶ " + group + ""); + widgetGroupVisible.put(group, !widgetGroupVisible.get(group)); + widgetGroups.get(group).forEach(comp -> comp.setVisible(widgetGroupVisible.get(group))); + + if(widgetGroupVisible.get(group)) + label.setText("▼ " + group + ""); else - label.setText("▼ " + group + ""); + label.setText("▶ " + group + ""); getComponent().revalidate(); } @@ -171,12 +163,7 @@ else if (widget.isLabeled()) { //Make sure components have correct starting visibility if (widgetGroups.containsKey(group) && widgetGroupVisible.containsKey(group)) - widgetGroups.get(group).forEach( comp -> { - if (widgetGroupVisible.get(group)) - comp.setVisible(true); - else - comp.setVisible(false); - }); + widgetGroups.get(group).forEach(comp -> comp.setVisible(widgetGroupVisible.get(group))); } @Override