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

/*
 * GUIUtilities.java - Various GUI utility functions
 * :tabSize=8:indentSize=8:noTabs=false:
 * :folding=explicit:collapseFolds=1:
 *
 * Copyright (C) 1999, 2004 Slava Pestov
 *
 * 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 2
 * of the License, or 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package org.gjt.sp.jedit;

//{{{ Imports
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.*;
import org.gjt.sp.jedit.browser.*;
import org.gjt.sp.jedit.gui.*;
import org.gjt.sp.jedit.menu.*;
import org.gjt.sp.jedit.syntax.SyntaxStyle;
import org.gjt.sp.jedit.syntax.Token;
import org.gjt.sp.util.Log;
//}}}

/**
 * Various GUI functions.

* * The most frequently used members of this class are: * *

    *
  • {@link #loadIcon(String)}
  • *
  • {@link #confirm(Component,String,Object[],int,int)}
  • *
  • {@link #error(Component,String,Object[])}
  • *
  • {@link #message(Component,String,Object[])}
  • *
  • {@link #showPopupMenu(JPopupMenu,Component,int,int)}
  • *
  • {@link #showVFSFileDialog(View,String,int,boolean)}
  • *
  • {@link #loadGeometry(Window,String)}
  • *
  • {@link #saveGeometry(Window,String)}
  • *
* * @author Slava Pestov * @version $Id: GUIUtilities.java,v 1.82 2004/06/04 00:18:34 spestov Exp $ */ public class GUIUtilities { //{{{ Some predefined icons /** * @deprecated Use GUIUtilities.loadIcon("new.gif"); * instead. */ public static Icon NEW_BUFFER_ICON; /** * @deprecated Use GUIUtilities.loadIcon("dirty.gif"); * instead. */ public static Icon DIRTY_BUFFER_ICON; /** * @deprecated Use GUIUtilities.loadIcon("readonly.gif"); * instead. */ public static Icon READ_ONLY_BUFFER_ICON; /** * @deprecated Use GUIUtilities.loadIcon("normal.gif"); * instead. */ public static Icon NORMAL_BUFFER_ICON; /** * @deprecated Use GUIUtilities.loadIcon("jedit-icon.gif"); * instead. */ public static Icon WINDOW_ICON; //}}} //{{{ Icon methods //{{{ setIconPath() method /** * Sets the path where jEdit looks for icons. * @since jEdit 4.2pre5 */ public static void setIconPath(String iconPath) { GUIUtilities.iconPath = iconPath; if(icons != null) icons.clear(); } //}}} //{{{ loadIcon() method /** * Loads an icon. * @param iconName The icon name * @since jEdit 2.6pre7 */ public static Icon loadIcon(String iconName) { if(icons == null) icons = new Hashtable(); // check if there is a cached version first Icon icon = (Icon)icons.get(iconName); if(icon != null) return icon; // get the icon if(MiscUtilities.isURL(iconName)) { icon = new ImageIcon(iconName.substring(5)); } else { try { URL url = new URL(iconPath + iconName); icon = new ImageIcon(url); } catch(Exception e) { try { URL url = new URL(defaultIconPath + iconName); icon = new ImageIcon(url); } catch(Exception ex) { Log.log(Log.ERROR,GUIUtilities.class, "Icon not found: " + iconName); Log.log(Log.ERROR,GUIUtilities.class,ex); return null; } } } icons.put(iconName,icon); return icon; } //}}} //{{{ getEditorIcon() method /** * Returns the default editor window image. */ public static Image getEditorIcon() { return ((ImageIcon)loadIcon("jedit-icon.gif")).getImage(); } //}}} //{{{ getPluginIcon() method /** * Returns the default plugin window image. */ public static Image getPluginIcon() { return getEditorIcon(); } //}}} //}}} //{{{ Menus, tool bars //{{{ loadMenuBar() method /** * Creates a menubar. Plugins should not need to call this method. * @param name The menu bar name * @since jEdit 3.2pre5 */ public static JMenuBar loadMenuBar(String name) { return loadMenuBar(jEdit.getActionContext(),name); } //}}} //{{{ loadMenuBar() method /** * Creates a menubar. Plugins should not need to call this method. * @param context An action context * @param name The menu bar name * @since jEdit 4.2pre1 */ public static JMenuBar loadMenuBar(ActionContext context, String name) { String menus = jEdit.getProperty(name); StringTokenizer st = new StringTokenizer(menus); JMenuBar mbar = new JMenuBar(); while(st.hasMoreTokens()) { mbar.add(loadMenu(context,st.nextToken())); } return mbar; } //}}} //{{{ loadMenu() method /** * Creates a menu. The menu label is set from the * name.label property. The menu contents is taken * from the name property, which is a whitespace * separated list of action names. An action name of - * inserts a separator in the menu. * @param name The menu name * @see #loadMenuItem(String) * @since jEdit 2.6pre2 */ public static JMenu loadMenu(String name) { return loadMenu(jEdit.getActionContext(),name); } //}}} //{{{ loadMenu() method /** * Creates a menu. The menu label is set from the * name.label property. The menu contents is taken * from the name property, which is a whitespace * separated list of action names. An action name of - * inserts a separator in the menu. * @param context An action context; either * jEdit.getActionContext() or * VFSBrowser.getActionContext(). * @param name The menu name * @see #loadMenuItem(String) * @since jEdit 4.2pre1 */ public static JMenu loadMenu(ActionContext context, String name) { return new EnhancedMenu(name, jEdit.getProperty(name.concat(".label")), context); } //}}} //{{{ loadPopupMenu() method /** * Creates a popup menu. * @param name The menu name * @since jEdit 2.6pre2 */ public static JPopupMenu loadPopupMenu(String name) { return loadPopupMenu(jEdit.getActionContext(),name); } //}}} //{{{ loadPopupMenu() method /** * Creates a popup menu. * @param context An action context; either * jEdit.getActionContext() or * VFSBrowser.getActionContext(). * @param name The menu name * @since jEdit 4.2pre1 */ public static JPopupMenu loadPopupMenu(ActionContext context, String name) { JPopupMenu menu = new JPopupMenu(); String menuItems = jEdit.getProperty(name); if(menuItems != null) { StringTokenizer st = new StringTokenizer(menuItems); while(st.hasMoreTokens()) { String menuItemName = st.nextToken(); if(menuItemName.equals("-")) menu.addSeparator(); else menu.add(loadMenuItem(context,menuItemName,false)); } } return menu; } //}}} //{{{ loadMenuItem() method /** * Creates a menu item. The menu item is bound to the action named by * name with label taken from the return value of the * {@link EditAction#getLabel()} method. * * @param name The menu item name * @see #loadMenu(String) * @since jEdit 2.6pre1 */ public static JMenuItem loadMenuItem(String name) { return loadMenuItem(jEdit.getActionContext(),name,true); } //}}} //{{{ loadMenuItem() method /** * Creates a menu item. * @param name The menu item name * @param setMnemonic True if the menu item should have a mnemonic * @since jEdit 3.1pre1 */ public static JMenuItem loadMenuItem(String name, boolean setMnemonic) { return loadMenuItem(jEdit.getActionContext(),name,setMnemonic); } //}}} //{{{ loadMenuItem() method /** * Creates a menu item. * @param context An action context; either * jEdit.getActionContext() or * VFSBrowser.getActionContext(). * @param name The menu item name * @param setMnemonic True if the menu item should have a mnemonic * @since jEdit 4.2pre1 */ public static JMenuItem loadMenuItem(ActionContext context, String name, boolean setMnemonic) { if(name.startsWith("%")) return loadMenu(context,name.substring(1)); String label = jEdit.getProperty(name + ".label"); if(label == null) label = name; char mnemonic; int index = label.indexOf('$'); if(index != -1 && label.length() - index > 1) { mnemonic = Character.toLowerCase(label.charAt(index + 1)); label = label.substring(0,index).concat(label.substring(++index)); } else mnemonic = '\0'; JMenuItem mi; if(jEdit.getBooleanProperty(name + ".toggle")) mi = new EnhancedCheckBoxMenuItem(label,name,context); else mi = new EnhancedMenuItem(label,name,context); if(!OperatingSystem.isMacOS() && setMnemonic && mnemonic != '\0') mi.setMnemonic(mnemonic); return mi; } //}}} //{{{ loadToolBar() method /** * Creates a toolbar. * @param name The toolbar name * @since jEdit 4.2pre2 */ public static Box loadToolBar(String name) { return loadToolBar(jEdit.getActionContext(),name); } //}}} //{{{ loadToolBar() method /** * Creates a toolbar. * @param context An action context; either * jEdit.getActionContext() or * VFSBrowser.getActionContext(). * @param name The toolbar name * @since jEdit 4.2pre2 */ public static Box loadToolBar(ActionContext context, String name) { Box toolBar = new Box(BoxLayout.X_AXIS); String buttons = jEdit.getProperty(name); if(buttons != null) { StringTokenizer st = new StringTokenizer(buttons); while(st.hasMoreTokens()) { String button = st.nextToken(); if(button.equals("-")) toolBar.add(Box.createHorizontalStrut(12)); else { JButton b = loadToolButton(context,button); if(b != null) toolBar.add(b); } } } toolBar.add(Box.createGlue()); return toolBar; } //}}} //{{{ loadToolButton() method /** * Loads a tool bar button. The tooltip is constructed from * the name.label and * name.shortcut properties and the icon is loaded * from the resource named '/org/gjt/sp/jedit/icons/' suffixed * with the value of the name.icon property. * @param name The name of the button */ public static EnhancedButton loadToolButton(String name) { return loadToolButton(jEdit.getActionContext(),name); } //}}} //{{{ loadToolButton() method /** * Loads a tool bar button. The tooltip is constructed from * the name.label and * name.shortcut properties and the icon is loaded * from the resource named '/org/gjt/sp/jedit/icons/' suffixed * with the value of the name.icon property. * @param context An action context; either * jEdit.getActionContext() or * VFSBrowser.getActionContext(). * @param name The name of the button * @since jEdit 4.2pre1 */ public static EnhancedButton loadToolButton(ActionContext context, String name) { String label = jEdit.getProperty(name + ".label"); if(label == null) label = name; Icon icon; String iconName = jEdit.getProperty(name + ".icon"); if(iconName == null) icon = loadIcon("BrokenImage.png"); else { icon = loadIcon(iconName); if(icon == null) icon = loadIcon("BrokenImage.png"); } String toolTip = prettifyMenuLabel(label); String shortcut1 = jEdit.getProperty(name + ".shortcut"); String shortcut2 = jEdit.getProperty(name + ".shortcut2"); if(shortcut1 != null || shortcut2 != null) { toolTip = toolTip + " (" + (shortcut1 != null ? shortcut1 : "") + ((shortcut1 != null && shortcut2 != null) ? " or " : "") + (shortcut2 != null ? shortcut2 : "") + ")"; } return new EnhancedButton(icon,toolTip,name,context); } //}}} //{{{ prettifyMenuLabel() method /** * `Prettifies' a menu item label by removing the `$' sign. This * can be used to process the contents of an action.label * property. */ public static String prettifyMenuLabel(String label) { int index = label.indexOf('$'); if(index != -1) { label = label.substring(0,index) .concat(label.substring(index + 1)); } return label; } //}}} //}}} //{{{ Canned dialog boxes //{{{ message() method /** * Displays a dialog box. * The title of the dialog is fetched from * the name.title property. The message is fetched * from the name.message property. The message * is formatted by the property manager with args as * positional parameters. * @param comp The component to display the dialog for * @param name The name of the dialog * @param args Positional parameters to be substituted into the * message text */ public static void message(Component comp, String name, Object[] args) { hideSplashScreen(); JOptionPane.showMessageDialog(comp, jEdit.getProperty(name.concat(".message"),args), jEdit.getProperty(name.concat(".title"),args), JOptionPane.INFORMATION_MESSAGE); } //}}} //{{{ error() method /** * Displays an error dialog box. * The title of the dialog is fetched from * the name.title property. The message is fetched * from the name.message property. The message * is formatted by the property manager with args as * positional parameters. * @param comp The component to display the dialog for * @param name The name of the dialog * @param args Positional parameters to be substituted into the * message text */ public static void error(Component comp, String name, Object[] args) { hideSplashScreen(); JOptionPane.showMessageDialog(comp, jEdit.getProperty(name.concat(".message"),args), jEdit.getProperty(name.concat(".title"),args), JOptionPane.ERROR_MESSAGE); } //}}} //{{{ input() method /** * Displays an input dialog box and returns any text the user entered. * The title of the dialog is fetched from * the name.title property. The message is fetched * from the name.message property. * @param comp The component to display the dialog for * @param name The name of the dialog * @param def The text to display by default in the input field */ public static String input(Component comp, String name, Object def) { return input(comp,name,null,def); } //}}} //{{{ inputProperty() method /** * Displays an input dialog box and returns any text the user entered. * The title of the dialog is fetched from * the name.title property. The message is fetched * from the name.message property. * @param comp The component to display the dialog for * @param name The name of the dialog * @param def The property whose text to display in the input field */ public static String inputProperty(Component comp, String name, String def) { return inputProperty(comp,name,null,def); } //}}} //{{{ input() method /** * Displays an input dialog box and returns any text the user entered. * The title of the dialog is fetched from * the name.title property. The message is fetched * from the name.message property. * @param comp The component to display the dialog for * @param name The name of the dialog * @param def The text to display by default in the input field * @param args Positional parameters to be substituted into the * message text * @since jEdit 3.1pre3 */ public static String input(Component comp, String name, Object[] args, Object def) { hideSplashScreen(); String retVal = (String)JOptionPane.showInputDialog(comp, jEdit.getProperty(name.concat(".message"),args), jEdit.getProperty(name.concat(".title")), JOptionPane.QUESTION_MESSAGE,null,null,def); return retVal; } //}}} //{{{ inputProperty() method /** * Displays an input dialog box and returns any text the user entered. * The title of the dialog is fetched from * the name.title property. The message is fetched * from the name.message property. * @param comp The component to display the dialog for * @param name The name of the dialog * @param args Positional parameters to be substituted into the * message text * @param def The property whose text to display in the input field * @since jEdit 3.1pre3 */ public static String inputProperty(Component comp, String name, Object[] args, String def) { hideSplashScreen(); String retVal = (String)JOptionPane.showInputDialog(comp, jEdit.getProperty(name.concat(".message"),args), jEdit.getProperty(name.concat(".title")), JOptionPane.QUESTION_MESSAGE, null,null,jEdit.getProperty(def)); if(retVal != null) jEdit.setProperty(def,retVal); return retVal; } //}}} //{{{ confirm() method /** * Displays a confirm dialog box and returns the button pushed by the * user. The title of the dialog is fetched from the * name.title property. The message is fetched * from the name.message property. * @param comp The component to display the dialog for * @param name The name of the dialog * @param args Positional parameters to be substituted into the * message text * @param buttons The buttons to display - for example, * JOptionPane.YES_NO_CANCEL_OPTION * @param type The dialog type - for example, * JOptionPane.WARNING_MESSAGE * @since jEdit 3.1pre3 */ public static int confirm(Component comp, String name, Object[] args, int buttons, int type) { hideSplashScreen(); return JOptionPane.showConfirmDialog(comp, jEdit.getProperty(name + ".message",args), jEdit.getProperty(name + ".title"),buttons,type); } //}}} //{{{ showVFSFileDialog() method /** * Displays a VFS file selection dialog box. * @param view The view, should be non-null * @param path The initial directory to display. May be null * @param type The dialog type. One of * {@link org.gjt.sp.jedit.browser.VFSBrowser#OPEN_DIALOG}, * {@link org.gjt.sp.jedit.browser.VFSBrowser#SAVE_DIALOG}, or * {@link org.gjt.sp.jedit.browser.VFSBrowser#CHOOSE_DIRECTORY_DIALOG}. * @param multipleSelection True if multiple selection should be allowed * @return The selected file(s) * @since jEdit 2.6pre2 */ public static String[] showVFSFileDialog(View view, String path, int type, boolean multipleSelection) { // the view should not be null, but some plugins might do this if(view == null) { Log.log(Log.WARNING,GUIUtilities.class, "showVFSFileDialog(): given null view, assuming jEdit.getActiveView()"); view = jEdit.getActiveView(); } hideSplashScreen(); VFSFileChooserDialog fileChooser = new VFSFileChooserDialog( view,path,type,multipleSelection); String[] selectedFiles = fileChooser.getSelectedFiles(); if(selectedFiles == null) return null; return selectedFiles; } //}}} //}}} //{{{ Colors and styles //{{{ parseColor() method /** * Converts a color name to a color object. The name must either be * a known string, such as `red', `green', etc (complete list is in * the java.awt.Color class) or a hex color value * prefixed with `#', for example `#ff0088'. * @param name The color name */ public static Color parseColor(String name) { return parseColor(name, Color.black); } //}}} //{{{ parseColor() method public static Color parseColor(String name, Color defaultColor) { if(name == null) return defaultColor; else if(name.startsWith("#")) { try { return Color.decode(name); } catch(NumberFormatException nf) { return defaultColor; } } else if("red".equals(name)) return Color.red; else if("green".equals(name)) return Color.green; else if("blue".equals(name)) return Color.blue; else if("yellow".equals(name)) return Color.yellow; else if("orange".equals(name)) return Color.orange; else if("white".equals(name)) return Color.white; else if("lightGray".equals(name)) return Color.lightGray; else if("gray".equals(name)) return Color.gray; else if("darkGray".equals(name)) return Color.darkGray; else if("black".equals(name)) return Color.black; else if("cyan".equals(name)) return Color.cyan; else if("magenta".equals(name)) return Color.magenta; else if("pink".equals(name)) return Color.pink; else return defaultColor; } //}}} //{{{ getColorHexString() method /** * Converts a color object to its hex value. The hex value * prefixed is with `#', for example `#ff0088'. * @param c The color object */ public static String getColorHexString(Color c) { String colString = Integer.toHexString(c.getRGB() & 0xffffff); return "#000000".substring(0,7 - colString.length()).concat(colString); } //}}} //{{{ parseStyle() method /** * Converts a style string to a style object. * @param str The style string * @param family Style strings only specify font style, not font family * @param size Style strings only specify font style, not font family * @exception IllegalArgumentException if the style is invalid * @since jEdit 3.2pre6 */ public static SyntaxStyle parseStyle(String str, String family, int size) throws IllegalArgumentException { return parseStyle(str,family,size,true); } //}}} //{{{ parseStyle() method /** * Converts a style string to a style object. * @param str The style string * @param family Style strings only specify font style, not font family * @param size Style strings only specify font style, not font family * @param color If false, the styles will be monochrome * @exception IllegalArgumentException if the style is invalid * @since jEdit 4.0pre4 */ public static SyntaxStyle parseStyle(String str, String family, int size, boolean color) throws IllegalArgumentException { Color fgColor = Color.black; Color bgColor = null; boolean italic = false; boolean bold = false; StringTokenizer st = new StringTokenizer(str); while(st.hasMoreTokens()) { String s = st.nextToken(); if(s.startsWith("color:")) { if(color) fgColor = GUIUtilities.parseColor(s.substring(6), Color.black); } else if(s.startsWith("bgColor:")) { if(color) bgColor = GUIUtilities.parseColor(s.substring(8), null); } else if(s.startsWith("style:")) { for(int i = 6; i < s.length(); i++) { if(s.charAt(i) == 'i') italic = true; else if(s.charAt(i) == 'b') bold = true; else throw new IllegalArgumentException( "Invalid style: " + s); } } else throw new IllegalArgumentException( "Invalid directive: " + s); } return new SyntaxStyle(fgColor,bgColor, new Font(family, (italic ? Font.ITALIC : 0) | (bold ? Font.BOLD : 0), size)); } //}}} //{{{ getStyleString() method /** * Converts a style into it's string representation. * @param style The style */ public static String getStyleString(SyntaxStyle style) { StringBuffer buf = new StringBuffer(); if(style.getForegroundColor() != null) { buf.append("color:" + getColorHexString(style.getForegroundColor())); } if(style.getBackgroundColor() != null) { buf.append(" bgColor:" + getColorHexString(style.getBackgroundColor())); } if(!style.getFont().isPlain()) { buf.append(" style:" + (style.getFont().isItalic() ? "i" : "") + (style.getFont().isBold() ? "b" : "")); } return buf.toString(); } //}}} //{{{ loadStyles() method /** * Loads the syntax styles from the properties, giving them the specified * base font family and size. * @param family The font family * @param size The font size * @since jEdit 3.2pre6 */ public static SyntaxStyle[] loadStyles(String family, int size) { return loadStyles(family,size,true); } //}}} //{{{ loadStyles() method /** * Loads the syntax styles from the properties, giving them the specified * base font family and size. * @param family The font family * @param size The font size * @param color If false, the styles will be monochrome * @since jEdit 4.0pre4 */ public static SyntaxStyle[] loadStyles(String family, int size, boolean color) { SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT]; // start at 1 not 0 to skip Token.NULL for(int i = 1; i < styles.length; i++) { try { String styleName = "view.style." + Token.tokenToString((byte)i) .toLowerCase(); styles[i] = GUIUtilities.parseStyle( jEdit.getProperty(styleName), family,size,color); } catch(Exception e) { Log.log(Log.ERROR,GUIUtilities.class,e); } } return styles; } //}}} //}}} //{{{ Loading, saving window geometry //{{{ loadGeometry() method /** * Loads a windows's geometry from the properties. * The geometry is loaded from the name.x, * name.y, name.width and * name.height properties. * * @param win The window * @param name The window name */ public static void loadGeometry(Window win, String name) { int x, y, width, height; Dimension size = win.getSize(); GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); Rectangle gcbounds = gd.getDefaultConfiguration().getBounds(); x = gcbounds.x; y = gcbounds.y; width = jEdit.getIntegerProperty(name + ".width",size.width); height = jEdit.getIntegerProperty(name + ".height",size.height); Component parent = win.getParent(); if(parent == null) { x += (gcbounds.width - width) / 2; y += (gcbounds.height - height) / 2; } else { Rectangle bounds = parent.getBounds(); x += bounds.x + (bounds.width - width) / 2; y += bounds.y + (bounds.height - height) / 2; } x = jEdit.getIntegerProperty(name + ".x",x); y = jEdit.getIntegerProperty(name + ".y",y); int extState = jEdit.getIntegerProperty(name + ".extendedState", 0); Rectangle desired = new Rectangle(x,y,width,height); adjustForScreenBounds(desired); if(OperatingSystem.isX11() && Debug.GEOMETRY_WORKAROUND) new UnixWorkaround(win,name,desired,extState); else { win.setBounds(desired); if(win instanceof Frame) setExtendedState((Frame)win,extState); } } //}}} //{{{ adjustForScreenBounds() method /** * Gives a rectangle the specified bounds, ensuring it is within the * screen bounds. * @since jEdit 4.2pre3 */ public static void adjustForScreenBounds(Rectangle desired) { // Make sure the window is displayed in visible region Rectangle osbounds = OperatingSystem.getScreenBounds(desired); if(desired.x < osbounds.x || desired.x+desired.width > desired.x + osbounds.width) { if (desired.width > osbounds.width) desired.width = osbounds.width; desired.x = (osbounds.width - desired.width) / 2; } if(desired.y < osbounds.y || desired.y+desired.height > osbounds.y + osbounds.height) { if (desired.height >= osbounds.height) desired.height = osbounds.height; desired.y = (osbounds.height - desired.height) / 2; } } //}}} //{{{ UnixWorkaround class static class UnixWorkaround { Window win; String name; Rectangle desired; Rectangle required; long start; boolean windowOpened; //{{{ UnixWorkaround constructor UnixWorkaround(Window win, String name, Rectangle desired, int extState) { this.win = win; this.name = name; this.desired = desired; int adjust_x, adjust_y, adjust_width, adjust_height; adjust_x = jEdit.getIntegerProperty(name + ".dx",0); adjust_y = jEdit.getIntegerProperty(name + ".dy",0); adjust_width = jEdit.getIntegerProperty(name + ".d-width",0); adjust_height = jEdit.getIntegerProperty(name + ".d-height",0); required = new Rectangle( desired.x - adjust_x, desired.y - adjust_y, desired.width - adjust_width, desired.height - adjust_height); Log.log(Log.DEBUG,GUIUtilities.class,"Window " + name + ": desired geometry is " + desired); Log.log(Log.DEBUG,GUIUtilities.class,"Window " + name + ": setting geometry to " + required); start = System.currentTimeMillis(); win.setBounds(required); if(win instanceof Frame) setExtendedState((Frame)win,extState); win.addComponentListener(new ComponentHandler()); win.addWindowListener(new WindowHandler()); } //}}} //{{{ ComponentHandler class class ComponentHandler extends ComponentAdapter { //{{{ componentMoved() method public void componentMoved(ComponentEvent evt) { if(System.currentTimeMillis() - start < 1000) { Rectangle r = win.getBounds(); if(!windowOpened && r.equals(required)) return; if(!r.equals(desired)) { Log.log(Log.DEBUG,GUIUtilities.class, "Window resize blocked: " + win.getBounds()); win.setBounds(desired); } } win.removeComponentListener(this); } //}}} //{{{ componentResized() method public void componentResized(ComponentEvent evt) { if(System.currentTimeMillis() - start < 1000) { Rectangle r = win.getBounds(); if(!windowOpened && r.equals(required)) return; if(!r.equals(desired)) { Log.log(Log.DEBUG,GUIUtilities.class, "Window resize blocked: " + win.getBounds()); win.setBounds(desired); } } win.removeComponentListener(this); } //}}} } //}}} //{{{ WindowHandler class class WindowHandler extends WindowAdapter { //{{{ windowOpened() method public void windowOpened(WindowEvent evt) { windowOpened = true; Rectangle r = win.getBounds(); Log.log(Log.DEBUG,GUIUtilities.class,"Window " + name + ": bounds after opening: " + r); jEdit.setIntegerProperty(name + ".dx", r.x - required.x); jEdit.setIntegerProperty(name + ".dy", r.y - required.y); jEdit.setIntegerProperty(name + ".d-width", r.width - required.width); jEdit.setIntegerProperty(name + ".d-height", r.height - required.height); win.removeWindowListener(this); } //}}} } //}}} } //}}} //{{{ saveGeometry() method /** * Saves a window's geometry to the properties. * The geometry is saved to the name.x, * name.y, name.width and * name.height properties. * @param win The window * @param name The window name */ public static void saveGeometry(Window win, String name) { if(win instanceof Frame) { jEdit.setIntegerProperty(name + ".extendedState", getExtendedState((Frame)win)); } Rectangle bounds = win.getBounds(); jEdit.setIntegerProperty(name + ".x",bounds.x); jEdit.setIntegerProperty(name + ".y",bounds.y); jEdit.setIntegerProperty(name + ".width",bounds.width); jEdit.setIntegerProperty(name + ".height",bounds.height); } //}}} //{{{ getExtendedState() method /** * On Java 1.4, calls Frame.getExtendedState(). * On Java 1.3, returns 0. * @since jEdit 4.2pre1 */ public static int getExtendedState(Frame frame) { if(OperatingSystem.hasJava14()) { try { java.lang.reflect.Method meth = Frame.class.getMethod("getExtendedState", new Class[0]); Integer extState = (Integer)meth.invoke(frame, new Object[0]); return extState.intValue(); } catch(Exception e) { Log.log(Log.ERROR,GUIUtilities.class,e); } } return 0; } //}}} //{{{ setExtendedState() method /** * On Java 1.4, calls Frame.setExtendedState(). * On Java 1.3, does nothing. * @since jEdit 4.2pre1 */ public static void setExtendedState(Frame frame, int extState) { if(OperatingSystem.hasJava14()) { try { java.lang.reflect.Method meth = Frame.class.getMethod("setExtendedState", new Class[] {int.class}); meth.invoke(frame, new Object[] { new Integer(extState)}); } catch(Exception e) { Log.log(Log.ERROR,GUIUtilities.class,e); } } } //}}} //{{{ centerOnScreen() method /** * Centers the given window on the screen. This method is needed because * JDK 1.3 does not have a JWindow.setLocationRelativeTo() * method. * @since jEdit 4.2pre3 */ public static void centerOnScreen(Window win) { GraphicsDevice gd = GraphicsEnvironment .getLocalGraphicsEnvironment() .getDefaultScreenDevice(); Rectangle gcbounds = gd.getDefaultConfiguration().getBounds(); int x = gcbounds.x + (gcbounds.width - win.getWidth()) / 2; int y = gcbounds.y + (gcbounds.height - win.getHeight()) / 2; win.setLocation(x,y); } //}}} //}}} //{{{ hideSplashScreen() method /** * Ensures that the splash screen is not visible. This should be * called before displaying any dialog boxes or windows at * startup. */ public static void hideSplashScreen() { if(splash != null) { splash.dispose(); splash = null; } } //}}} //{{{ createMultilineLabel() method /** * Creates a component that displays a multiple line message. This * is implemented by assembling a number of JLabels in * a JPanel. * @param str The string, with lines delimited by newline * (\n) characters. * @since jEdit 4.1pre3 */ public static JComponent createMultilineLabel(String str) { JPanel panel = new JPanel(new VariableGridLayout( VariableGridLayout.FIXED_NUM_COLUMNS,1,1,1)); int lastOffset = 0; for(;;) { int index = str.indexOf('\n',lastOffset); if(index == -1) break; else { panel.add(new JLabel(str.substring(lastOffset,index))); lastOffset = index + 1; } } if(lastOffset != str.length()) panel.add(new JLabel(str.substring(lastOffset))); return panel; } //}}} //{{{ requestFocus() method /** * Focuses on the specified component as soon as the window becomes * active. * @param win The window * @param comp The component */ public static void requestFocus(final Window win, final Component comp) { win.addWindowListener(new WindowAdapter() { public void windowActivated(WindowEvent evt) { SwingUtilities.invokeLater(new Runnable() { public void run() { comp.requestFocus(); } }); win.removeWindowListener(this); } }); } //}}} //{{{ isPopupTrigger() method /** * Returns if the specified event is the popup trigger event. * This implements precisely defined behavior, as opposed to * MouseEvent.isPopupTrigger(). * @param evt The event * @since jEdit 3.2pre8 */ public static boolean isPopupTrigger(MouseEvent evt) { return isRightButton(evt.getModifiers()); } //}}} //{{{ isMiddleButton() method /** * @param modifiers The modifiers flag from a mouse event * @since jEdit 4.1pre9 */ public static boolean isMiddleButton(int modifiers) { if (OperatingSystem.isMacOS()) { if((modifiers & MouseEvent.BUTTON1_MASK) != 0) return ((modifiers & MouseEvent.ALT_MASK) != 0); if(!OperatingSystem.hasJava14()) return ((modifiers & MouseEvent.BUTTON3_MASK) != 0); else return ((modifiers & MouseEvent.BUTTON2_MASK) != 0); } else return ((modifiers & MouseEvent.BUTTON2_MASK) != 0); } //}}} //{{{ isRightButton() method /** * @param modifiers The modifiers flag from a mouse event * @since jEdit 4.1pre9 */ public static boolean isRightButton(int modifiers) { if (OperatingSystem.isMacOS()) { if((modifiers & MouseEvent.BUTTON1_MASK) != 0) return ((modifiers & MouseEvent.CTRL_MASK) != 0); if(!OperatingSystem.hasJava14()) return ((modifiers & MouseEvent.BUTTON2_MASK) != 0); else return ((modifiers & MouseEvent.BUTTON3_MASK) != 0); } else return ((modifiers & MouseEvent.BUTTON3_MASK) != 0); } //}}} //{{{ showPopupMenu() method /** * Shows the specified popup menu, ensuring it is displayed within * the bounds of the screen. * @param popup The popup menu * @param comp The component to show it for * @param x The x co-ordinate * @param y The y co-ordinate * @since jEdit 4.0pre1 */ public static void showPopupMenu(JPopupMenu popup, Component comp, int x, int y) { showPopupMenu(popup,comp,x,y,true); } //}}} //{{{ showPopupMenu() method /** * Shows the specified popup menu, ensuring it is displayed within * the bounds of the screen. * @param popup The popup menu * @param comp The component to show it for * @param x The x co-ordinate * @param y The y co-ordinate * @param point If true, then the popup originates from a single point; * otherwise it will originate from the component itself. This affects * positioning in the case where the popup does not fit onscreen. * * @since jEdit 4.1pre1 */ public static void showPopupMenu(JPopupMenu popup, Component comp, int x, int y, boolean point) { int offsetX = 0; int offsetY = 0; int extraOffset = (point ? 1 : 0); Component win = comp; while(!(win instanceof Window || win == null)) { offsetX += win.getX(); offsetY += win.getY(); win = win.getParent(); } if(win != null) { Dimension size = popup.getPreferredSize(); Rectangle screenSize = win.getGraphicsConfiguration() .getBounds(); if(x + offsetX + size.width + win.getX() > screenSize.width && x + offsetX + win.getX() >= size.width) { //System.err.println("x overflow"); if(point) x -= (size.width + extraOffset); else x = (win.getWidth() - size.width - offsetX + extraOffset); } else { x += extraOffset; } //System.err.println("y=" + y + ",offsetY=" + offsetY // + ",size.height=" + size.height // + ",win.height=" + win.getHeight()); if(y + offsetY + size.height + win.getY() > screenSize.height && y + offsetY + win.getY() >= size.height) { if(point) y = (win.getHeight() - size.height - offsetY + extraOffset); else y = -size.height - 1; } else { y += extraOffset; } popup.show(comp,x,y); } else popup.show(comp,x + extraOffset,y + extraOffset); } //}}} //{{{ isAncestorOf() method /** * Returns if the first component is an ancestor of the * second by traversing up the component hierarchy. * * @param comp1 The ancestor * @param comp2 The component to check * @since jEdit 4.1pre5 */ public static boolean isAncestorOf(Component comp1, Component comp2) { while(comp2 != null) { if(comp1 == comp2) return true; else comp2 = comp2.getParent(); } return false; } //}}} //{{{ getParentDialog() method /** * Traverses the given component's parent tree looking for an * instance of JDialog, and return it. If not found, return null. * @param c The component */ public static JDialog getParentDialog(Component c) { Component p = c.getParent(); while (p != null && !(p instanceof JDialog)) p = p.getParent(); return (p instanceof JDialog) ? (JDialog) p : null; } //}}} //{{{ getComponentParent() method /** * Finds a parent of the specified component. * @param comp The component * @param clazz Looks for a parent with this class (exact match, not * derived). * @since jEdit 4.2pre1 */ public static Component getComponentParent(Component comp, Class clazz) { for(;;) { if(comp == null) break; if(comp instanceof JComponent) { Component real = (Component)((JComponent)comp) .getClientProperty("KORTE_REAL_FRAME"); if(real != null) comp = real; } if(comp.getClass().equals(clazz)) return comp; else if(comp instanceof JPopupMenu) comp = ((JPopupMenu)comp).getInvoker(); else if(comp instanceof FloatingWindowContainer) { comp = ((FloatingWindowContainer)comp) .getDockableWindowManager(); } else comp = comp.getParent(); } return null; } //}}} //{{{ getView() method /** * Finds the view parent of the specified component. * @since jEdit 4.0pre2 */ public static View getView(Component comp) { return (View)getComponentParent(comp,View.class); } //}}} //{{{ Package-private members //{{{ init() method static void init() { // don't do this in static{} since we need jEdit.initMisc() // run first so we have the jeditresource: protocol NEW_BUFFER_ICON = loadIcon("new.gif"); DIRTY_BUFFER_ICON = loadIcon("dirty.gif"); READ_ONLY_BUFFER_ICON = loadIcon("readonly.gif"); NORMAL_BUFFER_ICON = loadIcon("normal.gif"); WINDOW_ICON = loadIcon("jedit-icon.gif"); } //}}} //{{{ showSplashScreen() method static void showSplashScreen() { splash = new SplashScreen(); } //}}} //{{{ advanceSplashProgress() method static void advanceSplashProgress() { if(splash != null) splash.advance(); } //}}} //}}} //{{{ Private members private static SplashScreen splash; private static Hashtable icons; private static String iconPath = "jeditresource:/org/gjt/sp/jedit/icons/"; private static String defaultIconPath = "jeditresource:/org/gjt/sp/jedit/icons/"; private GUIUtilities() {} //}}} }
... 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.