📄 list.java.svn-base
字号:
*
* @return the renderer which is used to draw list elements
*/
public ListCellRenderer getRenderer() {
return renderer;
}
/**
* Returns the list orientation
*
* @return the list orientation HORIZONTAL or VERTICAL
* @see #HORIZONTAL
* @see #VERTICAL
*/
public int getOrientation() {
return orientation;
}
/**
* @inheritDoc
*/
public void refreshTheme() {
ListCellRenderer r = getRenderer();
if(renderingPrototype != null) {
r.getListCellRendererComponent(this, renderingPrototype, 0, false).refreshTheme();
} else {
if(getModel().getSize() > 0) {
r.getListCellRendererComponent(this, getModel().getItemAt(0), 0, false).refreshTheme();
} else {
r.getListCellRendererComponent(this, null, 0, false).refreshTheme();
}
}
Component focus = r.getListFocusComponent(this);
if(focus != null) {
focus.refreshTheme();
}
super.refreshTheme();
}
/**
* Sets the list orientation HORIZONTAL or VERTICAL
*
* @param orientation the list orientation HORIZONTAL or VERTICAL
* @see #HORIZONTAL
* @see #VERTICAL
*/
public void setOrientation(int orientation) {
this.orientation = orientation;
}
/**
* Makes sure the selected index is visible if it is not in the current view
* rect the list will scroll so it fits within
*
* @param rect the rectangle area to scroll to
*/
public void scrollRectToVisible(Rectangle rect) {
if (fixedSelection < FIXED_NONE_BOUNDRY) {
//Dimension elemSize = getElementSize();
if (orientation == VERTICAL) {
super.scrollRectToVisible(new Rectangle(getScrollX(), rect.getY() , rect.getSize().getWidth(), rect.getSize().getHeight() + itemGap), this);
} else {
super.scrollRectToVisible(new Rectangle(rect.getX(), getScrollY(), rect.getSize().getWidth() + itemGap, rect.getSize().getHeight()), this);
}
}
}
/**
* @inheritDoc
*/
public void setHandlesInput(boolean b) {
Form f = getComponentForm();
if(f != null) {
// prevent the list from losing focus if its the only element
// or when the user presses fire and there is no other component
super.setHandlesInput(b || f.isSingleFocusMode());
} else {
super.setHandlesInput(b);
}
}
/**
* @inheritDoc
*/
protected void fireClicked() {
boolean h = handlesInput();
setHandlesInput(!h);
if (h) {
fireActionEvent();
}
repaint();
}
/**
* @inheritDoc
*/
protected boolean isSelectableInteraction() {
return true;
}
/**
* @inheritDoc
*/
public void keyReleased(int keyCode) {
// other events are in keyReleased to prevent the next event from reaching the next form
int gameAction = Display.getInstance().getGameAction(keyCode);
if (gameAction == Display.GAME_FIRE) {
boolean h = handlesInput();
setHandlesInput(!h);
if (h) {
fireActionEvent();
}
repaint();
return;
}
if(numericKeyActions && gameAction != Display.GAME_LEFT &&
gameAction != Display.GAME_RIGHT && gameAction != Display.GAME_UP &&
gameAction != Display.GAME_DOWN) {
if(keyCode >= '1' && keyCode <= '9') {
int offset = keyCode - '1';
if(offset < getModel().getSize()) {
setSelectedIndex(offset);
fireActionEvent();
}
}
}
}
/**
* @inheritDoc
*/
public void keyPressed(int keyCode) {
// scrolling events are in keyPressed to provide immediate feedback
if (!handlesInput()) {
return;
}
int gameAction = Display.getInstance().getGameAction(keyCode);
int keyFwd;
int keyBck;
if (getOrientation() == VERTICAL) {
keyFwd = Display.GAME_DOWN;
keyBck = Display.GAME_UP;
if (gameAction == Display.GAME_LEFT || gameAction == Display.GAME_RIGHT) {
setHandlesInput(false);
}
} else {
keyFwd = Display.GAME_RIGHT;
keyBck = Display.GAME_LEFT;
if (gameAction == Display.GAME_DOWN || gameAction == Display.GAME_UP) {
setHandlesInput(false);
}
}
int selectedIndex = model.getSelectedIndex();
if (gameAction == keyBck) {
selectedIndex--;
if (selectedIndex < 0) {
if (fixedSelection != FIXED_NONE && fixedSelection != FIXED_NONE_ONE_ELEMENT_MARGIN_FROM_EDGE) {
selectedIndex = size() - 1;
} else {
selectedIndex = 0;
setHandlesInput(false);
}
}
} else if (gameAction == keyFwd) {
selectedIndex++;
if (selectedIndex >= size()) {
if (fixedSelection != FIXED_NONE && fixedSelection != FIXED_NONE_ONE_ELEMENT_MARGIN_FROM_EDGE) {
selectedIndex = 0;
} else {
selectedIndex = size() - 1;
setHandlesInput(false);
}
}
}
if (selectedIndex != model.getSelectedIndex()) {
model.setSelectedIndex(selectedIndex);
updateAnimationPosition(gameAction == keyFwd ? 1 : -1);
if (fixedSelection == FIXED_NONE || fixedSelection == FIXED_NONE_CYCLIC) {
selectElement(selectedIndex);
}
if(fixedSelection == FIXED_NONE_ONE_ELEMENT_MARGIN_FROM_EDGE) {
// are we going down?
if(keyFwd == gameAction) {
selectElement(Math.min(selectedIndex + 1, getModel().getSize() - 1));
} else {
selectElement(Math.max(selectedIndex - 1, 0));
}
}
}
repaint();
}
private void selectElement(int selectedIndex) {
Dimension size = getElementSize(false);
Rectangle rect;
if (getOrientation() == VERTICAL) {
rect = new Rectangle(getX(), (size.getHeight() + itemGap) * selectedIndex, getElementSize(true));
} else {
rect = new Rectangle((size.getWidth() + itemGap) * selectedIndex, getY(), getElementSize(true));
}
scrollRectToVisible(rect);
}
/**
* Updates the animation constant to a new value based on a keypress
*
* @param direction direction of the animation 1 or -1
*/
private void updateAnimationPosition(int direction) {
if (animationPosition != 0) {
return;
}
if (isSmoothScrolling()) {
if (orientation == VERTICAL) {
animationPosition += (direction * getElementSize(false).getHeight());
} else {
animationPosition += (direction * getElementSize(false).getWidth());
}
destination = Math.abs(animationPosition);
initListMotion();
}
}
private void initListMotion() {
listMotion = Motion.createSplineMotion(0, destination, getScrollAnimationSpeed());
listMotion.start();
}
/**
* Calculates the desired bounds for the component and returns them within the
* given rectangle.
*/
private void calculateComponentPosition(int index, int defaultWidth, Rectangle rect, Dimension rendererSize, Dimension selectedSize, boolean beforeSelected) {
Style style = getStyle();
int initialY = style.getPadding(TOP);
int initialX = style.getPadding(LEFT);
int selection = getSelectedIndex();
Dimension d = rect.getSize();
int selectedDiff;
// the algorithm illustrated here is very simple despite the "mess" of code...
// The idea is that if we have a "fixed" element we just add up the amount of pixels
// to get it into its place in the screen (nothing for top obviously).
// In order to cause the list to be cyclic we just subtract the list size
// which will cause the bottom elements to "return" from the top.
if (orientation == VERTICAL) {
int height = rendererSize.getHeight();
selectedDiff = selectedSize.getHeight() - height;
rect.setX(initialX);
d.setHeight(height);
d.setWidth(defaultWidth);
int y = 0;
int listHeight = getHeight() - style.getPadding(TOP) - style.getPadding(BOTTOM);
int totalHeight = (height + itemGap) * getModel().getSize() + selectedDiff;
switch (fixedSelection) {
case FIXED_CENTER:
y = listHeight / 2 - (height + itemGap+ selectedDiff) / 2 +
(index - selection) * (height + itemGap);
if(!beforeSelected){
y += selectedDiff;
}
y = recalcOffset(y, totalHeight, listHeight, height + itemGap);
break;
case FIXED_TRAIL:
y = listHeight - (height + itemGap + selectedDiff);
case FIXED_LEAD:
y += (index - selection) * (height + itemGap);
if(index - selection > 0){
y += selectedDiff;
}
y = recalcOffset(y, totalHeight, listHeight, height + itemGap);
break;
default:
y = index * (height + itemGap);
if(!beforeSelected){
y += selectedDiff;
}
break;
}
rect.setY(y + initialY);
if(index == selection){
d.setHeight(d.getHeight() + selectedDiff);
}
} else {
int width = rendererSize.getWidth();
selectedDiff = selectedSize.getWidth() - width;
rect.setY(initialY);
d.setHeight(getHeight() - style.getPadding(TOP) - style.getPadding(BOTTOM));
d.setWidth(width);
int x = 0;
int listWidth = getWidth() - style.getPadding(RIGHT) - style.getPadding(LEFT);
int totalWidth = (width + itemGap) * getModel().getSize() + selectedDiff;
switch (fixedSelection) {
case FIXED_CENTER:
x = listWidth / 2 - (width + itemGap +selectedDiff) / 2 +
(index - selection) * (width + itemGap);
if(!beforeSelected){
x += selectedDiff;
}
x = recalcOffset(x, totalWidth, listWidth, width + itemGap);
break;
case FIXED_TRAIL:
x = listWidth - (width + itemGap + selectedDiff);
case FIXED_LEAD:
x += (index - selection) * (width + itemGap);
if(index - selection > 0){
x += selectedDiff;
}
x = recalcOffset(x, totalWidth, listWidth, width + itemGap);
break;
default:
x = index * (width + itemGap);
if(!beforeSelected){
x += selectedDiff;
}
break;
}
rect.setX(initialX + x);
if(index == selection){
d.setWidth(d.getWidth() + selectedDiff);
}
}
}
/**
* Allows us to recalculate the bounds of a coordinate to make it "loop" back
* into view
*
* @param offset either x or y coordinate
* @param totalSize the total width or height of the list with all the elements (including scroll)
* @param viewSize the size visible to the user
* @param componentSize the size of the component
* @return offset after manipulation if such manipulation was performed
*/
private int recalcOffset(int offset, int totalSize, int viewSize, int componentSize) {
if (offset + animationPosition % componentSize > viewSize) {
offset -= totalSize;
} else {
if (offset + animationPosition % componentSize < 1 - componentSize) {
offset += totalSize;
}
}
return offset;
}
/**
* @inheritDoc
*/
public void paint(Graphics g) {
UIManager.getInstance().getLookAndFeel().drawList(g, this);
Style style = getStyle();
int width = getWidth() - style.getPadding(RIGHT) - style.getPadding(LEFT) - getSideGap();
if (isScrollableX()) {
width = Math.max(width, getPreferredW() - style.getPadding(RIGHT) - style.getPadding(LEFT) - getSideGap());
}
int numOfcomponents = model.getSize();
if(numOfcomponents == 0){
return;
}
int xTranslate = getX();
int yTranslate = getY();
g.translate(xTranslate, yTranslate);
Rectangle pos = new Rectangle();
Dimension rendererSize = getElementSize(false);
int selection = model.getSelectedIndex();
if (animationPosition != 0 && fixedSelection > FIXED_NONE_BOUNDRY) {
// selection should never move during animation of fixed elements
selection = -1;
if (orientation == VERTICAL) {
yTranslate += animationPosition;
g.translate(0, animationPosition);
} else {
xTranslate += animationPosition;
g.translate(animationPosition, 0);
}
}
int clipX = g.getClipX();
int clipY = g.getClipY();
int clipWidth = g.getClipWidth();
int clipHeight = g.getClipHeight();
if(paintFocusBehindList){
paintFocus(g, width, pos, rendererSize);
}
// this flag is for preformance improvements
// if we figured out that the list items are not visible anymore
// we should break from the List loop
boolean shouldBreak = false;
// improve performance for browsing the end of a very large list
int startingPoint = 0;
if(fixedSelection < FIXED_NONE_BOUNDRY) {
startingPoint = Math.max(0, pointerSelect(clipX + getAbsoluteX(), clipY + getAbsoluteY()) - 1);
}
for(int i = startingPoint; i < numOfcomponents; i++) {
// skip on the selected
if(i == getSelectedIndex() && animationPosition == 0){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -