alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (XMenuWindow.java)

This example Java source code file (XMenuWindow.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

awt, checkmark_size, dimension, event, geometry, image, mappingdata, point, rectangle, util, window_item_margin_left, window_item_margin_right, window_shortcut_spacing, window_spacing_left, window_spacing_right, xcheckboxmenuitempeer, xmenuitempeer, xmenupeer, xmenuwindow

The XMenuWindow.java Java example source code

/*
 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package sun.awt.X11;

import java.awt.*;
import java.awt.peer.*;
import java.awt.event.*;

import java.awt.image.BufferedImage;
import java.awt.geom.Point2D;

import java.util.Vector;
import sun.util.logging.PlatformLogger;

public class XMenuWindow extends XBaseMenuWindow {

    /************************************************
     *
     * Data members
     *
     ************************************************/

    private static PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XMenuWindow");

    /*
     * Primary members
     */
    private XMenuPeer menuPeer;

    /*
     * dimension constants
     */
    private final static int WINDOW_SPACING_LEFT = 2;
    private final static int WINDOW_SPACING_RIGHT = 2;
    private final static int WINDOW_SPACING_TOP = 2;
    private final static int WINDOW_SPACING_BOTTOM = 2;
    private final static int WINDOW_ITEM_INDENT = 15;
    private final static int WINDOW_ITEM_MARGIN_LEFT = 2;
    private final static int WINDOW_ITEM_MARGIN_RIGHT = 2;
    private final static int WINDOW_ITEM_MARGIN_TOP = 2;
    private final static int WINDOW_ITEM_MARGIN_BOTTOM = 2;
    private final static int WINDOW_SHORTCUT_SPACING = 10;

    /*
     * Checkmark
     */
    private static final int CHECKMARK_SIZE = 128;
    private static final int[] CHECKMARK_X = new int[] {1, 25,56,124,124,85, 64};  // X-coords
    private static final int[] CHECKMARK_Y = new int[] {59,35,67,  0, 12,66,123};  // Y-coords

    /************************************************
     *
     * Mapping data
     *
     ************************************************/

    static class MappingData extends XBaseMenuWindow.MappingData {
        /**
         * Rectangle for the caption
         * Necessary to fix 6267144: PIT: Popup menu label is not shown, XToolkit
         */
        private Rectangle captionRect;

        /**
         * Desired size of menu window
         */
        private Dimension desiredSize;

        /**
         * Width of largest checkmark
         * At the same time the left origin
         * of all item's text
         */
        private int leftMarkWidth;

        /**
         * Left origin of all shortcut labels
         */
        private int shortcutOrigin;

        /**
         * The origin of right mark
         * (submenu's arrow)
         */
        private int rightMarkOrigin;

        MappingData(XMenuItemPeer[] items, Rectangle captionRect, Dimension desiredSize, int leftMarkWidth, int shortcutOrigin, int rightMarkOrigin) {
            super(items);
            this.captionRect = captionRect;
            this.desiredSize = desiredSize;
            this.leftMarkWidth = leftMarkWidth;
            this.shortcutOrigin = shortcutOrigin;
            this.rightMarkOrigin = rightMarkOrigin;
        }

        /**
         * Constructs MappingData without items
         * This constructor should be used in case of errors
         */
        MappingData() {
            this.desiredSize = new Dimension(0, 0);
            this.leftMarkWidth = 0;
            this.shortcutOrigin = 0;
            this.rightMarkOrigin = 0;
        }

        public Rectangle getCaptionRect() {
            return this.captionRect;
        }

        public Dimension getDesiredSize() {
            return this.desiredSize;
        }

        public int getShortcutOrigin() {
            return this.shortcutOrigin;
        }

        public int getLeftMarkWidth() {
            return this.leftMarkWidth;
        }

        public int getRightMarkOrigin() {
            return this.rightMarkOrigin;
        }

    }


    /************************************************
     *
     * Construction
     *
     ************************************************/

    /**
     * Constructs XMenuWindow for specified XMenuPeer
     * null for XPopupMenuWindow
     */
    XMenuWindow(XMenuPeer menuPeer) {
        if (menuPeer != null) {
            this.menuPeer = menuPeer;
            this.target = menuPeer.getContainer().target;
            // Get menus from the target.
            Vector targetItemVector = null;
            targetItemVector = getMenuTargetItems();
            reloadItems(targetItemVector);
        }
    }

    /************************************************
     *
     * Initialization
     *
     ************************************************/
    /*
     * Overriden initialization
     */
    void postInit(XCreateWindowParams params) {
        super.postInit(params);
        //Fixed 6267182: PIT: Menu is not visible after
        //showing and disposing a file dialog, XToolkit
        //toFront() is called on every show
    }

    /************************************************
     *
     * Implementation of abstract methods
     *
     ************************************************/

    /**
     * @see XBaseMenuWindow.getParentMenuWindow()
     */
    protected XBaseMenuWindow getParentMenuWindow() {
        return (menuPeer != null) ? menuPeer.getContainer() : null;
    }

    /**
     * @see XBaseMenuWindow.map()
     */
    protected MappingData map() {
        //TODO:Implement popup-menu caption mapping and painting and tear-off
        int itemCnt;
        if (!isCreated()) {
            MappingData mappingData = new MappingData(new XMenuItemPeer[0], new Rectangle(0, 0, 0, 0), new Dimension(0, 0), 0, 0, 0);
            return mappingData;
        }
        XMenuItemPeer[] itemVector = copyItems();
        itemCnt = itemVector.length;
        //We need maximum width of components before calculating item's bounds
        Dimension captionSize = getCaptionSize();
        int maxWidth = (captionSize != null) ? captionSize.width : 0;
        int maxLeftIndent = 0;
        int maxRightIndent = 0;
        int maxShortcutWidth = 0;
        XMenuItemPeer.TextMetrics[] itemMetrics = new XMenuItemPeer.TextMetrics[itemCnt];
        for (int i = 0; i < itemCnt; i++) {
            XMenuItemPeer item = itemVector[i];
            itemMetrics[i] = itemVector[i].getTextMetrics();
            Dimension dim = itemMetrics[i].getTextDimension();
            if (dim != null) {
                if (itemVector[i] instanceof XCheckboxMenuItemPeer) {
                    maxLeftIndent = Math.max(maxLeftIndent, dim.height);
                } else if (itemVector[i] instanceof XMenuPeer) {
                    maxRightIndent = Math.max(maxRightIndent, dim.height);
                }
                maxWidth = Math.max(maxWidth, dim.width);
                maxShortcutWidth = Math.max(maxShortcutWidth, itemMetrics[i].getShortcutWidth());
            }
        }
        //Calculate bounds
        int nextOffset = WINDOW_SPACING_TOP;
        int shortcutOrigin = WINDOW_SPACING_LEFT + WINDOW_ITEM_MARGIN_LEFT + maxLeftIndent + maxWidth;
        if (maxShortcutWidth > 0) {
            shortcutOrigin = shortcutOrigin + WINDOW_SHORTCUT_SPACING;
        }
        int rightMarkOrigin = shortcutOrigin + maxShortcutWidth;
        int itemWidth = rightMarkOrigin + maxRightIndent + WINDOW_ITEM_MARGIN_RIGHT;
        int width = WINDOW_SPACING_LEFT + itemWidth + WINDOW_SPACING_RIGHT;
        //Caption rectangle
        Rectangle captionRect = null;
        if (captionSize != null) {
            captionRect = new Rectangle(WINDOW_SPACING_LEFT, nextOffset, itemWidth, captionSize.height);
            nextOffset += captionSize.height;
        } else {
            captionRect = new Rectangle(WINDOW_SPACING_LEFT, nextOffset, maxWidth, 0);
        }
        //Item rectangles
        for (int i = 0; i < itemCnt; i++) {
            XMenuItemPeer item = (XMenuItemPeer)itemVector[i];
            XMenuItemPeer.TextMetrics metrics = itemMetrics[i];
            Dimension dim = metrics.getTextDimension();
            if (dim != null) {
                int itemHeight = WINDOW_ITEM_MARGIN_TOP + dim.height + WINDOW_ITEM_MARGIN_BOTTOM;
                Rectangle bounds = new Rectangle(WINDOW_SPACING_LEFT, nextOffset, itemWidth, itemHeight);
                int y = (itemHeight + dim.height) / 2  - metrics.getTextBaseline();
                Point textOrigin = new Point(WINDOW_SPACING_LEFT + WINDOW_ITEM_MARGIN_LEFT + maxLeftIndent, nextOffset + y);
                nextOffset += itemHeight;
                item.map(bounds, textOrigin);
            } else {
                //Text metrics could not be determined because of errors
                //Map item with empty rectangle
                Rectangle bounds = new Rectangle(WINDOW_SPACING_LEFT, nextOffset, 0, 0);
                Point textOrigin = new Point(WINDOW_SPACING_LEFT + WINDOW_ITEM_MARGIN_LEFT + maxLeftIndent, nextOffset);
                item.map(bounds, textOrigin);
            }
        }
        int height = nextOffset + WINDOW_SPACING_BOTTOM;
        MappingData mappingData = new MappingData(itemVector, captionRect, new Dimension(width, height), maxLeftIndent, shortcutOrigin, rightMarkOrigin);
        return mappingData;
    }

    /**
     * @see XBaseMenuWindow.getSubmenuBounds()
     */
    protected Rectangle getSubmenuBounds(Rectangle itemBounds, Dimension windowSize) {
        Rectangle globalBounds = toGlobal(itemBounds);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Rectangle res;
        res = fitWindowRight(globalBounds, windowSize, screenSize);
        if (res != null) {
            return res;
        }
        res = fitWindowBelow(globalBounds, windowSize, screenSize);
        if (res != null) {
            return res;
        }
        res = fitWindowAbove(globalBounds, windowSize, screenSize);
        if (res != null) {
            return res;
        }
        res = fitWindowLeft(globalBounds, windowSize, screenSize);
        if (res != null) {
            return res;
        }
        return fitWindowToScreen(windowSize, screenSize);
   }

    /**
     * It's likely that size of items was changed
     * invoke resizing of window on eventHandlerThread
     */
    protected void updateSize() {
        resetMapping();
        if (isShowing()) {
            XToolkit.executeOnEventHandlerThread(target, new Runnable() {
                    public void run() {
                        Dimension dim = getDesiredSize();
                        reshape(x, y, dim.width, dim.height);
                    }
                });
        }
    }

    /************************************************
     *
     * Overridable caption-painting functions
     * Necessary to fix 6267144: PIT: Popup menu label is not shown, XToolkit
     *
     ************************************************/

    /**
     * Returns size of menu window's caption or null
     * if window has no caption.
     * Can be overriden for popup menus and tear-off menus
     */
    protected Dimension getCaptionSize() {
        return null;
    }

    /**
     * Paints menu window's caption.
     * Can be overriden for popup menus and tear-off menus.
     * Default implementation does nothing
     */
    protected void paintCaption(Graphics g, Rectangle rect) {
    }

    /************************************************
     *
     * General-purpose utility functions
     *
     ************************************************/

    /**
     * Returns corresponding menu peer
     */
    XMenuPeer getMenuPeer() {
        return menuPeer;
    }

    /**
     * Reads vector of items from target
     * This function is overriden in XPopupMenuPeer
     */
    Vector getMenuTargetItems() {
        return menuPeer.getTargetItems();
    }

    /**
     * Returns desired size calculated while mapping
     */
    Dimension getDesiredSize() {
        MappingData mappingData = (MappingData)getMappingData();
        return mappingData.getDesiredSize();
    }

    /**
     * Checks if menu window is created
     */
    boolean isCreated() {
        return getWindow() != 0;
    }

    /**
     * Performs delayed creation of menu window if necessary
     */
    boolean ensureCreated() {
        if (!isCreated()) {
            XCreateWindowParams params = getDelayedParams();
            params.remove(DELAYED);
            params.add(OVERRIDE_REDIRECT, Boolean.TRUE);
            params.add(XWindow.TARGET, target);
            init(params);
        }
        return true;
    }

    /**
     * Init window if it's not inited yet
     * and show it at specified coordinates
     * @param bounds bounding rectangle of window
     * in global coordinates
     */
    void show(Rectangle bounds) {
        if (!isCreated()) {
            return;
        }
        if (log.isLoggable(PlatformLogger.Level.FINER)) {
            log.finer("showing menu window + " + getWindow() + " at " + bounds);
        }
        XToolkit.awtLock();
        try {
            reshape(bounds.x, bounds.y, bounds.width, bounds.height);
            xSetVisible(true);
            //Fixed 6267182: PIT: Menu is not visible after
            //showing and disposing a file dialog, XToolkit
            toFront();
            selectItem(getFirstSelectableItem(), false);
        } finally {
            XToolkit.awtUnlock();
        }
    }

    /**
     * Hides menu window
     */
    void hide() {
        selectItem(null, false);
        xSetVisible(false);
    }

    /************************************************
     *
     * Painting
     *
     ************************************************/

    /**
     * Paints menu window
     */
    @Override
    public void paintPeer(Graphics g) {
        resetColors();
        int width = getWidth();
        int height = getHeight();

        flush();
        //Fill background of rectangle
        g.setColor(getBackgroundColor());
        g.fillRect(1, 1, width - 2, height - 2);
        draw3DRect(g, 0, 0, width, height, true);

        //Mapping data
        MappingData mappingData = (MappingData)getMappingData();

        //Paint caption
        paintCaption(g, mappingData.getCaptionRect());

        //Paint menus
        XMenuItemPeer[] itemVector = mappingData.getItems();
        Dimension windowSize =  mappingData.getDesiredSize();
        XMenuItemPeer selectedItem = getSelectedItem();
        for (int i = 0; i < itemVector.length; i++) {
            XMenuItemPeer item = itemVector[i];
            XMenuItemPeer.TextMetrics metrics = item.getTextMetrics();
            Rectangle bounds = item.getBounds();
            if (item.isSeparator()) {
                draw3DRect(g, bounds.x, bounds.y + bounds.height / 2,  bounds.width, 2, false);
            } else {
                //paint item
                g.setFont(item.getTargetFont());
                Point textOrigin = item.getTextOrigin();
                Dimension textDim = metrics.getTextDimension();
                if (item == selectedItem) {
                    g.setColor(getSelectedColor());
                    g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
                    draw3DRect(g, bounds.x, bounds.y, bounds.width, bounds.height, false);
                }
                g.setColor(item.isTargetItemEnabled() ? getForegroundColor() : getDisabledColor());
                g.drawString(item.getTargetLabel(), textOrigin.x, textOrigin.y);
                String shortcutText = item.getShortcutText();
                if (shortcutText != null) {
                    g.drawString(shortcutText, mappingData.getShortcutOrigin(), textOrigin.y);
                }
                if (item instanceof XMenuPeer) {
                    //calculate arrow coordinates
                    int markWidth = textDim.height * 4 / 5;
                    int markHeight = textDim.height * 4 / 5;
                    int markX = bounds.x + bounds.width - markWidth - WINDOW_SPACING_RIGHT - WINDOW_ITEM_MARGIN_RIGHT;
                    int markY = bounds.y + (bounds.height - markHeight) / 2;
                    //draw arrow
                    g.setColor(item.isTargetItemEnabled() ? getDarkShadowColor() : getDisabledColor());
                    g.drawLine(markX, markY + markHeight, markX + markWidth, markY + markHeight / 2);
                    g.setColor(item.isTargetItemEnabled() ? getLightShadowColor() : getDisabledColor());
                    g.drawLine(markX, markY, markX + markWidth, markY + markHeight / 2);
                    g.drawLine(markX, markY, markX, markY + markHeight);
                } else if (item instanceof XCheckboxMenuItemPeer) {
                    //calculate checkmark coordinates
                    int markWidth = textDim.height * 4 / 5;
                    int markHeight = textDim.height * 4 / 5;
                    int markX = WINDOW_SPACING_LEFT + WINDOW_ITEM_MARGIN_LEFT;
                    int markY = bounds.y + (bounds.height - markHeight) / 2;
                    boolean checkState = ((XCheckboxMenuItemPeer)item).getTargetState();
                    //draw checkmark
                    if (checkState) {
                        g.setColor(getSelectedColor());
                        g.fillRect(markX, markY, markWidth, markHeight);
                        draw3DRect(g, markX, markY, markWidth, markHeight, false);
                        int[] px = new int[CHECKMARK_X.length];
                        int[] py = new int[CHECKMARK_X.length];
                        for (int j = 0; j < CHECKMARK_X.length; j++) {
                            px[j] = markX + CHECKMARK_X[j] * markWidth / CHECKMARK_SIZE;
                            py[j] = markY + CHECKMARK_Y[j] * markHeight / CHECKMARK_SIZE;
                        }
                        g.setColor(item.isTargetItemEnabled() ? getForegroundColor() : getDisabledColor());
                        g.fillPolygon(px, py, CHECKMARK_X.length);
                    } else {
                        g.setColor(getBackgroundColor());
                        g.fillRect(markX, markY, markWidth, markHeight);
                        draw3DRect(g, markX, markY, markWidth, markHeight, true);
                    }
                }
            }
        }
        flush();
    }

}

Other Java examples (source code examples)

Here is a short list of links related to this Java XMenuWindow.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.