欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

booleanexpressioneditor.java

PIY(Program It Yourself)是一个基于Java的应用程序开发环境
JAVA
第 1 页 / 共 2 页
字号:
package piy.support;

import javax.swing.*;
import java.awt.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.awt.event.*;
import piy.*;

import java.io.File;
import java.util.*;

/**
* Frame in which user can edit boolean expressions.  Relies on PIY for comparator descriptors.
* <p>
* Muse: Should this be made a singleton?
* <p>
* This class is suspiciously similar to ActionListEditor - REFACTOR!
* @author David Vivash
* @version 1.0, 30/04/01
*/
public class BooleanExpressionEditor extends JFrame implements ActionListener, ChangeListener {

	private static final String OR_BEFORE	= "orBefore";
	private static final String OR_AFTER	= "orAfter";
	private static final String AND_BEFORE	= "andBefore";
	private static final String AND_AFTER	= "andAfter";

	private static final String DELETE		= "delete";
	private static final String SWAP		= "swap";


	private Color selectionColor = new Color(190, 170, 250);

	private BooleanComparable rootExpression = null;

	//The action descriptor that has currently been selected on the toolbar
	private ActionDescriptor toolbarSelection = null;

	private JScrollPane scroller = null;
	private ExpressionViewer viewer = null;
	private ScrollingButtonPanel[] comparatorPanel 	= null;
	private JTabbedPane tabPane 					= null;
	private PropertiesPanel propertiesPanel 		= new PropertiesPanel();
	private BooleanExpressionEditor editor			= null;

	private ExpressionIcon selected = null;
	private ExpressionIcon rootIcon = null;

	private static final int ADD = 0;
	private static final int SELECT = 1;

	private int editType = SELECT;
	
	private Property whereBound = null;

	private ActionDescriptor[] comparatorDescriptors = null;

	public BooleanExpressionEditor(BooleanComparable comparable, Property whereBound) {
		super("Boolean Expression Editor");

		rootExpression = comparable;
		comparatorDescriptors = PIY.getInstance().getComparators();
		editor = this;
		this.whereBound = whereBound;
		
		
		getContentPane().setLayout(new BorderLayout());

		JPanel topPanel = new JPanel() {
			public void paint(Graphics g) {
				super.paint(g);
				g.setColor(getBackground().darker());
				g.drawLine(60,2,60,getHeight()-8);
				g.setColor(getBackground().brighter());
				g.drawLine(61,2,61,getHeight()-8);
			}		
		};
		
		topPanel.setLayout(new BorderLayout());

		//---- Set up toolbar buttons -------
		JPanel toolbarButtons = new JPanel();

		toolbarButtons.setLayout(null);
		toolbarButtons.setPreferredSize(new Dimension(120,60));
		
		String sep = File.separator;
		String images = "piy" + sep + "images" + sep;

		FloatingButton andBefore = new FloatingButton(new ImageIcon(images + "insertbefore.gif").getImage(), AND_BEFORE, false);
		andBefore.addActionListener(this);
		andBefore.setBounds(4, 6, 22, 22);
		andBefore.setToolTipText("Insert AND before");

		FloatingButton andAfter = new FloatingButton(new ImageIcon(images + "insertafter.gif").getImage(), AND_AFTER, false);
		andAfter.addActionListener(this);
		andAfter.setBounds(30, 6, 22, 22);
		andAfter.setToolTipText("Insert AND after");

		FloatingButton orBefore = new FloatingButton(new ImageIcon(images + "orbefore.gif").getImage(), OR_BEFORE, false);
		orBefore.addActionListener(this);
		orBefore.setBounds(4, 34, 22, 22);
		orBefore.setToolTipText("Insert OR above");

		FloatingButton orAfter = new FloatingButton(new ImageIcon(images + "orafter.gif").getImage(), OR_AFTER, false);
		orAfter.addActionListener(this);
		orAfter.setBounds(30, 34, 22, 22);
		orAfter.setToolTipText("Insert OR below");

		FloatingButton delete = new FloatingButton(new ImageIcon(images + "bin.gif").getImage(), DELETE, false);
		delete.addActionListener(this);
		delete.setBounds(64, 20, 22, 22);
		delete.setToolTipText("Delete Selected");

		FloatingButton swap = new FloatingButton(new ImageIcon(images + "swap.gif").getImage(), SWAP, false);
		swap.addActionListener(this);
		swap.setBounds(90, 20, 22, 22);
		swap.setToolTipText("Swap Order");

		toolbarButtons.add(andBefore);
		toolbarButtons.add(andAfter);
		toolbarButtons.add(orBefore);
		toolbarButtons.add(orAfter);

		toolbarButtons.add(delete);
		toolbarButtons.add(swap);


		//------ Set up comparator buttons panel -----
		tabPane = new JTabbedPane();
		ArrayList collections = sortCategories();
		
		comparatorPanel = new ScrollingButtonPanel[collections.size()];

		FloatingButton toolButton		= null;
		ActionDescriptor[] descriptors	= null;
		
		for (int i=0; i<collections.size(); i++) {
			descriptors = (ActionDescriptor[])collections.get(i);
			comparatorPanel[i] = new ScrollingButtonPanel(descriptors.length, 26, 26, 4);
			tabPane.addTab(descriptors[0].getCategory(), comparatorPanel[i]);
			comparatorPanel[i].addChangeListener(this);

			for (int j=0; j<descriptors.length; j++) {
				comparatorPanel[i].addButton(toolButton = new FloatingButton(descriptors[j].getIcon(), ""+j, true));

				//where the action descriptor is located in the actionDescriptors array
				int num = findDescriptor(descriptors[j]);
				toolButton.setIdentifier(num);

				toolButton.setToolTipText(descriptors[j].getName());
			}
		}
		
		//Move the "General" tab to be the first tab in the pane
		int posOfGeneral = tabPane.indexOfTab("General");
		if (posOfGeneral != -1) {
			if (posOfGeneral != 0) { 
				Component generalPanel = tabPane.getComponentAt(posOfGeneral);
				tabPane.removeTabAt(posOfGeneral);
				tabPane.insertTab("General", null, generalPanel, null, 0);
			}
		}
		
		
		topPanel.add(toolbarButtons, BorderLayout.WEST);
		topPanel.add(tabPane, BorderLayout.CENTER);

		JPanel padding = new JPanel();
		padding.setPreferredSize(new Dimension(0,8));
		topPanel.add(padding, BorderLayout.SOUTH);

//		propertiesPanel = new JPanel();
		propertiesPanel.setPreferredSize(new Dimension(180,100));
		propertiesPanel.setMaximumSize(new Dimension(400,100));
		propertiesPanel.setMinimumSize(new Dimension(50,100));

		viewer = new ExpressionViewer();
		scroller = new JScrollPane(viewer);

		JSplitPane bottomPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, propertiesPanel, scroller);

		propertiesPanel.setPreferredSize(new Dimension(180,100));

		getContentPane().add(topPanel, BorderLayout.NORTH);
		getContentPane().add(bottomPanel, BorderLayout.CENTER);

		setSize(400,300);
	}
		
	/**
	* Find the specified Descriptor's location in the comparatorDescriptors array
	* @param descriptor the descriptor to search for
	* @return the descriptor's location in the comparatorDescriptors array, or -1 if it was not found
	*/
	private int findDescriptor(ActionDescriptor descriptor) {
		for (int i=0; i<comparatorDescriptors.length; i++) 
			if (descriptor == comparatorDescriptors[i])
				return i;

		return -1;
	}			
	
	/**
	* Retrieve the ActionDescriptor for a particular comparator class type.
	* @param comparator the class of the comparator whose action descriptor is required
	* @return the action descriptor of the specified comparator class, or null if an
	* an appropriate descriptor was not found
	*/
	protected ActionDescriptor getDescriptor(Class comparator) {
		//The NullAction will not be present in the descriptor array
		if (comparator == NullComparator.class) return NullComparatorDescriptor.getInstance();

		for (int i=0; i<comparatorDescriptors.length; i++)
			if (comparatorDescriptors[i].getDescribedClass() == comparator)
				return comparatorDescriptors[i];
	
		return null;
	}

	/**
	* Selects the specified icon, deselcting the last one.
	* @param icon the ExpressionIcon to select
	*/
	protected void select(ExpressionIcon icon) {

		if (selected != null) selected.setBackground(Color.white);
		selected = icon;
		if (selected != null) selected.setBackground(selectionColor);
		viewer.repaint();
		
		propertiesPanel.setup(icon == null ? null : icon.getComparable());
	}


	//----- ChangeListener method ------------
	private boolean editting = false;
	public void stateChanged(ChangeEvent e) {
		if (!editting) {
			ScrollingButtonPanel inside = (ScrollingButtonPanel)tabPane.getSelectedComponent();
			int pos = inside.getSelectedIndex();
		
			editting = true;
			//Clear selections on other tabs now
			for (int i=0; i<comparatorPanel.length; i++) 
				if (comparatorPanel[i] != inside) comparatorPanel[i].clearSelection();
			
			//TO DO!!!! Get the action descriptor that was selected
			if (pos == -1) {
				toolbarSelection = null;
			} else {
				FloatingButton button = (FloatingButton)inside.getSelectedButton();
				toolbarSelection = comparatorDescriptors[button.getIdentifier()];
			}

			
			editting = false;
			
			if (pos == -1) editType = SELECT;
			else editType = ADD;
		}
	}

	
	/**
	* Takes the comparator descriptors, and sorts them into a collection of arrays - each array contains
	* descriptors of comparators in the same category.  So sorts out all of the string comparators from 
	* the files comparators, for example.  Each entry in the array list returned is an ActionDescriptor[].
	* <p>
	* <b>This method needs refactoring.</b> This method is the same (virtually) as the sortCategories
	* method in the ActionListEditor.  Maybe it could be moved to a PIYUtilities class.
	* @return a collection of ActionDescriptor arrays, with each array containing descriptors in the
	* same category.
	*/
	private ArrayList sortCategories() {
		//generate a map from each category name to the number of actions in that category
		//ie categoryName(String) -> Count(Inteeger)
		HashMap nameToCount = new HashMap(comparatorDescriptors.length);
		Integer num = null;
	
		for (int i=0; i<comparatorDescriptors.length; i++) {
			num = (Integer)nameToCount.get(comparatorDescriptors[i].getCategory());
		
			if (num == null) //category name doesn't yet exist
				num = new Integer(1);
			else 
				num = new Integer(num.intValue() + 1);
			
			nameToCount.put(comparatorDescriptors[i].getCategory(), num);
		}
	
		//Now construct each array and store it in the arraylist to return.
		//We could return an array of ActionDescriptor arrays, but I think that's a bit
		//too confusing
		ArrayList toReturn = new ArrayList(nameToCount.size());
		ActionDescriptor[] array = null;
		String currentName = null;
		int arrayCounter = 0;
	
		//Iterate over each named category
		Iterator nameIterator = nameToCount.keySet().iterator();
		while (nameIterator.hasNext()) {
			currentName = (String)nameIterator.next();
			
			array = new ActionDescriptor[((Integer)nameToCount.get(currentName)).intValue()];
			arrayCounter = 0;
			for (int j=0; j<comparatorDescriptors.length; j++) {
				if (comparatorDescriptors[j].getCategory().equals(currentName)) {
					array[arrayCounter] = comparatorDescriptors[j];
					arrayCounter++;
				}
			}
			
			toReturn.add(array);
		}
		
		return toReturn;
	}
	
	public boolean getNegate() { return selected == null ? false : selected.getComparable().getNegate(); }
	public void setNegate(boolean negate) {
		if (selected == null) return;		
		selected.getComparable().setNegate(negate);
		negate(selected);
	}
	protected void negate(ExpressionIcon icon) {
		icon.setBorder(new LineBorder(icon.getComparable().getNegate() ? Color.red : Color.black, 1));
	}



	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();
		
		if (command == AND_BEFORE || command == OR_BEFORE) {
			ExpressionIcon parentIcon = selected.getParentIcon();

			if (parentIcon == null) {
				rootExpression = new BooleanExpression();
				((BooleanExpression)rootExpression).setFirst(new NullComparator());
				((BooleanExpression)rootExpression).setSecond(selected.getComparable());
				whereBound.setValue(rootExpression);
				if (command == OR_BEFORE) ((BooleanExpression)rootExpression).setAnd(false);
				rootIcon.setup(rootExpression, null);
			} else {
				BooleanExpression ex = new BooleanExpression();
				ex.setFirst(new NullComparator());
				ex.setSecond(selected.getComparable());				

				if (command == OR_BEFORE) ex.setAnd(false);
			
				if (((BooleanExpression)parentIcon.getComparable()).getFirst() == selected.getComparable()) ((BooleanExpression)parentIcon.getComparable()).setFirst(ex);
				else ((BooleanExpression)parentIcon.getComparable()).setSecond(ex);
				rootIcon.setup(rootExpression, null);					
			}	
		} else if (command == AND_AFTER || command == OR_AFTER) {
			ExpressionIcon parentIcon = selected.getParentIcon();
			if (parentIcon == null) {
				rootExpression = new BooleanExpression();
				((BooleanExpression)rootExpression).setSecond(new NullComparator());
				((BooleanExpression)rootExpression).setFirst(selected.getComparable());
				whereBound.setValue(rootExpression);
				if (command == OR_AFTER) ((BooleanExpression)rootExpression).setAnd(false);
				rootIcon.setup(rootExpression, null);
			} else {
				BooleanExpression ex = new BooleanExpression();
				ex.setSecond(new NullComparator());
				ex.setFirst(selected.getComparable());				
			
				if (command == OR_AFTER) ex.setAnd(false);

				if (((BooleanExpression)parentIcon.getComparable()).getFirst() == selected.getComparable()) ((BooleanExpression)parentIcon.getComparable()).setFirst(ex);
				else ((BooleanExpression)parentIcon.getComparable()).setSecond(ex);
				rootIcon.setup(rootExpression, null);					
			}			
		} else if (command == SWAP) {
			if ((selected != null) && (selected.getComparable() instanceof BooleanExpression)) {
				BooleanExpression toSwap = (BooleanExpression)selected.getComparable();
				if (toSwap instanceof BooleanExpression) {
					BooleanComparable temp = toSwap.getFirst();
					toSwap.setFirst(toSwap.getSecond());
					toSwap.setSecond(temp);
					selected.setup(selected.getComparable(), selected.getParentIcon());
				}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -