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

org.bidib.wizard.mvc.railcomplus.view.RailcomPlusView Maven / Gradle / Ivy

There is a newer version: 2.0.0-M1
Show newest version
package org.bidib.wizard.mvc.railcomplus.view;

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

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.table.TableColumn;

import org.bidib.jbidibc.core.RcPlusBindData;
import org.bidib.jbidibc.core.RcPlusUniqueIdData;
import org.bidib.jbidibc.core.enumeration.RcPlusPhase;
import org.bidib.wizard.locale.Resources;
import org.bidib.wizard.mvc.common.view.DockKeys;
import org.bidib.wizard.mvc.common.view.converter.TidConverter;
import org.bidib.wizard.mvc.main.view.table.AbstractEmptyTable;
import org.bidib.wizard.mvc.main.view.table.NumberWithButtonEditor;
import org.bidib.wizard.mvc.main.view.table.NumberWithButtonRenderer;
import org.bidib.wizard.mvc.railcomplus.model.RailcomPlusDecoderModel;
import org.bidib.wizard.mvc.railcomplus.model.RailcomPlusModel;
import org.bidib.wizard.mvc.railcomplus.model.listener.DecoderAddressListener;
import org.bidib.wizard.mvc.railcomplus.view.listener.RailcomPlusViewListener;
import org.jdesktop.swingx.decorator.Highlighter;
import org.jdesktop.swingx.decorator.HighlighterFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jgoodies.binding.adapter.Bindings;
import com.jgoodies.binding.adapter.SingleListSelectionAdapter;
import com.jgoodies.binding.beans.PropertyAdapter;
import com.jgoodies.binding.beans.PropertyConnector;
import com.jgoodies.binding.list.SelectionInList;
import com.jgoodies.binding.value.ConverterValueModel;
import com.jgoodies.binding.value.ValueHolder;
import com.jgoodies.binding.value.ValueModel;
import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.debug.FormDebugPanel;
import com.jgoodies.forms.factories.Borders;
import com.jgoodies.forms.layout.FormLayout;
import com.vlsolutions.swing.docking.DockKey;
import com.vlsolutions.swing.docking.Dockable;

public class RailcomPlusView implements Dockable {

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

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

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

    private final JPanel contentPanel;

    private SelectionInList decoderSelection;

    private ValueModel tidValueModel;

    private RailcomPlusModel railcomPlusModel;

    private ValueModel readButtonEnabled;

    private final JButton readTidButton = new JButton(Resources.getString(RailcomPlusView.class, "read_tid"));

    private final JButton updateSidButton = new JButton(Resources.getString(RailcomPlusView.class, "update_sid"));

    private final JButton updateTidButton = new JButton(Resources.getString(RailcomPlusView.class, "update_tid"));

    private final JButton pingOnceP0Button = new JButton(Resources.getString(RailcomPlusView.class, "ping_once_p0"));

    private final JButton pingOnceP1Button = new JButton(Resources.getString(RailcomPlusView.class, "ping_once_p1"));

    private final JButton pingButton = new JButton(Resources.getString(RailcomPlusView.class, "ping"));

    private final JButton pingOffButton = new JButton(Resources.getString(RailcomPlusView.class, "ping_off"));

    private final JButton findP0Button = new JButton(Resources.getString(RailcomPlusView.class, "find_p0"));

    private final JButton findP1Button = new JButton(Resources.getString(RailcomPlusView.class, "find_p1"));

    private JTextField currentTid;

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

    private final RailcomPlusTableTableModel tableModel;

    public RailcomPlusView(RailcomPlusModel railcomPlusModel) {

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

        LOGGER.info("Create new RailcomPlusView");

        this.railcomPlusModel = railcomPlusModel;

        decoderSelection =
            new SelectionInList(
                (ListModel) railcomPlusModel.getDecoderListModel());

        tableModel = new RailcomPlusTableTableModel(decoderSelection);

        // create a decoder table
        AbstractEmptyTable decoderTable = new AbstractEmptyTable(
            tableModel, Resources.getString(getClass(), "empty_table")) {
            @Override
            public boolean isSkipPackColumn() {
                return true;
            }
        };

        decoderTable.setSelectionModel(new SingleListSelectionAdapter(decoderSelection.getSelectionIndexHolder()));

        TableColumn tc = decoderTable.getColumnExt(RailcomPlusTableTableModel.COLUMN_MANUFACTURER);
        tc.setMinWidth(120);
        tc.setMaxWidth(150);
        tc.setPreferredWidth(150);
        tc.setCellRenderer(new DecoderManufacturerIdCellRenderer());

        tc = decoderTable.getColumnModel().getColumn(RailcomPlusTableTableModel.COLUMN_DECMUN);
        tc.setPreferredWidth(200);
        tc.setCellRenderer(new DecoderUniqueIdCellRenderer());

        TableColumn buttonColumn = decoderTable.getColumnModel().getColumn(RailcomPlusTableTableModel.COLUMN_ADDRESS);
        buttonColumn.setIdentifier(Integer.valueOf(RailcomPlusTableTableModel.COLUMN_ADDRESS));

        buttonColumn.setCellRenderer(new NumberWithButtonRenderer(">"));
        // TODO fix max value of address
        NumberWithButtonEditor editor = new NumberWithButtonEditor(">", 1024);
        editor.addButtonListener((RailcomPlusTableTableModel) tableModel);
        buttonColumn.setCellEditor(editor);

        Highlighter simpleStriping = HighlighterFactory.createSimpleStriping();
        decoderTable.setHighlighters(simpleStriping);

        // create form builder
        DefaultFormBuilder dialogBuilder = null;
        boolean debugDialog = false;
        if (debugDialog) {
            JPanel panel = new FormDebugPanel();
            dialogBuilder = new DefaultFormBuilder(new FormLayout(ENCODED_DIALOG_COLUMN_SPECS), panel);
        }
        else {
            JPanel panel = new JPanel(new BorderLayout());
            dialogBuilder = new DefaultFormBuilder(new FormLayout(ENCODED_DIALOG_COLUMN_SPECS), panel);
        }
        dialogBuilder.border(Borders.DIALOG);

        // create the textfield for the TID
        currentTid = new JTextField();
        currentTid.setEditable(false);
        dialogBuilder.append(Resources.getString(getClass(), "tid"), currentTid);

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

            @Override
            public void actionPerformed(ActionEvent e) {
                fireReadTid();
            }
        });
        dialogBuilder.append(readTidButton);

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

            @Override
            public void actionPerformed(ActionEvent e) {
                fireUpdateSid();
            }
        });
        dialogBuilder.append(updateSidButton);

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

            @Override
            public void actionPerformed(ActionEvent e) {
                fireUpdateTid();
            }
        });
        dialogBuilder.append(updateTidButton);

        tidValueModel = new PropertyAdapter(railcomPlusModel, RailcomPlusModel.PROPERTY_TID, true);

        final ValueModel tidConverterModel = new ConverterValueModel(tidValueModel, new TidConverter());

        // bind manually because we changed the document of the textfield
        Bindings.bind(currentTid, tidConverterModel, false);
        dialogBuilder.appendRow("3dlu");
        dialogBuilder.appendRow("pref");
        dialogBuilder.nextLine(2);

        DefaultFormBuilder buttonPanelBuilder = null;
        if (debugDialog) {
            JPanel panel = new FormDebugPanel();
            buttonPanelBuilder = new DefaultFormBuilder(new FormLayout(ENCODED_BUTTON_PANEL_COLUMN_SPECS), panel);
        }
        else {
            JPanel panel = new JPanel(new BorderLayout());
            buttonPanelBuilder = new DefaultFormBuilder(new FormLayout(ENCODED_BUTTON_PANEL_COLUMN_SPECS), panel);
        }

        pingOnceP0Button.setEnabled(false);
        pingOnceP0Button.setToolTipText("Send a PING_ONCE_P0");
        pingOnceP0Button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                firePingOnce(RcPlusPhase.P0);
            }
        });
        buttonPanelBuilder.append(pingOnceP0Button);

        pingOnceP1Button.setEnabled(false);
        pingOnceP1Button.setToolTipText("Send a PING_ONCE_P1");
        pingOnceP1Button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                firePingOnce(RcPlusPhase.P1);
            }
        });
        buttonPanelBuilder.append(pingOnceP1Button);

        pingButton.setEnabled(false);
        pingButton.setToolTipText("Send a PING(6)");
        pingButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                firePing();
            }
        });
        buttonPanelBuilder.append(pingButton);

        pingOffButton.setEnabled(false);
        pingOffButton.setToolTipText("Send a PING(0)");
        pingOffButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                firePingOff();
            }
        });
        buttonPanelBuilder.append(pingOffButton);

        findP0Button.setEnabled(false);
        findP0Button.setToolTipText("Send a FIND(P0)");
        findP0Button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                fireFind(RcPlusPhase.P0, new RcPlusUniqueIdData(0xFFFFFFFF, 0xFF));
            }
        });
        buttonPanelBuilder.append(findP0Button);

        findP1Button.setEnabled(false);
        findP1Button.setToolTipText("Send a FIND(P1)");
        findP1Button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                fireFind(RcPlusPhase.P1, new RcPlusUniqueIdData(0xFFFFFFFF, 0xFF));
            }
        });
        buttonPanelBuilder.append(findP1Button);

        dialogBuilder.append(buttonPanelBuilder.build(), 5);

        dialogBuilder.appendRow("3dlu");
        dialogBuilder.appendRow("fill:p:grow");
        dialogBuilder.nextLine(2);

        JScrollPane scrollTable = new JScrollPane(decoderTable);
        dialogBuilder.append(scrollTable, 9);

        contentPanel = dialogBuilder.build();

        // add bindings for enable/disable the write button
        PropertyConnector.connect(readButtonEnabled, "value", readTidButton, "enabled");
        PropertyConnector.connect(readButtonEnabled, "value", updateSidButton, "enabled");
        PropertyConnector.connect(readButtonEnabled, "value", pingOnceP0Button, "enabled");
        PropertyConnector.connect(readButtonEnabled, "value", pingOnceP1Button, "enabled");
        PropertyConnector.connect(readButtonEnabled, "value", pingButton, "enabled");
        PropertyConnector.connect(readButtonEnabled, "value", pingOffButton, "enabled");
        PropertyConnector.connect(readButtonEnabled, "value", findP0Button, "enabled");
        PropertyConnector.connect(readButtonEnabled, "value", findP1Button, "enabled");
        // PropertyConnector.connect(readButtonEnabled, "value", updateTidButton, "enabled");
        currentTid.setEditable(false);

        // TODO evaluate the feature FEATURE_GEN_RCPLUS_AVAILABLE
        readButtonEnabled.setValue(true);
    }

    private void fireReadTid() {

        for (RailcomPlusViewListener l : listeners) {
            l.readTid();
        }
    }

    private void fireUpdateSid() {
        for (RailcomPlusViewListener l : listeners) {
            l.updateSid();
        }
    }

    private void fireUpdateTid() {
        for (RailcomPlusViewListener l : listeners) {
            l.updateTid();
        }
    }

    private void firePingOnce(RcPlusPhase phase) {
        for (RailcomPlusViewListener l : listeners) {
            l.pingOnce(phase);
        }
    }

    private void firePing() {
        for (RailcomPlusViewListener l : listeners) {
            // TODO make the value configurable
            l.ping(6);
        }
    }

    private void firePingOff() {
        for (RailcomPlusViewListener l : listeners) {
            l.ping(0);
        }
    }

    private void fireFind(RcPlusPhase phase, RcPlusUniqueIdData decoder) {
        for (RailcomPlusViewListener l : listeners) {
            l.find(phase, decoder);
        }
    }

    private void fireBind(RcPlusBindData bindData) {
        for (RailcomPlusViewListener l : listeners) {
            l.bind(bindData);
        }
    }

    public void addRailcomPlusViewListener(RailcomPlusViewListener l) {
        listeners.add(l);
    }

    public void addDecoderAddressListener(DecoderAddressListener listener) {
        tableModel.addDecoderAddressListener(listener);
    }

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

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

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy