/***********************************************************************************
*
* Copyright (c) 2014 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;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.util.Callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pl.baczkowicz.mqttspy.connectivity.BaseMqttSubscription;
import pl.baczkowicz.mqttspy.connectivity.MqttAsyncConnection;
import pl.baczkowicz.mqttspy.connectivity.MqttSubscription;
import pl.baczkowicz.mqttspy.messages.FormattedMqttMessage;
import pl.baczkowicz.mqttspy.ui.utils.StylingUtils;
import pl.baczkowicz.spy.eventbus.IKBus;
import pl.baczkowicz.spy.ui.events.MessageIndexChangeEvent;
import pl.baczkowicz.spy.ui.properties.MessageContentProperties;
import pl.baczkowicz.spy.ui.storage.BasicMessageStoreWithSummary;
import pl.baczkowicz.spy.ui.utils.UiUtils;
/**
* Controller for the message list table.
*/
public class MessageListTableController implements Initializable
{
final static Logger logger = LoggerFactory.getLogger(MessageListTableController.class);
private ObservableList<MessageContentProperties<FormattedMqttMessage>> items;
@FXML
private TableView<MessageContentProperties<FormattedMqttMessage>> messageTable;
@FXML
private TableColumn<MessageContentProperties<FormattedMqttMessage>, String> messageTopicColumn;
@FXML
private TableColumn<MessageContentProperties<FormattedMqttMessage>, String> messageContentColumn;
@FXML
private TableColumn<MessageContentProperties<FormattedMqttMessage>, String> messageReceivedAtColumn;
private BasicMessageStoreWithSummary<FormattedMqttMessage> store;
private MqttAsyncConnection connection;
private IKBus eventBus;
public void initialize(URL location, ResourceBundle resources)
{
// Table
messageTopicColumn.setCellValueFactory(new PropertyValueFactory<MessageContentProperties<FormattedMqttMessage>, String>(
"topic"));
messageContentColumn
.setCellValueFactory(new PropertyValueFactory<MessageContentProperties<FormattedMqttMessage>, String>(
"lastReceivedPayload"));
messageReceivedAtColumn.setCellValueFactory(new PropertyValueFactory<MessageContentProperties<FormattedMqttMessage>, String>("lastReceivedTimestamp"));
messageReceivedAtColumn.setCellFactory(new Callback<TableColumn<MessageContentProperties<FormattedMqttMessage>, String>,
TableCell<MessageContentProperties<FormattedMqttMessage>, String>>()
{
public TableCell<MessageContentProperties<FormattedMqttMessage>, String> call(
TableColumn<MessageContentProperties<FormattedMqttMessage>, String> param)
{
final TableCell<MessageContentProperties<FormattedMqttMessage>, String> cell =
new TableCell<MessageContentProperties<FormattedMqttMessage>, String>()
{
@Override
public void updateItem(String item, boolean empty)
{
super.updateItem(item, empty);
if (!isEmpty())
{
setText(item.toString());
}
else
{
setText(null);
}
}
};
cell.setAlignment(Pos.TOP_CENTER);
return cell;
}
});
messageTable.setOnMouseClicked(new EventHandler<Event>()
{
@Override
public void handle(Event event)
{
selectItem();
}
});
messageTable
.setRowFactory(new Callback<TableView<MessageContentProperties<FormattedMqttMessage>>, TableRow<MessageContentProperties<FormattedMqttMessage>>>()
{
public TableRow<MessageContentProperties<FormattedMqttMessage>> call(
TableView<MessageContentProperties<FormattedMqttMessage>> tableView)
{
final TableRow<MessageContentProperties<FormattedMqttMessage>> row = new TableRow<MessageContentProperties<FormattedMqttMessage>>()
{
@Override
protected void updateItem(final MessageContentProperties<FormattedMqttMessage> item, boolean empty)
{
super.updateItem(item, empty);
if (!isEmpty() && item.getSubscription() != null)
{
final BaseMqttSubscription subscription = connection.getMqttSubscriptionForTopic(item.getSubscription());
if (subscription instanceof MqttSubscription)
{
this.setStyle(StylingUtils.createBgRGBString(
((MqttSubscription) subscription).getColor(),
getIndex() % 2 == 0 ? 0.8 : 0.6)
+ " -fx-background-radius: 6; ");
}
else
{
this.setStyle(null);
}
}
else
{
this.setStyle(null);
}
}
};
return row;
}
});
}
private void selectItem()
{
final MessageContentProperties<FormattedMqttMessage> item = messageTable.getSelectionModel().getSelectedItem();
if (item != null)
{
final List<FormattedMqttMessage> list = store.getMessages();
for (int i = 0; i < store.getMessages().size(); i++)
{
if (list.get(i).getId() == item.getId())
{
// logger.info("{} Changing selection to " + (array.length - i), store.getName());
eventBus.publish(new MessageIndexChangeEvent(i + 1, store, this));
// eventManager.changeMessageIndex(store, this, i + 1);
}
}
}
}
public void onMessageIndexChange(final MessageIndexChangeEvent event)
{
// Make sure this is not from itself
if (event.getDispatcher() == this)
{
return;
}
if (store.getMessages().size() > 0)
{
final long id = (store.getMessages().get(event.getIndex() - 1)).getId();
for (final MessageContentProperties<FormattedMqttMessage> item : items)
{
if (item.getId() == id)
{
if (!item.equals(messageTable.getSelectionModel().getSelectedItem()))
{
messageTable.getSelectionModel().select(item);
break;
}
}
}
}
}
public void init()
{
messageTable.setContextMenu(createMessageListTableContextMenu(messageTable));
messageTable.setItems(items);
}
public void setItems(final ObservableList<MessageContentProperties<FormattedMqttMessage>> items)
{
this.items = items;
}
public void setStore(final BasicMessageStoreWithSummary<FormattedMqttMessage> store)
{
this.store = store;
}
public void setConnection(final MqttAsyncConnection connection)
{
this.connection = connection;
}
public static ContextMenu createMessageListTableContextMenu(final TableView<MessageContentProperties<FormattedMqttMessage>> messageTable)
{
final ContextMenu contextMenu = new ContextMenu();
// Copy topic
final MenuItem copyTopicItem = new MenuItem("[Topic] Copy to clipboard");
copyTopicItem.setOnAction(new EventHandler<ActionEvent>()
{
public void handle(ActionEvent e)
{
final MessageContentProperties<FormattedMqttMessage> item = messageTable.getSelectionModel()
.getSelectedItem();
if (item != null)
{
UiUtils.copyToClipboard(item.topicProperty().getValue());
}
}
});
contextMenu.getItems().add(copyTopicItem);
// Separator
contextMenu.getItems().add(new SeparatorMenuItem());
// Copy content
final MenuItem copyContentItem = new MenuItem("[Content] Copy to clipboard");
copyContentItem.setOnAction(new EventHandler<ActionEvent>()
{
public void handle(ActionEvent e)
{
final MessageContentProperties<FormattedMqttMessage> item = messageTable.getSelectionModel()
.getSelectedItem();
if (item != null)
{
UiUtils.copyToClipboard(item.lastReceivedPayloadProperty().getValue());
}
}
});
contextMenu.getItems().add(copyContentItem);
return contextMenu;
}
public void setEventBus(final IKBus eventBus)
{
this.eventBus = eventBus;
}
}