defaultlookandfeel.java.svn-base
来自「j2me设计的界面包」· SVN-BASE 代码 · 共 1,456 行 · 第 1/4 页
SVN-BASE
1,456 行
/*
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.lwuit.plaf;
import com.sun.lwuit.TextField;
import com.sun.lwuit.geom.Dimension;
import com.sun.lwuit.Graphics;
import com.sun.lwuit.Image;
import com.sun.lwuit.Button;
import com.sun.lwuit.CheckBox;
import com.sun.lwuit.ComboBox;
import com.sun.lwuit.Component;
import com.sun.lwuit.Label;
import com.sun.lwuit.List;
import com.sun.lwuit.RadioButton;
import com.sun.lwuit.TextArea;
import com.sun.lwuit.list.ListCellRenderer;
import com.sun.lwuit.list.ListModel;
import com.sun.lwuit.Font;
import com.sun.lwuit.TabbedPane;
import com.sun.lwuit.events.FocusListener;
import com.sun.lwuit.geom.Rectangle;
import java.util.Calendar;
import java.util.Date;
/**
* Used to render the default look of LWUIT
*
* @author Chen Fishbein
*/
public class DefaultLookAndFeel extends LookAndFeel implements FocusListener {
private static final long DAY = 1000 * 60 * 60 * 24;
private Image[] chkBoxImages = null;
private Image comboImage = null;
private Image[] rButtonImages = null;
private static int DAY_SPACE_W = 12;
private static int DAY_SPACE_H = 15;
private long tickerSpeed = 50;
private boolean tickWhenFocused = true;
/** Creates a new instance of DefaultLookAndFeel */
public DefaultLookAndFeel() {
}
/**
* @inheritDoc
*/
public void bind(Component cmp) {
if (tickWhenFocused && cmp instanceof Label) {
((Label) cmp).addFocusListener(this);
}
}
/**
* Gets the ticker speed
*
* @return ticker speed in milliseconds
*/
public long getTickerSpeed() {
return tickerSpeed;
}
/**
* Sets the ticker speed
*
* @param tickerSpeed the speed in milliseconds
*/
public void setTickerSpeed(long tickerSpeed) {
this.tickerSpeed = tickerSpeed;
}
/**
* This method allows to set all Labels, Buttons, CheckBoxes, RadioButtons
* to start ticking when the text is too long.
* @param tickWhenFocused
*/
public void setTickWhenFocused(boolean tickWhenFocused) {
this.tickWhenFocused = tickWhenFocused;
}
/**
* Sets images for checkbox checked/unchecked modes
*
* @param checked the image to draw in order to represent a checked checkbox
* @param unchecked the image to draw in order to represent an uncheck checkbox
*/
public void setCheckBoxImages(Image checked, Image unchecked) {
if (checked == null || unchecked == null) {
chkBoxImages = null;
} else {
chkBoxImages = new Image[]{checked, unchecked};
}
}
/**
* Sets image for the combo box dropdown drawing
*
* @param picker picker image
*/
public void setComboBoxImage(Image picker) {
comboImage = picker;
}
/**
* Sets images for radio button selected/unselected modes
*
* @param selected the image to draw in order to represent a selected radio button
* @param unselected the image to draw in order to represent an unselected radio button
*/
public void setRadioButtonImages(Image selected, Image unselected) {
if (selected == null || unselected == null) {
rButtonImages = null;
} else {
rButtonImages = new Image[]{selected, unselected};
}
}
/**
* @inheritDoc
*/
public void drawButton(Graphics g, Button b) {
drawComponent(g, b, getIconFromState(b), null, 0);
}
/**
* @inheritDoc
*/
public void drawCheckBox(Graphics g, CheckBox cb) {
if (chkBoxImages != null) {
drawComponent(g, cb, getIconFromState(cb), chkBoxImages[cb.isSelected() ? 1 : 0], 0);
} else {
Style style = cb.getStyle();
int height = cb.getHeight();
drawComponent(g, cb, getIconFromState(cb), null, height + cb.getGap());
int gradientColor;
if (cb.hasFocus()) {
g.setColor(style.getFgSelectionColor());
gradientColor = style.getBgSelectionColor();
} else {
g.setColor(style.getFgColor());
gradientColor = style.getBgColor();
}
int width = height;
int tX = cb.getX() + style.getPadding(Component.LEFT);
int tY = cb.getY() + style.getPadding(Component.TOP) + (cb.getHeight() - style.getPadding(Component.TOP) - style.getPadding(Component.BOTTOM)) / 2 - height / 2;
g.translate(tX, tY);
int x = scaleCoordinate(1.04f, 16, width);
int y = scaleCoordinate(4.0f, 16, height);
int rectWidth = scaleCoordinate(10.9515f, 16, width);
int rectHeight = scaleCoordinate(10f, 16, height);
// brighten or darken the color slightly
int destColor = findDestColor(gradientColor);
g.fillLinearGradient(gradientColor, destColor, x + 1, y + 1, rectWidth - 2, rectHeight - 1, false);
g.drawRoundRect(x, y, rectWidth, rectHeight, 5, 5);
if (cb.isSelected()) {
int color = g.getColor();
g.setColor(0x111111);
g.translate(0, 1);
fillCheckbox(g, width, height);
g.setColor(color);
g.translate(0, -1);
fillCheckbox(g, width, height);
}
g.translate(-tX, -tY);
}
}
private static void fillCheckbox(Graphics g, int width, int height) {
int x1 = scaleCoordinate(2.0450495f, 16, width);
int y1 = scaleCoordinate(9.4227722f, 16, height);
int x2 = scaleCoordinate(5.8675725f, 16, width);
int y2 = scaleCoordinate(13.921746f, 16, height);
int x3 = scaleCoordinate(5.8675725f, 16, width);
int y3 = scaleCoordinate(11f, 16, height);
g.fillTriangle(x1, y1, x2, y2, x3, y3);
x1 = scaleCoordinate(14.38995f, 16, width);
y1 = scaleCoordinate(0.88766801f, 16, height);
g.fillTriangle(x1, y1, x2, y2, x3, y3);
}
private static int round(float x) {
int rounded = (int) x;
if (x - rounded > 0.5f) {
return rounded + 1;
}
return rounded;
}
/**
* Takes a floating point coordinate on a virtual axis and rusterizes it to
* a coordinate in the pixel surface. This is a very simple algorithm since
* anti-aliasing isn't supported.
*
* @param coordinate a position in a theoretical plain
* @param plain the amount of space in the theoretical plain
* @param pixelSize the amount of pixels available on the screen
* @return the pixel which we should color
*/
private static int scaleCoordinate(float coordinate, float plain, int pixelSize) {
return round(coordinate / plain * pixelSize);
}
/**
* @inheritDoc
*/
public void drawLabel(Graphics g, Label l) {
drawComponent(g, l, l.getIcon(), null, 0);
}
/**
* @inheritDoc
*/
public void drawRadioButton(Graphics g, RadioButton rb) {
if (rButtonImages != null) {
drawComponent(g, rb, getIconFromState(rb), rButtonImages[rb.isSelected() ? 1 : 0], 0);
} else {
Style style = rb.getStyle();
int height = rb.getHeight();
drawComponent(g, rb, getIconFromState(rb), null, height + rb.getGap());
if (rb.hasFocus()) {
g.setColor(style.getFgSelectionColor());
} else {
g.setColor(style.getFgColor());
}
height -= (style.getPadding(Component.TOP) + style.getPadding(Component.BOTTOM));
int x = rb.getX() + style.getPadding(Component.LEFT);
int y = rb.getY() + style.getPadding(Component.TOP);
g.drawArc(x, y, height, height, 0, 360);
if (rb.isSelected()) {
int color = g.getColor();
int destColor = findDestColor(color);
g.fillRadialGradient(color, destColor, x + 3, y + 3, height - 5, height - 5);
}
}
}
/**
* @inheritDoc
*/
public void drawComboBox(Graphics g, ComboBox cb) {
int border = 2;
Style style = cb.getStyle();
int leftPadding = style.getPadding(Component.LEFT);
int rightPadding = style.getPadding(Component.RIGHT);
setFG(g, cb);
ListModel model = cb.getModel();
ListCellRenderer renderer = cb.getRenderer();
Object value = model.getItemAt(model.getSelectedIndex());
int comboImageWidth;
if (comboImage != null) {
comboImageWidth = comboImage.getWidth();
} else {
comboImageWidth = style.getFont().getHeight();
}
if (model.getSize() > 0) {
Component cmp = renderer.getListCellRendererComponent(cb, value, model.getSelectedIndex(), cb.hasFocus());
cmp.setX(cb.getX() + leftPadding);
cmp.setY(cb.getY() + style.getPadding(Component.TOP));
cmp.setWidth(cb.getWidth() - comboImageWidth - 2 * rightPadding - leftPadding);
cmp.setHeight(cb.getHeight() - style.getPadding(Component.TOP) - style.getPadding(Component.BOTTOM));
cmp.paint(g);
}
g.setColor(style.getBgColor());
int y = cb.getY();
int height = cb.getHeight();
int width = comboImageWidth + border;
int x = cb.getX() + cb.getWidth() - comboImageWidth - rightPadding - border;
if (comboImage != null) {
g.fillRect(x, y, width, height);
g.drawImage(comboImage, x, y + height / 2 - comboImage.getHeight() / 2);
} else {
int color = g.getColor();
// brighten or darken the color slightly
int destColor = findDestColor(color);
g.fillLinearGradient(g.getColor(), destColor, x, y, width, height, false);
g.setColor(color);
g.drawRect(x, y, width, height - 1);
width--;
height--;
//g.drawRect(x, y, width, height);
g.translate(x + 1, y + 1);
g.setColor(0x111111);
int x1 = scaleCoordinate(2.5652081f, 16, width);
int y1 = scaleCoordinate(4.4753664f, 16, height);
int x2 = scaleCoordinate(8.2872691f, 16, width);
int y2 = scaleCoordinate(10f, 16, height);
int x3 = scaleCoordinate(13.516078f, 16, width);
int y3 = y1;
g.fillTriangle(x1, y1, x2, y2, x3, y3);
g.translate(-1, -1);
g.setColor(color);
g.fillTriangle(x1, y1, x2, y2, x3, y3);
//g.setColor(style.getFgColor());
//g.fillTriangle(x1 + 2, y1 + 2, x2, y2 - 2, x3 - 2, y3 + 2);
g.translate(-x, -y);
}
}
/**
* Finds a suitable destination color for gradient values
*/
private int findDestColor(int color) {
// brighten or darken the color slightly
int sourceR = color >> 16 & 0xff;
int sourceG = color >> 8 & 0xff;
int sourceB = color & 0xff;
if (sourceR > 128 && sourceG > 128 && sourceB > 128) {
// darken
sourceR = Math.max(sourceR >> 1, 0);
sourceG = Math.max(sourceG >> 1, 0);
sourceB = Math.max(sourceB >> 1, 0);
} else {
// brighten
sourceR = Math.min(sourceR << 1, 0xff);
sourceG = Math.min(sourceG << 1, 0xff);
sourceB = Math.min(sourceB << 1, 0xff);
}
return ((sourceR << 16) & 0xff0000) | ((sourceG << 8) & 0xff00) | (sourceB & 0xff);
}
/**
* @inheritDoc
*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?