From 6d454caf2bfa5207957b5da775ece2a249857ddd Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Fri, 19 Aug 2016 11:02:03 -0400 Subject: GUI reorganization --- .../bjc/utils/gui/panels/DropdownListPanel.java | 57 ++++++ .../bjc/utils/gui/panels/FormattedInputPanel.java | 66 +++++++ .../bjc/utils/gui/panels/HolderOutputPanel.java | 79 +++++++++ .../bjc/utils/gui/panels/ListParameterPanel.java | 137 ++++++++++++++ .../bjc/utils/gui/panels/SimpleInputPanel.java | 28 +++ .../java/bjc/utils/gui/panels/SimpleListPanel.java | 81 +++++++++ .../bjc/utils/gui/panels/SimpleSpinnerPanel.java | 25 +++ .../bjc/utils/gui/panels/SliderInputPanel.java | 196 +++++++++++++++++++++ .../java/bjc/utils/gui/panels/package-info.java | 5 + 9 files changed, 674 insertions(+) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/gui/panels/DropdownListPanel.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/gui/panels/FormattedInputPanel.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/gui/panels/HolderOutputPanel.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/gui/panels/ListParameterPanel.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleInputPanel.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleListPanel.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleSpinnerPanel.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/gui/panels/SliderInputPanel.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/gui/panels/package-info.java (limited to 'BJC-Utils2/src/main/java/bjc/utils/gui/panels') diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/panels/DropdownListPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/DropdownListPanel.java new file mode 100644 index 0000000..2231760 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/DropdownListPanel.java @@ -0,0 +1,57 @@ +package bjc.utils.gui.panels; + +import java.awt.BorderLayout; + +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListSelectionModel; + +import bjc.utils.funcdata.IList; +import bjc.utils.gui.layout.AutosizeLayout; +import bjc.utils.gui.layout.HLayout; + +public class DropdownListPanel extends JPanel { + private static final long serialVersionUID = 2719963952350133541L; + + @SuppressWarnings("unchecked") + public DropdownListPanel(String itemType, + DefaultListModel listModel, IList choices) { + setLayout(new AutosizeLayout()); + + JPanel itemInputPanel = new JPanel(); + itemInputPanel.setLayout(new BorderLayout()); + + JPanel addItemPanel = new JPanel(); + addItemPanel.setLayout(new HLayout(2)); + + JComboBox addItemBox = new JComboBox<>(); + choices.forEach(addItemBox::addItem); + + JButton addItemButton = new JButton("Add " + itemType); + + addItemPanel.add(addItemBox); + addItemPanel.add(addItemButton); + + JList itemList = new JList<>(listModel); + itemList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + JButton removeItemButton = new JButton("Remove " + itemType); + + addItemButton.addActionListener((ev) -> { + listModel.addElement((T) addItemBox.getSelectedItem()); + }); + + removeItemButton.addActionListener((ev) -> { + listModel.remove(itemList.getSelectedIndex()); + }); + + itemInputPanel.add(addItemPanel, BorderLayout.PAGE_START); + itemInputPanel.add(itemList, BorderLayout.CENTER); + itemInputPanel.add(removeItemButton, BorderLayout.PAGE_END); + + add(itemInputPanel); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/panels/FormattedInputPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/FormattedInputPanel.java new file mode 100644 index 0000000..54970ec --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/FormattedInputPanel.java @@ -0,0 +1,66 @@ +package bjc.utils.gui.panels; + +import java.util.function.Consumer; + +import javax.swing.JFormattedTextField; +import javax.swing.JFormattedTextField.AbstractFormatter; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import bjc.utils.gui.layout.HLayout; + +/** + * A simple panel allowing for input of a single formatted value + * + * @author ben + * + * @param + * The type of value being formatted + */ +public class FormattedInputPanel extends JPanel { + private static final long serialVersionUID = 5232016563558588031L; + private JFormattedTextField field; + + /** + * Create a new formatted input panel + * + * @param label + * The label for this panel + * @param length + * The length of this panel + * @param formatter + * The formatter to use for input + * @param valueReciever + * The action to call whenever the value changes + */ + @SuppressWarnings("unchecked") + public FormattedInputPanel(String label, int length, + AbstractFormatter formatter, + Consumer valueReciever) { + setLayout(new HLayout(2)); + + JLabel lab = new JLabel(label); + field = new JFormattedTextField(formatter); + + field.setColumns(length); + field.setFocusLostBehavior(JFormattedTextField.COMMIT_OR_REVERT); + field.addPropertyChangeListener("value", (event) -> { + // This is safe, because InputVal should be the type of + // whatever object the formatter is returning + valueReciever.accept((InputVal) field.getValue()); + }); + + add(lab); + add(field); + } + + /** + * Reset the value in this panel to a specified value + * + * @param value + * The value to set the panel to + */ + public void resetValues(InputVal value) { + field.setValue(value); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/panels/HolderOutputPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/HolderOutputPanel.java new file mode 100644 index 0000000..128dbfc --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/HolderOutputPanel.java @@ -0,0 +1,79 @@ +package bjc.utils.gui.panels; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.Timer; + +import bjc.utils.data.IHolder; +import bjc.utils.gui.layout.HLayout; + +/** + * A panel that outputs a value bound to a {@link IHolder} + * + * @author ben + * + */ +public class HolderOutputPanel extends JPanel { + private static final long serialVersionUID = 166573313903782080L; + private Timer updateTimer; + private JLabel value; + private int nDelay; + private IHolder val; + + /** + * Create a new display panel, backed by a holder + * + * @param lab + * The label to attach to this field + * @param valueHolder + * The holder to get the value from + * @param nDelay + * The delay in ms between value updates + */ + public HolderOutputPanel(String lab, IHolder valueHolder, + int nDelay) { + this.val = valueHolder; + this.nDelay = nDelay; + + setLayout(new HLayout(2)); + + JLabel label = new JLabel(lab); + value = new JLabel("(stopped)"); + + updateTimer = new Timer(nDelay, (event) -> { + value.setText(valueHolder.getValue()); + }); + + add(label); + add(value); + } + + /** + * Set this panel back to its initial state + */ + public void reset() { + stopUpdating(); + + value.setText("(stopped)"); + + updateTimer = new Timer(nDelay, (event) -> { + value.setText(val.getValue()); + }); + } + + /** + * Start updating the contents of the field from the holder + */ + public void startUpdating() { + updateTimer.start(); + } + + /** + * Stop updating the contents of the field from the holder + */ + public void stopUpdating() { + updateTimer.stop(); + + value.setText(value.getText() + " (stopped)"); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/panels/ListParameterPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/ListParameterPanel.java new file mode 100644 index 0000000..8769902 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/ListParameterPanel.java @@ -0,0 +1,137 @@ +package bjc.utils.gui.panels; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListSelectionModel; + +import bjc.utils.funcdata.IList; +import bjc.utils.gui.SimpleJList; +import bjc.utils.gui.layout.HLayout; +import bjc.utils.gui.layout.VLayout; + +/** + * A panel that has a list of objects and ways of manipulating that list + * + * @author ben + * + * @param + * The type of data stored in the list + */ +public class ListParameterPanel extends JPanel { + // Version id for serialization + private static final long serialVersionUID = 3442971104975491571L; + + /** + * Create a new panel using the specified actions for doing things + * + * @param addAction + * The action that provides items + * @param editAction + * The action that edits items + * @param removeAction + * The action that removes items + */ + public ListParameterPanel(Supplier addAction, + Consumer editAction, Consumer removeAction) { + this(addAction, editAction, removeAction, null); + } + + /** + * Create a new panel using the specified actions for doing things + * + * @param addAction + * The action that provides items + * @param editAction + * The action that edits items + * @param removeAction + * The action that removes items + * @param defaultValues + * The default values to put in the list + */ + public ListParameterPanel(Supplier addAction, + Consumer editAction, Consumer removeAction, + IList defaultValues) { + setLayout(new VLayout(2)); + + JList list; + + if (defaultValues != null) { + list = SimpleJList.buildFromList(defaultValues.toIterable()); + } else { + list = new JList<>(new DefaultListModel<>()); + } + + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + JPanel buttonPanel = new JPanel(); + + int numButtons = 0; + + if (addAction != null) { + numButtons++; + } + + if (editAction != null) { + numButtons++; + } + + if (removeAction != null) { + numButtons++; + } + + buttonPanel.setLayout(new HLayout(numButtons)); + + JButton addParam = null; + + if (addAction != null) { + addParam = new JButton("Add..."); + addParam.addActionListener((event) -> { + DefaultListModel model = (DefaultListModel) list + .getModel(); + + model.addElement(addAction.get()); + }); + } + + JButton editParam = null; + + if (editAction != null) { + editParam = new JButton("Edit..."); + editParam.addActionListener((event) -> { + editAction.accept(list.getSelectedValue()); + }); + } + + JButton removeParam = null; + + if (removeAction != null) { + removeParam = new JButton("Remove..."); + removeParam.addActionListener((event) -> { + DefaultListModel model = (DefaultListModel) list + .getModel(); + + removeAction.accept(model.remove(list.getSelectedIndex())); + }); + } + + if (addAction != null) { + buttonPanel.add(addParam); + } + + if (editAction != null) { + buttonPanel.add(editParam); + } + + if (removeAction != null) { + buttonPanel.add(removeParam); + } + + add(list); + add(buttonPanel); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleInputPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleInputPanel.java new file mode 100644 index 0000000..fd981ec --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleInputPanel.java @@ -0,0 +1,28 @@ +package bjc.utils.gui.panels; + +import java.awt.BorderLayout; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; + +public class SimpleInputPanel extends JPanel { + private static final long serialVersionUID = -4734279623645236868L; + + public final JTextField inputValue; + + public SimpleInputPanel(String label, int columns) { + setLayout(new BorderLayout()); + + JLabel inputLabel = new JLabel(label); + + if (columns < 1) { + inputValue = new JTextField(); + } else { + inputValue = new JTextField(columns); + } + + add(inputLabel, BorderLayout.LINE_START); + add(inputValue, BorderLayout.CENTER); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleListPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleListPanel.java new file mode 100644 index 0000000..8884163 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleListPanel.java @@ -0,0 +1,81 @@ +package bjc.utils.gui.panels; + +import java.awt.BorderLayout; +import java.util.function.Consumer; +import java.util.function.Predicate; + +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; + +import bjc.utils.gui.layout.AutosizeLayout; +import bjc.utils.gui.layout.HLayout; + +public class SimpleListPanel extends JPanel { + private static final long serialVersionUID = 2719963952350133541L; + + public SimpleListPanel(String itemType, + DefaultListModel listModel, + Predicate itemVerifier, + Consumer onVerificationFailure) { + setLayout(new AutosizeLayout()); + + JPanel itemInputPanel = new JPanel(); + itemInputPanel.setLayout(new BorderLayout()); + + JPanel addItemPanel = new JPanel(); + addItemPanel.setLayout(new HLayout(2)); + + JTextField addItemField = new JTextField(255); + JButton addItemButton = new JButton("Add " + itemType); + + addItemPanel.add(addItemField); + addItemPanel.add(addItemButton); + + JList itemList = new JList<>(listModel); + itemList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + JScrollPane listScroller = new JScrollPane(itemList); + + JButton removeItemButton = new JButton("Remove " + itemType); + + addItemButton.addActionListener((ev) -> { + addItem(listModel, itemVerifier, onVerificationFailure, + addItemField); + }); + + addItemField.addActionListener((ev) -> { + addItem(listModel, itemVerifier, onVerificationFailure, + addItemField); + }); + + removeItemButton.addActionListener((ev) -> { + listModel.remove(itemList.getSelectedIndex()); + }); + + itemInputPanel.add(addItemPanel, BorderLayout.PAGE_START); + itemInputPanel.add(listScroller, BorderLayout.CENTER); + itemInputPanel.add(removeItemButton, BorderLayout.PAGE_END); + + add(itemInputPanel); + } + + private static void addItem(DefaultListModel listModel, + Predicate itemVerifier, + Consumer onVerificationFailure, + JTextField addItemField) { + String potentialItem = addItemField.getText(); + + if (itemVerifier == null || itemVerifier.test(potentialItem)) { + listModel.addElement(potentialItem); + } else { + onVerificationFailure.accept(potentialItem); + } + + addItemField.setText(""); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleSpinnerPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleSpinnerPanel.java new file mode 100644 index 0000000..7bbf83e --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleSpinnerPanel.java @@ -0,0 +1,25 @@ +package bjc.utils.gui.panels; + +import java.awt.BorderLayout; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.SpinnerModel; + +public class SimpleSpinnerPanel extends JPanel { + private static final long serialVersionUID = -4734279623645236868L; + + public final JSpinner inputValue; + + public SimpleSpinnerPanel(String label, SpinnerModel model) { + setLayout(new BorderLayout()); + + JLabel inputLabel = new JLabel(label); + + inputValue = new JSpinner(model); + + add(inputLabel, BorderLayout.LINE_START); + add(inputValue, BorderLayout.CENTER); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SliderInputPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SliderInputPanel.java new file mode 100644 index 0000000..792db73 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SliderInputPanel.java @@ -0,0 +1,196 @@ +package bjc.utils.gui.panels; + +import java.text.ParseException; +import java.util.function.Consumer; + +import javax.swing.JFormattedTextField; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSlider; + +import bjc.utils.gui.layout.HLayout; + +/** + * A simple input panel for a slider-controlled value and a manual-input + * field for setting the slider + * + * @author ben + * + */ +public class SliderInputPanel extends JPanel { + private final class NumberFormatter + extends JFormattedTextField.AbstractFormatter { + private static final long serialVersionUID = -4448291795913908270L; + + private int minValue; + private int maxValue; + + private int initValue; + + public NumberFormatter(SliderSettings settings) { + minValue = settings.minValue; + maxValue = settings.maxValue; + + initValue = settings.initValue; + } + + @Override + public Object stringToValue(String text) throws ParseException { + try { + int val = Integer.parseInt(text); + + if (val < minValue) { + throw new ParseException( + "Value must be greater than " + minValue, 0); + } else if (val > maxValue) { + throw new ParseException( + "Value must be smaller than " + maxValue, 0); + } else { + return val; + } + } catch (NumberFormatException nfex) { + ParseException pex = new ParseException( + "Value must be a valid integer", 0); + + pex.initCause(nfex); + + throw pex; + } + } + + @Override + public String valueToString(Object value) throws ParseException { + if (value == null) { + return Integer.toString(initValue); + } + + return Integer.toString((Integer) value); + } + } + + /** + * Represents the settings for a slider + * + * @author ben + * + */ + public static class SliderSettings { + /** + * The minimum value of the slider + */ + public final int minValue; + /** + * The maximum value of the slider + */ + public final int maxValue; + + /** + * The initial value of the slider + */ + public final int initValue; + + /** + * Create a new slider settings, with the initial value in the + * middle + * + * @param min + * The minimum value of the slider + * @param max + * The maximum value of the slider + */ + public SliderSettings(int min, int max) { + this(min, max, (min + max) / 2); + } + + /** + * Create a new set of slider sttings + * + * @param min + * The minimum slider value + * @param max + * The maximum slider value + * @param init + * Th initial slider value + */ + public SliderSettings(int min, int max, int init) { + minValue = min; + maxValue = max; + + initValue = init; + } + } + + private static final long serialVersionUID = 2956394160569961404L; + private JSlider slider; + private JFormattedTextField field; + + /** + * Create a new slider input panel + * + * @param lab + * The label for the field + * @param settings + * The settings for slider values + * @param majorTick + * The setting for where to place big ticks + * @param minorTick + * The setting for where to place small ticks + * @param action + * The action to execute for a given value + */ + public SliderInputPanel(String lab, SliderSettings settings, + int majorTick, int minorTick, Consumer action) { + setLayout(new HLayout(3)); + + JLabel label = new JLabel(lab); + + slider = new JSlider(settings.minValue, settings.maxValue, + settings.initValue); + field = new JFormattedTextField(new NumberFormatter(settings)); + + slider.setMajorTickSpacing(majorTick); + slider.setMinorTickSpacing(minorTick); + slider.setPaintTicks(true); + slider.setPaintLabels(true); + + slider.addChangeListener((event) -> { + if (slider.getValueIsAdjusting()) { + // Do nothing + } else { + int sliderVal = slider.getValue(); + + field.setValue(sliderVal); + + action.accept(sliderVal); + } + }); + + field.setFocusLostBehavior(JFormattedTextField.COMMIT_OR_REVERT); + field.setColumns(15); + field.addPropertyChangeListener("value", (event) -> { + Object value = field.getValue(); + + if (value == null) { + // Do nothing + } else { + slider.setValue((Integer) value); + } + }); + + add(label); + add(slider); + add(field); + } + + /** + * Reset the values in this panel to a specified value + * + * @param value + * The value to reset the fields to + */ + public void resetValues(int value) { + slider.setValue(value); + + field.setValue(value); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/panels/package-info.java b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/package-info.java new file mode 100644 index 0000000..4361885 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/package-info.java @@ -0,0 +1,5 @@ +/** + * @author ben + * + */ +package bjc.utils.gui.panels; \ No newline at end of file -- cgit v1.2.3