
com.jidesoft.utils.PortingUtils Maven / Gradle / Ivy
/*
* @(#)PortingUtils.java 4/12/2006
*
* Copyright 2002 - 2006 JIDE Software Inc. All rights reserved.
*/
package com.jidesoft.utils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.geom.Area;
import java.util.ArrayList;
import java.util.List;
/**
* A class that keeps all 1.4/1.3 different stuff.
*/
public class PortingUtils {
private static Rectangle _virtualBounds = null;
/**
* Gets current focused components. If 1.3, just uses event's source; 1.4, used keyboard focus manager to get the
* correct focused component.
*
* @param event the event. This parameter is not used anymore in JDK 1.4+.
* @return current focused component
*/
@SuppressWarnings({"UnusedDeclaration"})
public static Component getCurrentFocusComponent(AWTEvent event) {
return KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
}
/**
* Gets frame's state. In 1.3, used getState; in 1.4, uses getExtendedState.
*
* @param frame the frame.
* @return frame's state
*/
public static int getFrameState(Frame frame) {
return frame.getExtendedState();
}
/**
* Sets frame's state. In 1.3, uses sets frame's state; in 1.4, uses gets frame's state.
*
* @param frame the frame
* @param state the state
*/
public static void setFrameState(Frame frame, int state) {
frame.setExtendedState(state);
}
/**
* Gets mouse modifiers. If 1.3, uses getModifiers; 1.4, getModifiersEx.
*
* @param e the mouse event
* @return mouse modifiers
*/
public static int getMouseModifiers(MouseEvent e) {
return e.getModifiersEx();
}
/**
* Makes sure the component won't receive the focus.
*
* @param component the component
*/
public static void removeFocus(JComponent component) {
component.setRequestFocusEnabled(false);
component.setFocusable(false);
}
/**
* Removes the button border.
*
* @param button the button
*/
public static void removeButtonBorder(AbstractButton button) {
button.setContentAreaFilled(false);
button.setMargin(new Insets(0, 0, 0, 0));
button.setBorder(BorderFactory.createEmptyBorder());
}
/**
* To make sure the rectangle is within the screen bounds.
*
* @param invoker the component which invokes this method.
* @param rect the rect.
* @return the rectange that is in the screen bounds.
*/
public static Rectangle containsInScreenBounds(Component invoker, Rectangle rect) {
Rectangle screenBounds = getScreenBounds(invoker);
Point p = rect.getLocation();
if (p.x + rect.width > screenBounds.x + screenBounds.width) {
p.x = screenBounds.x + screenBounds.width - rect.width;
}
if (p.y + rect.height > screenBounds.y + screenBounds.height) {
p.y = screenBounds.y + screenBounds.height - rect.height;
}
if (p.x < screenBounds.x) {
p.x = screenBounds.x;
}
if (p.y < screenBounds.y) {
p.y = screenBounds.y;
}
return new Rectangle(p, rect.getSize());
}
/**
* To make sure the rectangle has overlap with the screen bounds.
*
* @param invoker the component which invokes this method.
* @param rect the rect.
* @return the rectange that has overlap with the screen bounds.
*/
public static Rectangle overlapWithScreenBounds(Component invoker, Rectangle rect) {
Rectangle screenBounds = getScreenBounds(invoker);
Point p = rect.getLocation();
if (p.x > screenBounds.x + screenBounds.width) {
p.x = screenBounds.x + screenBounds.width - rect.width;
}
if (p.y > screenBounds.y + screenBounds.height) {
p.y = screenBounds.y + screenBounds.height - rect.height;
}
if (p.x + rect.width < screenBounds.x) {
p.x = screenBounds.x;
}
if (p.y + rect.height < screenBounds.y) {
p.y = screenBounds.y;
}
return new Rectangle(p, rect.getSize());
}
/**
* Gets the screen size. In JDK1.4+, the returned size will exclude task bar area on Windows OS.
*
* @param invoker the component which invokes this method.
* @return the screen size.
*/
public static Dimension getScreenSize(Component invoker) {
ensureVirtualBounds();
// to handle multi-display case
Dimension screenSize = _virtualBounds.getSize(); // Toolkit.getDefaultToolkit().getScreenSize();
// jdk1.4 only
if (invoker != null && !(invoker instanceof JApplet) && invoker.getGraphicsConfiguration() != null) {
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(invoker.getGraphicsConfiguration());
screenSize.width -= insets.left + insets.right;
screenSize.height -= insets.top + insets.bottom;
}
return screenSize;
}
/**
* Gets the screen size. In JDK1.4+, the returned size will exclude task bar area on Windows OS.
*
* @param invoker the component which invokes this method.
* @return the screen size.
*/
public static Dimension getLocalScreenSize(Component invoker) {
ensureVirtualBounds();
// jdk1.4 only
if (invoker != null && !(invoker instanceof JApplet) && invoker.getGraphicsConfiguration() != null) {
// to handle multi-display case
GraphicsConfiguration gc = invoker.getGraphicsConfiguration();
Rectangle bounds = gc.getBounds();
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
bounds.width -= insets.left + insets.right;
bounds.height -= insets.top + insets.bottom;
return bounds.getSize();
}
else {
return getScreenSize(invoker);
}
}
/**
* Gets the screen bounds. In JDK1.4+, the returned bounds will exclude task bar area on Windows OS.
*
* @param invoker the component which invokes this method.
* @return the screen bounds.
*/
public static Rectangle getScreenBounds(Component invoker) {
ensureVirtualBounds();
// to handle multi-display case
Rectangle bounds = (Rectangle) _virtualBounds.clone();
// TODO
// jdk1.4 only
if (invoker != null && !(invoker instanceof JApplet) && invoker.getGraphicsConfiguration() != null) {
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(invoker.getGraphicsConfiguration());
bounds.x += insets.left;
bounds.y += insets.top;
bounds.width -= insets.left + insets.right;
bounds.height -= insets.top + insets.bottom;
}
return bounds;
}
/**
* Gets the local monitor's screen bounds.
*
* @return the screen bounds.
*/
public static Rectangle getLocalScreenBounds() {
GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
return e.getMaximumWindowBounds();
}
private static void ensureVirtualBounds() {
if (_virtualBounds == null) {
_virtualBounds = new Rectangle();
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
for (GraphicsDevice gd : gs) {
GraphicsConfiguration gc = gd.getDefaultConfiguration();
_virtualBounds = _virtualBounds.union(gc.getBounds());
}
}
}
/**
* Makes the point parameter is within the screen bounds. If not, it will be modified to make sure it is in.
*
* @param invoker we will use this the invoker component to find out the current screen.
* @param point the point
* @deprecated Please use {@link #ensureOnScreen(java.awt.Rectangle)} instead.
*/
@Deprecated
public static void withinScreen(Component invoker, Point point) {
if (invoker != null && !(invoker instanceof JApplet)) {
GraphicsConfiguration gc = invoker.getGraphicsConfiguration();
Rectangle bounds = gc.getBounds();
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(invoker.getGraphicsConfiguration());
if (point.x < bounds.x + insets.left) {
point.x = bounds.x + insets.left;
}
if (point.x > bounds.x + bounds.width - insets.right) {
point.x = bounds.x + bounds.width - insets.right;
}
if (point.y < bounds.y + insets.top) {
point.y = bounds.y + insets.top;
}
if (point.y > bounds.y + bounds.height - insets.bottom) {
point.y = bounds.y + bounds.height - insets.bottom;
}
}
}
private static Area SCREEN_AREA;
private static Rectangle[] SCREENS;
private static Insets[] INSETS;
/**
* This method will find out all screen divices and calculate the total bounds. Methods such as {@link
* #ensureOnScreen(java.awt.Rectangle)}, {@link #getContainingScreenBounds(java.awt.Rectangle,boolean)} or {@link
* #getScreenArea()} will use this calculated bounds.
*/
synchronized public static void initializeScreenArea() {
SCREEN_AREA = new Area();
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
List screensList = new ArrayList();
List insetsList = new ArrayList();
GraphicsDevice[] screenDevices = environment.getScreenDevices();
for (GraphicsDevice device : screenDevices) {
GraphicsConfiguration configuration = device.getDefaultConfiguration();
Rectangle screenBounds = configuration.getBounds();
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(configuration);
screensList.add(screenBounds);
insetsList.add(insets);
SCREEN_AREA.add(new Area(screenBounds));
}
SCREENS = screensList.toArray(new Rectangle[screensList.size()]);
INSETS = insetsList.toArray(new Insets[screensList.size()]);
}
/**
* @deprecated please use {@link #initializeScreenArea()} instead.
*/
@SuppressWarnings({"UnusedDeclaration", "JavaDoc"})
@Deprecated
synchronized public static void initializeScreenArea(int priority) {
initializeScreenArea();
}
@Deprecated
public static boolean INITIALIZE_SCREEN_AREA_USING_THREAD = true;
/**
* @deprecated no longer need to use it as {@link #initializeScreenArea()} is fast enough
*/
@SuppressWarnings({"JavaDoc"})
@Deprecated
public static boolean isInitializationThreadAlive() {
return false;
}
/**
* @deprecated no longer need to use it as {@link #initializeScreenArea()} is fast enough
*/
@SuppressWarnings({"JavaDoc"})
@Deprecated
public static boolean isInitalizationThreadStarted() {
return true;
}
/**
* Ensures the rectangle is visible on the screen.
*
* @param invoker the invoking component
* @param bounds the input bounds
* @return the modified bounds.
*/
public static Rectangle ensureVisible(Component invoker, Rectangle bounds) {
Rectangle mainScreenBounds = PortingUtils.getLocalScreenBounds(); // this is fast. Only if it is outside this bounds, we try the more expensive one.
if (!mainScreenBounds.contains(bounds.getLocation())) {
Rectangle screenBounds = PortingUtils.getScreenBounds(invoker);
if (bounds.x > screenBounds.x + screenBounds.width || bounds.x < screenBounds.x) {
bounds.x = mainScreenBounds.x;
}
if (bounds.y > screenBounds.y + screenBounds.height || bounds.y < screenBounds.y) {
bounds.y = mainScreenBounds.y;
}
}
return bounds;
}
/**
* Modifies the position of rect so that it is completly on screen if that is possible.
*
* @param rect The rectange to move onto a single screen
* @return rect after its position has been modified
*/
public static Rectangle ensureOnScreen(Rectangle rect) {
// optimize it so that it is faster for most cases
Rectangle localScreenBounds = getLocalScreenBounds();
if (localScreenBounds.contains(rect)) {
return rect;
}
initializeScreenArea();
// check if rect is totaly on screen
if (SCREEN_AREA.contains(rect)) return rect;
// see if the top left is on any of the screens
Rectangle containgScreen = null;
Point rectPos = rect.getLocation();
for (Rectangle screenBounds : SCREENS) {
if (screenBounds.contains(rectPos)) {
containgScreen = screenBounds;
break;
}
}
// if not see if rect partialy on any screen
for (Rectangle screenBounds : SCREENS) {
if (screenBounds.intersects(rect)) {
containgScreen = screenBounds;
break;
}
}
// check if it was on any screen
if (containgScreen == null) {
// it was not on any of the screens so center it on the first screen
rect.x = (SCREENS[0].width - rect.width) / 2;
rect.y = (SCREENS[0].width - rect.width) / 2;
return rect;
}
else {
// move rect so it is completly on a single screen
// check X
int rectRight = rect.x + rect.width;
int screenRight = containgScreen.x + containgScreen.width;
if (rectRight > screenRight) {
rect.x = screenRight - rect.width;
}
if (rect.x < containgScreen.x) rect.x = containgScreen.x;
// check Y
int rectBottom = rect.y + rect.height;
int screenBottom = containgScreen.y + containgScreen.height;
if (rectBottom > screenBottom) {
rect.y = screenBottom - rect.height;
}
if (rect.y < containgScreen.y) rect.y = containgScreen.y;
// return corrected rect
return rect;
}
}
/**
* Gets the screen bounds that contains the rect. The screen bounds consider the screen insets if any.
*
* @param rect the rect of the component.
* @param considerInsets if consider the insets. The insets is for thing like Windows Task Bar.
* @return the screen bounds that contains the rect.
*/
public static Rectangle getContainingScreenBounds(Rectangle rect, boolean considerInsets) {
initializeScreenArea();
// check if rect is totaly on screen
// if (SCREEN_AREA.contains(rect)) return SCREEN_AREA;
// see if the top left is on any of the screens
Rectangle containgScreen = null;
Insets insets = null;
Point rectPos = rect.getLocation();
for (int i = 0; i < SCREENS.length; i++) {
Rectangle screenBounds = SCREENS[i];
if (screenBounds.contains(rectPos)) {
containgScreen = screenBounds;
insets = INSETS[i];
break;
}
}
// if not see if rect partialy on any screen
for (int i = 0; i < SCREENS.length; i++) {
Rectangle screenBounds = SCREENS[i];
if (screenBounds.intersects(rect)) {
containgScreen = screenBounds;
insets = INSETS[i];
break;
}
}
// fall back to the first screen
if (containgScreen == null) {
containgScreen = SCREENS[0];
insets = INSETS[0];
}
Rectangle bounds = new Rectangle(containgScreen);
if (considerInsets) {
bounds.x += insets.left;
bounds.y += insets.top;
bounds.width -= insets.left + insets.right;
bounds.height -= insets.top + insets.bottom;
}
return bounds;
}
/**
* Get screen area of all monitors.
*
* @return Union of all screens
*/
public static Area getScreenArea() {
initializeScreenArea();
return SCREEN_AREA;
}
/**
* Notifies user something is wrong. We use Toolkit beep method by default.
*/
public static void notifyUser() {
Toolkit.getDefaultToolkit().beep();
}
/**
* Checks the prerequisite needed by JIDE demos. If the prerequisite doesn't meet, it will prompt a message box and
* exit.
*/
public static void prerequisiteChecking() {
if (!SystemInfo.isJdk14Above()) {
PortingUtils.notifyUser();
JOptionPane.showMessageDialog(null, "J2SE 1.4 or above is required for this demo.", "JIDE Software, Inc.", JOptionPane.WARNING_MESSAGE);
java.lang.System.exit(0);
}
if (!SystemInfo.isJdk142Above()) {
PortingUtils.notifyUser();
JOptionPane.showMessageDialog(null, "J2SE 1.4.2 or above is recommended for this demo for the best experience of seamless integration with Windows XP.", "JIDE Software, Inc.", JOptionPane.WARNING_MESSAGE);
}
if (SystemInfo.isMacOSX()) { // set special properties for Mac OS X
java.lang.System.setProperty("apple.laf.useScreenMenuBar", "true");
System.setProperty("apple.awt.brushMetalLook", "true");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy