
org.bidib.wizard.mvc.railcomplus.controller.RailcomPlusController Maven / Gradle / Ivy
package org.bidib.wizard.mvc.railcomplus.controller;
import java.util.Collection;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.bidib.jbidibc.core.AddressData;
import org.bidib.jbidibc.core.DefaultMessageListener;
import org.bidib.jbidibc.core.RcPlusBindData;
import org.bidib.jbidibc.core.RcPlusDecoderAnswerData;
import org.bidib.jbidibc.core.RcPlusFeedbackBindData;
import org.bidib.jbidibc.core.RcPlusUniqueIdData;
import org.bidib.jbidibc.core.TidData;
import org.bidib.jbidibc.core.enumeration.AddressTypeEnum;
import org.bidib.jbidibc.core.enumeration.RcPlusAcknowledge;
import org.bidib.jbidibc.core.enumeration.RcPlusDecoderType;
import org.bidib.jbidibc.core.enumeration.RcPlusPhase;
import org.bidib.wizard.comm.Communication;
import org.bidib.wizard.comm.CommunicationFactory;
import org.bidib.wizard.locale.Resources;
import org.bidib.wizard.mvc.common.view.DockKeys;
import org.bidib.wizard.mvc.main.controller.MainControllerInterface;
import org.bidib.wizard.mvc.main.model.MainModel;
import org.bidib.wizard.mvc.main.model.Node;
import org.bidib.wizard.mvc.main.model.listener.NodeListListener;
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.RailcomPlusView;
import org.bidib.wizard.mvc.railcomplus.view.listener.RailcomPlusViewListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vlsolutions.swing.docking.Dockable;
import com.vlsolutions.swing.docking.DockableState;
import com.vlsolutions.swing.docking.DockingConstants;
import com.vlsolutions.swing.docking.DockingDesktop;
import com.vlsolutions.swing.docking.DockingUtilities;
import com.vlsolutions.swing.docking.RelativeDockablePosition;
import com.vlsolutions.swing.docking.TabbedDockableContainer;
public class RailcomPlusController implements NodeListListener {
private static final Logger LOGGER = LoggerFactory.getLogger(RailcomPlusController.class);
private DefaultMessageListener messageListener;
private RailcomPlusModel railcomPlusModel;
private RailcomPlusView railcomPlusView;
private final DockingDesktop desktop;
private final Node node;
private final MainModel mainModel;
public RailcomPlusController(final MainModel mainModel, final DockingDesktop desktop, final Node node) {
this.mainModel = mainModel;
this.desktop = desktop;
this.node = node;
}
public void start(final MainControllerInterface mainController) {
// check if the railcom view is already opened
String searchKey = DockKeys.RAILCOM_PLUS_VIEW;
LOGGER.info("Search for view with key: {}", searchKey);
Dockable view = desktop.getContext().getDockableByKey(searchKey);
if (view != null) {
LOGGER.info("Select the existing railcom plus view instead of open a new one.");
selectWindow(view);
return;
}
LOGGER.info("Create new RailcomPlusView.");
railcomPlusModel = new RailcomPlusModel();
railcomPlusView = new RailcomPlusView(railcomPlusModel);
DockableState[] dockables = desktop.getDockables();
LOGGER.info("Current dockables: {}", new Object[] { dockables });
if (dockables.length > 1) {
DockableState tabPanelNodeDetails = null;
// search the node details tab panel
for (DockableState dockable : dockables) {
if (DockKeys.DOCKKEY_TAB_PANEL.equals(dockable.getDockable().getDockKey())) {
LOGGER.info("Found the tab panel dockable.");
tabPanelNodeDetails = dockable;
break;
}
}
Dockable dock = desktop.getDockables()[1].getDockable();
if (tabPanelNodeDetails != null) {
LOGGER.info("Add the railcom plus view to the node details panel.");
dock = tabPanelNodeDetails.getDockable();
TabbedDockableContainer container = DockingUtilities.findTabbedDockableContainer(dock);
int order = 0;
if (container != null) {
order = container.getTabCount();
}
LOGGER.info("Add new railcomPlusView at order: {}", order);
desktop.createTab(dock, railcomPlusView, order, true);
}
else {
desktop.split(dock, railcomPlusView, DockingConstants.SPLIT_RIGHT);
// desktop.setDockableHeight(railcomPlusView, 0.2d);
}
}
else {
desktop.addDockable(railcomPlusView, RelativeDockablePosition.RIGHT);
}
final Communication communication = CommunicationFactory.getInstance();
railcomPlusView.addRailcomPlusViewListener(new RailcomPlusViewListener() {
private Node getCommandStationNode() {
// search the command station node
Collection nodes = mainController.getNodes();
Node commandStationNode = null;
for (Node node : nodes) {
if (node.isCommandStation()) {
commandStationNode = node;
LOGGER.info("Found a command station node: {}", commandStationNode);
break;
}
}
return commandStationNode;
}
@Override
public void readTid() {
LOGGER.info("Query the TID.");
Node commandStationNode = getCommandStationNode();
if (commandStationNode == null) {
LOGGER.warn("No command station node available! Operation aborted!");
// show dialog
JOptionPane.showMessageDialog(null,
Resources.getString(RailcomPlusController.class, "no_commandstation_available"));
return;
}
// clear the current TID
railcomPlusModel.setTid(null);
communication.getRcPlusTid(commandStationNode.getNode());
}
@Override
public void updateSid() {
TidData tidData = railcomPlusModel.getTid();
if (tidData != null) {
int sid = tidData.getSid();
sid++;
LOGGER.info("Incremented the SID: {}", sid);
Node commandStationNode = getCommandStationNode();
if (commandStationNode == null) {
LOGGER.warn("No command station node available! Operation aborted!");
// show dialog
JOptionPane.showMessageDialog(null,
Resources.getString(RailcomPlusController.class, "no_commandstation_available"));
return;
}
communication.setRcPlusTid(commandStationNode.getNode(), new TidData(tidData.getUniqueId(), sid));
}
else {
LOGGER.warn("No TID available! Operation aborted!");
// TODO add I18N
JOptionPane.showMessageDialog(null, "No TID available! Read TID before update SID!");
}
}
@Override
public void updateTid() {
TidData tidData = railcomPlusModel.getTid();
if (tidData != null) {
int sid = tidData.getSid();
RcPlusUniqueIdData uniqueId = tidData.getUniqueId();
uniqueId = new RcPlusUniqueIdData(/* uniqueId.getMun() + 1 */0x0D0C0B0A, uniqueId.getMid());
LOGGER.info("Incremented the TID: {}", uniqueId);
Node commandStationNode = getCommandStationNode();
if (commandStationNode == null) {
LOGGER.warn("No command station node available! Operation aborted!");
// show dialog
JOptionPane.showMessageDialog(null,
Resources.getString(RailcomPlusController.class, "no_commandstation_available"));
return;
}
communication.setRcPlusTid(commandStationNode.getNode(), new TidData(uniqueId, sid));
}
else {
LOGGER.warn("No TID available! Operation aborted!");
// TODO add I18N
JOptionPane.showMessageDialog(null, "No TID available! Read TID before update SID!");
}
}
public void pingOnce(RcPlusPhase phase) {
Node commandStationNode = getCommandStationNode();
if (commandStationNode == null) {
LOGGER.warn("No command station node available! Operation aborted!");
// show dialog
JOptionPane.showMessageDialog(null,
Resources.getString(RailcomPlusController.class, "no_commandstation_available"));
return;
}
communication.sendPingOnce(commandStationNode.getNode(), phase);
}
@Override
public void ping(int interval) {
Node commandStationNode = getCommandStationNode();
if (commandStationNode == null) {
LOGGER.warn("No command station node available! Operation aborted!");
// show dialog
JOptionPane.showMessageDialog(null,
Resources.getString(RailcomPlusController.class, "no_commandstation_available"));
return;
}
communication.sendPing(commandStationNode.getNode(), interval);
}
@Override
public void find(RcPlusPhase phase, RcPlusUniqueIdData decoder) {
Node commandStationNode = getCommandStationNode();
if (commandStationNode == null) {
LOGGER.warn("No command station node available! Operation aborted!");
// show dialog
JOptionPane.showMessageDialog(null,
Resources.getString(RailcomPlusController.class, "no_commandstation_available"));
return;
}
communication.sendFind(commandStationNode.getNode(), phase, decoder);
}
@Override
public void bind(RcPlusBindData bindData) {
Node commandStationNode = getCommandStationNode();
if (commandStationNode == null) {
LOGGER.warn("No command station node available! Operation aborted!");
// show dialog
JOptionPane.showMessageDialog(null,
Resources.getString(RailcomPlusController.class, "no_commandstation_available"));
return;
}
communication.sendBind(commandStationNode.getNode(), bindData);
}
});
try {
// Create the message listener for the railcom plus messages
messageListener = new DefaultMessageListener() {
@Override
public void csRcPlusTid(final byte[] address, final TidData tid) {
LOGGER.info("Received the TID: {}, address: {}", tid, address);
if (SwingUtilities.isEventDispatchThread()) {
railcomPlusModel.setTid(tid);
}
else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
railcomPlusModel.setTid(tid);
}
});
}
}
@Override
public void csRcPlusPingAcknState(byte[] address, RcPlusPhase phase, RcPlusAcknowledge acknState) {
LOGGER.info("Received the ping ackn state: {}, phase: {}, address:{}", acknState, phase, address);
// no implementation
}
@Override
public void csRcPlusBindAnswer(byte[] address, RcPlusDecoderAnswerData decoderAnswer) {
LOGGER.info("Received the bind answer: {}, address:{}", decoderAnswer, address);
// no implementation
}
@Override
public void csRcPlusFindAnswer(byte[] address, RcPlusPhase phase, RcPlusDecoderAnswerData decoderAnswer) {
LOGGER.info("Received the find answer: {}, phase: {}, address:{}", decoderAnswer, phase, address);
// no implementation
}
@Override
public void feedbackRcPlusBindAccepted(
byte[] address, int detectorNum, RcPlusDecoderType decoderType,
RcPlusFeedbackBindData rcPlusBindAccepted) {
LOGGER.info(
"Received the feedback bind accepted answer: {}, detectorNum: {}, decoderType: {}, address:{}",
rcPlusBindAccepted, detectorNum, decoderType, address);
}
@Override
public void feedbackRcPlusPongNew(
byte[] address, int detectorNum, RcPlusPhase phase, RcPlusDecoderType decoderType,
RcPlusUniqueIdData uniqueId) {
LOGGER.info(
"Received the feedback PONG NEW, uniqueId: {}, detectorNum: {}, decoderType: {}, address:{}",
uniqueId, detectorNum, decoderType, address);
RailcomPlusDecoderModel decoder = new RailcomPlusDecoderModel();
decoder.setDecoderMun(uniqueId.getMun());
decoder.setDecoderManufacturer(uniqueId.getMid());
railcomPlusModel.addDecoder(decoder);
}
@Override
public void feedbackRcPlusPongOkay(
byte[] address, int detectorNum, RcPlusPhase phase, RcPlusDecoderType decoderType,
RcPlusUniqueIdData uniqueId) {
LOGGER.info(
"Received the feedback PONG OKAY, uniqueId: {}, detectorNum: {}, decoderType: {}, address:{}",
uniqueId, detectorNum, decoderType, address);
RailcomPlusDecoderModel decoder = new RailcomPlusDecoderModel();
decoder.setDecoderMun(uniqueId.getMun());
decoder.setDecoderManufacturer(uniqueId.getMid());
railcomPlusModel.addDecoder(decoder);
}
};
CommunicationFactory.addMessageListener(messageListener);
}
catch (Exception ex) {
LOGGER.warn("Add message listener for railcom+ messages failed.", ex);
}
railcomPlusView.addDecoderAddressListener(new DecoderAddressListener() {
private Node getCommandStationNode() {
// search the command station node
Collection nodes = mainController.getNodes();
Node commandStationNode = null;
for (Node node : nodes) {
if (node.isCommandStation()) {
commandStationNode = node;
LOGGER.info("Found a command station node: {}", commandStationNode);
break;
}
}
return commandStationNode;
}
@Override
public void setAddress(RailcomPlusDecoderModel decoder) {
LOGGER.info("Set address of decoder: {}", decoder);
Node commandStationNode = getCommandStationNode();
if (commandStationNode == null) {
LOGGER.warn("No command station node available! Operation aborted!");
// show dialog
JOptionPane.showMessageDialog(null,
Resources.getString(RailcomPlusController.class, "no_commandstation_available"));
return;
}
try {
RcPlusUniqueIdData uniqueIdData =
new RcPlusUniqueIdData(decoder.getDecoderMun(), decoder.getDecoderManufacturer());
AddressData address =
new AddressData(decoder.getDecoderAddress(), AddressTypeEnum.LOCOMOTIVE_FORWARD);
RcPlusBindData bindData = new RcPlusBindData(uniqueIdData, address);
communication.sendBind(commandStationNode.getNode(), bindData);
}
catch (Exception ex) {
LOGGER.warn("Set decoder address failed.", ex);
}
}
});
// add the node list listener
mainModel.addNodeListListener(this);
}
private void selectWindow(Dockable dockable) {
TabbedDockableContainer container = DockingUtilities.findTabbedDockableContainer(dockable);
if (container != null) {
container.setSelectedDockable(dockable);
}
else {
LOGGER.warn("Container not available, select component directly.");
dockable.getComponent().requestFocusInWindow();
}
}
@Override
public void listChanged() {
LOGGER.info("The node list has changed.");
}
@Override
public void nodeChanged() {
LOGGER.debug("The node has changed, current node in model: {}", node);
if (SwingUtilities.isEventDispatchThread()) {
internalNodeChanged();
}
else {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
internalNodeChanged();
}
});
}
}
private void internalNodeChanged() {
LOGGER.debug("handle node has changed, node: {}", node);
if (node != null && node.equals(mainModel.getSelectedNode())) {
LOGGER.debug("The node in the model has not changed.");
return;
}
// check if we must close the scenery panel
// Dockable dmxSceneryDockable = desktop.getContext().getDockableByKey("DmxSceneryView");
if (railcomPlusView != null) {
LOGGER.info("Close the railcomPlusView panel: {}", railcomPlusView);
desktop.close(railcomPlusView);
}
// unregister node list listener
mainModel.removeNodeListListener(this);
}
@Override
public void nodeStateChanged() {
}
@Override
public void listNodeAdded(Node node) {
}
@Override
public void listNodeRemoved(Node node) {
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy