com.spears.ui.implementation.EmbeddedDesktop.java Source code

Java tutorial

Introduction

Here is the source code for com.spears.ui.implementation.EmbeddedDesktop.java

Source

/*
 * SPEARS: Simulated Physics and Environment for Autonomous Risk Studies
 * Copyright (C) 2017  Colorado School of Mines
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

package com.spears.ui.implementation;

import com.spears.objects.FreeThread;
import com.spears.wrapper.Globals;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.joda.time.DateTime;

import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JScrollBar;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;

class EmbeddedDesktop extends JDesktopPane {
    private static final Logger LOG = LogManager.getLogger(EmbeddedDesktop.class);

    private static final long serialVersionUID = 1092626769481787681L;

    protected ImageIcon background;
    protected boolean hasImage = false;

    protected int left_divs = 1;
    protected int right_divs = 1;

    protected double dividing_line = 0.5;

    protected List<EmbeddedFrame> comps_in_wells;

    private boolean on_resize = false, resizing = false;

    EmbeddedDesktop() {
        setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
        setUpWells();
        setUpEventListeners();
        new FreeThread(1000, this::repaint, FreeThread.FOREVER, "desktopClock");
    }

    private void setUpWells() {
        left_divs = UiConfiguration.getDesktopDivsLeft();
        right_divs = UiConfiguration.getDesktopDivsRight();
        dividing_line = UiConfiguration.getDesktopCenterLine();

        comps_in_wells = new ArrayList<>();
        hasImage = true;
        background = ImageFunctions.getImage("/images/spears logo.png");
        this.addMouseMotionListener(new MouseMotionListener() {
            @Override
            public void mouseMoved(MouseEvent e) {
                if (Math.abs(e.getX() - dividing_line * getWidth()) < 10) {
                    setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));
                    on_resize = true;
                } else {
                    setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                    on_resize = false;
                }
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                if (resizing) {
                    dividing_line = e.getX() / (double) getWidth();
                    if (dividing_line < 0.2) {
                        dividing_line = 0.2;
                    }
                    if (dividing_line > 0.8) {
                        dividing_line = 0.8;
                    }
                    for (Component c : comps_in_wells) {
                        if (c.getX() <= 1) {
                            c.setSize((int) (getWidth() * dividing_line) - 2, c.getHeight());
                        } else {
                            c.setSize((int) (getWidth() * (1 - dividing_line)) - 2, c.getHeight());
                            ignore_this_one = true;
                            c.setLocation((int) (getWidth() * dividing_line + 1), c.getY());
                        }
                    }
                    UiConfiguration.changeDesktopCenterLine(dividing_line);
                    repaint();
                }
            }
        });
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (on_resize) {
                    resizing = true;
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (resizing) {
                    resizing = false;
                    repaint();
                }
            }
        });
    }

    private void setUpEventListeners() {
        InternalEventHandler.registerInternalListener(this::frameEventHandler);
        InternalEventHandler.registerInternalListener(this::menuEventHandler);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.GRAY);
        final int margin = 10;
        if (isOpaque()) {
            if (hasImage) {
                try {
                    g.drawImage(background.getImage(), (this.getWidth() - background.getIconWidth()) / 2,
                            (this.getHeight() - background.getIconHeight()) / 2, null);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            g.drawString("Version: " + Globals.versionNumber, margin, getHeight() - 60);
            g.drawString("Developed by:", margin, getHeight() - 45);
            g.drawString("Van Bossuyt Group", margin, getHeight() - 30);
            g.drawString("Colorado School of Mines", margin, getHeight() - 15);

            DateTime real = DateTime.now();
            final int space = (int) g.getFontMetrics().getStringBounds("  MM/DD/YYYY  ", g).getWidth();
            String time = real.toString("hh:mm aa");
            g.drawString(time,
                    getWidth()
                            - (((int) g.getFontMetrics().getStringBounds(time, g).getWidth() + space) / 2 + margin),
                    getHeight() - 30);
            String date = real.toString("MM/dd/yyyy");
            g.drawString(date,
                    getWidth()
                            - (((int) g.getFontMetrics().getStringBounds(date, g).getWidth() + space) / 2 + margin),
                    getHeight() - 15);
        }
        if (resizing) {
            g.drawRect((int) (dividing_line * getWidth()) - 1, 0, 2, getHeight());
        }
    }

    private Component being_moved = null;

    public Component add(EmbeddedFrame frame) {
        frame.setOpenState(frame.getSize());
        frame.setLocation(getOpeningLocation());
        frame.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentMoved(ComponentEvent e) {
                if (e.getComponent().getY() < 0) {
                    e.getComponent().setLocation(e.getComponent().getX(), 0);
                }
                if (e.getComponent() != being_moved) {
                    being_moved = e.getComponent();
                    placeInDivision(e.getComponent());
                    being_moved = null;
                }
            }
        });
        InternalEventHandler.fireInternalEvent(EmbeddedFrameEvent.builder()
                .setAction(EmbeddedFrameEvent.Action.ADDED).setComponent(frame).build());
        frame.setVisible(true);
        Component out = super.add(frame);
        super.setComponentZOrder(frame, 0);
        setScrollsToTop(frame.getComponents());
        return out;
    }

    private boolean ignore_this_one = false;

    private void placeInDivision(Component comp) {
        if (ignore_this_one) {
            ignore_this_one = false;
            return;
        }
        EmbeddedFrame frame;
        try {
            frame = (EmbeddedFrame) comp;
        } catch (ClassCastException e) {
            return;
        }
        if (frame.getX() < 0 && left_divs > 0) {
            comps_in_wells.add(frame);
            if (!comps_in_wells.contains(frame)) {
                frame.setOpenState(frame.getSize());
            }
            frame.setResizable(false);
            int div = (int) Math.ceil((frame.getY() > 0 ? frame.getY() : 1) / (double) getHeight() * left_divs) - 1;
            ignore_this_one = true;
            frame.setLocation(1, (int) (div / (double) left_divs * getHeight()) + 1);
            frame.setSize((int) (getWidth() * dividing_line) - 2, (int) (getHeight() / (double) left_divs) - 2);
        } else if (frame.getX() + frame.getWidth() > getWidth() && right_divs > 0) {
            comps_in_wells.add(frame);
            if (!comps_in_wells.contains(frame)) {
                frame.setOpenState(frame.getSize());
            }
            frame.setResizable(false);
            int div = (int) Math.ceil((frame.getY() > 0 ? frame.getY() : 1) / (double) getHeight() * right_divs)
                    - 1;
            ignore_this_one = true;
            frame.setSize((int) (getWidth() * (1 - dividing_line)) - 2,
                    (int) (getHeight() / (double) right_divs) - 2);
            frame.setLocation(getWidth() - frame.getWidth() + 1,
                    (int) (div / (double) right_divs * getHeight()) + 1);
        } else if (comps_in_wells.contains(frame) && frame.getX() > 2
                && frame.getX() + frame.getWidth() < getWidth() - 2) {
            comps_in_wells.remove(frame);
            frame.setResizable(true);
            int x = (frame.getWidth() - frame.getOpenState().width) / 2;
            frame.setSize(frame.getOpenState());
            frame.setLocation(frame.getX() + x, frame.getY());
        }
    }

    private void frameEventHandler(EmbeddedFrameEvent e) {

    }

    @SuppressWarnings("incomplete-switch")
    private void menuEventHandler(MenuCommandEvent e) {
        switch (e.getAction()) {
        case NEW_FRAME:
            try {
                @SuppressWarnings("unchecked")
                EmbeddedFrame frame = ((Class<? extends EmbeddedFrame>) e.getValue()).newInstance();
                this.add(frame);
            } catch (InstantiationException | IllegalAccessException | ClassCastException e1) {
                LOG.log(Level.ERROR, "The new frame could not be added", e1);
            }
            break;
        case SHOW_FRAME:
            EmbeddedFrame frame = (EmbeddedFrame) e.getValue();
            frame.setVisible(true);
            if (frame.isIcon()) {
                frame.deiconify();
            }
            frame.requestFocus();
            break;
        case GRID_CHANGE:
            String newval = (String) e.getValue();
            if (newval.charAt(0) == 'L') {
                this.left_divs = Integer.parseInt(newval.charAt(1) + "");
            } else if (newval.charAt(0) == 'R') {
                this.right_divs = Integer.parseInt(newval.charAt(1) + "");
            } else {
                LOG.log(Level.DEBUG, "The divisions value \"{}\" could not be parsed", newval);
            }
            //TODO reset frames already in divisions
            break;
        }
    }

    private Point startLocation = new Point(100, 100);

    private Point getOpeningLocation() {
        Point out = new Point(startLocation);
        startLocation = new Point(
                startLocation.getX() + 50 < this.getWidth() - 500 ? (int) startLocation.getX() + 50 : 100,
                startLocation.getY() + 50 < this.getHeight() - 500 ? (int) startLocation.getY() + 50 : 100);
        return out;
    }

    private void setScrollsToTop(Component[] comps) {
        for (Component comp : comps) {
            if (comp instanceof JScrollBar) {
                ((JScrollBar) comp).setValue(((JScrollBar) comp).getMinimum());
            }
            //         else if (comp instanceof JScrollPane){
            //            JScrollBar vert = ((JScrollPane)comp).getVerticalScrollBar();
            //            vert.setValue(vert.getMinimum());
            //            System.out.println("Set: "+vert.toString() + String.format("  Min: %d  Max: %d  Val: %d", vert.getMinimum(), vert.getMaximum(), vert.getValue()));
            //            JScrollBar horz = ((JScrollPane)comp).getHorizontalScrollBar();
            //            horz.setValue(horz.getMinimum());
            //            System.out.println("Set: "+horz.toString() + String.format("  Min: %d  Max: %d  Val: %d", horz.getMinimum(), horz.getMaximum(), horz.getValue()));
            //         }
            else if (comp instanceof Container) {
                setScrollsToTop(((Container) comp).getComponents());
            }
        }
    }

}