booleanexpressioneditor.java
字号:
}
} else if (command == DELETE) {
if (selected != null) {
if (selected.getParentIcon() == null) { //top level icon
rootExpression = new NullComparator();
whereBound.setValue(rootExpression);
rootIcon.setup(rootExpression, null);
} else {
ExpressionIcon oldParent = selected.getParentIcon();
BooleanComparable toBecome = null;
if ( ((BooleanExpression)oldParent.getComparable()).getFirst() == selected.getComparable()) {
toBecome = ((BooleanExpression)oldParent.getComparable()).getSecond();
} else {
toBecome = ((BooleanExpression)oldParent.getComparable()).getFirst();
}
ExpressionIcon oldParentParent = oldParent.getParentIcon();
if (oldParentParent == null) { //top level
rootExpression = toBecome;
whereBound.setValue(rootExpression);
rootIcon.setup(rootExpression, null);
} else {
if ( ((BooleanExpression)oldParentParent.getComparable()).getFirst() == oldParent.getComparable()) {
((BooleanExpression)oldParentParent.getComparable()).setFirst(toBecome);
} else {
((BooleanExpression)oldParentParent.getComparable()).setSecond(toBecome);
}
rootIcon.setup(rootExpression, null);
}
}
select(null);
}
}
}
/**
* These icons provide the mechanism by which individual comparators can be selected in
* the expression. The size required by one of these is determined by the size of
* the sub-expressions. There is generally one top level one of these, which contains
* more internally.
* @author David Vivash
* @version 1.0, 30/04/01
*/
private class ExpressionIcon extends JPanel implements MouseListener {
private BooleanComparable expression = null;
private ExpressionIcon parentIcon = null;
private ImageIcon icon = null;
//coords for the line joining two components in the expression
private int lineX = 0, lineY = 0;
private static final int xGap = 48, yGap = 32, xPadding = 6, yPadding = 6, xSize=48, ySize=48;
public ExpressionIcon() {
setBackground(Color.white);
setLayout(null);
addMouseListener(this);
}
/**
* Constructs a new expression icon. If the supplied comparator is a boolean expression,
* this constructor will add new expression icons internally to deal with it.
* @param ex the comparator to construct an icon for. If null, this constructor throws
* an Error - to create NullComparators, use the NullComparator object instead
* @param parentIcon the expression icon that contains this one. A top level icon
* should set this parameter to null
*/
public void setup(BooleanComparable ex, ExpressionIcon parentIcon) {
if (ex == null) throw new Error("Comparator was null");
removeAll();
this.expression = ex;
this.parentIcon = parentIcon;
if (ex instanceof BooleanExpression) {
BooleanExpression boolEx = (BooleanExpression)ex;
ExpressionIcon first = new ExpressionIcon();
first.setup(boolEx.getFirst(), this);
ExpressionIcon second = new ExpressionIcon();
second.setup(boolEx.getSecond(), this);
add(first);
add(second);
if (boolEx.getAnd()) {
Dimension size1 = getRequiredSize(first.getComparable());
Dimension size2 = getRequiredSize(second.getComparable());
int maxHeight = size1.height > size2.height ? size1.height : size2.height;
first.setLocation(new Point(xPadding, yPadding + (maxHeight - size1.height)/2));
second.setLocation(new Point(size1.width + xPadding+xGap, yPadding + (maxHeight - size2.height)/2));
lineX = size1.width + xPadding;
lineY = yPadding + maxHeight/2;
} else {
Dimension size1 = getRequiredSize(first.getComparable());
Dimension size2 = getRequiredSize(second.getComparable());
int maxWidth = size1.width > size2.width ? size1.width : size2.width;
first.setLocation(new Point(xPadding + (maxWidth - size1.width)/2, yPadding));
second.setLocation(new Point(xPadding + (maxWidth - size2.width)/2, yPadding + size1.height + yGap));
lineX = xPadding + maxWidth/2;
lineY = size1.height + yPadding;
}
} else if (ex instanceof BooleanComparable) {
icon = editor.getDescriptor(ex.getClass()).getBigIcon();
}
editor.negate(this);
this.setSize(getRequiredSize(ex));
if (scroller != null) scroller.validate();
}
public BooleanComparable getComparable() { return expression; }
public ExpressionIcon getParentIcon() { return parentIcon; }
public Dimension getRequiredSize(BooleanComparable comp) {
if (comp == null) return new Dimension(xSize, ySize);
if (comp instanceof PIYComparator) return new Dimension(xSize, ySize);
if (comp instanceof BooleanExpression) {
BooleanExpression boolEx = (BooleanExpression)comp;
boolean leftToRight = boolEx.getAnd(); //we display ANDs left to right, ORs top to bottom
Dimension size1 = getRequiredSize(boolEx.getFirst());
Dimension size2 = getRequiredSize(boolEx.getSecond());
int maxHeight = size1.height > size2.height ? size1.height : size2.height;
int maxWidth = size1.width > size2.width ? size1.width : size2.width;
if (leftToRight) {
return new Dimension(size1.width + size2.width + xPadding*2 + xGap,
maxHeight + yPadding*2);
} else {
return new Dimension(maxWidth + xPadding*2,
size1.height + size2.height + yPadding*2 + yGap);
}
}
return new Dimension(0, 0);
}
public Dimension getPreferredSize() { return getRequiredSize(expression); }
/**
* Paints the icon - it is either an expression (where it joins two comparators together)
* or it is a comparator (where it draws the icon).
* @param g the graphics context on which to draw
*/
public void paint(Graphics g) {
super.paint(g);
if (expression instanceof BooleanExpression) {
//draw lines
if ( ((BooleanExpression)expression).getAnd() ) {
g.drawLine(lineX, lineY, xGap + lineX, lineY);
g.drawString("AND", lineX + xGap/2 - g.getFontMetrics().stringWidth("AND")/2, lineY - 2);
} else {
g.drawLine(lineX, lineY, lineX, lineY + yGap);
g.drawString("OR", lineX + 4, lineY + yGap/2 + g.getFontMetrics().getHeight()/2 - 4);
}
} else if (expression instanceof BooleanComparable) {
g.drawImage(icon.getImage(), getWidth()/2-icon.getIconWidth()/2, getHeight()/2-icon.getIconHeight()/2, this);
}
}
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
public void mouseClicked(MouseEvent e) {
switch (editType) {
case SELECT:
editor.select(this);
break;
case ADD:
if (expression instanceof NullComparator) {
//add the selected comparator to the expression
try{
PIYComparator toSelect = (PIYComparator)toolbarSelection.getDescribedClass().newInstance();
if (parentIcon == null) { //top level icon
whereBound.setValue(toSelect);
setup(toSelect, null);
} else {
BooleanExpression parent = (BooleanExpression)parentIcon.getComparable();
if (parent.getFirst() == expression) parent.setFirst(toSelect);
else parent.setSecond(toSelect);
setup(toSelect, parentIcon);
}
for (int i=0; i<comparatorPanel.length; i++)
comparatorPanel[i].clearSelection(); //deselect the icon on the toolbar
scroller.validate();
} catch (Exception X) {
System.out.println("Unable to insert comparator into expression");
X.printStackTrace();
}
repaint();
editor.select(this);
}
break;
}
}
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
}
private class ExpressionViewer extends JPanel implements MouseListener {
public ExpressionViewer() {
super();
setBackground(Color.white);
setLayout(null);
ExpressionIcon icon = new ExpressionIcon();
icon.setup(rootExpression, null);
add(icon);
addMouseListener(this);
rootIcon = icon;
}
public Dimension getPreferredSize() { return rootIcon.getPreferredSize(); }
//------- Mouse Listener methods ----------
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mouseClicked(MouseEvent e) {
editor.select(null); //the user hasn't clicked on any of the internal icons, so clear the selection
}
}
/**
* The panel which displays the properties and property support of the currently selected comparator.
* @author David Vivash
* @version 1.0, 01/05/01
*/
private class PropertiesPanel extends JPanel implements ActionListener {
private BooleanComparable comparable = null;
private JComboBox combo = null;
public PropertiesPanel() {
setLayout(new BorderLayout());
}
/**
* Each time an action is selected in the action list viewer, this method should be called
* to update the properties.
* @param action the action that has been selected
*/
public void setup(BooleanComparable comparable) {
this.comparable = comparable;
//get rid of the old properties panels
removeAll();
if ((comparable != null) && !(comparable instanceof NullComparator)) {
//Set up the top panel which displays the name of the PIYAction on a yellow background
JPanel top = new JPanel();
top.setBackground(Color.yellow);
top.setBorder(new LineBorder(Color.black));
top.setMinimumSize(new Dimension(64,64));
ActionDescriptor descriptor = getDescriptor(comparable.getClass());
if (descriptor != null) top.add(new JLabel(descriptor.getName() + " Properties"));
else top.add(new JLabel("Comparator Properties"));
JPanel propPane = new JPanel();
JScrollPane propertyScroller = new JScrollPane(propPane);
add(top, BorderLayout.NORTH);
add(propertyScroller, BorderLayout.CENTER);
//Get the class support panels for this action
//Layout the class support panels
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
propPane.setLayout(gridbag);
c.fill = GridBagConstraints.HORIZONTAL;
c.ipadx = 4; c.ipady = 8;
c.insets = new Insets(4,4,4,4);
ClassSupport negateSupport = new BoolSupport(new Property(editor, "Negate", boolean.class));
JLabel label = new JLabel("Negate?");
JPanel negatePanel = new JPanel();
negatePanel.setLayout(new BorderLayout());
negatePanel.add(label, BorderLayout.WEST);
negatePanel.add(negateSupport, BorderLayout.CENTER);
c.gridx = 0; c.weightx = 1.0;
gridbag.setConstraints(negatePanel, c);
propPane.add(negatePanel);
int ypos = 1;
if (comparable instanceof PIYComparator) {
PIYComparator comp = (PIYComparator)comparable;
//add support for first
Class firstType = comp.getFirstType();
if ( (firstType != null) && (firstType != void.class)) {
FixedPropertySupport firstProperty = new FixedPropertySupport(new Property(comp, "First", firstType));
c.gridy = ypos; c.gridx = 0;
gridbag.setConstraints(firstProperty, c);
propPane.add(firstProperty);
++ypos;
}
//Add combo box here...
combo = new JComboBox(comp.getModes());
combo.setSelectedItem(comp.getMode());
c.gridy = ypos; c.gridx = 0;
combo.setPreferredSize(new Dimension(0, 24));
gridbag.setConstraints(combo, c);
propPane.add(combo);
combo.addActionListener(this);
++ypos;
//now add support for second
Class secondType = comp.getSecondType();
if ( (firstType != null) && (firstType != void.class)) {
FixedPropertySupport secondProperty = new FixedPropertySupport(new Property(comp, "Second", secondType));
c.gridy = ypos; c.gridx = 0;
gridbag.setConstraints(secondProperty, c);
propPane.add(secondProperty);
++ypos;
}
}
//add a blank panel at the bottom to make sure the (real) properties are
//aligned to the top of the frame.
c.gridy = ypos; c.weighty = 1.0;
JPanel blank = new JPanel();
gridbag.setConstraints(blank, c);
propPane.add(blank);
}
validate();
repaint();
}
private ActionDescriptor getDescriptor(Class type) {
for (int i=0; i<comparatorDescriptors.length; i++)
if (comparatorDescriptors[i].getDescribedClass() == type) return comparatorDescriptors[i];
return null;
}
public void actionPerformed(ActionEvent e) {
((PIYComparator)comparable).setMode((String)combo.getSelectedItem());
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -