/* CloudTrail Viewer, is a Java desktop application for reading AWS CloudTrail logs files. Copyright (C) 2017 Mark P. Haskins This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package io.haskins.java.cloudtrailviewer.controller.components; import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon; import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView; import io.haskins.java.cloudtrailviewer.model.DashboardWidget; import io.haskins.java.cloudtrailviewer.model.event.Event; import io.haskins.java.cloudtrailviewer.service.DashboardService; import io.haskins.java.cloudtrailviewer.service.EventService; import io.haskins.java.cloudtrailviewer.service.EventTableService; import io.haskins.java.cloudtrailviewer.service.listener.EventServiceListener; import io.haskins.java.cloudtrailviewer.service.listener.EventTableServiceListener; import io.haskins.java.cloudtrailviewer.utils.EventUtils; import javafx.beans.binding.Bindings; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.transformation.FilteredList; import javafx.collections.transformation.SortedList; import javafx.fxml.FXML; import javafx.geometry.Pos; import javafx.geometry.Side; import javafx.scene.control.*; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; /** * This component provides the TableView location at the bottom of the application. * * Created by markhaskins on 26/01/2017. */ @Component public class EventTableController implements EventTableServiceListener, EventServiceListener { @FXML private TableView<Event> tableView; @FXML private Label searchLabel; @FXML private TextField searchField; @FXML private Label resultCount; @FXML private HBox hboxPopup; @FXML private Button popupMenu; private ContextMenu colPopup = new ContextMenu(); private ObservableList<Event> filteredEvents = FXCollections.observableArrayList(); private DashboardService dashboardService; @Autowired public EventTableController(EventService eventService, EventTableService eventTableService, DashboardService dashboardService) { eventTableService.addListener(this); eventService.registerAsListener(this); this.dashboardService = dashboardService; } @FXML private void showPopupMenu() { colPopup.show(popupMenu, Side.LEFT, 0, 0); } @FXML public void initialize() { tableView.setRowFactory(tv -> { TableRow<Event> row = new TableRow<>(); row.setOnMouseClicked(event -> { if (event.getClickCount() ==2 && !row.isEmpty()) { Event rowItem = row.getItem(); DashboardWidget widget = new DashboardWidget(); widget.setWidget("Json"); widget.setTitle("Event JSON"); widget.setWidth(425); widget.setHeight(600); widget.setPayload(rowItem); dashboardService.addWidgetToDashboard(widget); } }); return row; }); tableView.setItems(filteredEvents); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); FilteredList<Event> filteredData = new FilteredList<>(filteredEvents, p -> true); searchField.textProperty().addListener((observable, oldValue, newValue) -> filteredData.setPredicate(event -> { if (newValue== null || newValue.isEmpty()) { return true; } String lowerCaseFilter = newValue.toLowerCase(); if (event.getRawJSON() == null) { EventUtils.addRawJson(event); } return event.getRawJSON().toLowerCase().contains(lowerCaseFilter); })); SortedList<Event> sortedData = new SortedList<>(filteredData); sortedData.comparatorProperty().bind(tableView.comparatorProperty()); tableView.setItems(sortedData); searchLabel.setGraphic(new FontAwesomeIconView(FontAwesomeIcon.SEARCH)); resultCount.textProperty().bind(Bindings.size(filteredData).asString()); HBox.setHgrow(hboxPopup, Priority.ALWAYS); hboxPopup.setAlignment(Pos.CENTER_RIGHT); popupMenu.setGraphic(new FontAwesomeIconView(FontAwesomeIcon.COG)); createPopupMenu(); } /** * Updates the table with the provided events. * @param events a List of Events */ public void setEvents(List<Event> events) { if (events != null && !events.isEmpty()) { filteredEvents.clear(); filteredEvents.addAll(events); } } @Override public void newEvent(Event event) { } @Override public void newEvents(List<Event> events) { } @Override public void loadingFile(int fileNum, int totalFiles) { } @Override public void finishedLoading(boolean reload) { } @Override public void clearEvents() { filteredEvents.clear(); } private void createPopupMenu() { ObservableList<TableColumn<Event,?>> cols = tableView.getColumns(); for (TableColumn col : cols) { String name = col.textProperty().get(); CheckMenuItem item = new CheckMenuItem(name); item.setSelected(col.isVisible()); item.setOnAction(event -> { col.setVisible(!col.isVisible()); item.setSelected(col.isVisible()); }); colPopup.getItems().add(item); } } }