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

org.bidib.wizard.mvc.pt.view.PtProgrammerView Maven / Gradle / Ivy

There is a newer version: 2.0.29
Show newest version
package org.bidib.wizard.mvc.pt.view;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;

import org.bidib.jbidibc.messages.enums.CommandStationProgState;
import org.bidib.jbidibc.messages.enums.CommandStationState;
import org.bidib.jbidibc.messages.enums.PtOperation;
import org.bidib.wizard.api.locale.Resources;
import org.bidib.wizard.model.status.CommandStationStatus;
import org.bidib.wizard.mvc.common.view.panel.DisabledPanel;
import org.bidib.wizard.mvc.pt.model.PtProgrammerModel;
import org.bidib.wizard.mvc.pt.model.listener.ConfigVariableListener;
import org.bidib.wizard.mvc.pt.view.listener.PtProgrammerViewListener;
import org.bidib.wizard.mvc.pt.view.panel.AddressPanel;
import org.bidib.wizard.mvc.pt.view.panel.DirectAccessPanel;
import org.bidib.wizard.mvc.pt.view.panel.RailcomPanel;
import org.bidib.wizard.mvc.pt.view.panel.listener.PtRequestListener;
import org.bidib.wizard.mvc.pt.view.panel.listener.PtResultListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jgoodies.forms.builder.ButtonBarBuilder;
import com.jgoodies.forms.builder.FormBuilder;
import com.jgoodies.forms.debug.FormDebugPanel;
import com.jgoodies.forms.factories.Paddings;
import com.vlsolutions.swing.docking.DockKey;
import com.vlsolutions.swing.docking.Dockable;
import com.vlsolutions.swing.docking.DockingDesktop;

public class PtProgrammerView implements Dockable {
    private static final Logger LOGGER = LoggerFactory.getLogger(PtProgrammerView.class);

    private final DockKey DOCKKEY = new DockKey("PtProgrammerView");

    private final Collection listeners = new LinkedList();

    private final PtProgrammerModel cvProgrammerModel;

    private Timer switchToProgramModeController;

    private final JButton closeButton = new JButton(Resources.getString(getClass(), "close"));

    private static final String ENCODED_DIALOG_COLUMN_SPECS = "pref, 3dlu, fill:50dlu:grow";

    private static final String ENCODED_DIALOG_ROW_SPECS = "p, 3dlu";

    private DirectAccessPanel directAccessPanel;

    private AddressPanel addressPanel;

    private RailcomPanel railcomPanel;

    private List ptResultListeners = new LinkedList();

    private final JTabbedPane tabbedPane;

    private final JPanel contentPanel;

    public PtProgrammerView(final PtProgrammerModel ptProgrammerModel) {
        this.cvProgrammerModel = ptProgrammerModel;

        DOCKKEY.setName(Resources.getString(getClass(), "title"));
        // turn off autohide and close features
        DOCKKEY.setFloatEnabled(true);
        DOCKKEY.setAutoHideEnabled(false);

        tabbedPane = new JTabbedPane();

        PtRequestListener ptRequestListener = new PtRequestListener() {
            @Override
            public void sendRequest(
                PtResultListener ptResultListener, PtOperation operation, int cvNumber, int cvValue) {
                LOGGER.info("Send request, ptResultListener: {}", ptResultListener);

                for (PtResultListener resultListener : ptResultListeners) {
                    resultListener.setActive(resultListener.equals(ptResultListener));
                }

                // disable the other tabs
                int selectedIndex = tabbedPane.getSelectedIndex();
                LOGGER.info("Disable the unselected tabs, selectedIndex: {}", selectedIndex);
                for (int index = 0; index < tabbedPane.getTabCount(); index++) {
                    tabbedPane.setEnabledAt(index, index == selectedIndex);
                }

                // send the request
                for (PtProgrammerViewListener l : listeners) {
                    l.sendRequest(operation, cvNumber, cvValue);
                }
            }
        };

        directAccessPanel = new DirectAccessPanel(cvProgrammerModel);
        directAccessPanel.addPtRequestListener(ptRequestListener);
        ptResultListeners.add(directAccessPanel);

        addressPanel = new AddressPanel(cvProgrammerModel);
        addressPanel.addPtRequestListener(ptRequestListener);
        ptResultListeners.add(addressPanel);

        railcomPanel = new RailcomPanel(cvProgrammerModel);
        railcomPanel.addPtRequestListener(ptRequestListener);
        ptResultListeners.add(railcomPanel);

        closeButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                close();
            }
        });

        // prepare the close button
        JPanel buttons = new ButtonBarBuilder().addGlue().addButton(closeButton).build();

        FormBuilder dialogBuilder = null;
        boolean debugDialog = false;
        if (debugDialog) {
            JPanel panel = new FormDebugPanel();
            dialogBuilder =
                FormBuilder.create().columns(ENCODED_DIALOG_COLUMN_SPECS).rows(ENCODED_DIALOG_ROW_SPECS).panel(panel);
        }
        else {
            JPanel panel = new JPanel(new BorderLayout());
            dialogBuilder =
                FormBuilder.create().columns(ENCODED_DIALOG_COLUMN_SPECS).rows(ENCODED_DIALOG_ROW_SPECS).panel(panel);
        }
        dialogBuilder.border(Paddings.DIALOG);

        tabbedPane
            .addTab(Resources.getString(getClass(), "tab-address"), null/* icon */, addressPanel.createPanel(),
                Resources.getString(getClass(), "tab-address.tooltip"));
        tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);

        tabbedPane
            .addTab(Resources.getString(getClass(), "tab-railcom"), null/* icon */, railcomPanel.createPanel(),
                Resources.getString(getClass(), "tab-railcom.tooltip"));
        tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);

        tabbedPane
            .addTab(Resources.getString(getClass(), "tab-direct-access"), null/* icon */,
                directAccessPanel.createPanel(), Resources.getString(getClass(), "tab-direct-access.tooltip"));
        tabbedPane.setMnemonicAt(2, KeyEvent.VK_3);

        dialogBuilder.appendRows("fill:p:grow");
        dialogBuilder.add(tabbedPane).xyw(1, 1, 3);

        dialogBuilder.appendRows("3dlu");
        dialogBuilder.add(buttons).xyw(1, 3, 3);

        contentPanel = dialogBuilder.build();

        DisabledPanel.disable(contentPanel);
        closeButton.setEnabled(true);

        cvProgrammerModel.addConfigVariableListener(new ConfigVariableListener() {
            @Override
            public void commandStationStateChanged(final CommandStationState commandStationState) {
                LOGGER.info("The commandStationState has changed: {}", commandStationState);
                if (SwingUtilities.isEventDispatchThread()) {
                    signalCommandStationStateChanged(commandStationState);
                }
                else {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            signalCommandStationStateChanged(commandStationState);
                        }
                    });
                }
            }

            @Override
            public void commandStationProgStateChanged(final CommandStationProgState commandStationProgState) {
                LOGGER.info("commandStationProgStateChanged: {}", commandStationProgState);
                if (SwingUtilities.isEventDispatchThread()) {
                    signalCommandStationProgStateChanged(commandStationProgState);
                }
                else {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            signalCommandStationProgStateChanged(commandStationProgState);
                        }
                    });
                }
            }
        });
    }

    @Override
    public Component getComponent() {
        return contentPanel;
    }

    @Override
    public DockKey getDockKey() {
        return DOCKKEY;
    }

    public void prepareDockable(DockingDesktop desktop, int x, int y) {

        desktop.addDockable(this);
        // desktop.setFloating(this, true);
        // switch to programming mode ...
        initialize();
    }

    private JDialog dialog;

    public void showDialog(JFrame parent, int x, int y) {

        dialog = new JDialog(parent, false);

        // dialog.setResizable(false);
        dialog.setTitle(Resources.getString(getClass(), "title"));
        dialog.setLayout(new BorderLayout());
        dialog.setContentPane(contentPanel);

        dialog.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                close();
            }
        });
        dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        dialog.pack();

        dialog
            .setMinimumSize(new Dimension((int) contentPanel.getPreferredSize().getWidth() + 10,
                (int) contentPanel.getPreferredSize().getHeight() + 35));

        dialog.setLocation(x, y);

        dialog.setVisible(true);

        // switch to programming mode ...
        initialize();
    }

    public void initialize() {
        //
        LOGGER.info("Switch CS to Programming mode.");

        switchToProgramModeController = new Timer(2000, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                switchToProgramModeController.stop();

                LOGGER.warn("Switch CommandStation to ProgrammMode was not established in 2 seconds!");
                JOptionPane
                    .showMessageDialog(contentPanel,
                        Resources.getString(PtProgrammerView.class, "switch-to-prog-mode-failed.message"),
                        Resources.getString(PtProgrammerView.class, "switch-to-prog-mode-failed.title"),
                        JOptionPane.ERROR_MESSAGE);

                // close the programming dialog
                close();
            }
        });
        switchToProgramModeController.setRepeats(false);
        switchToProgramModeController.start();

        // check if the booster already on because otherwise the activation of the prog mode does not work
        CommandStationStatus commandStationState = fireGetCurrentCommandStationState();
        if (CommandStationStatus.isOffState(commandStationState)) {
            LOGGER
                .info("Command station state is: {}. Set the command station to ON state before switch to prog mode.",
                    commandStationState);

            switchToProgramModeController.start();

            switchToProgModeAfterSwitchCommandStationOn = true;
            // Set the command station to ON state before switch to prog mode.
            addLogText("Switch command station ON.");
            fireSetProgrammingMode(false);

            // if (switchToProgramModeController != null) {
            // LOGGER.info("Restart switch timer.");
            // switchToProgramModeController.restart();
            // }
        }
        else {
            switchToProgramModeController.start();

            LOGGER.info("Switch the command station to programming mode.");
            addLogText("Switch to programming mode.");
            fireSetProgrammingMode(true);
        }
    }

    private boolean switchToProgModeAfterSwitchCommandStationOn;

    public void addPtProgrammerViewListener(PtProgrammerViewListener l) {
        listeners.add(l);
    }

    private void addLogText(final String logLine, Object... args) {
        for (PtResultListener listener : ptResultListeners) {
            listener.addLogText(logLine, args);
        }
    }

    private void signalCommandStationStateChanged(CommandStationState commandStationState) {
        if (CommandStationState.PROG.equals(commandStationState)) {
            if (switchToProgramModeController != null) {
                LOGGER.info("The command station has switched to programming mode. Stop the control timer.");
                switchToProgramModeController.stop();
                switchToProgramModeController = null;

                addLogText("Switched to programming mode passed.");

                DisabledPanel.enable(contentPanel);
            }
            else {
                LOGGER.info("No control timer available.");
            }
        }
        else if (switchToProgModeAfterSwitchCommandStationOn) {
            switchToProgModeAfterSwitchCommandStationOn = false;
            if (switchToProgramModeController != null) {
                LOGGER.info("The command station has switched to ON mode. Restart the control timer.");
                switchToProgramModeController.restart();

                addLogText("Switch to programming mode.");
                fireSetProgrammingMode(true);
            }
        }
    }

    private void signalCommandStationProgStateChanged(CommandStationProgState commandStationProgState) {

        if (commandStationProgState != null) {
            // enable the tabs before the result is passed to the listeners
            switch (commandStationProgState) {
                case PROG_START:
                case PROG_RUNNING:
                    break;
                default:
                    // enable all tabs
                    LOGGER.info("Enable the tabs");
                    for (int index = 0; index < tabbedPane.getTabCount(); index++) {
                        tabbedPane.setEnabledAt(index, true);
                    }
                    break;
            }
        }

        for (PtResultListener listener : ptResultListeners) {
            listener.signalCommandStationProgStateChanged(commandStationProgState);
        }
    }

    public void close() {
        contentPanel.setVisible(false);

        if (switchToProgramModeController != null) {
            LOGGER.info("The command station has switched to programming mode. Stop the control timer.");
            switchToProgramModeController.stop();
            switchToProgramModeController = null;
        }

        LOGGER.info("Terminate the programming mode!");
        fireSetProgrammingMode(false);

        LOGGER.info("Close the dialog.");
        fireClose();

        if (dialog != null) {
            dialog.dispose();

            dialog = null;
        }
    }

    private void fireClose() {
        for (PtProgrammerViewListener l : listeners) {
            l.close();
        }
    }

    private void fireSetProgrammingMode(boolean activateProgMode) {
        for (PtProgrammerViewListener l : listeners) {
            l.sendCommandStationStateRequest(activateProgMode);
        }
    }

    private CommandStationStatus fireGetCurrentCommandStationState() {
        for (PtProgrammerViewListener l : listeners) {
            return l.getCurrentCommandStationState();
        }
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy