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

org.bidib.wizard.dcca.client.view.DccAdvView Maven / Gradle / Ivy

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

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.util.Collection;
import java.util.LinkedList;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.BevelBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableColumn;
import javax.swing.text.BadLocationException;

import org.bidib.jbidibc.messages.enums.DccAdvLogonType;
import org.bidib.wizard.api.locale.Resources;
import org.bidib.wizard.client.common.converter.StringConverter;
import org.bidib.wizard.client.common.table.AbstractEmptyTable;
import org.bidib.wizard.client.common.table.NumberWithButtonEditor;
import org.bidib.wizard.client.common.table.NumberWithButtonRenderer;
import org.bidib.wizard.client.common.text.InputValidationDocument;
import org.bidib.wizard.client.common.text.WizardComponentFactory;
import org.bidib.wizard.client.common.view.BasicPopupMenu;
import org.bidib.wizard.client.common.view.DockKeys;
import org.bidib.wizard.client.common.view.listener.ButtonListener;
import org.bidib.wizard.dcca.client.controller.listener.DccAdvControllerListener;
import org.bidib.wizard.dcca.client.model.DccAdvDecoderModel;
import org.bidib.wizard.dcca.client.model.DccAdvModel;
import org.bidib.wizard.dcca.client.view.converter.CommandStationIdConverter;
import org.bidib.wizard.dcca.client.view.converter.SessionIdConverter;
import org.bidib.wizard.dcca.client.view.glazed.DccAdvEventTableModel;
import org.bidib.wizard.dcca.client.view.glazed.StatusBarCalculations;
import org.bidib.wizard.dcca.client.view.glazed.TriggerableCount;
import org.bidib.wizard.dcca.client.view.listener.DccAdvViewListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jgoodies.binding.adapter.Bindings;
import com.jgoodies.binding.beans.PropertyAdapter;
import com.jgoodies.binding.beans.PropertyConnector;
import com.jgoodies.binding.value.ConverterValueModel;
import com.jgoodies.binding.value.ValueHolder;
import com.jgoodies.binding.value.ValueModel;
import com.jgoodies.forms.builder.FormBuilder;
import com.jgoodies.forms.debug.FormDebugPanel;
import com.jgoodies.forms.factories.Paddings;
import com.jidesoft.grid.TablePopupMenuInstaller;
import com.vlsolutions.swing.docking.DockKey;
import com.vlsolutions.swing.docking.Dockable;
import com.vlsolutions.swing.docking.DockableState;
import com.vlsolutions.swing.docking.DockingDesktop;
import com.vlsolutions.swing.docking.event.DockableStateChangeEvent;
import com.vlsolutions.swing.docking.event.DockableStateChangeListener;

import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.ListSelection;
import ca.odell.glazedlists.gui.TableFormat;
import ca.odell.glazedlists.impl.beans.BeanTableFormat;
import ca.odell.glazedlists.swing.DefaultEventSelectionModel;
import ca.odell.glazedlists.swing.GlazedListsSwing;

public class DccAdvView implements Dockable {

    private static final Logger LOGGER = LoggerFactory.getLogger(DccAdvView.class);

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

    private static final String ENCODED_DIALOG_ROW_SPECS = "p, 3dlu, fill:200dlu:grow, 3dlu, p, 3dlu, p";

    private static final String ENCODED_BUTTON_PANEL_COLUMN_SPECS =
        "pref, 3dlu, pref, 3dlu, pref, 3dlu, pref, 3dlu, pref, 3dlu, pref, 3dlu, pref, 3dlu, pref, 3dlu, pref, 3dlu, pref, 3dlu, pref";

    private static final String ENCODED_BUTTON_PANEL_ROW_SPECS = "p";

    private final JPanel contentPanel;

    private final DockableStateChangeListener dockableStateChangeListener;

    private final DccAdvModel dccAdvModel;

    // private SelectionInList passiveDecoderSelection;
    //
    // private final DccAdvTableModel passiveTableModel;
    private EventList passiveDecoderSource;

    // private SelectionInList activeDecoderSelection;

    // private final DccAdvTableModel activeTableModel;
    private EventList activeDecoderSource;

    private AbstractEmptyTable activeDecoderTable;

    private TriggerableCount activeDecodersCount;

    private final JTextArea logsArea = new JTextArea();

    private JTextField currentCommandStationId;

    private ValueModel readButtonEnabled;

    private ValueModel startDetectionButtonEnabled;

    private final JButton readCommandStationIdButton =
        new JButton(Resources.getString(DccAdvView.class, "readCommandStationId"));

    private JTextField currentSessionId;

    private final JButton updateSessionIdButton = new JButton(Resources.getString(DccAdvView.class, "updateSessionId"));

    private JButton startDetectionButton;

    private JButton stopDetectionButton;

    private final Collection listeners = new LinkedList<>();

    private ValueModel commandStationIdValueModel;

    private ValueModel sessionIdValueModel;

    private ValueModel logonTypeModel;

    private JComponent[] logonTypeButtons;

    private ValueModel repetitionsValueModel;

    private ValueModel intervalValueModel;

    private ValueModel autoAssignEnabled;

    public DccAdvView(final DockingDesktop desktop, final DccAdvModel dccAdvModel,
        final DccAdvControllerListener railcomPlusControllerListener) {

        this.dccAdvModel = dccAdvModel;

        DockKeys.DOCKKEY_DCC_ADV_VIEW.setName(Resources.getString(getClass(), "title"));
        DockKeys.DOCKKEY_DCC_ADV_VIEW.setFloatEnabled(true);
        DockKeys.DOCKKEY_DCC_ADV_VIEW.setAutoHideEnabled(false);

        LOGGER.info("Create new DccAdvView");

        // @formatter:off
        String[] propertyNames = new String[] {
             "decoderUniqueId",
             "shortGui",
             "decoderWishAddress",
             "decoderAddress",
             "shortName",
             "productName",
             "firmwareId",
             "fullName",
             "detectionStatus"
         };
         String[] columnLabels = new String[] {
             Resources.getString(DccAdvEventTableModel.class, "decoderUniqueId"),
             Resources.getString(DccAdvEventTableModel.class, "icon"), 
             Resources.getString(DccAdvEventTableModel.class, "wishAddress"),
             Resources.getString(DccAdvEventTableModel.class, "address"),
             Resources.getString(DccAdvEventTableModel.class, "shortName"),
             Resources.getString(DccAdvEventTableModel.class, "productName"),
             Resources.getString(DccAdvEventTableModel.class, "firmwareId"),
             Resources.getString(DccAdvEventTableModel.class, "fullName"),
             Resources.getString(DccAdvEventTableModel.class, "detectionStatus")
         };
         boolean[] editable = new boolean[] {
             false,
             false,
             false,
             true,
             false,
             false,
             false,
             false,
             false
         };
         // @formatter:on

        final TableFormat tableFormat =
            new BeanTableFormat(DccAdvDecoderModel.class, propertyNames, columnLabels, editable);

        // EventList source = GlazedLists.eventList(this.dccAdvModel.getActiveDecoderListModel());
        activeDecoderSource = GlazedListsSwing.swingThreadProxyList(this.dccAdvModel.getActiveDecoderListModel());

        DccAdvEventTableModel activeTableModel = new DccAdvEventTableModel(activeDecoderSource, tableFormat);

        // create the selection model
        final DefaultEventSelectionModel activeSelectionModel =
            new DefaultEventSelectionModel<>(activeDecoderSource);
        activeSelectionModel.setSelectionMode(ListSelection.SINGLE_SELECTION);

        final ListSelectionListener activeSelectionListener = new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {

                LOGGER.info("The selection has changed: {}", e);

                if (!e.getValueIsAdjusting()) {
                    EventList selectedList = activeSelectionModel.getSelected();
                    if (!selectedList.isEmpty()) {
                        DccAdvDecoderModel selected = selectedList.get(0);
                        LOGGER.info("Selected instance: {}", selected);
                    }
                }
            }
        };
        activeSelectionModel.addListSelectionListener(activeSelectionListener);

        // create the active decoder table
        activeDecoderTable =
            new AbstractEmptyTable(activeTableModel, Resources.getString(DccAdvView.class, "empty_table-active")) {
                private static final long serialVersionUID = 1L;
            };

        // set the selection model
        activeDecoderTable.setSelectionModel(activeSelectionModel);

        final JPopupMenu decoderTableMenu = new DecoderTableMenu(this);
        // activeDecoderTable.add(decoderTableMenu);
        final TablePopupMenuInstaller installer = new TablePopupMenuInstaller(activeDecoderTable) {
            @Override
            protected JPopupMenu createPopupMenu() {
                return decoderTableMenu;
            }

            @Override
            protected void customizeMenuItems(JTable table, JPopupMenu popup, int clickingRow, int clickingColumn) {
                LOGGER.info("Customize the popup menu: {}", popup);

                // if (clickingRow > -1 && table.getSelectedRow() != clickingRow) {
                // table.setRowSelectionInterval(clickingRow, clickingRow);
                // }

                super.customizeMenuItems(table, popup, clickingRow, clickingColumn);
            }
        };

        activeDecodersCount = new TriggerableCount<>(activeDecoderSource);

        // activeDecoderTable
        // .setSelectionModel(new SingleListSelectionAdapter(activeDecoderSelection.getSelectionIndexHolder()));

        TableColumn tc = activeDecoderTable.getColumnModel().getColumn(DccAdvEventTableModel.COLUMN_DECODER_UNIQUEID);
        tc.setPreferredWidth(60);
        tc.setCellRenderer(new DecoderUniqueIdCellRenderer());

        tc = activeDecoderTable.getColumnModel().getColumn(DccAdvEventTableModel.COLUMN_ICON);
        tc.setPreferredWidth(20);
        tc.setCellRenderer(new DecoderIconCellRenderer());

        TableColumn wishAddrColumn =
            activeDecoderTable.getColumnModel().getColumn(DccAdvEventTableModel.COLUMN_WISH_ADDRESS);
        wishAddrColumn.setIdentifier(Integer.valueOf(DccAdvEventTableModel.COLUMN_WISH_ADDRESS));
        wishAddrColumn.setCellRenderer(new DecoderAddressRenderer());
        wishAddrColumn.setPreferredWidth(60);

        TableColumn buttonColumn = activeDecoderTable.getColumnModel().getColumn(DccAdvEventTableModel.COLUMN_ADDRESS);
        buttonColumn.setIdentifier(Integer.valueOf(DccAdvEventTableModel.COLUMN_ADDRESS));
        buttonColumn.setPreferredWidth(60);

        // The max value of address is 10239
        NumberWithButtonEditor editor = new NumberWithButtonEditor(">", 10239);
        // editor.addButtonListener(activeTableModel);
        buttonColumn.setCellEditor(editor);
        NumberWithButtonRenderer renderer = new NumberWithButtonRenderer(">");
        buttonColumn.setCellRenderer(renderer);

        editor.addButtonListener(new ButtonListener() {

            @Override
            public void buttonPressed(int row, int column, Object value) {
                LOGGER.info("Address assign button was pressed, row: {}", row);
                final DccAdvDecoderModel dccAdvDecoder = activeTableModel.getElementAt(row);
                fireAssignAddress(dccAdvDecoder);
            }

        });

        tc = activeDecoderTable.getColumnModel().getColumn(DccAdvEventTableModel.COLUMN_SHORTNAME);
        tc.setPreferredWidth(40);

        tc = activeDecoderTable.getColumnModel().getColumn(DccAdvEventTableModel.COLUMN_PRODUCTNAME);
        tc.setPreferredWidth(40);

        tc = activeDecoderTable.getColumnModel().getColumn(DccAdvEventTableModel.COLUMN_FIRMWAREID);
        tc.setPreferredWidth(40);

        tc = activeDecoderTable.getColumnModel().getColumn(DccAdvEventTableModel.COLUMN_FULLNAME);
        tc.setPreferredWidth(120);

        // create the passive decoder table
        final TableFormat passiveTableFormat =
            new BeanTableFormat(DccAdvDecoderModel.class, propertyNames, columnLabels, editable);

        // EventList source = GlazedLists.eventList(this.dccAdvModel.getActiveDecoderListModel());
        passiveDecoderSource = GlazedListsSwing.swingThreadProxyList(this.dccAdvModel.getPassiveDecoderListModel());

        DccAdvEventTableModel passiveTableModel = new DccAdvEventTableModel(passiveDecoderSource, passiveTableFormat);

        AbstractEmptyTable passiveDecoderTable =
            new AbstractEmptyTable(passiveTableModel, Resources.getString(DccAdvView.class, "empty_table-passive")) {
                private static final long serialVersionUID = 1L;

                // @Override
                // public boolean isSkipPackColumn() {
                // return true;
                // }
            };

        // passiveDecoderTable
        // .setSelectionModel(new SingleListSelectionAdapter(passiveDecoderSelection.getSelectionIndexHolder()));

        tc = passiveDecoderTable.getColumnModel().getColumn(DccAdvEventTableModel.COLUMN_DECODER_UNIQUEID);
        tc.setPreferredWidth(100);
        tc.setCellRenderer(new DecoderUniqueIdCellRenderer());

        TableColumn addressColumn =
            passiveDecoderTable.getColumnModel().getColumn(DccAdvEventTableModel.COLUMN_ADDRESS);
        addressColumn.setIdentifier(Integer.valueOf(DccAdvEventTableModel.COLUMN_ADDRESS));
        addressColumn.setPreferredWidth(60);

        // The max value of address is 10239
        editor = new NumberWithButtonEditor(">", 10239);
        editor.setButtonEnabled(false);
        editor.addButtonListener(passiveTableModel);
        addressColumn.setCellEditor(editor);
        renderer = new NumberWithButtonRenderer(">");
        renderer.setButtonEnabled(false);
        addressColumn.setCellRenderer(renderer);

        // create form builder
        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);

        // create the textfield for the TID
        commandStationIdValueModel =
            new PropertyAdapter(dccAdvModel, DccAdvModel.PROPERTY_COMMANDSTATION_ID, true);

        final ValueModel commandStationIdConverterModel =
            new ConverterValueModel(commandStationIdValueModel, new CommandStationIdConverter());

        currentCommandStationId = new JTextField();
        InputValidationDocument commandStationIdDocument =
            new InputValidationDocument(10, InputValidationDocument.ALPHANUM_AND_SPACE);
        currentCommandStationId.setDocument(commandStationIdDocument);

        // bind manually because we changed the document of the textfield
        Bindings.bind(currentCommandStationId, commandStationIdConverterModel, false);
        currentCommandStationId.setEditable(false);

        dialogBuilder.add(Resources.getString(getClass(), "commandStationId")).xy(1, 1);
        dialogBuilder.add(currentCommandStationId).xy(3, 1);

        readButtonEnabled = new ValueHolder(false);
        readCommandStationIdButton.setEnabled(false);
        readCommandStationIdButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                fireReadCommandStationId();
            }
        });
        // dialogBuilder.append(readCommandStationIdButton);

        sessionIdValueModel = new PropertyAdapter(dccAdvModel, DccAdvModel.PROPERTY_SESSION_ID, true);

        final ValueModel sessionIdConverterModel =
            new ConverterValueModel(sessionIdValueModel, new SessionIdConverter());

        currentSessionId = new JTextField();
        InputValidationDocument sessionIdDocument = new InputValidationDocument(3, InputValidationDocument.NUMERIC);
        currentSessionId.setDocument(sessionIdDocument);

        // bind manually because we changed the document of the textfield
        Bindings.bind(currentSessionId, sessionIdConverterModel, false);
        currentSessionId.setEditable(false);

        dialogBuilder.add(Resources.getString(getClass(), "sessionId")).xy(5, 1);
        dialogBuilder.add(currentSessionId).xy(7, 1);

        updateSessionIdButton.setEnabled(false);
        updateSessionIdButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                fireUpdateSessionId();
            }
        });
        dialogBuilder.add(readCommandStationIdButton).xy(9, 1);
        dialogBuilder.add(updateSessionIdButton).xy(11, 1);

        JScrollPane scrollTableActiveDecoders = new JScrollPane(activeDecoderTable);

        JScrollPane scrollTablePassiveDecoders = new JScrollPane(passiveDecoderTable);

        // logs area is not editable
        logsArea.setEditable(false);
        logsArea.setFont(new Font("Monospaced", Font.PLAIN, 11));
        JScrollPane logsPane = new JScrollPane(logsArea);

        logsPane.setAutoscrolls(true);

        JSplitPane splitPaneDecoderTables =
            new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollTableActiveDecoders, scrollTablePassiveDecoders);
        splitPaneDecoderTables.setDividerLocation(400);

        // Create a split pane with the two scroll panes in it.
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, splitPaneDecoderTables, logsPane);
        splitPane.setOneTouchExpandable(true);
        splitPane.setDividerLocation(800);

        dialogBuilder.add(splitPane).xyw(1, 3, 13);

        FormBuilder buttonPanelBuilder = null;
        if (debugDialog) {
            JPanel panel = new FormDebugPanel();
            buttonPanelBuilder =
                FormBuilder
                    .create().columns(ENCODED_BUTTON_PANEL_COLUMN_SPECS).rows(ENCODED_BUTTON_PANEL_ROW_SPECS)
                    .panel(panel);
        }
        else {
            JPanel panel = new JPanel(new BorderLayout());
            buttonPanelBuilder =
                FormBuilder
                    .create().columns(ENCODED_BUTTON_PANEL_COLUMN_SPECS).rows(ENCODED_BUTTON_PANEL_ROW_SPECS)
                    .panel(panel);
        }

        startDetectionButtonEnabled =
            new PropertyAdapter(dccAdvModel, DccAdvModel.PROPERTY_INIT_PASSED, true);

        startDetectionButton = new JButton(Resources.getString(DccAdvView.class, "startDetection"));
        startDetectionButton.setEnabled(false);
        startDetectionButton.setToolTipText("Press to start the decoder detection");
        startDetectionButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                fireStartDetection();
            }
        });
        buttonPanelBuilder.add(startDetectionButton).xy(1, 1);

        logonTypeModel = new PropertyAdapter(dccAdvModel, DccAdvModel.PROPERTY_DCCADVLOGONTYPE, true);
        logonTypeButtons = new JComponent[DccAdvLogonType.values().length];
        int index = 0;

        int column = 3;
        for (DccAdvLogonType logonType : DccAdvLogonType.values()) {

            JRadioButton radio =
                WizardComponentFactory
                    .createRadioButton(logonTypeModel, logonType,
                        Resources.getString(DccAdvLogonType.class, logonType.getKey()));
            logonTypeButtons[index++] = radio;

            // add radio button
            buttonPanelBuilder.add(radio).xy(column, 1);
            column += 2;
        }

        // add fields repetitions and interval
        repetitionsValueModel = new PropertyAdapter(dccAdvModel, DccAdvModel.PROPERTY_REPETITIONS, true);

        final ValueModel repetitionsConverterModel =
            new ConverterValueModel(repetitionsValueModel, new StringConverter(new DecimalFormat("#")));

        JTextField repetitionsText = new JTextField();
        InputValidationDocument repetitionsDocument = new InputValidationDocument(3, InputValidationDocument.NUMERIC);
        repetitionsText.setDocument(repetitionsDocument);
        repetitionsText.setColumns(3);

        // bind manually because we changed the document of the textfield
        Bindings.bind(repetitionsText, repetitionsConverterModel, false);

        buttonPanelBuilder.add(Resources.getString(DccAdvView.class, "repetitions")).xy(column, 1);
        column += 2;
        buttonPanelBuilder.add(repetitionsText).xy(column, 1);
        column += 2;

        intervalValueModel =
            new PropertyAdapter(dccAdvModel, DccAdvModel.PROPERTY_LOGONENABLE_INTERVAL, true);

        final ValueModel intervalConverterModel =
            new ConverterValueModel(intervalValueModel, new StringConverter(new DecimalFormat("#")));

        JTextField intervalText = new JTextField();
        InputValidationDocument intervalDocument = new InputValidationDocument(3, InputValidationDocument.NUMERIC);
        intervalText.setDocument(intervalDocument);
        intervalText.setColumns(3);

        // bind manually because we changed the document of the textfield
        Bindings.bind(intervalText, intervalConverterModel, false);

        buttonPanelBuilder.add(Resources.getString(DccAdvView.class, "interval")).xy(column, 1);
        column += 2;
        buttonPanelBuilder.add(intervalText).xy(column, 1);
        column += 2;

        autoAssignEnabled =
            new PropertyAdapter(dccAdvModel, DccAdvModel.PROPERTY_AUTO_ASSIGN_ENABLED, true);

        JCheckBox checkAutoAssign =
            WizardComponentFactory
                .createCheckBox(autoAssignEnabled, Resources.getString(DccAdvView.class, "autoAssignEnabled"));

        buttonPanelBuilder.add(checkAutoAssign).xy(column, 1);
        column += 2;

        stopDetectionButton = new JButton(Resources.getString(DccAdvView.class, "stopDetection"));
        stopDetectionButton.setEnabled(false);
        stopDetectionButton.setToolTipText("Press to stop the decoder detection");
        stopDetectionButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                fireStopDetection();
            }
        });
        buttonPanelBuilder.add(stopDetectionButton).xy(column, 1);

        dialogBuilder.add(buttonPanelBuilder.build()).xyw(1, 5, 13);

        JLabel activeDecodersCounterLabel = new JLabel();
        activeDecodersCounterLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
        dialogBuilder.add(activeDecodersCounterLabel).xyw(1, 7, 13);

        StatusBarCalculations
            .bind(activeDecodersCounterLabel, activeDecodersCount, null,
                Resources.getString(DccAdvView.class, "activeDecodersCountPrefix"));

        contentPanel = dialogBuilder.build();

        // add bindings for enable/disable the write button
        PropertyConnector.connect(readButtonEnabled, "value", readCommandStationIdButton, "enabled");
        PropertyConnector.connect(readButtonEnabled, "value", updateSessionIdButton, "enabled");

        PropertyConnector.connect(startDetectionButtonEnabled, "value", startDetectionButton, "enabled");
        PropertyConnector.connect(startDetectionButtonEnabled, "value", stopDetectionButton, "enabled");

        // initially disabled
        readButtonEnabled.setValue(false);
        startDetectionButtonEnabled.setValue(false);

        // popup menu for console view
        JPopupMenu popupMenu = new BasicPopupMenu();
        JMenuItem clearConsole = new JMenuItem(Resources.getString(getClass(), "clear_console"));
        clearConsole.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                fireClearConsole();
            }
        });
        popupMenu.add(clearConsole);
        logsArea.setComponentPopupMenu(popupMenu);

        dockableStateChangeListener = new DockableStateChangeListener() {

            @Override
            public void dockableStateChanged(DockableStateChangeEvent event) {

                LOGGER
                    .info("The state has changed, newState: {}, prevState: {}", event.getNewState(),
                        event.getPreviousState());

                DockableState newState = event.getNewState();
                if (newState.getDockable().equals(DccAdvView.this) && newState.isClosed()) {
                    LOGGER.info("The DccAdvView is closed.");
                    // we are closed
                    desktop.removeDockableStateChangeListener(dockableStateChangeListener);

                    if (railcomPlusControllerListener != null) {
                        railcomPlusControllerListener.viewClosed();
                    }
                }

            }
        };
        desktop.addDockableStateChangeListener(dockableStateChangeListener);
    }

    @Override
    public DockKey getDockKey() {
        return DockKeys.DOCKKEY_DCC_ADV_VIEW;
    }

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

    public void initialize() {
        // evaluate the feature FEATURE_GEN_DCCADV_AVAILABLE
        for (DccAdvViewListener l : listeners) {
            boolean isFeatureDccAdvAvailable = l.isFeatureDccAdvAvailable();
            if (isFeatureDccAdvAvailable) {
                LOGGER.info("The feature FEATURE_GEN_DCCADV_AVAILABLE is active, enable the buttons.");
                readButtonEnabled.setValue(isFeatureDccAdvAvailable);
                break;
            }
        }

        fireReadCommandStationId();
    }

    public void addDccAdvViewListener(DccAdvViewListener listener) {
        if (!listeners.contains(listener)) {
            listeners.add(listener);
        }
    }

    private void fireClearConsole() {
        LOGGER.info("Clear the console.");

        logsArea.setText(null);
    }

    private void fireReadCommandStationId() {
        LOGGER.info("Read the command station id.");
        for (DccAdvViewListener l : listeners) {
            l.readCommandStationId();
        }
    }

    private void fireUpdateSessionId() {
        LOGGER.info("Update the session id.");
        for (DccAdvViewListener l : listeners) {
            l.updateSessionId();
        }
    }

    private void fireStartDetection() {
        LOGGER.info("Start detection.");
        for (DccAdvViewListener l : listeners) {
            l.startDetection();
        }
    }

    private void fireStopDetection() {
        for (DccAdvViewListener l : listeners) {
            l.stopDetection();
        }
    }

    private void fireAssignAddress(final DccAdvDecoderModel dccAdvDecoder) {
        for (DccAdvViewListener l : listeners) {
            l.assignAddress(dccAdvDecoder);
        }
    }

    /**
     * Add a log message to the log pane.
     * 
     * @param logMessage
     *            the log message
     */
    public void addLog(final String logMessage) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                final StringBuilder sb = new StringBuilder(logMessage);
                sb.append("\n");

                try {
                    int lines = logsArea.getLineCount();
                    if (lines > 500) {
                        // remove the first 50 lines
                        int end = logsArea.getLineEndOffset(/* lines - */50);
                        logsArea.getDocument().remove(0, end);
                    }
                }
                catch (BadLocationException ex) {
                    LOGGER.warn("Remove some lines from logsArea failed.", ex);
                }

                // Update and scroll pane to the bottom
                logsArea.append(sb.toString());

                logsArea.invalidate();
            }
        });
    }

    public void clearActiveDecodersList() {
        LOGGER.info("Clear the active decoders list.");

        activeDecoderTable.clearSelection();

        activeDecoderSource.clear();

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy