org.fife.ui.rsyntaxtextarea.focusabletip.SizeGrip Maven / Gradle / Ivy
The newest version!
/*
* 12/23/2008
*
* SizeGrip.java - A size grip component that sits at the bottom of the window,
* allowing the user to easily resize that window.
*
* This library is distributed under a modified BSD license. See the included
* RSyntaxTextArea.License.txt file for details.
*/
package org.fife.ui.rsyntaxtextarea.focusabletip;
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Window;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.MouseInputAdapter;
/**
* A component that allows its parent window to be resizable, similar to the
* size grip seen on status bars.
*
* @author Robert Futrell
* @version 1.0
*/
class SizeGrip extends JPanel {
/**
* The size grip to use if we're on OS X.
*/
private Image osxSizeGrip;
public SizeGrip() {
MouseHandler adapter = new MouseHandler();
addMouseListener(adapter);
addMouseMotionListener(adapter);
setPreferredSize(new Dimension(16, 16));
}
/**
* Overridden to ensure that the cursor for this component is appropriate
* for the orientation.
*
* @param o The new orientation.
*/
@Override
public void applyComponentOrientation(ComponentOrientation o) {
possiblyFixCursor(o.isLeftToRight());
super.applyComponentOrientation(o);
}
/**
* Creates and returns the OS X size grip image.
*
* @return The OS X size grip.
*/
private Image createOSXSizeGrip() {
ClassLoader cl = getClass().getClassLoader();
URL url = cl.getResource("org/fife/ui/rsyntaxtextarea/focusabletip/osx_sizegrip.png");
if (url==null) {
// We're not running in a jar - we may be debugging in Eclipse,
// for example
File f = new File("../RSyntaxTextArea/src/org/fife/ui/rsyntaxtextarea/focusabletip/osx_sizegrip.png");
if (f.isFile()) {
try {
url = f.toURI().toURL();
} catch (MalformedURLException mue) { // Never happens
mue.printStackTrace();
return null;
}
}
else {
return null; // Can't find resource or image file
}
}
Image image = null;
try {
image = ImageIO.read(url);
} catch (IOException ioe) { // Never happens
ioe.printStackTrace();
}
return image;
}
/**
* Paints this panel.
*
* @param g The graphics context.
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension dim = getSize();
if (osxSizeGrip!=null) {
g.drawImage(osxSizeGrip, dim.width-16, dim.height-16, null);
return;
}
Color c1 = UIManager.getColor("Label.disabledShadow");
Color c2 = UIManager.getColor("Label.disabledForeground");
ComponentOrientation orientation = getComponentOrientation();
if (orientation.isLeftToRight()) {
int width = dim.width -= 3;
int height = dim.height -= 3;
g.setColor(c1);
g.fillRect(width-9,height-1, 3,3);
g.fillRect(width-5,height-1, 3,3);
g.fillRect(width-1,height-1, 3,3);
g.fillRect(width-5,height-5, 3,3);
g.fillRect(width-1,height-5, 3,3);
g.fillRect(width-1,height-9, 3,3);
g.setColor(c2);
g.fillRect(width-9,height-1, 2,2);
g.fillRect(width-5,height-1, 2,2);
g.fillRect(width-1,height-1, 2,2);
g.fillRect(width-5,height-5, 2,2);
g.fillRect(width-1,height-5, 2,2);
g.fillRect(width-1,height-9, 2,2);
}
else {
int height = dim.height -= 3;
g.setColor(c1);
g.fillRect(10,height-1, 3,3);
g.fillRect(6,height-1, 3,3);
g.fillRect(2,height-1, 3,3);
g.fillRect(6,height-5, 3,3);
g.fillRect(2,height-5, 3,3);
g.fillRect(2,height-9, 3,3);
g.setColor(c2);
g.fillRect(10,height-1, 2,2);
g.fillRect(6,height-1, 2,2);
g.fillRect(2,height-1, 2,2);
g.fillRect(6,height-5, 2,2);
g.fillRect(2,height-5, 2,2);
g.fillRect(2,height-9, 2,2);
}
}
/**
* Ensures that the cursor for this component is appropriate for the
* orientation.
*
* @param ltr Whether the current component orientation is LTR.
*/
protected void possiblyFixCursor(boolean ltr) {
int cursor = Cursor.NE_RESIZE_CURSOR;
if (ltr) {
cursor = Cursor.NW_RESIZE_CURSOR;
}
if (cursor!=getCursor().getType()) {
setCursor(Cursor.getPredefinedCursor(cursor));
}
}
@Override
public void updateUI() {
super.updateUI();
// TODO: Key off of Aqua LaF, not just OS X, as this size grip looks
// bad on other LaFs on Mac such as Nimbus.
if (System.getProperty("os.name").contains("OS X")) {
if (osxSizeGrip==null) {
osxSizeGrip = createOSXSizeGrip();
}
}
else { // Clear memory in case of runtime LaF change.
osxSizeGrip = null;
}
}
/**
* Listens for mouse events on this panel and resizes the parent window
* appropriately.
*/
/*
* NOTE: We use SwingUtilities.convertPointToScreen() instead of just using
* the locations relative to the corner component because the latter proved
* buggy - stretch the window too wide and some kind of arithmetic error
* started happening somewhere - our window would grow way too large.
*/
private class MouseHandler extends MouseInputAdapter {
private Point origPos;
@Override
public void mouseDragged(MouseEvent e) {
Point newPos = e.getPoint();
SwingUtilities.convertPointToScreen(newPos, SizeGrip.this);
int xDelta = newPos.x - origPos.x;
int yDelta = newPos.y - origPos.y;
Window wind = SwingUtilities.getWindowAncestor(SizeGrip.this);
if (wind!=null) { // Should always be true
if (getComponentOrientation().isLeftToRight()) {
int w = wind.getWidth();
if (newPos.x>=wind.getX()) {
w += xDelta;
}
int h = wind.getHeight();
if (newPos.y>=wind.getY()) {
h += yDelta;
}
wind.setSize(w,h);
}
else { // RTL
int newW = Math.max(1, wind.getWidth()-xDelta);
int newH = Math.max(1, wind.getHeight()+yDelta);
wind.setBounds(newPos.x, wind.getY(), newW, newH);
}
// invalidate()/validate() needed pre-1.6.
wind.invalidate();
wind.validate();
}
origPos.setLocation(newPos);
}
@Override
public void mousePressed(MouseEvent e) {
origPos = e.getPoint();
SwingUtilities.convertPointToScreen(origPos, SizeGrip.this);
}
@Override
public void mouseReleased(MouseEvent e) {
origPos = null;
}
}
}