123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- package holeg.ui.view.inspector;
- import holeg.interfaces.LocalMode;
- import holeg.interfaces.TimelineDependent;
- import holeg.model.HolonElement;
- import holeg.model.HolonSwitch;
- import holeg.preferences.ColorPreference;
- import holeg.preferences.ImagePreference;
- import holeg.ui.controller.Control;
- import holeg.ui.model.GuiSettings;
- import holeg.ui.view.image.Import;
- import holeg.utility.listener.ResizeListener;
- import holeg.utility.math.Maths;
- import holeg.utility.math.decimal.Format;
- import java.awt.BorderLayout;
- import java.awt.Color;
- import java.awt.Component;
- import java.awt.Dimension;
- import java.awt.event.ItemEvent;
- import java.util.Set;
- import java.util.logging.Logger;
- import java.util.stream.Collectors;
- import javax.swing.Box;
- import javax.swing.GrayFilter;
- import javax.swing.ImageIcon;
- import javax.swing.JButton;
- import javax.swing.JComboBox;
- import javax.swing.JLabel;
- import javax.swing.JOptionPane;
- import javax.swing.JPanel;
- import javax.swing.JScrollPane;
- import javax.swing.JSplitPane;
- import javax.swing.JToolBar;
- /**
- * With the Inspector you can inspect the selection of the canvas objects.
- * For all HolonElements in all selected HolonObjects a table is generated.
- * When selecting a HolonSwitch the OnOff Cycle can be adjusted.
- */
- public class Inspector extends JSplitPane {
- private static final Logger log = Logger.getLogger(Inspector.class.getName());
- private final UnitGraph unitGraph;
- private final InspectorTable table;
- private final JPanel scrollGraph = new JPanel();
- private final JPanel graphLabel = new JPanel();
- private final JLabel maxGraph = new JLabel("100%");
- private final JLabel medGraph = new JLabel("50%");
- private final JLabel minGraph = new JLabel("0%");
- private final JPanel globalCurveLabel = new JPanel();
- private final JLabel minEnergy = new JLabel("0.0");
- private final JLabel maxEnergy = new JLabel("0.0");
- private final JLabel zeroEnergy = new JLabel("0.0");
- private final JToolBar toolBarGraph = new JToolBar();
- private final ImageIcon localPeriodButtonImageEnabled = new ImageIcon(
- Import.loadImage(ImagePreference.Button.Inspector.Graph));
- private final ImageIcon localPeriodButtonImageDisabled = new ImageIcon(
- GrayFilter.createDisabledImage(Import.loadImage(ImagePreference.Button.Inspector.Graph)));
- private final String[] comboContext = {"", "5", "10", "20", "100", "1000"};
- private final JComboBox<String> localPeriodInput = new JComboBox<>(comboContext);
- private final JButton resetButton = new JButton("",
- new ImageIcon(Import.loadImage(ImagePreference.Button.Inspector.Reset)));
- private final JButton localPeriodButton = new JButton("", localPeriodButtonImageEnabled);
- public Inspector(Control control) {
- table = new InspectorTable(control);
- unitGraph = new UnitGraph(control);
- table.OnElementSelectionChanged.addListener(this::updateUnitGraph);
- initUI();
- control.OnSelectionChanged.addListener(this::updateGlobalCurve);
- }
- private void initUI() {
- this.setOrientation(JSplitPane.VERTICAL_SPLIT);
- JScrollPane scrollPane = new JScrollPane(table);
- scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
- this.setTopComponent(scrollPane);
- this.setBottomComponent(scrollGraph);
- this.setDividerLocation(550);
- scrollGraph.setLayout(new BorderLayout());
- scrollGraph.add(unitGraph, BorderLayout.CENTER);
- // Set up of the Properties section
- graphLabel.setLayout(new BorderLayout(0, 10));
- graphLabel.add(maxGraph, BorderLayout.NORTH);
- graphLabel.add(medGraph, BorderLayout.CENTER);
- graphLabel.add(minGraph, BorderLayout.SOUTH);
- globalCurveLabel.setLayout(null);
- globalCurveLabel.setMinimumSize(new Dimension(20, 0));
- globalCurveLabel.setPreferredSize(new Dimension(20, 0));
- maxEnergy.setForeground(Color.red);
- minEnergy.setForeground(Color.red);
- zeroEnergy.setForeground(ColorPreference.UnitGraph.ZeroLineColor);
- globalCurveLabel.add(maxEnergy);
- globalCurveLabel.add(zeroEnergy);
- globalCurveLabel.add(minEnergy);
- this.globalCurveLabel.addComponentListener((ResizeListener) resize -> updateGlobalCurve());
- toolBarGraph.setFloatable(false);
- toolBarGraph.setAlignmentY(Component.RIGHT_ALIGNMENT);
- localPeriodButton.setToolTipText("Toggle Local/Global Mode");
- toolBarGraph.add(localPeriodButton);
- // ComboBox
- localPeriodInput.setEditable(true);
- localPeriodInput.setVisible(false);
- localPeriodInput.setMaximumSize(new Dimension(20, 23));
- localPeriodInput.addItemListener(aListener -> {
- if (aListener.getStateChange() == ItemEvent.DESELECTED) {
- validateInput(localPeriodInput.getEditor().getItem().toString(), true);
- }
- });
- toolBarGraph.add(localPeriodInput);
- // localPeriodButtonFunction
- localPeriodButton.addActionListener(actionEvent -> {
- boolean newState = !localPeriodInput.isVisible();
- changeLocalPeriodButtonAppearance(newState);
- log.info("LocalPeriodButton");
- });
- toolBarGraph.add(Box.createHorizontalGlue());
- resetButton.setToolTipText("Reset");
- resetButton.addActionListener(actionEvent -> unitGraph.reset());
- toolBarGraph.add(resetButton);
- scrollGraph.add(graphLabel, BorderLayout.WEST);
- scrollGraph.add(globalCurveLabel, BorderLayout.EAST);
- scrollGraph.add(toolBarGraph, BorderLayout.NORTH);
- }
- /**
- * Validate the LocalMode Input and when its valid save on the Element.
- *
- * @param text the inputText to validate.
- * @param bShowMessage when true, open a MessageDialog when text invalid.
- */
- private void validateInput(String text, boolean bShowMessage) {
- int localPeriodInputValue;
- try {
- localPeriodInputValue = Integer.parseInt(text);
- } catch (NumberFormatException e) {
- if (bShowMessage) {
- JOptionPane.showMessageDialog(null,
- '"' + text + '"' + " is not a valid Input. \n Use whole numbers.");
- }
- return;
- }
- LocalMode.Period period = new LocalMode.Period(7);
- period.setInterval(localPeriodInputValue);
- unitGraph.setPeriod(period);
- }
- /**
- * This Method updates the UnitGraph, saves the old LocalModeState and load the new
- * LocalModeState.
- *
- * @param elements The new Element to load the UnitGraph
- */
- private void updateUnitGraph(Set<HolonElement> elements) {
- // SaveOld LocalMode State.
- if (localPeriodInput.isVisible()) {
- // Save Old State
- validateInput(localPeriodInput.getEditor().getItem().toString(), false);
- }
- // Update UnitGraph
- unitGraph.clearSeries();
- for (TimelineDependent element : elements) {
- unitGraph.addNewSeries(element);
- }
- if (elements.isEmpty()) {
- GuiSettings.getSelectedObjects().stream().filter(obj -> obj instanceof HolonSwitch)
- .forEach(obj -> unitGraph.addNewSeries((HolonSwitch) obj));
- }
- // if (elements.isEmpty()) {
- // this.setDividerLocation(1.0);
- // }
- // Load LocalMode State.
- changeLocalPeriodButtonAppearance(unitGraph.isUsingLocalPeriod());
- localPeriodInput.getEditor()
- .setItem(
- unitGraph.isLocalPeriedDifferentInSeries() ? "-" : unitGraph.getFirstLocalPeriod());
- }
- private void updateGlobalCurve() {
- Set<HolonElement> elements = InspectorTable.extractElements(GuiSettings.getSelectedObjects())
- .collect(Collectors.toSet());
- unitGraph.setGlobalCurve(elements);
- double maxEnergy = elements.stream().map(HolonElement::getEnergy).filter(energy -> energy > 0)
- .reduce(0.0f,
- Float::sum);
- double minEnergy = elements.stream().map(HolonElement::getEnergy).filter(energy -> energy < 0)
- .reduce(0.0f,
- Float::sum);
- double percentage = Maths.invLerp(maxEnergy, minEnergy, 0.0);
- int widgetHeight = this.globalCurveLabel.getHeight();
- int zeroYPos = (int) (widgetHeight * percentage) - 5;
- this.minEnergy.setText(Format.doubleTwoPlaces(minEnergy));
- this.maxEnergy.setText(Format.doubleTwoPlaces(maxEnergy));
- this.maxEnergy.setBounds(0, 0, this.maxEnergy.getPreferredSize().width,
- this.maxEnergy.getPreferredSize().height);
- this.minEnergy.setBounds(0, widgetHeight - this.minEnergy.getPreferredSize().height,
- this.minEnergy.getPreferredSize().width,
- this.minEnergy.getPreferredSize().height);
- this.zeroEnergy.setBounds(0, zeroYPos, this.zeroEnergy.getPreferredSize().width,
- this.zeroEnergy.getPreferredSize().height);
- this.globalCurveLabel.setPreferredSize(new Dimension(
- Math.max(this.zeroEnergy.getPreferredSize().width,
- Math.max(this.maxEnergy.getPreferredSize().width,
- this.minEnergy.getPreferredSize().width)),
- 0));
- }
- /**
- * Displayed the actual LocalModeState.
- *
- * @param enabled the state
- */
- private void changeLocalPeriodButtonAppearance(boolean enabled) {
- localPeriodInput.setVisible(enabled);
- localPeriodButton.setIcon(
- enabled ? localPeriodButtonImageEnabled : localPeriodButtonImageDisabled);
- }
- }
|