/***********************************************************************************
*
* Copyright (c) 2015 Kamil Baczkowicz
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*
* Kamil Baczkowicz - initial API and implementation and/or initial documentation
*
*/
package pl.baczkowicz.mqttspy.ui.controllers.edit;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.AnchorPane;
import javafx.util.Callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pl.baczkowicz.mqttspy.configuration.ConfiguredConnectionDetails;
import pl.baczkowicz.mqttspy.configuration.generated.TabbedSubscriptionDetails;
import pl.baczkowicz.mqttspy.configuration.generated.UserInterfaceMqttConnectionDetails;
import pl.baczkowicz.mqttspy.ui.EditConnectionController;
import pl.baczkowicz.spy.ui.properties.BaseTopicProperty;
import pl.baczkowicz.spy.ui.properties.SubscriptionTopicProperties;
/**
* Controller for editing a single connection - subscriptions tab.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class EditConnectionSubscriptionsController extends AnchorPane implements Initializable, EditConnectionSubController
{
private final static Logger logger = LoggerFactory.getLogger(EditConnectionSubscriptionsController.class);
/** The parent controller. */
private EditConnectionController parent;
// Action buttons
@FXML
private Button removeSubscriptionButton;
// Pubs / subs
@FXML
private TextField searchScriptsText;
// Tables
@FXML
private TableView<SubscriptionTopicProperties> subscriptionsTable;
@FXML
private TableColumn<SubscriptionTopicProperties, String> subscriptionTopicColumn;
@FXML
private TableColumn<SubscriptionTopicProperties, String> scriptColumn;
@FXML
private TableColumn<SubscriptionTopicProperties, Integer> qosSubscriptionColumn;
@FXML
private TableColumn<SubscriptionTopicProperties, Boolean> createTabSubscriptionColumn;
// Other fields
private final ChangeListener basicOnChangeListener = new ChangeListener()
{
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue)
{
onChange();
}
};
// ===============================
// === Initialisation ============
// ===============================
public void initialize(URL location, ResourceBundle resources)
{
// Subscriptions
searchScriptsText.textProperty().addListener(basicOnChangeListener);
createTabSubscriptionColumn.setCellValueFactory(new PropertyValueFactory<SubscriptionTopicProperties, Boolean>("show"));
createTabSubscriptionColumn.setCellFactory(new Callback<TableColumn<SubscriptionTopicProperties, Boolean>, TableCell<SubscriptionTopicProperties, Boolean>>()
{
public TableCell<SubscriptionTopicProperties, Boolean> call(
TableColumn<SubscriptionTopicProperties, Boolean> p)
{
final TableCell<SubscriptionTopicProperties, Boolean> cell = new TableCell<SubscriptionTopicProperties, Boolean>()
{
@Override
public void updateItem(final Boolean item, boolean empty)
{
super.updateItem(item, empty);
if (!isEmpty())
{
final SubscriptionTopicProperties shownItem = getTableView().getItems().get(getIndex());
CheckBox box = new CheckBox();
box.selectedProperty().bindBidirectional(shownItem.showProperty());
box.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent event)
{
logger.info("New value = {} {}",
shownItem.topicProperty().getValue(),
shownItem.showProperty().getValue());
onChange();
}
});
setGraphic(box);
}
else
{
setGraphic(null);
}
}
};
cell.setAlignment(Pos.CENTER);
return cell;
}
});
subscriptionTopicColumn.setCellValueFactory(new PropertyValueFactory<SubscriptionTopicProperties, String>("topic"));
subscriptionTopicColumn.setCellFactory(TextFieldTableCell.<SubscriptionTopicProperties>forTableColumn());
subscriptionTopicColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<SubscriptionTopicProperties, String>>()
{
@Override
public void handle(CellEditEvent<SubscriptionTopicProperties, String> event)
{
BaseTopicProperty p = event.getRowValue();
String newValue = event.getNewValue();
p.topicProperty().set(newValue);
logger.debug("New value = {}", subscriptionsTable.getSelectionModel().getSelectedItem().topicProperty().getValue());
onChange();
}
});
scriptColumn.setCellValueFactory(new PropertyValueFactory<SubscriptionTopicProperties, String>("script"));
scriptColumn.setCellFactory(TextFieldTableCell.<SubscriptionTopicProperties>forTableColumn());
scriptColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<SubscriptionTopicProperties, String>>()
{
@Override
public void handle(CellEditEvent<SubscriptionTopicProperties, String> event)
{
SubscriptionTopicProperties p = event.getRowValue();
String newValue = event.getNewValue();
p.scriptProperty().set(newValue);
logger.debug("New value = {}", subscriptionsTable.getSelectionModel().getSelectedItem().scriptProperty().getValue());
onChange();
}
});
final ObservableList<Integer> qosChoice = FXCollections.observableArrayList (
new Integer(0),
new Integer(1),
new Integer(2)
);
qosSubscriptionColumn.setCellValueFactory(new PropertyValueFactory<SubscriptionTopicProperties, Integer>("qos"));
qosSubscriptionColumn.setCellFactory(new Callback<TableColumn<SubscriptionTopicProperties, Integer>, TableCell<SubscriptionTopicProperties, Integer>>()
{
public TableCell<SubscriptionTopicProperties, Integer> call(
TableColumn<SubscriptionTopicProperties, Integer> p)
{
final TableCell<SubscriptionTopicProperties, Integer> cell = new TableCell<SubscriptionTopicProperties, Integer>()
{
@Override
public void updateItem(final Integer item, boolean empty)
{
super.updateItem(item, empty);
if (!isEmpty())
{
final SubscriptionTopicProperties shownItem = getTableView().getItems().get(getIndex());
ChoiceBox box = new ChoiceBox();
box.setItems(qosChoice);
box.setId("subscriptionQosChoice");
int qos = shownItem.qosProperty().getValue();
box.getSelectionModel().select(qos);
box.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Integer>()
{
@Override
public void changed(ObservableValue<? extends Integer> observable, Integer oldValue, Integer newValue)
{
shownItem.qosProperty().setValue(newValue);
logger.info("New value = {} {}",
shownItem.topicProperty().getValue(),
shownItem.qosProperty().getValue());
onChange();
}
});
setGraphic(box);
}
else
{
setGraphic(null);
}
}
};
cell.setAlignment(Pos.CENTER);
return cell;
}
});
qosSubscriptionColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<SubscriptionTopicProperties, Integer>>()
{
@Override
public void handle(CellEditEvent<SubscriptionTopicProperties, Integer> event)
{
SubscriptionTopicProperties p = event.getRowValue();
Integer newValue = event.getNewValue();
p.qosProperty().set(newValue);
logger.debug("New value = {}", subscriptionsTable.getSelectionModel().getSelectedItem().qosProperty().getValue());
onChange();
}
});
}
public void init()
{
// Nothing to do
}
// ===============================
// === FXML ======================
// ===============================
@FXML
private void addSubscription()
{
final SubscriptionTopicProperties item = new SubscriptionTopicProperties("/sampleSubscription/", "", 0, false);
subscriptionsTable.getItems().add(item);
onChange();
}
@FXML
private void removeSubscription()
{
final SubscriptionTopicProperties item = subscriptionsTable.getSelectionModel().getSelectedItem();
if (item != null)
{
subscriptionsTable.getItems().remove(item);
onChange();
}
}
// ===============================
// === Logic =====================
// ===============================
public void onChange()
{
parent.onChange();
}
@Override
public UserInterfaceMqttConnectionDetails readValues(final UserInterfaceMqttConnectionDetails connection)
{
// Subscriptions
connection.setSearchScripts(searchScriptsText.getText());
for (final SubscriptionTopicProperties subscriptionDetails : subscriptionsTable.getItems())
{
final TabbedSubscriptionDetails newSubscriptionDetails = new TabbedSubscriptionDetails();
newSubscriptionDetails.setTopic(subscriptionDetails.topicProperty().getValue());
newSubscriptionDetails.setScriptFile(subscriptionDetails.scriptProperty().getValue());
newSubscriptionDetails.setCreateTab(subscriptionDetails.showProperty().getValue());
newSubscriptionDetails.setQos(subscriptionDetails.qosProperty().getValue());
connection.getSubscription().add(newSubscriptionDetails);
}
return connection;
}
@Override
public void displayConnectionDetails(final ConfiguredConnectionDetails connection)
{
// Subscriptions
searchScriptsText.setText(connection.getSearchScripts());
removeSubscriptionButton.setDisable(true);
subscriptionsTable.getItems().clear();
for (final TabbedSubscriptionDetails sub : connection.getSubscription())
{
subscriptionsTable.getItems().add(new SubscriptionTopicProperties(
sub.getTopic(),
sub.getScriptFile() == null ? "" : sub.getScriptFile(),
sub.getQos(), sub.isCreateTab()));
}
subscriptionsTable.getSelectionModel().selectedItemProperty().addListener(new ChangeListener()
{
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue)
{
removeSubscriptionButton.setDisable(false);
}
});
}
// ===============================
// === Setters and getters =======
// ===============================
@Override
public void setParent(final EditConnectionController controller)
{
this.parent = controller;
}
}