/*
* Jajuk
* Copyright (C) The Jajuk Team
* http://jajuk.info
*
* 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.jajuk.util;
import com.jhlabs.image.PerspectiveFilter;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.ExecutionException;
import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.jajuk.ui.helpers.FontManager;
import org.jajuk.ui.helpers.FontManager.JajukFont;
import org.jajuk.ui.helpers.TwoStepsDisplayable;
import org.jajuk.ui.perspectives.IPerspective;
import org.jajuk.ui.perspectives.PerspectiveManager;
import org.jajuk.ui.views.IView;
import org.jajuk.ui.widgets.CommandJPanel;
import org.jajuk.ui.widgets.InformationJPanel;
import org.jajuk.ui.widgets.PerspectiveBarJPanel;
import org.jajuk.ui.windows.JajukFullScreenWindow;
import org.jajuk.ui.windows.JajukMainWindow;
import org.jajuk.ui.windows.JajukSlimbar;
import org.jajuk.ui.windows.JajukSystray;
import org.jajuk.util.log.Log;
import org.jdesktop.swingx.JXBusyLabel;
import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.decorator.Highlighter;
import org.jdesktop.swingx.decorator.HighlighterFactory;
import org.pushingpixels.substance.api.DecorationAreaType;
import org.pushingpixels.substance.api.SubstanceColorScheme;
import org.pushingpixels.substance.api.SubstanceLookAndFeel;
import org.pushingpixels.substance.api.SubstanceSkin;
import org.pushingpixels.substance.api.skin.SkinInfo;
import org.pushingpixels.substance.api.skin.SubstanceBusinessLookAndFeel;
/**
* Set of GUI convenient methods.
*/
public final class UtilGUI {
/* different types of Cursors that are available */
/** The Constant WAIT_CURSOR. */
public static final Cursor WAIT_CURSOR = new Cursor(Cursor.WAIT_CURSOR);
/** The Constant LINK_CURSOR. */
public static final Cursor LINK_CURSOR = new Cursor(Cursor.HAND_CURSOR);
/** The Constant DEFAULT_CURSOR. */
public static final Cursor DEFAULT_CURSOR = new Cursor(Cursor.DEFAULT_CURSOR);
// Current cursor that is displayed
private static Cursor currentCursor = DEFAULT_CURSOR;
/** Substance theme. */
private static String theme;
/** Alternate color rows highlighter used in every table. */
private static Highlighter alternateColorHighlighter;
/**
* Return whether the given highlighter is the alternateColorHighlighter.
*
* @param other
*
* @return whether the given highlighter is the alternateColorHighlighter
*/
public static boolean isAlternateColorHighlighter(Highlighter other) {
return other.equals(alternateColorHighlighter);
}
/**
* Reset the alternateColorHighlighter (during a theme change for eg).
*/
public static void resetAlternateColorHighlighter() {
alternateColorHighlighter = null;
}
/** Current active color scheme *. */
private static SubstanceColorScheme colorScheme;
/** Set cursor thread, stored to avoid construction. */
private static Runnable setCursorThread = new Runnable() {
@Override
public void run() {
Container container = null;
IPerspective perspective = PerspectiveManager.getCurrentPerspective();
if (perspective != null) {
// Log.debug("** Set cursor: " + currentCursor);
container = perspective.getContentPane();
container.setCursor(currentCursor);
CommandJPanel.getInstance().setCursor(currentCursor);
InformationJPanel.getInstance().setCursor(currentCursor);
PerspectiveBarJPanel.getInstance().setCursor(currentCursor);
}
}
};
/**
* Private constructor to prevent instantiation of utility class.
*/
private UtilGUI() {
}
/**
* Display a given image in a frame (for debuging purpose).
*
* @param ii
*/
public static void displayImage(final ImageIcon ii) {
final JFrame jf = new JFrame();
jf.add(new JLabel(ii));
jf.pack();
jf.setVisible(true);
}
/**
* Write down a memory image to a file.
*
* @param src
* @param dest
*/
public static void extractImage(final Image src, final File dest) {
final BufferedImage bi = UtilGUI.toBufferedImage(src);
// Need alpha only for png and gif files);
try {
ImageIO.write(bi, UtilSystem.getExtension(dest), dest);
} catch (final IOException e) {
Log.error(e);
}
}
/**
* Gets the graphics device of main frame.
*
* @return the current display of the main frame
*/
public static GraphicsDevice getGraphicsDeviceOfMainFrame() {
GraphicsEnvironment localGraphicsEnvironment = GraphicsEnvironment
.getLocalGraphicsEnvironment();
for (int i = 0; i < GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices().length; i++) {
GraphicsDevice graphicsDevice = localGraphicsEnvironment.getScreenDevices()[i];
if (graphicsDevice.getDefaultConfiguration().getBounds()
.contains(JajukMainWindow.getInstance().getLocation())) {
return graphicsDevice;
}
}
return localGraphicsEnvironment.getDefaultScreenDevice();
}
/**
* Gets the centred panel.
*
* @param jc
*
* @return an horizontaly centred panel
*/
public static JPanel getCentredPanel(final JComponent jc) {
return UtilGUI.getCentredPanel(jc, BoxLayout.X_AXIS);
}
/**
* Gets the centred panel.
*
* @param jc
* @param iOrientation : vertical or horizontal orientation, use BoxLayout.X_AXIS or
* BoxLayout.Y_AXIS
*
* @return a centred panel
*/
public static JPanel getCentredPanel(final JComponent jc, final int iOrientation) {
final JPanel jpOut = new JPanel();
jpOut.setLayout(new BoxLayout(jpOut, iOrientation));
if (iOrientation == BoxLayout.X_AXIS) {
jpOut.add(Box.createHorizontalGlue());
jpOut.add(jc);
jpOut.add(Box.createHorizontalGlue());
} else {
jpOut.add(Box.createVerticalGlue());
jpOut.add(jc);
jpOut.add(Box.createVerticalGlue());
}
return jpOut;
}
/**
* Gets the html color.
*
* @param color java color
*
* @return HTML RGB color ex: FF0000
*/
public static String getHTMLColor(final Color color) {
return Long.toString(color.getRed(), 16) + Long.toString(color.getGreen(), 16)
+ Long.toString(color.getBlue(), 16);
}
/**
* Get required image with specified url.
*
* @param url
*
* @return the image
*/
public static ImageIcon getImage(final URL url) {
ImageIcon ii = null;
final String sURL = url.toString();
try {
if (UtilSystem.iconCache.containsKey(sURL)) {
ii = UtilSystem.iconCache.get(sURL);
} else {
ii = new ImageIcon(url);
UtilSystem.iconCache.put(sURL, ii);
}
} catch (final Exception e) {
Log.error(e);
}
return ii;
}
/**
* Gets the limited message.
*
* @param sText text to display, lines separated by \n characters
* @param limit : max number of lines to be displayed without scroller
*
* @return formated message: either a string, or a textarea
*/
public static Object getLimitedMessage(final String sText, final int limit) {
final int iNbLines = new StringTokenizer(sText, "\n").countTokens();
Object message = null;
if (iNbLines > limit) {
final JTextArea area = new JTextArea(sText);
area.setRows(10);
area.setColumns(50);
area.setLineWrap(true);
message = new JScrollPane(area);
} else {
message = sText;
}
return message;
}
/**
* code from
* http://java.sun.com/developer/onlineTraining/new2java/supplements/
* 2005/July05.html#1 Used to correctly display long messages
*
* @param maxCharactersPerLineCount
*
* @return the narrow option pane
*/
public static JOptionPane getNarrowOptionPane(final int maxCharactersPerLineCount) {
// Our inner class definition
class NarrowOptionPane extends JOptionPane {
private static final long serialVersionUID = 1L;
int lmaxCharactersPerLineCount;
NarrowOptionPane(final int maxCharactersPerLineCount) {
super();
this.lmaxCharactersPerLineCount = maxCharactersPerLineCount;
}
@Override
public int getMaxCharactersPerLineCount() {
return lmaxCharactersPerLineCount;
}
}
return new NarrowOptionPane(maxCharactersPerLineCount);
}
/**
* Resize an image.
*
* @param img image to resize
* @param iNewWidth
* @param iNewHeight
*
* @return resized image
*/
public static ImageIcon getResizedImage(final ImageIcon img, final int iNewWidth,
final int iNewHeight) {
Image scaleImg = img.getImage().getScaledInstance(iNewWidth, iNewHeight,
Image.SCALE_AREA_AVERAGING);
// Leave source image cache here as we may want to keep original image
// but free the new image
scaleImg.flush();
return new ImageIcon(scaleImg);
}
/**
* Show busy label when searching lyrics over provided panel.
* @param panel panel to override.
*/
public static void showBusyLabel(final JXPanel panel) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
panel.removeAll();
Dimension dim = new Dimension(panel.getWidth() / 3, panel.getWidth() / 3);
final JXBusyLabel busy = new JXBusyLabel(dim);
busy.setBusy(true);
JPanel inner = new JPanel();
inner.setMinimumSize(new Dimension(panel.getWidth(), panel.getHeight()));
inner.setLayout(new BoxLayout(inner, BoxLayout.X_AXIS));
inner.add(Box.createHorizontalGlue());
inner.add(UtilGUI.getCentredPanel(busy, BoxLayout.Y_AXIS));
inner.add(Box.createHorizontalGlue());
panel.add(inner);
panel.revalidate();
panel.repaint();
}
});
}
/**
* Gets the scaled image.
*
* @param img
* @param iScale
*
* @return a scaled image
*/
public static ImageIcon getScaledImage(final ImageIcon img, final int iScale) {
int iNewWidth;
int iNewHeight;
// Height is smaller or equal than width : try to optimize width
iNewWidth = iScale; // take all possible width
// we check now if height will be visible entirely with optimized width
final float fWidthRatio = (float) iNewWidth / img.getIconWidth();
if (img.getIconHeight() * (fWidthRatio) <= iScale) {
iNewHeight = (int) (img.getIconHeight() * fWidthRatio);
} else {
// no? so we optimize width
iNewHeight = iScale;
iNewWidth = (int) (img.getIconWidth() * ((float) iNewHeight / img.getIconHeight()));
}
return UtilGUI.getResizedImage(img, iNewWidth, iNewHeight);
}
/**
* Setup Substance look and feel.
*
* @param pTheme
*/
public static void setupSubstanceLookAndFeel(final String pTheme) {
// Check the theme is known, if not take the default theme
final Map<String, SkinInfo> themes = SubstanceLookAndFeel.getAllSkins();
theme = pTheme;
if (themes.get(theme) == null) {
theme = Const.LNF_DEFAULT_THEME;
Conf.setProperty(Const.CONF_OPTIONS_LNF, Const.LNF_DEFAULT_THEME);
}
// Set substance LAF
try {
UIManager.setLookAndFeel(new SubstanceBusinessLookAndFeel());
} catch (UnsupportedLookAndFeelException e) {
Log.error(e);
}
// Set substance LAF
SubstanceLookAndFeel.setSkin(themes.get(theme).getClassName());
// hide some useless elements such locker for not editable labels
UIManager.put(SubstanceLookAndFeel.SHOW_EXTRA_WIDGETS, Boolean.FALSE);
// Store current color scheme (cannot change for the wall session)
colorScheme = SubstanceLookAndFeel.getCurrentSkin().getActiveColorScheme(DecorationAreaType.NONE);
// Set view foreground colors
SubstanceSkin theme = SubstanceLookAndFeel.getCurrentSkin();
SubstanceColorScheme scheme = theme.getActiveColorScheme(DecorationAreaType.NONE);
Color foregroundActive = null;
Color foregroundInactive = null;
Color backgroundActive = null;
Color backgroundInactive = null;
if (scheme.isDark()) {
foregroundActive = Color.BLACK;
foregroundInactive = Color.WHITE;
backgroundActive = scheme.getUltraLightColor();
backgroundInactive = scheme.getUltraDarkColor();
} else {
foregroundActive = Color.WHITE;
foregroundInactive = Color.BLACK;
backgroundActive = scheme.getDarkColor();
backgroundInactive = scheme.getLightColor();
}
UIManager.put("InternalFrame.activeTitleForeground", foregroundActive);
UIManager.put("InternalFrame.inactiveTitleForeground", foregroundInactive);
UIManager.put("InternalFrame.activeTitleBackground", backgroundActive);
UIManager.put("InternalFrame.inactiveTitleBackground", backgroundInactive);
UIManager.put("DockViewTitleBar.titleFont",
FontManager.getInstance().getFont(JajukFont.VIEW_FONT));
}
/**
* Display given container at given position.
*
* @param window
* @param iFromTop max number of pixels from top
* @param iFromLeft max number of pixels from left
*/
public static void setShuffleLocation(final Window window, final int iFromTop, final int iFromLeft) {
window.setLocation((int) (Math.random() * iFromTop), (int) (Math.random() * iFromLeft)); //NOSONAR
}
/**
* Set current cursor as waiting cursor.
*/
public static synchronized void waiting() {
if (!currentCursor.equals(WAIT_CURSOR)) {
currentCursor = WAIT_CURSOR;
SwingUtilities.invokeLater(setCursorThread);
}
}
/**
* Set current cursor as default cursor.
*/
public static synchronized void stopWaiting() {
if (!currentCursor.equals(DEFAULT_CURSOR)) {
currentCursor = DEFAULT_CURSOR;
SwingUtilities.invokeLater(setCursorThread);
}
}
/**
* To buffered image.
*
* @param image the input image
*
* @return the buffered image
*/
public static BufferedImage toBufferedImage(final Image image) {
return UtilGUI.toBufferedImage(image, image.getWidth(null), image.getHeight(null));
}
/**
* Create a buffered image without forced alpha channel.
*
* @param image the input image
* @param targetWidth
* @param targetHeight
*
* @return the buffered image
*/
public static BufferedImage toBufferedImage(final Image image, final int targetWidth,
final int targetHeight) {
return UtilGUI.toBufferedImage(image, targetWidth, targetHeight, false);
}
/**
* Transform an image to a BufferedImage
* <p>
* Code adapted from from http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
* </p>
*
* @param image the input image
* @param targetWidth
* @param targetHeight
* @param forcedAlpha Force using an alpha channel for target image
*
* @return buffered image from an image
*/
public static BufferedImage toBufferedImage(final Image image, final int targetWidth,
final int targetHeight, boolean forcedAlpha) {
if (image instanceof BufferedImage) {
return ((BufferedImage) image);
} else {
// This code ensures that all the pixels in the image are loaded
Image loadedImage = new ImageIcon(image).getImage();
// Use right target format according to need for alpha chanel or not (less memory use if no
// alpha)
int type = BufferedImage.TYPE_INT_RGB;
if (forcedAlpha || hasAlpha(image)) {
type = BufferedImage.TYPE_INT_ARGB;
}
BufferedImage ret = null;
int w, h;
// Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage()
// until the target size is reached
w = image.getWidth(null);
h = image.getHeight(null);
// See http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html for
// explanations about this algorithm.
// Basically, we perform image creation dichotomy to create high quality thumb at low price
do {
// When w/y reaches thumb height/width, it's time to to use the target thumb size exactly
if (w <= targetHeight || h <= targetHeight) {
w = targetWidth;
h = targetHeight;
} else {
if (w > targetWidth) {
w /= 2;
if (w < targetWidth) {
w = targetWidth;
}
}
if (h > targetHeight) {
h /= 2;
if (h < targetHeight) {
h = targetHeight;
}
}
}
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
// If the input buffered image doesn't yet exist, use the input image
if (ret != null) {
g2.drawImage(ret, 0, 0, w, h, null);
} else {
g2.drawImage(loadedImage, 0, 0, w, h, null);
}
g2.dispose();
ret = tmp;
} while (w != targetWidth || h != targetHeight);
image.flush();
loadedImage.flush();
return ret;
}
}
/**
* Get3d image.
*
* @param img
*
* @return the 3d image
*/
public static BufferedImage get3dImage(Image img) {
int angle = 30;
int gap = 10;
float opacity = 0.3f;
float fadeHeight = 0.6f;
// cover
BufferedImage coverImage = UtilGUI.toBufferedImage(img, Const.MIRROW_COVER_SIZE,
Const.MIRROW_COVER_SIZE, true);
PerspectiveFilter filter1 = new PerspectiveFilter(0, angle,
Const.MIRROW_COVER_SIZE - angle / 2, (int) (angle * (5.0 / 3.0)), Const.MIRROW_COVER_SIZE
- angle / 2, Const.MIRROW_COVER_SIZE, 0, Const.MIRROW_COVER_SIZE + angle);
coverImage = filter1.filter(coverImage, null);
// reflection
int imageWidth = coverImage.getWidth();
int imageHeight = coverImage.getHeight();
BufferedImage reflection = new BufferedImage(imageWidth, imageHeight,
BufferedImage.TYPE_INT_ARGB);
Graphics2D rg = reflection.createGraphics();
rg.drawRenderedImage(coverImage, null);
rg.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN));
rg.setPaint(new GradientPaint(0, imageHeight * fadeHeight, new Color(0.0f, 0.0f, 0.0f, 0.0f),
0, imageHeight, new Color(0.0f, 0.0f, 0.0f, opacity)));
rg.fillRect(0, 0, imageWidth, imageHeight);
rg.dispose();
PerspectiveFilter filter2 = new PerspectiveFilter(0, 0, coverImage.getHeight() - angle / 2,
angle * 2, coverImage.getHeight() - angle / 2, coverImage.getHeight() + angle * 2, 0,
coverImage.getHeight());
BufferedImage reflectedImage = filter2.filter(reflection, null);
// now draw everything on one bufferedImage
BufferedImage finalImage = new BufferedImage(imageWidth, (int) (1.4 * imageHeight),
BufferedImage.TYPE_INT_ARGB);
Graphics g = finalImage.getGraphics();
Graphics2D g2d = (Graphics2D) g;
g2d.drawRenderedImage(coverImage, null);
g2d.translate(0, 2 * imageHeight + gap);
g2d.scale(1, -1);
g2d.drawRenderedImage(reflectedImage, null);
g2d.dispose();
reflection.flush();
coverImage.flush();
return finalImage;
}
/**
* This method returns true if the specified image has transparent pixels
* Found at http://www.exampledepot.com/egs/java.awt.image/HasAlpha.html
*
* @param image
*
* @return true if the specified image has transparent pixels
*/
public static boolean hasAlpha(Image image) {
try {
// If buffered image, the color model is readily available
if (image instanceof BufferedImage) {
BufferedImage bimage = (BufferedImage) image;
return bimage.getColorModel().hasAlpha();
}
// Use a pixel grabber to retrieve the image's color model;
// grabbing a single pixel is usually sufficient
PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
pg.grabPixels();
// Get the image's color model
ColorModel cm = pg.getColorModel();
if (cm != null) {
return cm.hasAlpha();
}
} catch (Exception e) {
Log.error(e);
}
return false;
}
/**
* Method to attempt a dynamic update for any GUI accessible by this JVM. It
* will filter through all frames and sub-components of the frames.
*/
public static void updateAllUIs() {
Frame frames[];
frames = Frame.getFrames();
for (final Frame element : frames) {
UtilGUI.updateWindowUI(element);
}
// update tray
if (JajukSystray.isLoaded() && (JajukSystray.getInstance().getMenu() != null)) {
UtilGUI.updateComponentTreeUI(JajukSystray.getInstance().getMenu());
}
}
/**
* A simple minded look and feel change: ask each node in the tree to
* <code>updateUI()</code> -- that is, to initialize its UI property with the
* current look and feel. Based on the Sun
* SwingUtilities.updateComponentTreeUI, but ensures that the update happens
* on the components of a JToolbar before the JToolbar itself.
*
* @param c
*/
public static void updateComponentTreeUI(final Component c) {
UtilGUI.updateComponentTreeUI0(c);
c.invalidate();
c.validate();
c.repaint();
}
/**
* Update component tree u i0.
*
* @param c
*/
private static void updateComponentTreeUI0(final Component c) {
Component[] children = null;
if (c instanceof JToolBar) {
children = ((JToolBar) c).getComponents();
if (children != null) {
for (final Component element : children) {
UtilGUI.updateComponentTreeUI0(element);
}
}
((JComponent) c).updateUI();
} else {
if (c instanceof JComponent) {
((JComponent) c).updateUI();
}
if (c instanceof JMenu) {
children = ((JMenu) c).getMenuComponents();
} else if (c instanceof Container) {
children = ((Container) c).getComponents();
}
if (children != null) {
for (final Component element : children) {
UtilGUI.updateComponentTreeUI0(element);
}
}
}
}
/**
* Method to attempt a dynamic update for all components of the given
* <code>Window</code>.
*
* @param window The <code>Window</code> for which the look and feel update has to
* be performed against.
*/
public static void updateWindowUI(final Window window) {
try {
UtilGUI.updateComponentTreeUI(window);
} catch (final Exception exception) {
Log.error(exception);
}
final Window windows[] = window.getOwnedWindows();
for (final Window element : windows) {
UtilGUI.updateWindowUI(element);
}
}
/**
* Gets the alternate highlighter.
*
* @return a theme-dependent alternate row highlighter used in tables or trees
*/
public static Highlighter getAlternateHighlighter() {
if (alternateColorHighlighter != null) {
return alternateColorHighlighter;
}
SubstanceSkin theme = SubstanceLookAndFeel.getCurrentSkin();
SubstanceColorScheme scheme = theme.getActiveColorScheme(DecorationAreaType.NONE);
Color color1 = scheme.getWatermarkStampColor();
Color color2 = scheme.getWatermarkDarkColor();
Highlighter highlighter = HighlighterFactory.createAlternateStriping(color1, color2);
alternateColorHighlighter = highlighter;
return highlighter;
}
/**
* Checks if is over.
*
* @param location
* @param dimension
*
* @return whether the current mouse cursor if above a given component
*/
public static boolean isOver(Point location, Dimension dimension) {
java.awt.Point p = MouseInfo.getPointerInfo().getLocation();
if (p.getX() <= location.getX() || p.getY() <= location.getY()) {
return false;
}
return (p.getX() < (dimension.getWidth() + location.getX()) && p.getY() < (dimension
.getHeight() + location.getY()));
}
/**
* Gets the ultra light color.
*
* @return ultralight color for current color scheme
*/
static public Color getUltraLightColor() {
return colorScheme.getUltraLightColor();
}
/**
* Gets the foreground color.
*
* @return foreground color for current color scheme
*/
static public Color getForegroundColor() {
return colorScheme.getForegroundColor();
}
/**
* Display a dialog with given url picture.
*
* @param url
*
* @throws MalformedURLException the malformed url exception
*/
static public void showPictureDialog(String url) throws MalformedURLException {
JDialog jd = new JDialog(JajukMainWindow.getInstance());
ImageIcon ii = new ImageIcon(new URL(url));
JPanel jp = new JPanel();
jp.setLayout(new BoxLayout(jp, BoxLayout.X_AXIS));
JLabel jl = new JLabel(ii);
jp.add(jl);
jd.setContentPane(jp);
jd.pack();
jd.setLocationRelativeTo(JajukMainWindow.getInstance());
jd.setVisible(true);
}
/**
* Registers the ESCAPE key on the Panel so that it closes the Dialog.
*
* @param window
* @param pane
*/
public static void setEscapeKeyboardAction(final Window window, JComponent pane) {
final KeyEventDispatcher dispatcher = new KeyEventDispatcher() {
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
// For some reasons (under Linux at least), pressing escape only trigger PRESSED
// and RELEASED key events
if (e.getKeyCode() == KeyEvent.VK_ESCAPE && e.getID() == KeyEvent.KEY_PRESSED
&& window.isFocused()) {
window.dispose();
return true;
}
return false;
}
};
// Add keystroke to close window when pressing escape
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(dispatcher);
// make sure the key event dispatcher is removed as soon as the Window is closing
window.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(dispatcher);
}
@Override
public void windowClosed(WindowEvent e) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(dispatcher);
}
});
}
/**
* Build GUI for a TwoStateDisplayable component.
* <p>
* <exception catching is preferred in the longCall() method without throwing
* it to the fastCall() one.
* </p>
*
* @param displayable
*/
public static void populate(final TwoStepsDisplayable displayable) {
SwingWorker<Object, Void> sw = new SwingWorker<Object, Void>() {
@Override
protected Object doInBackground() {
return displayable.longCall();
}
@Override
protected void done() {
try {
Object in = get();
displayable.shortCall(in);
} catch (InterruptedException e) {
Log.error(e);
} catch (ExecutionException e) {
Log.error(e);
}
}
};
sw.execute();
}
/**
* Center a given window to the center of the screen.
*
* @param window
*/
public static void centerWindow(Window window) {
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension screenSize = tk.getScreenSize();
int screenHeight = screenSize.height;
int screenWidth = screenSize.width;
window.setLocation((screenWidth / 2) - (window.getWidth() / 2),
(screenHeight / 2) - (window.getHeight() / 2));
}
/**
* Return any displayed window (between main window, slimbar...)
*
* @return any displayed window (between main window, slimbar...)
*/
public static Window getActiveWindow() {
if (JajukMainWindow.getInstance().getWindowStateDecorator().isDisplayed()) {
return JajukMainWindow.getInstance();
} else if (JajukSlimbar.getInstance().getWindowStateDecorator().isDisplayed()) {
return JajukSlimbar.getInstance();
} else if (JajukFullScreenWindow.getInstance().getWindowStateDecorator().isDisplayed()) {
return JajukFullScreenWindow.getInstance();
} else {
// Can happen in sys tray mode only
return null;
}
}
/**
* Gets the given component's parent view.
*
* @param component the component
*
* @return the parent view or null if none IView is among its ancestors
*/
public static IView getParentView(Component component) {
try {
Component parent = component.getParent();
while (parent != null && !(parent instanceof IView)) {
parent = parent.getParent();
}
return (IView) parent;
} catch (RuntimeException e) {
// Make sure to trap strange events
return null;
}
}
}