com.jidesoft.swing.DefaultOverlayable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jide-oss Show documentation
Show all versions of jide-oss Show documentation
JIDE Common Layer (Professional Swing Components)
/*
* @(#)DefaultOverlayable.java 7/31/2007
*
* Copyright 2002 - 2007 JIDE Software Inc. All rights reserved.
*/
package com.jidesoft.swing;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Vector;
/**
* DefaultOverlayable
is the default implementation of Overlayable
using JPanel as the base
* component.
*/
public class DefaultOverlayable extends JPanel implements Overlayable, ComponentListener {
private JComponent _actualComponent;
private Insets _overlayLocationInsets = new Insets(0, 0, 0, 0);
private List _overlayComponents;
private Map _overlayLocations;
public DefaultOverlayable() {
initComponents();
}
public DefaultOverlayable(JComponent component) {
initComponents();
setActualComponent(component);
}
public DefaultOverlayable(JComponent actualComponent, JComponent overlayComponent, int overlayLocation) {
initComponents();
setActualComponent(actualComponent);
addOverlayComponent(overlayComponent, overlayLocation);
}
public DefaultOverlayable(JComponent actualComponent, JComponent overlayComponent) {
initComponents();
setActualComponent(actualComponent);
addOverlayComponent(overlayComponent, SwingConstants.CENTER);
}
private void initComponents() {
setLayout(null);
_overlayComponents = new Vector();
_overlayLocations = new Hashtable();
}
/**
* Override to consider the overlayLocationInsets. If the overlayLocationInsets's edges are positive number, we will
* increase the preferred size so that the overlayo component can be shown. If they are negative, we will still keep
* the super.getPreferredSize.
*
* @return the preferred size of the DefaultOverlayable.
*/
@Override
public Dimension getPreferredSize() {
Dimension size = getActualComponent() == null ? new Dimension(0, 0) : getActualComponent().getPreferredSize();
Insets insets = getOverlayLocationInsets();
if (insets != null) {
size.width += Math.max(0, insets.left) + Math.max(0, insets.right);
size.height += Math.max(0, insets.top) + Math.max(0, insets.bottom);
}
return size;
}
@Override
public void setPreferredSize(Dimension preferredSize) {
super.setPreferredSize(preferredSize);
if (getActualComponent() != null) {
if (preferredSize != null) {
Insets insets = getOverlayLocationInsets();
if (insets != null) {
preferredSize.width -= Math.max(0, insets.left) + Math.max(0, insets.right);
preferredSize.width = Math.max(0, preferredSize.width);
preferredSize.height -= Math.max(0, insets.top) + Math.max(0, insets.bottom);
preferredSize.height = Math.max(0, preferredSize.height);
}
}
getActualComponent().setPreferredSize(preferredSize);
}
}
@Override
public Dimension getMinimumSize() {
Dimension size = getActualComponent() == null ? new Dimension(0, 0) : getActualComponent().getMinimumSize();
Insets insets = getOverlayLocationInsets();
if (insets != null) {
size.width += Math.max(0, insets.left) + Math.max(0, insets.right);
size.height += Math.max(0, insets.top) + Math.max(0, insets.bottom);
}
return size;
}
@Override
public void setMinimumSize(Dimension minimumSize) {
super.setMinimumSize(minimumSize);
if (getActualComponent() != null) {
if (minimumSize != null) {
Insets insets = getOverlayLocationInsets();
if (insets != null) {
minimumSize.width -= Math.max(0, insets.left) + Math.max(0, insets.right);
minimumSize.width = Math.max(0, minimumSize.width);
minimumSize.height -= Math.max(0, insets.top) + Math.max(0, insets.bottom);
minimumSize.height = Math.max(0, minimumSize.height);
}
}
getActualComponent().setMinimumSize(minimumSize);
}
}
@Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
Insets insets = getOverlayLocationInsets();
if (insets != null) {
x = Math.max(0, insets.left);
y = Math.max(0, insets.top);
width -= Math.max(0, insets.left) + Math.max(0, insets.right);
height -= Math.max(0, insets.top) + Math.max(0, insets.bottom);
}
if (getActualComponent() != null) {
getActualComponent().setBounds(x, y, width, height);
}
updateLocation();
}
private void updateLocation() {
JComponent[] components = getOverlayComponents();
for (JComponent c : components) {
if (c == null) {
return;
}
Rectangle r = getOverlayComponentBounds(c);
c.setBounds(r);
}
}
/**
* Gets the bounds of an overlay component.
* @param component an overlay component
* @return the bounds of the overlay component.
*/
protected Rectangle getOverlayComponentBounds(JComponent component) {
Component relativeComponent = getActualComponent();
Rectangle bounds = relativeComponent.getBounds();
if (relativeComponent != getActualComponent()) {
bounds = SwingUtilities.convertRectangle(relativeComponent.getParent(), bounds, getActualComponent());
}
Rectangle overlayBounds = new Rectangle(bounds);
Insets insets = getOverlayLocationInsets();
overlayBounds.x -= insets.left;
overlayBounds.y -= insets.top;
overlayBounds.width += insets.left + insets.right;
overlayBounds.height += insets.top + insets.bottom;
int cx = 0;
int cy = 0;
Dimension size = component.getPreferredSize();
int cw = size.width;
int ch = size.height;
int overlayLocation = getOverlayLocation(component);
// adjust the location based on the orientation
if (overlayLocation == LEADING) {
if (component.getComponentOrientation() == ComponentOrientation.LEFT_TO_RIGHT) {
overlayLocation = WEST;
}
else if (component.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT) {
overlayLocation = EAST;
}
}
else if (overlayLocation == TRAILING) {
if (component.getComponentOrientation() == ComponentOrientation.LEFT_TO_RIGHT) {
overlayLocation = EAST;
}
else if (component.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT) {
overlayLocation = WEST;
}
}
switch (overlayLocation) {
case CENTER:
cx = bounds.x + (bounds.width - cw) / 2;
cy = bounds.y + (bounds.height - ch) / 2;
break;
case NORTH:
cx = bounds.x + (bounds.width - cw) / 2;
cy = overlayBounds.y;
break;
case SOUTH:
cx = bounds.x + (bounds.width - cw) / 2;
cy = overlayBounds.y + overlayBounds.height - ch;
break;
case WEST:
cx = overlayBounds.x;
cy = bounds.y + (bounds.height - ch) / 2;
break;
case EAST:
cx = overlayBounds.x + overlayBounds.width - cw;
cy = bounds.y + (bounds.height - ch) / 2;
break;
case NORTH_WEST:
cx = overlayBounds.x;
cy = overlayBounds.y;
break;
case NORTH_EAST:
cx = overlayBounds.x + overlayBounds.width - cw;
cy = overlayBounds.y;
break;
case SOUTH_WEST:
cx = overlayBounds.x;
cy = overlayBounds.y + overlayBounds.height - ch;
break;
case SOUTH_EAST:
cx = overlayBounds.x + overlayBounds.width - cw;
cy = overlayBounds.y + overlayBounds.height - ch;
break;
}
return new Rectangle(cx, cy, cw, ch);
}
public int getOverlayLocation(JComponent component) {
Integer location = _overlayLocations.get(component);
if (location != null) {
return location;
}
else {
return -1;
}
}
public void setOverlayLocation(JComponent component, int location) {
setOverlayLocation(component, null, location);
}
@SuppressWarnings({"UnusedDeclaration"})
private void setOverlayLocation(JComponent component, Component relativeComponent, int location) {
boolean updated = false;
int old = getOverlayLocation(component);
if (old != location) {
_overlayLocations.put(component, location);
updated = true;
}
if (updated) {
updateLocation();
}
}
public void addOverlayComponent(JComponent component) {
addOverlayComponent(component, SwingConstants.CENTER, -1);
}
public void addOverlayComponent(JComponent component, int location) {
addOverlayComponent(component, location, -1);
}
public void addOverlayComponent(JComponent component, int location, int index) {
addOverlayComponent(component, null, location, index);
}
private void addOverlayComponent(JComponent component, Component relativeComponent, int location, int index) {
if (_overlayComponents.contains(component)) {
_overlayComponents.remove(component);
}
if (index == -1) {
_overlayComponents.add(component);
add(component, getComponentCount() - 1); // add it before the the actual component
}
else {
_overlayComponents.add(index, component);
add(component, index);
}
setOverlayLocation(component, relativeComponent, location);
}
public void removeOverlayComponent(JComponent component) {
if (_overlayComponents.contains(component)) {
_overlayComponents.remove(component);
_overlayLocations.remove(component);
remove(component);
}
}
public JComponent[] getOverlayComponents() {
return _overlayComponents.toArray(new JComponent[_overlayComponents.size()]);
}
public JComponent getActualComponent() {
return _actualComponent;
}
public void setActualComponent(JComponent actualComponent) {
if (_actualComponent != null) {
remove(_actualComponent);
_actualComponent.putClientProperty(CLIENT_PROPERTY_OVERLAYABLE, null);
}
_actualComponent = actualComponent;
_actualComponent.putClientProperty(CLIENT_PROPERTY_OVERLAYABLE, this);
add(_actualComponent);
Container container = getParent();
if (container != null) {
invalidate();
container.validate();
}
}
public Insets getOverlayLocationInsets() {
return _overlayLocationInsets;
}
public void setOverlayLocationInsets(Insets overlayLocationInsets) {
_overlayLocationInsets = overlayLocationInsets;
Container container = getParent();
if (container != null) {
invalidate();
container.validate();
}
}
public void setOverlayVisible(boolean visible) {
JComponent[] components = getOverlayComponents();
for (JComponent component : components) {
component.setVisible(visible);
}
}
public void componentResized(ComponentEvent e) {
updateLocation();
}
public void componentMoved(ComponentEvent e) {
updateLocation();
}
public void componentShown(ComponentEvent e) {
updateLocation();
}
public void componentHidden(ComponentEvent e) {
updateLocation();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy