forked from j62/ctbrec
Add context menu to logging table
This commit is contained in:
parent
792a6c10c8
commit
fe9ac0680d
|
@ -7,8 +7,13 @@ import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.LoggerContext;
|
||||||
|
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
|
||||||
import ch.qos.logback.classic.spi.IThrowableProxy;
|
import ch.qos.logback.classic.spi.IThrowableProxy;
|
||||||
import ch.qos.logback.classic.spi.LoggingEvent;
|
import ch.qos.logback.classic.spi.LoggingEvent;
|
||||||
import ch.qos.logback.classic.spi.StackTraceElementProxy;
|
import ch.qos.logback.classic.spi.StackTraceElementProxy;
|
||||||
|
@ -19,9 +24,16 @@ import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.scene.control.ContextMenu;
|
||||||
|
import javafx.scene.control.MenuItem;
|
||||||
|
import javafx.scene.control.SelectionMode;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
import javafx.scene.control.TableColumn;
|
import javafx.scene.control.TableColumn;
|
||||||
import javafx.scene.control.TableView;
|
import javafx.scene.control.TableView;
|
||||||
|
import javafx.scene.input.Clipboard;
|
||||||
|
import javafx.scene.input.ClipboardContent;
|
||||||
|
import javafx.scene.input.ContextMenuEvent;
|
||||||
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.BorderPane;
|
||||||
|
|
||||||
public class LoggingTab extends Tab {
|
public class LoggingTab extends Tab {
|
||||||
|
@ -33,6 +45,7 @@ public class LoggingTab extends Tab {
|
||||||
private ObservableList<LoggingEvent> filteredEvents = FXCollections.observableArrayList();
|
private ObservableList<LoggingEvent> filteredEvents = FXCollections.observableArrayList();
|
||||||
private DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
private DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||||
private volatile boolean tabClosed = false;
|
private volatile boolean tabClosed = false;
|
||||||
|
private ContextMenu popup;
|
||||||
private Object eventBustSubscriber = new Object() {
|
private Object eventBustSubscriber = new Object() {
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void publishLoggingEevent(LoggingEvent event) {
|
public void publishLoggingEevent(LoggingEvent event) {
|
||||||
|
@ -75,6 +88,14 @@ public class LoggingTab extends Tab {
|
||||||
});
|
});
|
||||||
table.getColumns().add(time);
|
table.getColumns().add(time);
|
||||||
|
|
||||||
|
TableColumn<LoggingEvent, String> location = createTableColumn("Location", 250, idx++);
|
||||||
|
location.setCellValueFactory(cdf -> {
|
||||||
|
StackTraceElement loc = cdf.getValue().getCallerData()[0];
|
||||||
|
String l = loc.getFileName() + ":" + loc.getLineNumber();
|
||||||
|
return new SimpleStringProperty(l);
|
||||||
|
});
|
||||||
|
table.getColumns().add(location);
|
||||||
|
|
||||||
TableColumn<LoggingEvent, String> msg = createTableColumn("Message", 2000, idx++);
|
TableColumn<LoggingEvent, String> msg = createTableColumn("Message", 2000, idx++);
|
||||||
msg.setCellValueFactory(cdf -> new SimpleStringProperty(createLogMessage(cdf.getValue())));
|
msg.setCellValueFactory(cdf -> new SimpleStringProperty(createLogMessage(cdf.getValue())));
|
||||||
table.getColumns().add(msg);
|
table.getColumns().add(msg);
|
||||||
|
@ -93,6 +114,59 @@ public class LoggingTab extends Tab {
|
||||||
|
|
||||||
filter.setPromptText("Search");
|
filter.setPromptText("Search");
|
||||||
filter.textProperty().addListener( (observableValue, oldValue, newValue) -> filter());
|
filter.textProperty().addListener( (observableValue, oldValue, newValue) -> filter());
|
||||||
|
|
||||||
|
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
||||||
|
table.addEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, event -> {
|
||||||
|
popup = createContextMenu();
|
||||||
|
if (popup != null) {
|
||||||
|
popup.show(table, event.getScreenX(), event.getScreenY());
|
||||||
|
}
|
||||||
|
event.consume();
|
||||||
|
});
|
||||||
|
table.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
|
||||||
|
if (popup != null) {
|
||||||
|
popup.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContextMenu createContextMenu() {
|
||||||
|
final ObservableList<LoggingEvent> selectedEvents = table.getSelectionModel().getSelectedItems();
|
||||||
|
if (selectedEvents.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
MenuItem copy = new MenuItem("Copy");
|
||||||
|
copy.setOnAction(e -> {
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
String formattedMessages = getFormattedMessages(selectedEvents);
|
||||||
|
final Clipboard clipboard = Clipboard.getSystemClipboard();
|
||||||
|
final ClipboardContent content = new ClipboardContent();
|
||||||
|
content.putString(formattedMessages);
|
||||||
|
clipboard.setContent(content);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ContextMenu menu = new ContextMenu(copy);
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFormattedMessages(ObservableList<LoggingEvent> selectedEvents) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||||
|
LoggerContext loggerContext = rootLogger.getLoggerContext();
|
||||||
|
loggerContext.reset();
|
||||||
|
|
||||||
|
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
|
||||||
|
encoder.setContext(loggerContext);
|
||||||
|
encoder.setPattern("%date %level [%thread] %logger{10} [%file:%line] %msg%n");
|
||||||
|
encoder.start();
|
||||||
|
|
||||||
|
for (LoggingEvent evt : selectedEvents) {
|
||||||
|
byte[] encode = encoder.encode(evt);
|
||||||
|
sb.append(new String(encode));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createLogMessage(LoggingEvent evt) {
|
private String createLogMessage(LoggingEvent evt) {
|
||||||
|
|
Loading…
Reference in New Issue