actionlisteditor.java
字号:
}
/**
* Inserts a Null PIYAction before the currently selected icon.
*/
public void insertBefore() {
if (selected != null) {
selected.getActionList().add(selected.getActionList().getIndex(selected.getPIYAction()), new NullAction());
removeAll();
selected = setupList(list, new Point(0,0), new Dimension(getRequiredWidth(list), getRequiredHeight(list)), selected.getPIYAction());
repaint();
}
}
/**
* Inserts a Null PIYAction after the currently selected icon.
*/
public void insertAfter() {
if (selected != null) {
selected.getActionList().add(selected.getActionList().getIndex(selected.getPIYAction())+1, new NullAction());
removeAll();
selected = setupList(list, new Point(0,0), new Dimension(getRequiredWidth(list), getRequiredHeight(list)), selected.getPIYAction());
repaint();
}
}
/**
* Removes the currently selected action (if there is one), and then selects null.
*/
public void removeSelectedAction() {
if (selected != null) {
selected.getActionList().removeAction(selected.getPIYAction());
restructureList(list);
removeAll();
setupList(list, new Point(0,0), new Dimension(getRequiredWidth(list), getRequiredHeight(list)), null);
selectAction(null);
repaint();
}
}
public void paint(Graphics g) {
//paint the components
super.paint(g);
if (list != null) {
//draw all of the lines
paintListLines(list, new Point(0,0), new Dimension(getRequiredWidth(list), getRequiredHeight(list)), g);
//show which actionicon is selected
if (selected != null) {
g.setColor(selectColor);
for (int i=1; i<=selectThickness; i++)
g.drawRect(selected.getX()-i, selected.getY()-i, selected.getWidth()+2*i-1, selected.getHeight()+2*i-1);
}
}
}
/**
* Paints the lines connecting actions in an action list.
* @param list the list for which the lines should be painted
* @param position the top left corner coords of the space gien to draw the lines
* @param size the width and height given to draw this list
* @param g the graphics context on which the paint the list lines
*/
private void paintListLines(ActionList list, Point position, Dimension size, Graphics g) {
int current = (size.width - getRequiredWidth(list))/2 + (int)position.getX();
int y = size.height/2 + (int)position.getY();
PIYAction act = null;
for (int i=0; i<list.size()-1; i++) {
act = list.get(i);
current+=40;
if (act instanceof IfAction) {
IfAction ifAct = (IfAction)act;
int width1 = getRequiredWidth(ifAct.getTrueList());
int width2 = getRequiredWidth(ifAct.getFalseList());
int reqWidth = width1 > width2 ? width1 : width2;
paintListLines(ifAct.getTrueList(), new Point(current + ifBeforeWidth, (int)position.getY()),
new Dimension(reqWidth, size.height/2), g);
paintListLines(ifAct.getFalseList(), new Point(current + ifBeforeWidth, (int)position.getY()+size.height/2),
new Dimension(reqWidth, size.height/2), g);
drawIfBranch(current, y, width1, width2, size.height/2, g);
current += ifBeforeWidth + reqWidth + ifAfterWidth;
} else {
drawArrow(current, y, arrowWidth, g);
current += arrowWidth;
}
}
}
/**
* Draws a line with an arrow on the end, from left to right.
* @param x the leftmost x position of the arrow line
* @param y the y coordinate of the arrow line
* @param size the length of the line to draw to the right (length includes arrowhead size)
* @param g the graphics context on which to draw the arrow
*/
private void drawArrow(int x, int y, int size, Graphics g) {
g.drawLine(x, y, x+size, y);
g.fillPolygon(new int[] {x+size-5, x+size, x+size-5},
new int[] {y-3, y, y+3},
3);
}
/**
* Draws the branch from an IfAction into its two branches, and from the two branches back
* to the original at the end.
* @param x the x position (immediately after the IfAction icon)
* @param y the y position of the branch (midway down the IfAction icon)
* @param width1 the required width of the first branch
* @param width2 the required width of the second branch
* @param height the required height of the tallest branch
* @param g the graphics context on which the branches should be drawn
*/
private void drawIfBranch(int x, int y, int width1, int width2, int height, Graphics g) {
int reqWidth = width1 > width2 ? width1 : width2;
g.drawLine(x, y, x+ifBeforeWidth/2, y);
g.drawLine(x+ifBeforeWidth/2, y-height/2, x+ifBeforeWidth/2, y+height/2);
drawArrow(x+ifBeforeWidth/2, y-height/2, ifBeforeWidth/2 + (reqWidth - width1)/2, g);
drawArrow(x+ifBeforeWidth/2, y+height/2, ifBeforeWidth/2 + (reqWidth - width2)/2, g);
int posAcross = x+reqWidth+ifBeforeWidth+ifAfterWidth/2;
g.drawLine(x+ifBeforeWidth+width1+(reqWidth - width1)/2, y-height/2, posAcross, y-height/2);
g.drawLine(x+ifBeforeWidth+width2+(reqWidth - width2)/2, y+height/2, posAcross, y+height/2);
g.drawLine(posAcross, y-height/2, posAcross, y+height/2);
drawArrow(posAcross, y, ifAfterWidth/2, g);
}
/**
* Sets up the list view by creating an icon for every action and positioning
* them accordingly. (Also restructures the list if needed).
* @param list the list for which to create and position icons
* @param position to top left coordinate of the space into which the icons
* should be positioned
* @param size the width and height of the space the collection of icons must
* take up
* @param action the action which is currently selected - you can provide this information
* so that this method can tell you the reference of the icon created for the action
* @return the action icon created for the action specified
*/
public ActionIcon setupList(ActionList list, Point position, Dimension size, PIYAction action) {
ActionDescriptor desc = null;
ActionIcon current = null;
ActionIcon icon = null; //this is the icon which will be returned - it should represent the action
int top = size.height/2-20 + (int)position.getY(); //icon positioned in the middle of the vertical coords
int currentPos = size.width/2 - getRequiredWidth(list)/2 + (int)position.getX() ;
for (int i=0; i<list.size(); i++) {
desc = getDescriptor(list.get(i).getClass());
add(current = new ActionIcon(list.get(i), list, desc.getBigIcon()));
if (action == list.get(i)) icon = current;
current.setBounds(currentPos, top, 40, 40);
current.addActionListener(this);
currentPos += 40;
if (list.get(i) instanceof IfAction) {
ActionList trueList, falseList;
int width1 = getRequiredWidth( trueList = ((IfAction)list.get(i)).getTrueList() );
int width2 = getRequiredWidth( falseList = ((IfAction)list.get(i)).getFalseList());
int required = (width1 > width2) ? width1 : width2;
ActionIcon icon1 = setupList(trueList, new Point(currentPos+ifBeforeWidth, (int)position.getY()), new Dimension(required, size.height/2), action);
ActionIcon icon2 = setupList(falseList, new Point(currentPos+ifBeforeWidth, (int)position.getY()+size.height/2), new Dimension(required, size.height/2), action);
icon = (icon1 != null) ? icon1 : ((icon2 != null) ? icon2 : icon);
currentPos += ifBeforeWidth + required + ifAfterWidth;
} else currentPos += arrowWidth;
}
selectAction(icon);
return icon;
}
/**
* Sets the list displayed in the panel.
* @param actionList the list to display
*/
public void setList(ActionList actionList) {
list = actionList;
if (list != null) restructureList(list);
removeAll();
selected = null;
//sets up the list and selects the first action in it
if (list != null)
selectAction(setupList(list, new Point(0,0), new Dimension(getRequiredWidth(list), getRequiredHeight(list)), list.get(0)));
else selectAction(null);
scroller.validate();
repaint();
}
/**
* Retrieve the ActionDescriptor for a particular action class type.
* @param action the class of the action whose actiondescriptor is required
* @return the action descriptor of the specified action class, or null if an
* an appropriate descriptor was not found
*/
protected ActionDescriptor getDescriptor(Class action) {
//The NullAction will not be present in the descriptor array
if (action == NullAction.class) return NullDescriptor.getInstance();
for (int i=0; i<actionDescriptors.length; i++)
if (actionDescriptors[i].getDescribedClass() == action)
return actionDescriptors[i];
return null;
}
/**
* Deletes the currently selected list and informs the properties panel. Doesn't inform the
* action list names combo box.
*/
public void deleteList() {
if (list != null) {
PIYNamer names = ProjectHandler.getInstance().getProject().getActionListNamer();
names.removeValue(names.getName(list));
}
}
/**
* Goes through a list and restructures it so that the actionlist viewer can view it. The
* restructuring is to ensure that all IfActions have an action after them, and all
* actionlists have at least one action.
* @param list the list to restructure
*/
private void restructureList(ActionList list) {
if (list != null) {
if (list.size() == 0) list.add(new NullAction());
//we don't allow the list to end on an IfAction for drawing (aesthetic) reasons
if (list.get(list.size()-1) instanceof IfAction) list.add(new NullAction());
for (int i=0; i<list.size(); i++) {
if (list.get(i) instanceof IfAction) {
restructureList(((IfAction)list.get(i)).getTrueList());
restructureList(((IfAction)list.get(i)).getFalseList());
}
}
}
}
/**
* Selects the specified action icon, informing the properties panel to display its properties
* @param action the action icon to select
*/
public void selectAction(ActionIcon action) {
selected = action;
propertiesPanel.setup(selected == null ? null : selected.getPIYAction());
repaint();
}
/**
* Sets the editype behaviour of this viewer when a null action is selected. If type = SELECT,
* when the Null PIYAction is clicked it becomes selected. If type = ADD, when a Null PIYAction is
* clicked, it is replaced with the currently selected action type on the toolbar.
* @param type one of SELECT or ADD
*/
public void setEditType(int type) {
if ((type == SELECT) || (type == ADD))
editType = type;
}
/**
* This calculates how much horizontal space the actionlist view takes up. Each
* action takes up 40 (for the icon) + arrowWidth (for the arrow), unless it is an IfAction,
* which takes up 40 (for the icon) + space before and after (for the lines) + the amount of space
* required by the longest of its two internal actionlists.
* @param a the action list whose width is to be determined
* @return the number of pixels required
*/
public int getRequiredWidth(ActionList a) {
if (a == null) return 0;
int width = 0;
for (int i=0; i<a.size(); i++) {
width += a.get(i) instanceof IfAction ?
40 + ifBeforeWidth + ifAfterWidth + Math.max(getRequiredWidth(((IfAction)a.get(i)).getTrueList()),
getRequiredWidth(((IfAction)a.get(i)).getFalseList())) :
40 + arrowWidth;
}
return width - arrowWidth;
}
/**
* Calculate how much horizontal space is required by an actionlist. This
* will be 40 if the list is just a sequence of actions, but if the list
* includes an IfAction then the list takes 40 + the height of the truelist +
* the height of the falselist. Note that we take the maximum required height
* out of <i>all</i> of the IfActions present in any one actionlist.
*
* @param a the list for which the height should be determined
* @return the amount of horizontal space the list <i>a</i> requires
*/
public int getRequiredHeight(ActionList a) {
if (a == null) return 0;
int height = 40;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -