org.wings.SDimension Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2000,2005 wingS development team.
*
* This file is part of wingS (http://wingsframework.org).
*
* wingS is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* Please see COPYING for the complete licence.
*/
package org.wings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.text.ParsePosition;
/**
* Holds preferred component sizes (dimensions).
*
* Web browsers support different notations for sizes. Absolute pixel values,
* realtive percentages (of the available viewport) and
* special CSS values as 'inherit' and 'auto' (Default).
* This class if capable of handling all these cases.
*/
public class SDimension implements Serializable {
private static final long serialVersionUID = 1L;
/**
* String constant for CSS dimension 'auto'.
* This is the default width used by wings as well as by CSS capable browsers.
*/
public final static String AUTO = "auto";
/**
* String for CSS dimension 'inherit'.
* With this value the preferred size is inherited by the surrounding element.
*/
public final static String INHERIT = "inherit";
/**
* Integer constant for CSS dimension 'auto'.
* This is the default width used by wings as well as by CSS capable browsers.
*/
public final static int AUTO_INT = -1;
/**
* Integer constant for CSS dimension 'inherit'.
* With this value the preferred size is inherited by the surrounding element.
*/
public final static int INHERIT_INT = -2;
/**
* Immutable SDimension constants for a component taking up the full available width.
*/
public static final SDimension FULLWIDTH = new UnmodifiableDimension("100%", null);
/**
* Immutable SDimension constants for a component taking up the full available height.
*/
public static final SDimension FULLHEIGHT = new UnmodifiableDimension(null, "100%");
/**
* Immutable SDimension constants for a component taking up the full available area.
*/
public static final SDimension FULLAREA = new UnmodifiableDimension("100%", "100%");
/**
* Immutable SDimension constants for a component taking up normal space
*/
public static final SDimension AUTOAREA = new UnmodifiableDimension(AUTO, AUTO);
private final transient static Logger log = LoggerFactory.getLogger(SDimension.class);
private int widthInt = AUTO_INT;
private int heightInt = AUTO_INT;
private String widthUnit;
private String heightUnit;
public SDimension() {
}
public SDimension(SDimension dim) {
this(dim.getWidth(), dim.getHeight());
}
public SDimension(String width, String height) {
setWidth(width);
setHeight(height);
}
/**
* Construct a new dimension with absolute values.
* The value is interpreted as absolute pixel values.
*
* @param width the preferred width in pixel. Use -1 for AUTO.
* @param height the preferred height in pixel. Use -1 for AUTO.
* @see #setSize(int,int)
*/
public SDimension(int width, int height) {
setSize(width, height);
}
/**
* Construct a new dimension with absolute values.
* The value is interpreted as absolute pixel values.
*
* @param width the preferred width in pixel. You may pass null
.
* @param height the preferred height in pixel. You may pass null
.
* @see #setSize(int,int)
*/
public SDimension(Integer width, Integer height) {
setSize(width != null ? width : AUTO_INT, height != null ? height : AUTO_INT);
}
/**
* Sets the preferred width via an string. Expects an dimension/unit compount i.e.
* "120px" or "80%" but will assume px by default.
* @param width A preferred witdth.
*/
public void setWidth(String width) {
this.widthInt = extractNumericValue(width);
this.widthUnit = extractUnit(width);
}
/**
* Sets the preferred height via an string. Expects an dimension/unit compount i.e.
* "120px" or "80%" but will assume px by default.
* @param height A preferred height.
*/
public void setHeight(String height) {
this.heightInt = extractNumericValue(height);
this.heightUnit = extractUnit(height);
}
/**
* Set width in pixel.
* This appends "px" to the integer value.
*
* @param width if -1 set {@link SDimension#widthInt} to null
*/
public void setWidth(int width) {
widthInt = width;
widthUnit = width < 0 ? null : "px";
}
/**
* Set height in pixel.
* This appends "px" to the integer value.
*
* @param height if -1 set {@link SDimension#heightInt} to null
*/
public void setHeight(int height) {
heightInt = height;
heightUnit = height < 0 ? null : "px";
}
/**
* @return The preferred width i.e. like 120px
or 80%
or auto
*/
public String getWidth() {
return toString(widthInt, widthUnit);
}
/**
* @return The preferred height i.e. like 120px
or 80%
or auto
*/
public String getHeight() {
return toString(heightInt, heightUnit);
}
/**
* Get just the width as number without trailing
* unit.
*/
public int getWidthInt() {
return widthInt;
}
/**
* Get just the height as number without trailing
* unit.
*/
public int getHeightInt() {
return heightInt;
}
/**
* @return The unit of the current width. Returns null
for {@link #AUTO} and {@link #INHERIT}.
* Otherwise always returns a non-null value!
*/
public String getWidthUnit() {
return widthInt < 0 ? null : (((widthUnit != null && widthUnit.length() > 0) ? widthUnit : "px")) ;
}
/**
* @return The unit of the current height. Returns null
for {@link #AUTO} and {@link #INHERIT}.
* Otherwise always returns a non-null value!
*/
public String getHeightUnit() {
return heightInt < 0 ? null : (((heightUnit != null && heightUnit.length() > 0) ? heightUnit : "px"));
}
/**
* Set the size of this Dimension object to the specified width and height.
*
* @see #setHeight(String)
* @see #setWidth(String)
*/
public void setSize(String width, String height) {
setWidth(width);
setHeight(height);
}
/**
* Set the size of this Dimension object to the specified width and height
* and append "px" to both values.
*
* @see #setHeight(int)
* @see #setWidth(int)
*/
public void setSize(int width, int height) {
setWidth(width);
setHeight(height);
}
public String toString() {
return "width: " + getWidth() + "; height: " + getHeight();
}
/**
* Extract number from string.
*
* @return extracted integer. f.e.: "120px" becomes 120
*/
protected static int getIntValue(String sizeString) {
if (sizeString == null) {
return AUTO_INT;
}
if (sizeString.trim().equalsIgnoreCase(AUTO)) {
return AUTO_INT;
}
if (sizeString.trim().equalsIgnoreCase(INHERIT)) {
return INHERIT_INT;
}
try {
return new DecimalFormat().parse(sizeString, new ParsePosition(0)).intValue();
} catch (Exception e) {
log.warn("Can not parse [" + sizeString + ']', e);
}
return AUTO_INT;
}
protected static String toString(int size, String unit) {
if (size == INHERIT_INT) {
return INHERIT;
} else if (size < 0) {
return AUTO;
} else if (unit != null && unit.length() > 0) {
return Integer.toString(size) + unit;
} else {
// default: assume px
return Integer.toString(size) + "px";
}
}
/**
* Extract number from string.
*
* @return extracted integer. f.e.: "120px" becomes 120 or {@link #AUTO_INT} if null
*/
protected static int extractNumericValue(String value) {
if (value == null || value.equalsIgnoreCase(AUTO)) {
return AUTO_INT;
} else if (value.equalsIgnoreCase(INHERIT)) {
return INHERIT_INT;
} else {
try {
return new DecimalFormat().parse(value, new ParsePosition(0)).intValue();
} catch (Exception e) {
return AUTO_INT;
}
}
}
/**
* Tries to extract unit from passed string. I.e. returtn "px" if you pass "120px".
*
* @param value A compound number/unit string. May be null
* @return The unit or null
if not possible.
*/
private static String extractUnit(String value) {
if (value == null) {
return null;
} else {
try {
ParsePosition position = new ParsePosition(0);
new DecimalFormat().parse(value, position).intValue();
return value.substring(position.getIndex()).trim();
} catch (Exception e) {
return null;
}
}
}
private final static class UnmodifiableDimension extends SDimension {
private static final long serialVersionUID = 2933909201279046938L;
private static final String errorMsg =
"Predefined SDimension objects (FULLAREA, FULLWIDTH, ...) are unmodifiable! To change " +
"the size of a component with such a dimension a new SDimension object has to be set. ";
private boolean initialized = false;
public UnmodifiableDimension(String width, String height) {
super(width, height);
initialized = true;
}
@Override
public void setWidth(int width) {
if (!initialized) {
super.setWidth(width);
} else {
throw new UnsupportedOperationException(errorMsg);
}
}
@Override
public void setWidth(String width) {
if (!initialized) {
super.setWidth(width);
} else {
throw new UnsupportedOperationException(errorMsg);
}
}
@Override
public void setHeight(int height) {
if (!initialized) {
super.setHeight(height);
} else {
throw new UnsupportedOperationException(errorMsg);
}
}
@Override
public void setHeight(String height) {
if (!initialized) {
super.setHeight(height);
} else {
throw new UnsupportedOperationException(errorMsg);
}
}
@Override
public void setSize(String width, String height) {
if (!initialized) {
super.setSize(width, height);
} else {
throw new UnsupportedOperationException(errorMsg);
}
}
@Override
public void setSize(int width, int height) {
if (!initialized) {
super.setSize(width, height);
} else {
throw new UnsupportedOperationException(errorMsg);
}
}
}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof SDimension)) {
return false;
}
final SDimension sDimension = (SDimension) o;
if (heightInt != sDimension.heightInt || widthInt != sDimension.widthInt) {
return false;
}
if (heightUnit != null ? !heightUnit.equals(sDimension.heightUnit) : sDimension.heightUnit != null) {
return false;
}
return widthUnit != null ? widthUnit.equals(sDimension.widthUnit) : sDimension.widthUnit == null;
}
public int hashCode() {
return widthInt;
}
}