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

com.pekinsoft.desktop.StatusBar Maven / Gradle / Ivy

Go to download

A simple platform on which Java/Swing desktop applications may be built. This updated version has packaged the entire library into a single JAR file. We have also made the following changes: ToolBarGenerator should now create ButtonGroups properly for state actions. ApplicationContext has accessors for the WindowManager, DockingManager, StatusDisplayer, and ProgressHandler implementations. It defaults to testing the Application's MainView and the MainView's StatusBar, then uses the Lookup, if the MainView and its StatusBar do not implement the desired interfaces. StatusMessage now uses the com.pekinsoft.desktop.error.ErrorLevel instead of the java.util.logging.Level, so that the levels will no longer need to be cast in order to be used.

The newest version!
/*
 * Copyright (C) 2024 PekinSOFT Systems
 *
 * 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 3 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, see .
 *
 * *****************************************************************************
 *  Project    :   application-framework-api
 *  Class      :   StatusBar.java
 *  Author     :   Sean Carrick
 *  Created    :   Oct 28, 2024
 *  Modified   :   Oct 28, 2024
 *
 *  Purpose: See class JavaDoc for explanation
 *
 *  Revision History:
 *
 *  WHEN          BY                   REASON
 *  ------------  -------------------  -----------------------------------------
 *  Oct 28, 2024  Sean Carrick         Initial creation.
 * *****************************************************************************
 */
package com.pekinsoft.desktop;

import com.pekinsoft.api.*;
import com.pekinsoft.desktop.error.ErrorInfo;
import com.pekinsoft.desktop.notifications.support.DockingNotificationsPanel;
import com.pekinsoft.framework.*;
import com.pekinsoft.utils.PropertyKeys;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

/**
 *
 * @author Sean Carrick
 */
public class StatusBar extends JPanel
        implements Notifier, ProgressHandler, PropertyChangeListener,
        StatusDisplayer, PropertyKeys {

    private static StatusBar instance = null;

    public static StatusBar getInstance() {
        if (instance == null) {
            instance = new StatusBar();
        }

        return instance;
    }

    /**
     * Creates new form StatusBar
     */
    public StatusBar() {
        context = Application.getInstance().getContext();
        resourceMap = context.getResourceMap(getClass());
        logger = context.getLogger(getClass());

        logger.log(Level.FINEST, "Configuring the StatusBar instance...");

        int messageTimeout = resourceMap.getInteger("messageTimeout");
        messageTimer = new Timer(messageTimeout, (ActionEvent evt) -> {
            logger.log(Level.FINEST, "Resetting the status message due to "
                    + "messageTimer timeout...");
            messageLabel.setText("");
        });

        logger.log(Level.FINEST, "Initializing the busyIcons...");
        for (int x = 0; x < busyIcons.length; x++) {
            busyIcons[x] = resourceMap.getIcon("busyIcons[" + x + "]");
        }
        idleIcon = resourceMap.getIcon("idleIcon");
        fullIcon = resourceMap.getIcon("fullIcon");
        emptyIcon = resourceMap.getIcon("emptyIcon");

        int busyAnimationRate = resourceMap.getInteger("busyAnimationRate");
        animationTimer = new Timer(busyAnimationRate, (ActionEvent evt) -> {
            busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
            busyIconLabel.setIcon(busyIcons[busyIconIndex]);
        });

        initComponents();
    }

    @Override
    public void setProgress(int progress) {
        logger.log(Level.FINER, "Updating the progress bar from {0} to {1}",
                new Object[]{progressBar.getValue(), progress});
        progressBar.setValue(progress);
    }

    @Override
    public void setNotification(ErrorInfo info) {
        context.firePropertyChange(KEY_ADD_NOTIFICATION, null, info);
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if (evt.getPropertyName() != null) {
            switch (evt.getPropertyName()) {
                case KEY_TASK_STARTED -> {
                    if (!animationTimer.isRunning()) {
                        busyIconIndex = 0;
                        animationTimer.start();
                        busyIconLabel.setIcon(busyIcons[0]);
                    }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                }
                case KEY_TASK_DONE -> {
                    if (animationTimer.isRunning()) {
                        animationTimer.stop();
                        busyIconIndex = 0;
                        busyIconLabel.setIcon(idleIcon);
                    }
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                }
                case KEY_TASK_PROGRESS -> {
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    setProgress((int) evt.getNewValue());
                }
                case KEY_TASK_MESSAGE -> {
                    // Since this is a message from a BackgroundTask, we will
                    //+ set it as a MessageType.INFO.
                    setMessage((String) evt.getNewValue(), MessageType.INFO);
                }
                case KEY_STATUS_MESSAGE -> {
                    StatusMessage sm = (StatusMessage) evt.getNewValue();
                    setMessage(sm.getMessage(), sm.getMessageType());
                }
            }
        }
    }

    @Override
    public void setMessage(String message, MessageType type) {
        logger.log(Level.FINEST, "Setting the status message to {0}", message);
        messageLabel.setForeground(type.asColor());
        messageLabel.setFont(type.getFont());
        messageLabel.setText(message);
        messageTimer.restart();
    }

    /**
     * This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // //GEN-BEGIN:initComponents
    private void initComponents() {

        messageLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();
        notifierLabel = new javax.swing.JLabel();
        busyIconLabel = new javax.swing.JLabel();

        setName("Form"); // NOI18N

        messageLabel.setBorder(javax.swing.BorderFactory.createEmptyBorder(3, 3, 3, 3));
        messageLabel.setName("messageLabel"); // NOI18N

        progressBar.setBorder(javax.swing.BorderFactory.createEmptyBorder(3, 3, 3, 3));
        progressBar.setName("progressBar"); // NOI18N

        notifierLabel.setFont(new java.awt.Font("Dialog", 1, 11)); // NOI18N
        notifierLabel.setForeground(new java.awt.Color(255, 255, 255));
        notifierLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        notifierLabel.setIcon(emptyIcon);
        notifierLabel.setBorder(javax.swing.BorderFactory.createEmptyBorder(3, 3, 3, 3));
        notifierLabel.setIconTextGap(0);
        notifierLabel.setMaximumSize(new java.awt.Dimension(16, 16));
        notifierLabel.setMinimumSize(new java.awt.Dimension(16, 16));
        notifierLabel.setName("notifierLabel"); // NOI18N
        notifierLabel.setPreferredSize(new java.awt.Dimension(16, 16));
        notifierLabel.addMouseListener(clickListener);

        busyIconLabel.setIcon(idleIcon);
        busyIconLabel.setBorder(javax.swing.BorderFactory.createEmptyBorder(3, 3, 3, 3));
        busyIconLabel.setMaximumSize(new java.awt.Dimension(16, 16));
        busyIconLabel.setMinimumSize(new java.awt.Dimension(16, 16));
        busyIconLabel.setName("busyIconLabel"); // NOI18N
        busyIconLabel.setPreferredSize(new java.awt.Dimension(16, 16));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(messageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 925, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(notifierLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(busyIconLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                .addComponent(busyIconLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(notifierLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(messageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
    }// //GEN-END:initComponents

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel busyIconLabel;
    private javax.swing.JLabel messageLabel;
    private javax.swing.JLabel notifierLabel;
    private javax.swing.JProgressBar progressBar;
    // End of variables declaration//GEN-END:variables

    private final Logger logger;
    private final ApplicationContext context;
    private final ResourceMap resourceMap;
    private final Icon[] busyIcons = new Icon[15];
    private final Icon idleIcon;
    private final Icon fullIcon;
    private final Icon emptyIcon;
    private final Timer messageTimer;
    private final Timer animationTimer;
    private final MouseAdapter clickListener = new NotifierListener();

    private int busyIconIndex = 0;

    private final class NotifierListener extends MouseAdapter {

        @Override
        public void mouseClicked(MouseEvent e) {
            WindowManager mgr = WindowManager.getDefault();
            if (mgr != null) {
                if (mgr instanceof DockingManager docker) {
                    docker.show(DockingNotificationsPanel.getInstance());
                } else {
                    JFrame frame = new JFrame(
                            resourceMap.getString("notifications.frame.title"));
                    frame.add(DockingNotificationsPanel.getInstance());
                    mgr.show(frame);
                }
            }
        }

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy