Mercurial > hg > heapstats
view analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/fx/plugin/builtin/log/LogController.java @ 272:dd85c1cbc8c8
Bug 3752: Migrate to OpenJFX 13
Reviewed-by: ykubota
https://github.com/HeapStats/heapstats/pull/144
author | Yasumasa Suenaga <yasuenag@gmail.com> |
---|---|
date | Fri, 27 Sep 2019 14:47:03 +0900 |
parents | |
children |
line wrap: on
line source
/* * Copyright (C) 2014-2019 Yasumasa Suenaga * * 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 2 * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package jp.co.ntt.oss.heapstats.fx.plugin.builtin.log; import javafx.application.Platform; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.event.Event; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.SplitPane; import javafx.scene.control.TextField; import javafx.stage.FileChooser; import javafx.stage.FileChooser.ExtensionFilter; import jp.co.ntt.oss.heapstats.fx.MainWindowController; import jp.co.ntt.oss.heapstats.container.log.ArchiveData; import jp.co.ntt.oss.heapstats.container.log.DiffData; import jp.co.ntt.oss.heapstats.container.log.LogData; import jp.co.ntt.oss.heapstats.lambda.ConsumerWrapper; import jp.co.ntt.oss.heapstats.lambda.FunctionWrapper; import jp.co.ntt.oss.heapstats.api.plugin.PluginController; import jp.co.ntt.oss.heapstats.fx.plugin.builtin.log.tabs.LogDetailsController; import jp.co.ntt.oss.heapstats.fx.plugin.builtin.log.tabs.LogResourcesController; import jp.co.ntt.oss.heapstats.task.ParseLogFile; import jp.co.ntt.oss.heapstats.api.utils.HeapStatsUtils; import jp.co.ntt.oss.heapstats.fx.utils.TaskAdapter; import java.io.File; import java.net.URL; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; /** * FXML Controller of LOG builtin plugin. * * @author Yasumasa Suenaga */ public class LogController extends PluginController implements Initializable { @FXML private LogResourcesController logResourcesController; @FXML private LogDetailsController logDetailsController; @FXML private Label startTimeLabel; @FXML private Label endTimeLabel; @FXML private TextField logFileList; @FXML private Button okBtn; @FXML private SplitPane rangePane; private ObjectProperty<LocalDateTime> rangeStart; private ObjectProperty<LocalDateTime> rangeEnd; private List<LogData> logEntries; private List<DiffData> diffEntries; private ObjectProperty<ObservableList<ArchiveData>> archiveList; /** * Update caption of label which represents time of selection. * * @param target Label compornent to draw. * @param newValue Percentage of timeline. This value is between 0.0 and 1.0 . */ private void updateRangeLabel(Label target, double newValue){ if(!Optional.ofNullable(logEntries).map(List::isEmpty).orElse(true)){ LocalDateTime start = logEntries.get(0).getDateTime(); LocalDateTime end = logEntries.get(logEntries.size() - 1).getDateTime(); long diff = start.until(end, ChronoUnit.MILLIS); LocalDateTime newTime = start.plus((long)(diff * (Math.round(newValue * 100.0d) / 100.0d)), ChronoUnit.MILLIS); if(target == startTimeLabel){ rangeStart.set(newTime.truncatedTo(ChronoUnit.SECONDS)); } else{ rangeEnd.set(newTime.plusSeconds(1).truncatedTo(ChronoUnit.SECONDS)); } target.setText(newTime.format(HeapStatsUtils.getDateTimeFormatter())); } } /** * Initializes the controller class. */ @Override public void initialize(URL url, ResourceBundle rb) { super.initialize(url, rb); logEntries = null; diffEntries = null; rangeStart = new SimpleObjectProperty<>(); rangeEnd = new SimpleObjectProperty<>(); rangePane.getDividers().get(0).positionProperty().addListener((v, o, n) -> updateRangeLabel(startTimeLabel, n.doubleValue())); rangePane.getDividers().get(1).positionProperty().addListener((v, o, n) -> updateRangeLabel(endTimeLabel, n.doubleValue())); archiveList = new SimpleObjectProperty<>(FXCollections.emptyObservableList()); logResourcesController.archiveListProperty().bind(archiveList); logDetailsController.archiveListProperty().bind(archiveList); setOnWindowResize((v, o, n) -> Platform.runLater(logResourcesController::drawEventLineToChart)); } /** * onSucceeded event handler for LogFileParser. * * @param parser Targeted LogFileParser. */ private void onLogFileParserSucceeded(ParseLogFile parser) { logEntries = parser.getLogEntries(); diffEntries = parser.getDiffEntries(); rangePane.getDividers().get(0).setPosition(0.0d); rangePane.getDividers().get(1).setPosition(1.0d); rangePane.setDisable(false); okBtn.setDisable(false); } /** * Event handler of LogFile button. * * @param event ActionEvent of this event. */ @FXML public void onLogFileClick(ActionEvent event) { FileChooser dialog = new FileChooser(); ResourceBundle resource = ResourceBundle.getBundle("logResources", new Locale(HeapStatsUtils.getLanguage())); dialog.setTitle(resource.getString("dialog.filechooser.title")); dialog.setInitialDirectory(new File(HeapStatsUtils.getDefaultDirectory())); dialog.getExtensionFilters().addAll(new ExtensionFilter("Log file (*.csv)", "*.csv"), new ExtensionFilter("All files", "*.*")); List<File> logList = dialog.showOpenMultipleDialog(MainWindowController.getInstance().getOwner()); if (logList != null) { logResourcesController.clearAllItems(); logDetailsController.clearAllItems(); HeapStatsUtils.setDefaultDirectory(logList.get(0).getParent()); String logListStr = logList.stream() .map(File::getAbsolutePath) .collect(Collectors.joining("; ")); logFileList.setText(logListStr); TaskAdapter<ParseLogFile> task = new TaskAdapter<>(new ParseLogFile(logList, true)); task.setOnSucceeded(evt -> onLogFileParserSucceeded(task.getTask())); super.bindTask(task); Thread parseThread = new Thread(task); parseThread.start(); } } /** * Event handler of OK button. * * @param event ActionEvent of this event. */ @FXML private void onOkClick(ActionEvent event) { /* Get range */ LocalDateTime start = rangeStart.getValue(); LocalDateTime end = rangeEnd.getValue(); List<LogData> targetLogData = logEntries.parallelStream() .filter(d -> ((d.getDateTime().compareTo(start) >= 0) && (d.getDateTime().compareTo(end) <= 0))) .collect(Collectors.toList()); List<DiffData> targetDiffData = diffEntries.parallelStream() .filter(d -> ((d.getDateTime().compareTo(start) >= 0) && (d.getDateTime().compareTo(end) <= 0))) .collect(Collectors.toList()); Task<Void> task = logResourcesController.createDrawResourceCharts(targetLogData, targetDiffData); super.bindTask(task); Thread drawChartThread = new Thread(task); drawChartThread.start(); archiveList.set(FXCollections.observableArrayList(targetLogData.stream() .filter(d -> d.getArchivePath() != null) .map(new FunctionWrapper<>(ArchiveData::new)) .peek(new ConsumerWrapper<>(a -> a.parseArchive())) .collect(Collectors.toList()))); } /** * Returns plugin name. This value is used to show in main window tab. * * @return Plugin name. */ @Override public String getPluginName() { return "Log Data"; } @Override public EventHandler<Event> getOnPluginTabSelected() { return null; } @Override public String getLicense() { return PluginController.LICENSE_GPL_V2; } @Override public Map<String, String> getLibraryLicense() { return null; } @Override public Runnable getOnCloseRequest() { return null; } @Override public void setData(Object data, boolean select) { super.setData(data, select); logFileList.setText((String) data); TaskAdapter<ParseLogFile> task = new TaskAdapter<>(new ParseLogFile(Arrays.asList(new File((String) data)), true)); task.setOnSucceeded(evt -> onLogFileParserSucceeded(task.getTask())); super.bindTask(task); Thread parseThread = new Thread(task); parseThread.start(); } }