All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jdplus.toolkit.desktop.plugin.ui.calendar.ChainedGregorianCalendarPanel Maven / Gradle / Ivy

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jdplus.toolkit.desktop.plugin.ui.calendar;

import jdplus.toolkit.desktop.plugin.util.IDialogDescriptorProvider;
import jdplus.toolkit.desktop.plugin.util.ListenerState;
import jdplus.toolkit.desktop.plugin.properties.ComboBoxPropertyEditor;
import jdplus.toolkit.desktop.plugin.properties.NodePropertySetBuilder;
import jdplus.toolkit.base.api.timeseries.calendars.CalendarManager;
import jdplus.toolkit.base.api.timeseries.regression.ModellingContext;
import jdplus.toolkit.base.api.util.Arrays2;
import jdplus.toolkit.base.api.util.Constraint;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.openide.DialogDescriptor;
import org.openide.explorer.ExplorerManager;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.Sheet;
import org.openide.util.Exceptions;
import org.openide.util.lookup.Lookups;

/**
 *
 * @author Philippe Charles
 */
public class ChainedGregorianCalendarPanel extends JPanel implements ExplorerManager.Provider, IDialogDescriptorProvider {

    // PROPERTIES DEFINITION
    public static final String CALENDAR_NAME_PROPERTY = "calendarName";
    public static final String FIRST_CALENDAR_PROPERTY = "firstCalendar";
    public static final String SECOND_CALENDAR_PROPERTY = "secondCalendar";
    public static final String DAY_BREAK_PROPERTY = "dayBreak";
    // PROPERTIES
    private String calendarName;
    private String firstCalendar;
    private String secondCalendar;
    private LocalDate dayBreak;
    // OTHER
    final ExplorerManager em;
    final NameTextFieldListener nameTextFieldListener;

    /**
     * Creates new form NationalCalendarPanel
     */
    public ChainedGregorianCalendarPanel() {
        this.calendarName = "";
        this.firstCalendar = "";
        this.secondCalendar = "";
        this.dayBreak = null;

        this.em = new ExplorerManager();

        initComponents();

        em.setRootContext(new ChainedCalendarNode(this));
        try {
            em.setSelectedNodes(new Node[]{em.getRootContext()});
        } catch (PropertyVetoException ex) {
            Exceptions.printStackTrace(ex);
        }

        this.nameTextFieldListener = new NameTextFieldListener();

        nameTextField.getDocument().addDocumentListener(nameTextFieldListener);

        addPropertyChangeListener(evt -> {
            switch (evt.getPropertyName()) {
                case CALENDAR_NAME_PROPERTY:
                    onCalendarNameChange();
                    break;
                case FIRST_CALENDAR_PROPERTY:
                    onFirstCalendarChange();
                    break;
                case SECOND_CALENDAR_PROPERTY:
                    onSecondCalendarChange();
                    break;
                case DAY_BREAK_PROPERTY:
                    onDayBreakChange();
                    break;
            }
        });
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // //GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        nameTextField = new javax.swing.JTextField();
        propertySheetView1 = new org.openide.explorer.propertysheet.PropertySheetView();

        jLabel1.setText("Name:");

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(propertySheetView1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, nameTextField)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, layout.createSequentialGroup()
                        .add(jLabel1)
                        .add(0, 260, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(4, 4, 4)
                .add(jLabel1)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(nameTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(propertySheetView1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 161, Short.MAX_VALUE)
                .addContainerGap())
        );
    }// //GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabel1;
    private javax.swing.JTextField nameTextField;
    private org.openide.explorer.propertysheet.PropertySheetView propertySheetView1;
    // End of variables declaration//GEN-END:variables

    //
    protected void onCalendarNameChange() {
        if (nameTextFieldListener.state == ListenerState.READY) {
            nameTextFieldListener.state = ListenerState.SUSPENDED;
            nameTextField.setText(calendarName);
            nameTextFieldListener.state = ListenerState.READY;
        }
    }

    protected void onFirstCalendarChange() {
    }

    protected void onSecondCalendarChange() {
    }

    protected void onDayBreakChange() {
    }
    //

    //
    public String getCalendarName() {
        return calendarName;
    }

    public void setCalendarName(String calendarName) {
        String old = this.calendarName;
        this.calendarName = calendarName != null ? calendarName : "";
        firePropertyChange(CALENDAR_NAME_PROPERTY, old, this.calendarName);
    }

    public String getFirstCalendar() {
        return firstCalendar;
    }

    public void setFirstCalendar(String firstCalendar) {
        String old = this.firstCalendar;
        this.firstCalendar = firstCalendar;
        firePropertyChange(FIRST_CALENDAR_PROPERTY, old, this.firstCalendar);
    }

    public String getSecondCalendar() {
        return secondCalendar;
    }

    public void setSecondCalendar(String secondCalendar) {
        String old = this.secondCalendar;
        this.secondCalendar = secondCalendar;
        firePropertyChange(SECOND_CALENDAR_PROPERTY, old, this.secondCalendar);
    }

    public LocalDate getDayBreak() {
        return dayBreak;
    }

    public void setDayBreak(LocalDate dayBreak) {
        LocalDate old = this.dayBreak;
        this.dayBreak = dayBreak;
        firePropertyChange(DAY_BREAK_PROPERTY, old, this.dayBreak);
    }

    @Override
    public ExplorerManager getExplorerManager() {
        return em;
    }
    //

    static class ChainedCalendarNode extends AbstractNode {

        public ChainedCalendarNode(ChainedGregorianCalendarPanel bean) {
            super(Children.LEAF, Lookups.singleton(bean));
        }

        @Override
        protected Sheet createSheet() {
            ChainedGregorianCalendarPanel bean = getLookup().lookup(ChainedGregorianCalendarPanel.class);

            List tmp = new ArrayList<>(Arrays.asList(ModellingContext.getActiveContext().getCalendars().getNames()));
            tmp.remove(bean.getCalendarName());
            Object[] names = tmp.toArray();

            Sheet result = super.createSheet();
            NodePropertySetBuilder b = new NodePropertySetBuilder();
            b.with(String.class)
                    .select(bean, FIRST_CALENDAR_PROPERTY)
                    .editor(ComboBoxPropertyEditor.class)
                    .attribute(ComboBoxPropertyEditor.VALUES_ATTRIBUTE, names)
                    .display("First")
                    .add();
            b.with(LocalDate.class)
                    .select(bean, DAY_BREAK_PROPERTY)
                    .display("Day break")
                    .add();
            b.with(String.class)
                    .select(bean, SECOND_CALENDAR_PROPERTY)
                    .editor(ComboBoxPropertyEditor.class)
                    .attribute(ComboBoxPropertyEditor.VALUES_ATTRIBUTE, names)
                    .display("Second")
                    .add();
            result.put(b.build());
            return result;
        }
    }

    private class NameTextFieldListener implements DocumentListener {

        ListenerState state = ListenerState.READY;

        void update() {
            if (state == ListenerState.READY) {
                state = ListenerState.SENDING;
                setCalendarName(nameTextField.getText());
                state = ListenerState.READY;
            }
        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            update();
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            update();
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
        }
    }

    @Override
    public DialogDescriptor createDialogDescriptor(String title) {
        return new ChainedDialogDescriptor(this, title);
    }

    private static class ChainedDialogDescriptor extends CustomDialogDescriptor {

        ChainedDialogDescriptor(ChainedGregorianCalendarPanel p, String title) {
            super(p, title, new ChainedConstraintData(p, p.getCalendarName()));
            validate(ChainedConstraints.values());
        }

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            switch (evt.getPropertyName()) {
                case CALENDAR_NAME_PROPERTY:
                    validate(ChainedConstraints.CALENDAR_NAME, ChainedConstraints.FIRST_NAME, ChainedConstraints.DAY_BREAK, ChainedConstraints.SECOND_NAME);
                    break;
                case FIRST_CALENDAR_PROPERTY:
                    validate(ChainedConstraints.FIRST_NAME, ChainedConstraints.CALENDAR_NAME, ChainedConstraints.DAY_BREAK, ChainedConstraints.SECOND_NAME);
                    break;
                case DAY_BREAK_PROPERTY:
                    validate(ChainedConstraints.DAY_BREAK, ChainedConstraints.CALENDAR_NAME, ChainedConstraints.FIRST_NAME, ChainedConstraints.SECOND_NAME);
                    break;
                case SECOND_CALENDAR_PROPERTY:
                    validate(ChainedConstraints.SECOND_NAME, ChainedConstraints.CALENDAR_NAME, ChainedConstraints.FIRST_NAME, ChainedConstraints.DAY_BREAK);
                    break;
            }
        }
    }

    private static class ChainedConstraintData {

        final ChainedGregorianCalendarPanel panel;
        final String originalName;
        final CalendarManager manager;

        ChainedConstraintData(ChainedGregorianCalendarPanel panel, String originalName) {
            this.panel = panel;
            this.originalName = originalName;
            this.manager = ModellingContext.getActiveContext().getCalendars();
        }
    }

    private enum ChainedConstraints implements Constraint {

        CALENDAR_NAME {
            @Override
            public String check(ChainedConstraintData t) {
                String name = t.panel.getCalendarName();
                if (name.isEmpty()) {
                    return "The name of the calendar cannot be empty";
                }
                if (!t.originalName.equals(name) && t.manager.contains(name)) {
                    return "The name of the calendar is already used";
                }
                return null;
            }
        },
        FIRST_NAME {
            @Override
            public String check(ChainedConstraintData t) {
                String first = t.panel.getFirstCalendar();
                if (first.isEmpty()) {
                    return "The name of the first calendar cannot be empty";
                }
                if (first.equals(t.panel.getSecondCalendar())) {
                    return "The name of the first calendar is already used";
                }
                return null;
            }
        },
        DAY_BREAK {
            @Override
            public String check(ChainedConstraintData t) {
                if (t.panel.getDayBreak() == null) {
                    return "Day break cannot be null";
                }
                return null;
            }
        },
        SECOND_NAME {
            @Override
            public String check(ChainedConstraintData t) {
                String second = t.panel.getSecondCalendar();
                if (second.isEmpty()) {
                    return "The name of the second calendar cannot be empty";
                }
                if (second.equals(t.panel.getFirstCalendar())) {
                    return "The name of the second calendar is already used";
                }
                return null;
            }
        }
    }

    @Override
    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
        if (!Arrays2.arrayEquals(oldValue, newValue)) {
            super.firePropertyChange(propertyName, oldValue, newValue);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy