Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
editor.util.EditorUtilities Maven / Gradle / Ivy
package editor.util;
import editor.LabFrame;
import editor.Scheme;
import editor.plugin.typeloader.ITypeFactory;
import gw.lang.reflect.IFunctionType;
import gw.lang.reflect.IMethodInfo;
import gw.lang.reflect.IType;
import gw.lang.reflect.TypeSystem;
import gw.lang.reflect.gs.ClassType;
import gw.lang.reflect.gs.IGosuClass;
import gw.lang.reflect.gs.IGosuClassTypeInfo;
import gw.lang.reflect.gs.IGosuEnhancement;
import gw.lang.reflect.gs.IGosuProgram;
import gw.lang.reflect.gs.ITemplateType;
import gw.lang.reflect.java.IJavaType;
import gw.lang.reflect.java.JavaTypes;
import java.nio.file.Path;
import gw.util.PathUtil;
import manifold.util.ReflectUtil;
import java.awt.AWTEvent;
import java.awt.ActiveEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.KeyboardFocusManager;
import java.awt.MenuComponent;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.datatransfer.Clipboard;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageProducer;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JRootPane;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.filechooser.FileSystemView;
public class EditorUtilities
{
static final HashMap ICON_TABLE = new HashMap<>();
private static final String BACKGROUND_QUEUE_NAME = "backgroundTasks";
static Map CONTAINS_FOCUS;
static Map FOCUS_CONTAINS;
/**
* Platform dependent keystroke info
*/
public static final String CONTROL_KEY_NAME;
public static final int CONTROL_KEY_MASK;
static
{
if( PlatformUtil.isMac() )
{
CONTROL_KEY_MASK = KeyEvent.META_MASK;
CONTROL_KEY_NAME = "meta";
}
else
{
CONTROL_KEY_MASK = KeyEvent.CTRL_MASK;
CONTROL_KEY_NAME = "control";
}
}
static public void doBackgroundOp( final Runnable run )
{
editor.util.TaskQueue backgroundQueue = getBackgroundQueue();
if( backgroundQueue != null )
{
backgroundQueue.postTask(
new Runnable()
{
public void run()
{
run.run();
}
} );
}
else
{
run.run();
}
}
private static editor.util.TaskQueue getBackgroundQueue()
{
return editor.util.TaskQueue.getInstance( BACKGROUND_QUEUE_NAME );
}
/**
* Pumps through all current events in the background operation queue. Note that this is *NOT* a settle.
* Any operations added after this method is invoked will not be executed.
*/
public static void settleBackgroundOps()
{
editor.util.TaskQueue backgroundQueue = getBackgroundQueue();
if( backgroundQueue != null )
{
final Object wait = new Object();
synchronized( wait )
{
doBackgroundOp( new Runnable()
{
public void run()
{
synchronized( wait )
{
wait.notifyAll();
}
}
} );
try
{
wait.wait();
}
catch( InterruptedException e )
{
//ignore
}
}
}
}
public static void removePopupBorder( final Container c )
{
EventQueue.invokeLater(
() -> {
Container p = c;
while( p != null )
{
if( p instanceof JComponent )
{
((JComponent)p).setBorder( null );
}
p = p.getParent();
}
} );
}
public static void centerWindowInFrame( Component window, Window frame )
{
// Note FileDialog instances in jdk 1.4.1 have no size until FileDialog.show()
// which blocks i.e., we can't center FileDialogs.
Dimension dimCenter;
Point ptOffset;
if( frame != null )
{
if( (!(frame instanceof Frame) || ((Frame)frame).getState() != Frame.ICONIFIED) && frame.isShowing() )
{
// Center in frame
dimCenter = frame.getSize();
ptOffset = frame.getLocation();
}
else
{
// Retry either containing window or screen
centerWindowInFrame( window, null );
return;
}
}
else
{
Window owner = SwingUtilities.getWindowAncestor( window );
if( owner != null && owner.isShowing() && (owner.getMinimumSize().height < owner.getHeight()) )
{
// Retry with owner window as frame
if( (!(owner instanceof Frame) || ((Frame)owner).getState() != Frame.ICONIFIED) && owner.isShowing() )
{
// Center in frame
dimCenter = owner.getSize();
ptOffset = owner.getLocation();
window.setLocation( ptOffset.x + (dimCenter.width - window.getWidth()) / 2, ptOffset.y + (dimCenter.height - window.getHeight()) / 2 );
}
return;
}
// Center in screen
Rectangle screenRect = getPrimaryMonitorScreenRect();
dimCenter = new Dimension( (int)screenRect.getWidth(), (int)screenRect.getHeight() );
ptOffset = new Point( (int)screenRect.getX(), (int)screenRect.getY() );
}
window.setLocation( ptOffset.x + (dimCenter.width - window.getWidth()) / 2, ptOffset.y + (dimCenter.height - window.getHeight()) / 2 );
}
public static Rectangle getPrimaryMonitorScreenRect()
{
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gds = ge.getScreenDevices();
return gds[0].getConfigurations()[0].getBounds();
}
public static ImageIcon loadIcon( String strRes )
{
if( strRes == null || strRes.length() == 0 )
{
return null;
}
ImageIcon icon = ICON_TABLE.get( strRes );
if( icon == null && !strRes.contains( " | " ) )
{
try
{
if( Scheme.active().isDark() && !strRes.contains( "_dark." ) )
{
int iDot = strRes.lastIndexOf( '.' );
if( iDot >= 0 )
{
String strResDark = strRes.substring( 0, iDot ) + "_dark" + strRes.substring( iDot );
icon = loadIcon( strResDark );
}
}
if( icon == null )
{
URL resource = editor.util.EditorUtilities.class.getClassLoader().getResource( strRes );
if( resource != null )
{
icon = new ImageIcon( resource );
}
}
}
catch( Exception e )
{
// just return null
}
if( icon != null )
{
ICON_TABLE.put( strRes, icon );
}
}
return icon;
}
public static Icon findIcon( Path fileOrDir )
{
if( PathUtil.isDirectory( fileOrDir ) )
{
if( LabFrame.instance().getGosuPanel().getExperimentView().getExperiment().getSourcePath().contains( PathUtil.getAbsolutePathName( fileOrDir ) ) )
{
return loadIcon( "images/srcfolder.png" );
}
return loadIcon( "images/folder.png" );
}
String classNameForFile = TypeNameUtil.getTypeNameForFile( fileOrDir );
if( classNameForFile != null )
{
IType type = TypeSystem.getByFullNameIfValid( classNameForFile );
if( type != null )
{
return findIcon( type );
}
}
if( PathUtil.isFile( fileOrDir ) )
{
try
{
return FileSystemView.getFileSystemView().getSystemIcon( fileOrDir.toFile() );
}
catch( UnsupportedOperationException e )
{
// eat
}
}
return loadIcon( "images/FileText.png" );
}
public static Icon findIcon( IType type )
{
if( type instanceof IGosuClass )
{
if( type.isInterface() )
{
if( ((IGosuClass)type).isStructure() )
{
return findIcon( ClassType.Structure );
}
else if( ((IGosuClass)type).isAnnotation() )
{
return findIcon( ClassType.Annotation );
}
return findIcon( ClassType.Interface );
}
else if( type instanceof ITemplateType )
{
return findIcon( ClassType.Template );
}
else if( type instanceof IGosuEnhancement )
{
return findIcon( ClassType.Enhancement );
}
else if( type instanceof IGosuProgram )
{
return findIcon( ClassType.Program );
}
else if( type.isEnum() )
{
return findIcon( ClassType.Enum );
}
else
{
return findIcon( ClassType.Class );
}
}
else if( type instanceof IJavaType )
{
return EditorUtilities.loadIcon( "images/javaclass.png" );
}
else if( type != null )
{
ITypeFactory factory = type.getTypeLoader().getInterface( ITypeFactory.class );
if( factory != null )
{
return EditorUtilities.loadIcon( factory.getIcon() );
}
}
return EditorUtilities.loadIcon( "images/empty16x16.gif" );
}
public static Icon findIcon( ClassType classType )
{
switch( classType )
{
case Class:
return EditorUtilities.loadIcon( "images/class.png" );
case Enum:
return EditorUtilities.loadIcon( "images/enum.png" );
case Interface:
return EditorUtilities.loadIcon( "images/interface.png" );
case Structure:
return EditorUtilities.loadIcon( "images/structure.png" );
case Annotation:
return EditorUtilities.loadIcon( "images/annotation.png" );
case Enhancement:
return EditorUtilities.loadIcon( "images/Enhancement.png" );
case Program:
return EditorUtilities.loadIcon( "images/program.png" );
case Template:
return EditorUtilities.loadIcon( "images/template.png" );
case JavaClass:
return EditorUtilities.loadIcon( "images/javaclass.png" );
}
return null;
}
public static void handleUncaughtException( Throwable e )
{
handleUncaughtException( "", e );
}
public static void handleUncaughtException( String s, Throwable e )
{
System.out.println( s );
e.printStackTrace();
}
public static void settleEventQueue()
{
EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
while( eventQueue.peekEvent() != null )
{
try
{
AWTEvent event = Toolkit.getDefaultToolkit().getSystemEventQueue().getNextEvent();
Object src = event.getSource();
if( event instanceof ActiveEvent )
{
((ActiveEvent)event).dispatch();
}
else if( src instanceof Component )
{
((Component)src).dispatchEvent( event );
}
else if( src instanceof MenuComponent )
{
((MenuComponent)src).dispatchEvent( event );
}
}
catch( Throwable e )
{
handleUncaughtException( "", e );
}
}
}
public static Clipboard getClipboard()
{
return LabFrame.instance().getGosuPanel().getClipboard();
}
public static Frame frameForComponent( Component comp )
{
for( Component p = comp; p != null; p = p.getParent() )
{
if( p instanceof Frame )
{
return (Frame)p;
}
}
return null;
}
public static Window windowForComponent( Component comp )
{
for( Component p = comp; p != null; p = p.getParent() )
{
if( p instanceof Window )
{
return (Window)p;
}
}
return null;
}
public static String buildFunctionIntellisenseString( boolean bFeatureLiteralCompletion, IFunctionType functionType )
{
StringBuilder sb = new StringBuilder();
String rawName = functionType.getDisplayName();
sb.append( rawName );
sb.append( "()" );
return sb.toString();
}
public static Window getWindow()
{
return KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
}
public static Image createSystemColorImage( Image i )
{
SystemColorFilter filter = new SystemColorFilter();
ImageProducer prod = new FilteredImageSource( i.getSource(), filter );
return Toolkit.getDefaultToolkit().createImage( prod );
}
public static void displayInformation( String strMsg )
{
displayMessageBox( strMsg, JOptionPane.INFORMATION_MESSAGE, false );
}
//--------------------------------------------------------------------------------------------------
public static void displayError( Throwable e )
{
displayMessageBox( e == null ? "Error performing operation." : e.getMessage(), JOptionPane.ERROR_MESSAGE, false );
}
//--------------------------------------------------------------------------------------------------
public static void displayError( String strMsg )
{
displayMessageBox( strMsg, JOptionPane.ERROR_MESSAGE, false );
}
//--------------------------------------------------------------------------------------------------
public static void displayWarning( String strMsg )
{
displayMessageBox( strMsg, JOptionPane.WARNING_MESSAGE, false );
}
//--------------------------------------------------------------------------------------------------
public static void displayMessageBox( String strMsg, final int iType, boolean bWrapText )
{
final String strWrappedMsg = bWrapText ? wrapText( strMsg ) : strMsg;
Runnable logMsgBox = new Runnable()
{
public void run()
{
JOptionPane.showMessageDialog( getWindow(), strWrappedMsg, "", iType );
}
};
if( EventQueue.isDispatchThread() )
{
logMsgBox.run();
}
else
{
try
{
EventQueue.invokeAndWait( logMsgBox );
}
catch( Throwable t )
{
t.printStackTrace();
}
}
}
public static String wrapText( String strText )
{
return wrapText( strText, 60 );
}
public static String wrapText( String strText, int iLineLen )
{
StringBuilder sb = new StringBuilder();
while( strText != null )
{
if( strText.length() > iLineLen )
{
sb.append( strText.substring( 0, 60 ) ).append( "\n" );
strText = strText.substring( 60 );
}
else
{
sb.append( strText );
strText = null;
}
}
return sb.toString();
}
public static void convertRectangleToScreen( Rectangle rectangle, Component component )
{
Point loc = rectangle.getLocation();
SwingUtilities.convertPointToScreen( loc, component );
rectangle.setLocation( loc );
}
public static java.util.List filterStrings( Collection extends CharSequence> collection, String filter )
{
if( filter != null )
{
int iDotIndex = filter.lastIndexOf( '.' );
if( iDotIndex >= 0 )
{
filter = filter.substring( iDotIndex + 1 );
}
}
java.util.List filteredTypes = new ArrayList();
if( filter != null && filter.length() > 0 )
{
int iFlags = 0;
if( filter.indexOf( '*' ) < 0 &&
Character.isUpperCase( filter.charAt( 0 ) ) )
{
filter = camelCasePrefix( filter );
}
else
{
iFlags = Pattern.CASE_INSENSITIVE;
}
// Replace all wildcard '*' chars with the regex ".*" expression
filter = filter.replaceAll( "\\*", "\\.\\*" );
// A '#' char indicates that the proper regex syntax has already been embedded in the string;
// we only need to replace the '#' with '*'
filter = filter.replaceAll( "\\#", "\\*" );
boolean bHasDot = filter.indexOf( '~' ) >= 0;
filter = filter.replaceAll( "~", "(\\\\.|" + '\u2024' + ")" );
// Match the expression string followed by any number of chars
try
{
Pattern pattern = Pattern.compile( filter + (filter.startsWith( ".*" ) ? "" : ".*"), iFlags );
for( CharSequence cs : collection )
{
String strType = cs.toString();
String strName = bHasDot ? strType : getRelativeTypeName( strType );
if( pattern.matcher( strName ).find() )
{
filteredTypes.add( strType );
}
}
}
catch( PatternSyntaxException e )
{
// Skip
}
}
return filteredTypes;
}
private static String camelCasePrefix( String strPrefix )
{
StringBuilder sb = new StringBuilder();
for( int i = strPrefix.length() - 1; i >= 0; i-- )
{
char c = strPrefix.charAt( i );
sb.insert( 0, c );
if( i != 0 && Character.isUpperCase( c ) )
{
// Each uppercase char in the prefix match all but uppercase chars preceding it e.g.,
// "AcT" matches any string starting with "Ac" followed by any number of non-uppercase chars followed by "T".
// It's the same as the regex "Ac[^A-Z]*T"
sb.insert( 0, "[^A-Z]#" );
}
}
return sb.toString();
}
private static String getRelativeTypeName( String strType )
{
int iIndex = strType.lastIndexOf( '.' );
if( iIndex > 0 )
{
return strType.substring( iIndex + 1 );
}
return strType;
}
public static void hideToolTip( JComponent c )
{
ReflectUtil.method( ToolTipManager.sharedInstance(), "hide", JComponent.class ).invoke( c );
}
public static JRootPane rootPaneForComponent( Component comp )
{
for( Component p = comp; p != null; p = p.getParent() )
{
if( p instanceof JRootPane )
{
return (JRootPane)p;
}
if( comp instanceof JFrame )
{
return ((JFrame)comp).getRootPane();
}
if( comp instanceof JDialog )
{
return ((JDialog)comp).getRootPane();
}
if( comp instanceof JWindow )
{
return ((JWindow)comp).getRootPane();
}
}
return null;
}
public static void invokeInDispatchThread( Runnable task )
{
if( task == null )
{
return;
}
if( EventQueue.isDispatchThread() )
{
task.run();
}
else
{
try
{
EventQueue.invokeAndWait( task );
}
catch( Throwable t )
{
handleUncaughtException( t );
}
}
}
public static void invokeNowOrLater( Runnable task )
{
if( task == null )
{
return;
}
if( EventQueue.isDispatchThread() )
{
task.run();
}
else
{
try
{
EventQueue.invokeLater( task );
}
catch( Throwable t )
{
handleUncaughtException( t );
}
}
}
public static Process browse( String strURL ) throws IOException
{
String strCmd;
if( PlatformUtil.isWindows() )
{
strCmd = "rundll32 url.dll,FileProtocolHandler " + strURL;
}
else
{
//## todo: barf
strCmd = "firefox " + strURL;
}
return Runtime.getRuntime().exec( strCmd );
}
/**
* Finds the first widget above the passed in widget of the given class
*/
public static T findAncestor( Component start, Class aClass )
{
if( start == null )
{
return null;
}
return findAtOrAbove( start.getParent(), aClass );
}
/**
* Finds the first widget at or above the passed in widget of the given class
*/
public static T findAtOrAbove( Component start, Class aClass )
{
Component comp = start;
while( comp != null )
{
if( aClass.isInstance( comp ) )
{
return (T)comp;
}
else
{
comp = comp.getParent();
}
}
return null;
}
public static List findDecendents( Component configUI, Class aClass )
{
return findDecendents( configUI, aClass, c -> true );
}
private static void _findDecendents( ArrayList comps, Component component, Class aClass, Predicate recurseToChildren )
{
if( aClass.isInstance( component ) )
{
//noinspection unchecked
comps.add( (T)component );
}
if( component instanceof Container )
{
Container container = (Container)component;
Component[] components = container.getComponents();
if( recurseToChildren.test( container ) )
{
for( Component child : components )
{
_findDecendents( comps, child, aClass, recurseToChildren );
}
if( container instanceof JMenu )
{
JPopupMenu popupMenu = ((JMenu)container).getPopupMenu();
if( popupMenu != null )
{
_findDecendents( comps, popupMenu, aClass, recurseToChildren );
}
}
}
}
}
public static List findDecendents( Component configUI, Class aClass, Predicate recurseToChildren )
{
ArrayList comps = new ArrayList<>();
_findDecendents( comps, configUI, aClass, recurseToChildren );
return comps;
}
public static boolean isRunnable( IType type )
{
if( type == null || !type.isValid() )
{
return false;
}
if( LabFrame.instance().getGosuPanel().isRunning() ||
LabFrame.instance().getGosuPanel().isDebugging() )
{
return false;
}
// Is Program?
if( type instanceof IGosuProgram )
{
return true;
}
if( type instanceof IGosuClass && !type.isAbstract() &&
((IGosuClassTypeInfo)type.getTypeInfo()).isPublic() )
{
// Is Main class?
IMethodInfo main = type.getTypeInfo().getMethod( "main", JavaTypes.STRING().getArrayType() );
if( main != null && main.isStatic() && main.getReturnType() == JavaTypes.pVOID() )
{
return true;
}
// Is Test class?
if( type.getTypeInfo().getConstructor() != null )
{
IType baseTest = TypeSystem.getByFullNameIfValid( "junit.framework.Assert" );
if( baseTest != null )
{
return baseTest.isAssignableFrom( type );
}
return type.getName().endsWith( "Test" );
}
}
return false;
}
public static void fixSwingFocusBugWhenPopupCloses( Component c )
{
// This is a fix to workaround a bug with Swing JPopupMenu. Withou this
// focus is stolen from a subsequent selected field. See Bug CC-1140.
editor.util.EditorUtilities.rootPaneForComponent( c ).dispatchEvent( new MouseEvent( c, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), 0, 3, 3, 1, false ) );
}
public static Component showWaitCursor( final boolean bWait )
{
return WaitCursorRunner.showWaitCursor( bWait );
}
public static void showWaitCursor( boolean bWait, Component c )
{
WaitCursorRunner.showWaitCursor( bWait, c );
}
public static void doWaitOperation( Runnable op )
{
Component key = showWaitCursor( true );
try
{
op.run();
}
finally
{
showWaitCursor( false, key );
}
}
public static Component getFocus()
{
return KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
}
public static Window getFocusedWindow()
{
return KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
}
public static Window getActiveWindow()
{
Window activeWindow = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
if( activeWindow == null )
{
Frame[] frames = Frame.getFrames();
if( frames != null && frames.length > 0 )
{
return frames[0];
}
}
return activeWindow;
}
public static boolean containsFocus( Component c )
{
addFocusListener();
Boolean containsFocus = CONTAINS_FOCUS.get( c );
if( containsFocus != null )
{
return containsFocus;
}
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
// Verify focusOwner is a descendant of c
for( Component temp = focusOwner; temp != null; temp = (temp instanceof Window) ? null : temp.getParent() )
{
if( temp == c )
{
CONTAINS_FOCUS.put( c, true );
return true;
}
}
CONTAINS_FOCUS.put( c, false );
return false;
}
public static boolean focusContains( Component c )
{
addFocusListener();
Boolean focusContains = FOCUS_CONTAINS.get( c );
if( focusContains != null )
{
return focusContains;
}
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
// Verify c is a descendant of focusOwner
for( Component temp = c; temp != null; temp = (temp instanceof Window) ? null : temp.getParent() )
{
if( temp == focusOwner )
{
FOCUS_CONTAINS.put( c, true );
return true;
}
}
FOCUS_CONTAINS.put( c, false );
return false;
}
private static void addFocusListener()
{
if( CONTAINS_FOCUS != null )
{
return;
}
CONTAINS_FOCUS = new HashMap<>();
FOCUS_CONTAINS = new HashMap<>();
KeyboardFocusManager focusMgr = KeyboardFocusManager.getCurrentKeyboardFocusManager();
focusMgr.addPropertyChangeListener( "permanentFocusOwner",
evt -> {
CONTAINS_FOCUS.clear();
FOCUS_CONTAINS.clear();
} );
}
public static boolean isInFocusLineage( Component c )
{
return containsFocus( c ) || focusContains( c );
}
public static Point getXYForDialogRelativeToStudioFrame( int width, int height )
{
Rectangle screenRect = getPrimaryMonitorScreenRect();
return new Point( (int)(screenRect.getX() + (screenRect.getWidth() - width) / 2),
(int)(screenRect.getY() + (screenRect.getHeight() - height) / 2) );
}
public static String hex( Color color )
{
return Integer.toHexString( (color.getRGB() & 0xffffff) | 0x1000000 ).substring( 1 );
}
public static String getFontFamilyOrDefault( String name, String defaultFont )
{
if( Arrays.stream( GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames() ).anyMatch( e -> e.equalsIgnoreCase( name ) ) )
{
return name;
}
return defaultFont;
}
}