org.bidib.wizard.mvc.logger.view.LogsPane Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bidibwizard-client Show documentation
Show all versions of bidibwizard-client Show documentation
jBiDiB BiDiB Wizard Client Application POM
package org.bidib.wizard.mvc.logger.view;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.text.SimpleDateFormat;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import org.bidib.wizard.api.locale.Resources;
import org.bidib.wizard.client.common.view.BasicPopupMenu;
import org.bidib.wizard.core.logger.BidibLogsAppender;
import org.bidib.wizard.mvc.common.view.text.CopyAllAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.spi.AppenderAttachable;
import io.reactivex.rxjava3.disposables.Disposable;
public class LogsPane {
private static final Logger LOGGER = LoggerFactory.getLogger(LogsPane.class);
private final JScrollPane logsPane;
private final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
private final JTextArea logsArea;
private BidibLogsAppender bidibAppender;
private Disposable loggingDisposable;
private final JPopupMenu popupMenu;
private JCheckBoxMenuItem autoScrollsItem;
private JMenuItem clearItem;
/**
* Creates the text area, sets it as non-editable and sets an observer to intercept logs.
*/
public LogsPane() {
this.logsPane = new JScrollPane() {
private static final long serialVersionUID = 1L;
@Override
protected void processMouseWheelEvent(MouseWheelEvent e) {
super.processMouseWheelEvent(e);
if (logsArea.getAutoscrolls()) {
LOGGER.info("Clear the flag on the autoScrollsItem and disable autoscrolls.");
// clear the flag on the autoScrollsItem
autoScrollsItem.setSelected(false);
logsArea.setAutoscrolls(false);
logsArea.setCaretPosition(logsArea.getCaretPosition() > 0 ? logsArea.getCaretPosition() - 1 : 0);
}
}
};
this.logsArea = new JTextArea() {
private static final long serialVersionUID = 1L;
@Override
protected void processMouseEvent(MouseEvent e) {
if (getAutoscrolls() && e.getID() == MouseEvent.MOUSE_RELEASED && !e.isPopupTrigger()) {
LOGGER.info("Clear the flag on the autoScrollsItem.");
// clear the flag on the autoScrollsItem
autoScrollsItem.setSelected(false);
}
super.processMouseEvent(e);
}
};
logsArea.setEditable(false);
logsArea.setFont(new Font("Monospaced", Font.PLAIN, 11));
logsPane.getViewport().add(logsArea, null);
addObserverToBidibLogAppender();
logsPane.setAutoscrolls(true);
popupMenu = new BasicPopupMenu() {
private static final long serialVersionUID = 1L;
};
prepareMenuItems(popupMenu);
logsArea.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (e.getClickCount() == 1 && e.isPopupTrigger()) {
LOGGER.debug("Show the popup menu.");
e.consume();
popupMenu.show(logsArea, e.getX(), e.getY());
}
}
@Override
public void mouseReleased(MouseEvent e) {
LOGGER.debug("Mouse released.");
if (e.isPopupTrigger()) {
mousePressed(e);
}
}
});
}
private void prepareMenuItems(JPopupMenu menu) {
autoScrollsItem = new JCheckBoxMenuItem(Resources.getString(getClass(), "autoScrolls"));
autoScrollsItem.setSelected(true);
autoScrollsItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
logsArea.setCaretPosition(logsArea.getDocument().getLength());
boolean enabled = autoScrollsItem.isSelected();
LOGGER.info("Set autoscrolls enabled: {}", enabled);
if (enabled) {
logsArea.setAutoscrolls(enabled);
logsArea.setCaretPosition(logsArea.getDocument().getLength());
}
else {
logsArea.setAutoscrolls(enabled);
logsArea.setCaretPosition(logsArea.getCaretPosition() > 0 ? logsArea.getCaretPosition() - 1 : 0);
}
}
});
addMenuItem(menu, autoScrollsItem);
clearItem = new JMenuItem(Resources.getString(getClass(), "clear"));
clearItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
logsArea.setText(null);
logsArea.setCaretPosition(logsArea.getDocument().getLength());
boolean enabled = autoScrollsItem.isSelected();
logsArea.setAutoscrolls(!enabled);
logsArea.setAutoscrolls(enabled);
}
catch (Exception ex) {
LOGGER.warn("Clear logsarea failed.", ex);
}
}
});
addMenuItem(menu, clearItem);
JMenuItem copyAllToClipboard = new JMenuItem(Resources.getString(getClass(), "copyAllToClipboard"));
copyAllToClipboard.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
fireCopyAllToClipboard();
}
});
addMenuItem(menu, copyAllToClipboard);
}
private void addMenuItem(Object menu, JMenuItem menuItem) {
if (menu instanceof JMenu) {
((JMenu) menu).add(menuItem);
}
else if (menu instanceof JPopupMenu) {
((JPopupMenu) menu).add(menuItem);
}
}
private void fireCopyAllToClipboard() {
LOGGER.info("Copy all content to clipboard.");
ActionEvent copyAll = new ActionEvent(logsArea, 0, CopyAllAction.copyAllAction);
CopyAllAction action = new CopyAllAction();
action.actionPerformed(copyAll);
}
/**
* Returns the JScrollPane object.
*
* @return the JScrollPane object.
*/
public JScrollPane get() {
return logsPane;
}
/**
* Adds this object to the Bidib logs appender observable, to intercept logs.
*
* The goal is to be informed when the log appender will received some RX/TX logs.
* When a log is written, the appender will notify this class which will display it in the text area.
*
*/
@SuppressWarnings("unchecked")
private void addObserverToBidibLogAppender() {
String appenderName = BidibLogsAppender.APPENDER_NAME;
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
for (Logger logger : context.getLoggerList()) {
Appender appender = ((AppenderAttachable) logger).getAppender(appenderName);
if (appender instanceof BidibLogsAppender) {
bidibAppender = (BidibLogsAppender) appender;
break;
}
}
if (bidibAppender == null) {
LoggerFactory.getLogger(LogsPane.class).error("Can't find appender with name: {}", appenderName);
}
else {
loggingDisposable = bidibAppender.getLoggingSubject().subscribe(le -> publishLoggingEvent(le));
}
}
protected void publishLoggingEvent(final ILoggingEvent log) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
int lines = logsArea.getLineCount();
if (lines > 2000) {
// remove the first 50 lines
int end = logsArea.getLineEndOffset(/* lines - */50);
logsArea.getDocument().remove(0, end);
}
}
catch (BadLocationException ex) {
LOGGER.warn("Remove some lines from logsArea failed.", ex);
}
// Update and scroll pane to the bottom
ILoggingEvent loggingEvent = log;
logsArea.append(dateFormat.format(loggingEvent.getTimeStamp()));
logsArea.append(" - ");
logsArea.append(loggingEvent.getFormattedMessage());
logsArea.append(System.lineSeparator());
// logsArea.setCaretPosition(logsArea.getDocument().getLength());
// logsArea.invalidate();
}
});
}
public void close() {
if (bidibAppender != null) {
LOGGER.info("Remove observer from appender.");
try {
loggingDisposable.dispose();
loggingDisposable = null;
}
catch (Exception ex) {
LOGGER.warn("Remove observer from appender failed.", ex);
}
bidibAppender = null;
}
}
}