All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bidib.wizard.mvc.logger.view.LogsPane Maven / Gradle / Ivy

There is a newer version: 2.0.29
Show newest version
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; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy