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

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 *
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.core.windows.view.ui;

import org.netbeans.core.windows.ModeImpl;
import org.netbeans.core.windows.WindowManagerImpl;
import org.openide.util.Utilities;
import org.openide.windows.TopComponent;

import javax.swing.*;
import java.awt.*;
import java.awt.event.AWTEventListener;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.lang.ref.WeakReference;



/** Component which takes an array of TopComponents, displays icons for
 * them and allows the user to navigate and select.  Typical usage:
 * 
RecentViewListDlg.invoke (someWindow, someTopComponentArray, 0)
* The navigation keys may be adjusted via the setKeys method. *

The popup will not automatically close due to external (i.e. focus) * events, but provides a method cancelLast() which will * close the last-opened popup if any. Client code is expected to * decide what events should trigger cancelling of the popup. The * popup will close in response to the releaseKey being * released (in which case it is setting the selected TopComponent). * * @author Tim Boudreau */ public class RecentViewListDlg extends JComponent implements AWTEventListener, LayoutManager { private TopComponent[] tcs; private JLabel label; private IconPanel ic; private int sel=-1; private static int triggerKey; private static int reverseKey; private static int releaseKey; private static Popup currPopup = null; private static boolean shown = false; /** Creates a new instance of RecentViewListDlg */ private RecentViewListDlg() { init(); setFont(UIManager.getFont("Label.font")); } /** Set the keys which will trigger selection/closing of the popup. * @param trigger The key which will cause the selection to change, as a key code * defined on KeyEvent (e.g. VK_TAB). * @param reverse The key which, when pressed, reverses the traversal direction. * @param release The key which, when released, signals that the dialog should be closed * and the selected TopComponent should be activated. */ public static void setKeys(int trigger, int reverse, int release) { triggerKey = trigger; reverseKey = reverse; releaseKey = release; } /** Invoke the popup with the specified target as the dialog parent, using the * passed array of TopComponents and the passed selection index. * @param target The target component which will own the popup dialog. * @param tcs The array of TopComponents that the dialog should allow the user to * navigate through. * @param selected The index of the component which should initially be selected when * the dialog appears. */ public static void invoke(Component target, TopComponent[] tcs, int selected, int triggerKey, int reverseKey, int releaseKey) { RecentViewListDlg.triggerKey = triggerKey; RecentViewListDlg.reverseKey = reverseKey; RecentViewListDlg.releaseKey = releaseKey; RecentViewListDlg dlg = instance(); dlg.setTopComponents(tcs); dlg.setSelection(selected); Dimension d = dlg.getPreferredSize(); Rectangle r = Utilities.getUsableScreenBounds(); int x = r.x + ((r.width/2) - (d.width / 2)); int y = r.x + ((r.height/2) - (d.height / 2)); Popup pop = PopupFactory.getSharedInstance().getPopup(target, dlg, x, y); if (currPopup != null) { currPopup.hide(); shown = false; } currPopup = pop; pop.show(); shown = true; } /** Cancel the popup if present, causing it to close without the active * TopComponent being changed. * @return True if a popup was closed. */ public static boolean cancelLast() { boolean result = currPopup != null; if (result) { currPopup.hide(); currPopup = null; shown = false; } return result; } /** Returns true if dialog is displayed. * TopComponent being changed. * @return True if a popup was closed. */ public static boolean isShown () { return shown; } /** Test execution, invoking the popup with all the opened TopComponents. * This method should be deleted for production use. */ public static void main(String[] args) { TopComponent[] tcs = (TopComponent[]) TopComponent.getRegistry().getOpened().toArray(new TopComponent[0]); Component target = Frame.getFrames()[0]; invoke(target, tcs, 0, KeyEvent.VK_TAB, KeyEvent.VK_SHIFT, KeyEvent.VK_CONTROL); } public void addNotify() { super.addNotify(); Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.FOCUS_EVENT_MASK | AWTEvent.KEY_EVENT_MASK); } public void removeNotify(){ super.removeNotify(); Toolkit.getDefaultToolkit().removeAWTEventListener(this); } private void setSelection(int i) { if (i == sel) { return; } if (i >= tcs.length) { i = 0; } if (i < 0) { i = tcs.length - 1; } ic.setSelectedIndex(i); sel = i; label.setText(WindowManagerImpl.getInstance().getTopComponentDisplayName(tcs[i])); repaint(); } private void init() { label = new JLabel(); label.setBorder(BorderFactory.createLoweredBevelBorder()); setBorder(BorderFactory.createRaisedBevelBorder()); label.setHorizontalAlignment(SwingConstants.CENTER); ic = new IconPanel(); add(label); add(ic); setLayout(this); } private void setTopComponents(TopComponent[] tcs) { this.tcs = tcs; //Selection index must be reset so that setSelection will //work correctly. (It did not when there was 2 items in input array and their //order was changed after every invocation.) sel = -1; Image[] icons = new Image[tcs.length]; for (int i=0; i < tcs.length; i++) { icons[i] = tcs[i].getIcon(); } ic.setIcons(icons); } private static WeakReference ref = null; private static RecentViewListDlg instance () { RecentViewListDlg result = null; if (ref != null) { result = (RecentViewListDlg) ref.get(); } if (result == null) { result = new RecentViewListDlg(); ref = new WeakReference(result); } return result; } private int textHeight=-1; private int getTextHeight() { if (textHeight == -1) { textHeight = calcTextHeight(); } return textHeight; } private int calcTextHeight() { Graphics g = getGraphics(); if (g == null) { g = new BufferedImage(20,20,BufferedImage.TYPE_INT_ARGB).getGraphics(); } FontMetrics fm = g.getFontMetrics(getFont()); return fm.getHeight(); } boolean fwd=true; // XXX Have a look how is the key events handled in JPopupMenu+its UI, // There should be used probably another mechanism then AWTEventListener // -> input and action map, if possible. public void eventDispatched(AWTEvent event) { int code; switch (event.getID()) { case FocusEvent.FOCUS_GAINED: break; case KeyEvent.KEY_PRESSED: code = ((KeyEvent) event).getKeyCode(); if (code == reverseKey) { fwd = false; } else if (code == triggerKey) { setSelection(sel + (fwd ? 1 : -1)); } else if(code == KeyEvent.VK_ESCAPE) { // XXX see above cancelLast(); } break; case KeyEvent.KEY_RELEASED: code = ((KeyEvent) event).getKeyCode(); if (code == releaseKey) { TopComponent tc = tcs[sel]; cancelLast(); // #37226 Unmaximized the other mode if needed. WindowManagerImpl wm = WindowManagerImpl.getInstance(); ModeImpl mode = (ModeImpl)wm.findMode(tc); if(mode != null && mode != wm.getMaximizedMode()) { wm.setMaximizedMode(null); } tc.requestActive(); } else if (code == reverseKey) { fwd=true; } break; } } public void addLayoutComponent(String name, Component comp) { //do nothing } public void layoutContainer(Container parent) { Dimension d = ic.getPreferredSize(); ic.setBounds(5, 5, d.width+1, d.height+1); label.setBounds(10, d.height+10, getWidth()-20, getTextHeight() + 4); } public Dimension minimumLayoutSize(Container parent) { return preferredLayoutSize(parent); } public Dimension preferredLayoutSize(Container parent) { Dimension result = ic.getPreferredSize(); Dimension d2 = label.getPreferredSize(); result.height+= d2.height+20; result.width +=10; return result; } public void removeLayoutComponent(Component comp) { //do nothing } private static class IconPanel extends JComponent { private int GAP = 5; private int WRAP_AT=12; private Image[] icons; private int sel; public void setIcons(Image[] ic) { this.icons = ic; } public void setSelectedIndex(int idx) { sel = idx; repaint(); } public void paint(Graphics g) { int x=GAP; int y=GAP; for (int i=0; i < icons.length; i++) { int w=24; int h=24; if (icons[i] != null) { int xpos = x; int ypos = y; int iw = icons[i].getWidth(this); int ih = icons[i].getHeight(this); if (iw < w) { xpos += ((w-iw)/2)- (GAP/2); } if (ih < h) { ypos += ((h-ih)/2)- (GAP/2); } new ImageIcon(icons[i]).paintIcon(this, g, xpos, ypos); } else { noIconIcon.paintIcon(this, g, x, y); } if (i == sel) { Color selColor = UIManager.getColor("textHighlight"); //NOI18N if (selColor == null) { selColor = Color.blue; } g.setColor(selColor.darker()); g.drawRect(x-GAP, y-GAP, w + GAP-1, h + GAP-1); } x+=w + GAP; if ((i+1) % WRAP_AT==0) { y +=h+GAP; x=GAP; } } } public Dimension getPreferredSize() { int rowCount = (icons.length / WRAP_AT) + 1; Dimension result = new Dimension((24 * WRAP_AT) + (GAP * WRAP_AT), (rowCount * 24) + (GAP * rowCount)); return result; } private Icon noIconIcon = new Icon() { public int getIconHeight() { return 16; } public int getIconWidth() { return 16; } public void paintIcon(Component c, Graphics g, int x, int y) { g.setColor(Color.RED); FontMetrics fm = g.getFontMetrics(); g.drawString("?", x+7, y+4+fm.getAscent()); //NOI18N } }; } }

... 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.