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

org.opentcs.kernelcontrolcenter.ControlCenterInfoHandler Maven / Gradle / Ivy

/**
 * Copyright (c) The openTCS Authors.
 *
 * This program is free software and subject to the MIT license. (For details,
 * see the licensing information (LICENSE.txt) you should have received with
 * this copy of the software.)
 */
package org.opentcs.kernelcontrolcenter;

import static java.util.Objects.requireNonNull;

import com.google.inject.assistedinject.Assisted;
import jakarta.inject.Inject;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret;
import org.opentcs.access.NotificationPublicationEvent;
import org.opentcs.common.ClientConnectionMode;
import org.opentcs.common.PortalManager;
import org.opentcs.data.notification.UserNotification;
import org.opentcs.kernelcontrolcenter.util.KernelControlCenterConfiguration;
import org.opentcs.util.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A logging handler that writes all INFO-logs to KernelControlCenter's logging text area.
 */
public class ControlCenterInfoHandler
    implements
      EventHandler {

  /**
   * This class's Logger.
   */
  private static final Logger LOG = LoggerFactory.getLogger(ControlCenterInfoHandler.class);
  /**
   * Formats time stamps.
   */
  private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter
      .ofLocalizedDateTime(FormatStyle.SHORT)
      .withLocale(Locale.getDefault())
      .withZone(ZoneId.systemDefault());
  /**
   * This class's configuration.
   */
  private final KernelControlCenterConfiguration configuration;
  /**
   * The text area we're writing in.
   */
  private final JTextArea textArea;
  /**
   * A flag whether the text area scrolls.
   */
  private boolean autoScroll;

  /**
   * Creates a new ControlCenterInfoHandler.
   *
   * @param textArea The textArea we are writing to.
   * @param configuration This class' configuration.
   */
  @Inject
  public ControlCenterInfoHandler(
      @Assisted
      JTextArea textArea,
      KernelControlCenterConfiguration configuration
  ) {
    this.textArea = requireNonNull(textArea, "textArea");
    this.configuration = requireNonNull(configuration, "configuration");

    autoScroll = true;
  }

  @Override
  public void onEvent(Object event) {
    if (event instanceof PortalManager.ConnectionState) {
      PortalManager.ConnectionState connectionState = (PortalManager.ConnectionState) event;
      SwingUtilities.invokeLater(() -> {
        publish(
            new UserNotification(
                "Kernel connection state: " + connectionState.name(),
                UserNotification.Level.INFORMATIONAL
            )
        );
      });
    }
    else if (event instanceof ClientConnectionMode) {
      ClientConnectionMode applicationState = (ClientConnectionMode) event;
      SwingUtilities.invokeLater(() -> {
        publish(
            new UserNotification(
                "Application state: " + applicationState.name(),
                UserNotification.Level.INFORMATIONAL
            )
        );
      });
    }
    else if (event instanceof NotificationPublicationEvent) {
      SwingUtilities.invokeLater(
          () -> publish(((NotificationPublicationEvent) event).getNotification())
      );
    }
  }

  /**
   * Defines if the textArea autoscrolls.
   *
   * @param autoScroll true if it should, false otherwise
   */
  public void setAutoScroll(boolean autoScroll) {
    this.autoScroll = autoScroll;
  }

  /**
   * Displays the notification.
   *
   * @param notification The notification
   */
  private void publish(UserNotification notification) {
    DefaultCaret caret = (DefaultCaret) textArea.getCaret();
    if (autoScroll) {
      caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
      textArea.setCaretPosition(textArea.getDocument().getLength());
    }
    else {
      caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
    }

    textArea.append(format(notification));
    textArea.append("\n");
    checkLength();
  }

  private String format(UserNotification notification) {
    return DATE_FORMAT.format(notification.getTimestamp())
        + " " + notification.getLevel()
        + ": [" + notification.getSource() + "] "
        + notification.getText();
  }

  /**
   * Checks if the length of the document in our textArea is greater than our {@code maxDocLength}
   * and cuts it if neccessary.
   */
  private synchronized void checkLength() {
    SwingUtilities.invokeLater(() -> {
      int docLength = textArea.getDocument().getLength();

      if (docLength > configuration.loggingAreaCapacity()) {
        try {
          textArea.getDocument().remove(0, docLength - configuration.loggingAreaCapacity());
        }
        catch (BadLocationException e) {
          LOG.warn("Caught exception", e);
        }
      }
    });
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy