All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ij.gui.GUI Maven / Gradle / Ivy

Go to download

ImageJ is an open source Java image processing program inspired by NIH Image for the Macintosh.

There is a newer version: 1.54m
Show newest version
package ij.gui;
import ij.*;
import java.awt.*;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.UIManager;

/** This class consists of static GUI utility methods. */
public class GUI {
	private static final Font DEFAULT_FONT = IJ.font12;
	private static Color lightGray = new Color(240,240,240);
	private static boolean isWindows8;
	private static Color scrollbarBackground = new Color(245,245,245);

	static {
		if (IJ.isWindows()) {
			String osname = System.getProperty("os.name");
			isWindows8 = osname.contains("unknown") || osname.contains("8");
		}
	}

	/** Positions the specified window in the center of the screen that contains target. */
	public static void center(Window win, Component target) {
		if (win == null)
			return;
		Rectangle bounds = getMaxWindowBounds(target);
		Dimension window = win.getSize();
		if (window.width == 0)
			return;
		int left = bounds.x + Math.max(0, (bounds.width - window.width) / 2);
		int top = bounds.y + Math.max(0, (bounds.height - window.height) / 4);
		win.setLocation(left, top);
	}
	
	/** Positions the specified window in the center of the
		 screen containing the "ImageJ" window. */
	public static void centerOnImageJScreen(Window win) {
		center(win, IJ.getInstance());
	}

	public static void center(Window win) {
		center(win, win);
	}
	
	private static java.util.List getScreenConfigs() {
		java.util.ArrayList configs = new java.util.ArrayList();
		for (GraphicsDevice device : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
			configs.add(device.getDefaultConfiguration());
		}
		return configs;
	}
	
	/**
	 * Get maximum bounds for the screen that contains a given point.
	 * @param point Coordinates of point.
	 * @param accountForInsets Deduct the space taken up by menu and status bars, etc. (after point is found to be inside bonds)
	 * @return Rectangle of bounds or null if point not inside of any screen.
	 */
	public static Rectangle getScreenBounds(Point point, boolean accountForInsets) {
		if (GraphicsEnvironment.isHeadless())
			return new Rectangle(0,0,0,0);
		for (GraphicsConfiguration config : getScreenConfigs()) {
			Rectangle bounds = config.getBounds();
			if (bounds != null && bounds.contains(point)) {
				Insets insets = accountForInsets ? Toolkit.getDefaultToolkit().getScreenInsets(config) : null;
				return shrinkByInsets(bounds, insets);
			}
		}
		return null;		
	}
	
	/**
	 * Get maximum bounds for the screen that contains a given component.
	 * @param component An AWT component located on the desired screen.
	 * If null is provided, the default screen is used.
	 * @param accountForInsets Deduct the space taken up by menu and status bars, etc.
	 * @return Rectangle of bounds.
	 */	
	public static Rectangle getScreenBounds(Component component, boolean accountForInsets) {
		if (GraphicsEnvironment.isHeadless())
			return new Rectangle(0,0,0,0);
		GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();		
		GraphicsConfiguration gc = component == null ? ge.getDefaultScreenDevice().getDefaultConfiguration() :
													   component.getGraphicsConfiguration();   
		Insets insets = accountForInsets ? Toolkit.getDefaultToolkit().getScreenInsets(gc) : null;
		return shrinkByInsets(gc.getBounds(), insets);
	}

	public static Rectangle getScreenBounds(Point point) {
		return getScreenBounds(point, false);
	}		

	public static Rectangle getScreenBounds(Component component) {
		return getScreenBounds(component, false);
	}			

	public static Rectangle getScreenBounds() {
		return getScreenBounds((Component)null);
	}			

	public static Rectangle getMaxWindowBounds(Point point) {
		return getScreenBounds(point, true);
	}

	public static Rectangle getMaxWindowBounds(Component component) {
		return getScreenBounds(component, true);
	}
	
	public static Rectangle getMaxWindowBounds() {
		return getMaxWindowBounds((Component)null);
	}
	
	private static Rectangle shrinkByInsets(Rectangle bounds, Insets insets) {
		Rectangle shrunk = new Rectangle(bounds);
		if (insets == null) return shrunk; 
		shrunk.x += insets.left;
		shrunk.y += insets.top;
		shrunk.width -= insets.left + insets.right;
		shrunk.height -= insets.top + insets.bottom;
		return shrunk;
	}
	
	public static Rectangle getZeroBasedMaxBounds() {
		for (GraphicsConfiguration config : getScreenConfigs()) {
			Rectangle bounds = config.getBounds();
			if (bounds != null && bounds.x == 0 && bounds.y == 0)
				return bounds;
		}
		return null;
	}
	
	public static Rectangle getUnionOfBounds() {
		Rectangle unionOfBounds = new Rectangle();
		for (GraphicsConfiguration config : getScreenConfigs()) {
			unionOfBounds = unionOfBounds.union(config.getBounds());
		}
		return unionOfBounds;
	}
	
    static private Frame frame;
    
    /** Obsolete */
    public static Image createBlankImage(int width, int height) {
        if (width==0 || height==0)
            throw new IllegalArgumentException("");
		if (frame==null) {
			frame = new Frame();
			frame.pack();
			frame.setBackground(Color.white);
		}
        Image img = frame.createImage(width, height);
        return img;
    }
    
    /** Lightens overly dark scrollbar background on Windows 8. */
    public static void fix(Scrollbar sb) {
    }
    
    public static boolean showCompositeAdvisory(ImagePlus imp, String title) {
    	if (imp==null || imp.getCompositeMode()!=IJ.COMPOSITE || imp.getNChannels()==1 || IJ.macroRunning())
    		return true;
    	String msg = "Channel "+imp.getC()+" of this color composite image will be processed.";
		GenericDialog gd = new GenericDialog(title);
		gd.addMessage(msg);
		gd.showDialog();
		return !gd.wasCanceled();
	}
	
	/**
	 * Scales an AWT component according to {@link Prefs#getGuiScale()}.
	 * @param component the AWT component to be scaled. If a container, scaling is applied to all its child components
	 */
	public static void scale(final Component component) {
		final float scale = (float)Prefs.getGuiScale();
		if (scale==1f)
			return;
		if (component instanceof Container)
			scaleComponents((Container)component, scale);
		else
			scaleComponent(component, scale);
	}

	private static void scaleComponents(final Container container, final float scale) {
		for (final Component child : container.getComponents()) {
			if (child instanceof Container)
				scaleComponents((Container) child, scale);
			else
				scaleComponent(child, scale);
		}
	}

	private static void scaleComponent(final Component component, final float scale) {
		Font font = component.getFont();
		if (font == null)
			font = DEFAULT_FONT;
		font = font.deriveFont(scale*font.getSize());
		component.setFont(font);
	}

	public static void scalePopupMenu(final PopupMenu popup) {
		final float scale = (float)Prefs.getGuiScale();
		if (scale==1f)
			return;
		Font font = popup.getFont();
		if (font == null)
			font = DEFAULT_FONT;
		font = font.deriveFont(scale*font.getSize());
		popup.setFont(font);
	}
	
	/**
	 * Tries to detect if a Swing component is unscaled and scales it it according
	 * to {@link #getGuiScale()}.
	 * 

* This is mainly relevant to linux: Swing components scale automatically on * most platforms, specially since Java 8. However there are still exceptions to * this on linux: e.g., In Ubuntu, Swing components do scale, but only under the * GTK L&F. (On the other hand AWT components do not scale at all on * hiDPI screens on linux). *

*

* This method tries to avoid exaggerated font sizes by detecting if a component * has been already scaled by the UIManager, applying only * {@link #getGuiScale()} to the component's font if not. *

* * @param component the component to be scaled * @return true, if component's font was resized */ public static boolean scale(final JComponent component) { final double guiScale = Prefs.getGuiScale(); if (guiScale == 1d) return false; Font font = component.getFont(); if (font == null && component instanceof JList) font = UIManager.getFont("List.font"); else if (font == null && component instanceof JTable) font = UIManager.getFont("Table.font"); else if (font == null) font = UIManager.getFont("Label.font"); if (font.getSize() > DEFAULT_FONT.getSize()) return false; if (component instanceof JTable) ((JTable) component).setRowHeight((int) (((JTable) component).getRowHeight() * guiScale * 0.9)); else if (component instanceof JList) ((JList) component).setFixedCellHeight((int) (((JList) component).getFixedCellHeight() * guiScale * 0.9)); component.setFont(font.deriveFont((float) guiScale * font.getSize())); return true; } /** Works around an OpenJDK bug on Windows that * causes the scrollbar thumb color and background * color to be almost identical. */ public static final void fixScrollbar(Scrollbar sb) { if (IJ.isWindows()) sb.setBackground(scrollbarBackground); } /** Returns a new NonBlockingGenericDialog with the given title, * except when Java is running in headless mode, in which case * a GenericDialog is be returned. */ public static GenericDialog newNonBlockingDialog(String title) { if (GraphicsEnvironment.isHeadless()) return new GenericDialog(title); else return new NonBlockingGenericDialog(title); } /** Returns a new NonBlockingGenericDialog with the given title * if Prefs.nonBlockingFilterDialogs is 'true' and 'imp' is * displayed, otherwise returns a GenericDialog. * @param title Dialog title * @param imp The image associated with this dialog */ public static GenericDialog newNonBlockingDialog(String title, ImagePlus imp) { if (Prefs.nonBlockingFilterDialogs && imp!=null && imp.getWindow()!=null) { NonBlockingGenericDialog gd = new NonBlockingGenericDialog(title); gd.imp = imp; return gd; } else return new GenericDialog(title); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy