xiaoxia
8 years ago
1 changed files with 201 additions and 249 deletions
@ -1,303 +1,255 @@ |
|||||||
package com.fr.design.mainframe.widget; |
package com.fr.design.mainframe; |
||||||
|
|
||||||
/** |
import java.awt.Component; |
||||||
* Created by xiaxiang on 2016/9/30. |
import java.awt.event.MouseAdapter; |
||||||
*/ |
import java.awt.event.MouseEvent; |
||||||
import java.awt.*; |
import java.util.ArrayList; |
||||||
import java.awt.event.*; |
|
||||||
import javax.swing.*; |
import javax.swing.DropMode; |
||||||
import javax.swing.plaf.*; |
import javax.swing.JPopupMenu; |
||||||
import javax.swing.plaf.basic.*; |
import javax.swing.JTree; |
||||||
import javax.swing.plaf.metal.*; |
import javax.swing.tree.TreePath; |
||||||
import javax.swing.tree.*; |
import javax.swing.tree.TreeSelectionModel; |
||||||
|
|
||||||
import com.fr.design.designer.beans.*; |
import com.fr.design.constants.UIConstants; |
||||||
|
import com.fr.design.designer.beans.AdapterBus; |
||||||
|
import com.fr.design.designer.beans.ComponentAdapter; |
||||||
import com.fr.design.designer.beans.events.DesignerEditListener; |
import com.fr.design.designer.beans.events.DesignerEditListener; |
||||||
import com.fr.design.designer.beans.events.DesignerEvent; |
import com.fr.design.designer.beans.events.DesignerEvent; |
||||||
import com.fr.design.designer.creator.XCreator; |
import com.fr.design.designer.creator.*; |
||||||
import com.fr.design.gui.icontainer.UIScrollPane; |
import com.fr.design.designer.treeview.ComponentTreeCellRenderer; |
||||||
import com.fr.design.mainframe.ComponentTree; |
import com.fr.design.designer.treeview.ComponentTreeModel; |
||||||
import com.sun.java.swing.plaf.motif.*; |
import com.fr.stable.StringUtils; |
||||||
import com.sun.java.swing.plaf.windows.*; |
|
||||||
|
public class ComponentTree extends JTree { |
||||||
/** |
|
||||||
* 控件树下拉列表框 |
private FormDesigner designer; |
||||||
*/ |
private ComponentTreeModel model; |
||||||
public class UITreeComboBox extends JComboBox{ |
|
||||||
/** |
public ComponentTree(FormDesigner designer) { |
||||||
* 显示用的树 |
this.designer = designer; |
||||||
*/ |
this.setBackground(UIConstants.NORMAL_BACKGROUND); |
||||||
private ComponentTree tree; |
setRootVisible(true); |
||||||
|
setCellRenderer(new ComponentTreeCellRenderer()); |
||||||
public UITreeComboBox(ComponentTree componentTree){ |
getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); |
||||||
this.setTree(componentTree); |
this.setDragEnabled(false); |
||||||
tree.getDesigner().addDesignerEditListener(new TreeComboBoxDesignerEditAdapter()); |
this.setDropMode(DropMode.ON_OR_INSERT); |
||||||
// for(int i=0; i<tree.getRowCount(); i++)
|
this.setTransferHandler(new TreeTransferHandler()); |
||||||
// {
|
this.refreshTreeRoot(); |
||||||
// tree.expandRow(i);
|
addTreeSelectionListener(designer); |
||||||
// }
|
|
||||||
setPreferredSize(new Dimension(200, 20)); |
// this.addMouseListener(new MouseAdapter() {
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void mouseClicked(MouseEvent e) {
|
||||||
|
// if (e.isPopupTrigger()) {
|
||||||
|
// popupMenu(e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void mousePressed(MouseEvent e) {
|
||||||
|
// if (e.isPopupTrigger()) {
|
||||||
|
// popupMenu(e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void mouseReleased(MouseEvent e) {
|
||||||
|
// if (e.isPopupTrigger()) {
|
||||||
|
// popupMenu(e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
setEditable(true); |
||||||
|
} |
||||||
|
|
||||||
|
public FormDesigner getDesigner() { |
||||||
|
return designer; |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* 设置树 |
* 构造函数 |
||||||
* @param tree ComponentTree |
* |
||||||
|
* @param designer 设计界面组件 |
||||||
|
* @param model 构造JTree的model |
||||||
*/ |
*/ |
||||||
public void setTree(ComponentTree tree){ |
public ComponentTree(FormDesigner designer,ComponentTreeModel model) { |
||||||
this.tree = tree; |
this(designer); |
||||||
if(tree != null){ |
this.setModel(model); |
||||||
this.setSelectedItem(tree.getSelectionPath()); |
|
||||||
this.setRenderer(new UITreeComboBoxRenderer()); |
|
||||||
} |
|
||||||
this.updateUI(); |
|
||||||
} |
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** |
/** |
||||||
* 取得树 |
* 是否可编辑 |
||||||
* @return JTree |
* @param path 树路径 |
||||||
|
* @return 是则返回true |
||||||
*/ |
*/ |
||||||
public ComponentTree getTree(){ |
@Override |
||||||
return tree; |
public boolean isPathEditable(TreePath path) { |
||||||
|
Object object = path.getLastPathComponent(); |
||||||
|
if (object == designer.getRootComponent()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return super.isPathEditable(path); |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* 设置当前选择的树路径 |
* 将值转换为文本 |
||||||
* @param o Object |
* @param value 值 |
||||||
|
* @param selected 是否选中 |
||||||
|
* @param expanded 扩展 |
||||||
|
* @param leaf 是否叶子 |
||||||
|
* @param row 行 |
||||||
|
* @param hasFocus 是否焦点 |
||||||
|
* |
||||||
|
* @return 返回文本 |
||||||
*/ |
*/ |
||||||
public void setSelectedItem(Object o){ |
@Override |
||||||
tree.setSelectionPath((TreePath)o); |
public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { |
||||||
getModel().setSelectedItem(o); |
if (value != null && value instanceof XCreator) { |
||||||
} |
return ((XCreator) value).toData().getWidgetName(); |
||||||
|
|
||||||
public void updateUI(){ |
|
||||||
ComboBoxUI cui = (ComboBoxUI)UIManager.getUI(this); |
|
||||||
if(cui instanceof MetalComboBoxUI){ |
|
||||||
cui = new MetalJTreeComboBoxUI(); |
|
||||||
} else if(cui instanceof MotifComboBoxUI){ |
|
||||||
cui = new MotifJTreeComboBoxUI(); |
|
||||||
} else { |
} else { |
||||||
cui = new WindowsJTreeComboBoxUI(); |
return super.convertValueToText(value, selected, expanded, leaf, row, hasFocus); |
||||||
} |
|
||||||
setUI(cui); |
|
||||||
} |
|
||||||
|
|
||||||
// UI Inner classes -- one for each supported Look and Feel
|
|
||||||
class MetalJTreeComboBoxUI extends MetalComboBoxUI{ |
|
||||||
protected ComboPopup createPopup() { |
|
||||||
return new TreePopup(comboBox); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
class WindowsJTreeComboBoxUI extends WindowsComboBoxUI{ |
public void setAndScrollSelectionPath(TreePath treepath) { |
||||||
protected ComboPopup createPopup() { |
setSelectionPath(treepath); |
||||||
return new TreePopup(comboBox); |
scrollPathToVisible(treepath); |
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class MotifJTreeComboBoxUI extends MotifComboBoxUI{ |
|
||||||
protected ComboPopup createPopup() { |
|
||||||
return new TreePopup(comboBox); |
|
||||||
} |
|
||||||
} |
} |
||||||
|
|
||||||
|
// private void popupMenu(MouseEvent e) {
|
||||||
|
// TreePath path = this.getSelectionPath();
|
||||||
|
// if (path == null) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// Component component = (Component) path.getLastPathComponent();
|
||||||
|
// if (!(component instanceof XCreator)) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, (XCreator) component);
|
||||||
|
// JPopupMenu menu = adapter.getContextPopupMenu(e);
|
||||||
|
// menu.show(this, e.getX(), e.getY());
|
||||||
|
// }
|
||||||
|
|
||||||
/** |
/** |
||||||
* <p>Title: UITreeComboBoxRenderer</p> |
* 刷新 |
||||||
* <p>Description: 树形结构而来的DefaultListCellRenderer </p> |
|
||||||
*/ |
*/ |
||||||
class UITreeComboBoxRenderer extends DefaultListCellRenderer { |
public void refreshUI() { |
||||||
public Component getListCellRendererComponent(JList list, Object value, |
updateUI(); |
||||||
int index, boolean isSelected, boolean cellHasFocus){ |
|
||||||
if(tree != null && tree.getSelectedTreePath().length > 0){ |
|
||||||
TreePath path = tree.getSelectedTreePath()[0]; |
|
||||||
tree.setAndScrollSelectionPath(path); |
|
||||||
Object node = path.getLastPathComponent(); |
|
||||||
value = node; |
|
||||||
TreeCellRenderer r = tree.getCellRenderer(); |
|
||||||
JLabel lb = (JLabel)r.getTreeCellRendererComponent( |
|
||||||
tree, value, isSelected, false, false, index, |
|
||||||
cellHasFocus); |
|
||||||
return lb; |
|
||||||
} |
|
||||||
return super.getListCellRendererComponent(list, value, index, |
|
||||||
isSelected, cellHasFocus); |
|
||||||
} |
|
||||||
} |
} |
||||||
|
|
||||||
|
|
||||||
private class TreeComboBoxDesignerEditAdapter implements DesignerEditListener { |
|
||||||
|
|
||||||
@Override |
|
||||||
public void fireCreatorModified(DesignerEvent evt) { |
|
||||||
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_SELECTED) { |
|
||||||
TreePath[] paths = tree.getSelectedTreePath(); |
|
||||||
if (tree != null && paths.length > 0) { |
|
||||||
tree.setAndScrollSelectionPath(paths[0]); |
|
||||||
setSelectedItem(paths[0]); |
|
||||||
MenuSelectionManager.defaultManager().clearSelectedPath(); |
|
||||||
} |
|
||||||
|
|
||||||
} else if (evt.getCreatorEventID() == DesignerEvent.CREATOR_PASTED) { |
|
||||||
tree.refreshUI(); |
|
||||||
TreePath[] paths = tree.getSelectedTreePath(); |
|
||||||
if (tree != null && paths.length > 0) { |
|
||||||
tree.setAndScrollSelectionPath(paths[0]); |
|
||||||
setSelectedItem(paths[0]); |
|
||||||
MenuSelectionManager.defaultManager().clearSelectedPath(); |
|
||||||
} |
|
||||||
} else if (evt.getCreatorEventID() == DesignerEvent.CREATOR_CUTED) { |
|
||||||
tree.refreshUI(); |
|
||||||
setSelectedItem(null); |
|
||||||
MenuSelectionManager.defaultManager().clearSelectedPath(); |
|
||||||
} else { |
|
||||||
tree.refreshUI(); |
|
||||||
repaint(); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean equals(Object o) { |
public TreePath[] getSelectedTreePath() { |
||||||
return o.getClass() == this.getClass(); |
XCreator[] creators = designer.getSelectionModel().getSelection().getSelectedCreators(); |
||||||
|
TreePath[] paths = new TreePath[creators.length]; |
||||||
|
|
||||||
|
for (int i = 0; i < paths.length; i++) { |
||||||
|
paths[i] = buildTreePath(creators[i]); |
||||||
} |
} |
||||||
|
return paths; |
||||||
} |
} |
||||||
|
|
||||||
/** |
|
||||||
* 测试 |
|
||||||
*/ |
|
||||||
// public static void main(String args[]){
|
|
||||||
// JFrame frame = new JFrame("UITreeComboBox");
|
|
||||||
// final UITreeComboBox box = new UITreeComboBox(new ComponentTree(new FormDesigner()));
|
|
||||||
// box.setPreferredSize(new Dimension(300, 28));
|
|
||||||
// frame.getContentPane().add(box);
|
|
||||||
// frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
|
||||||
// frame.pack();
|
|
||||||
// frame.setVisible(true);
|
|
||||||
// }
|
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* <p>Title: UITreeComboBox</p> |
|
||||||
* <p>Description: TreePopup</p> |
|
||||||
*/ |
|
||||||
class TreePopup extends JPopupMenu implements ComboPopup{ |
|
||||||
protected UITreeComboBox comboBox; |
|
||||||
protected JScrollPane scrollPane; |
|
||||||
|
|
||||||
protected MouseMotionListener mouseMotionListener; |
|
||||||
protected MouseListener mouseListener; |
|
||||||
|
|
||||||
|
|
||||||
public void popupMenu(MouseEvent e) { |
/** |
||||||
TreePath path = comboBox.getTree().getSelectionPath(); |
*搜索指定名称的路径 |
||||||
if (path == null) { |
* |
||||||
return; |
* @param text 名称 |
||||||
} |
* @return 树路径 |
||||||
Component component = (Component) path.getLastPathComponent(); |
*/ |
||||||
if (!(component instanceof XCreator)) { |
public TreePath[] search(String text) { |
||||||
return; |
if (StringUtils.isNotEmpty(text)) { |
||||||
|
text = text.toLowerCase(); |
||||||
} |
} |
||||||
com.fr.design.designer.beans.ComponentAdapter adapter = AdapterBus.getComponentAdapter(comboBox.getTree().getDesigner(), (XCreator) component); |
ArrayList<XCreator> searchList = new ArrayList<XCreator>(); |
||||||
JPopupMenu menu = adapter.getContextPopupMenu(e); |
XLayoutContainer root = designer.getRootComponent(); |
||||||
menu.show(comboBox, e.getX(), e.getY()); |
searchFormRoot(root, searchList, text); |
||||||
} |
TreePath[] paths = new TreePath[searchList.size()]; |
||||||
|
|
||||||
public TreePopup(JComboBox comboBox){ |
for (int i = 0; i < paths.length; i++) { |
||||||
this.comboBox = (UITreeComboBox)comboBox; |
paths[i] = buildTreePath(searchList.get(i)); |
||||||
setLayout(new BorderLayout()); |
} |
||||||
setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled()); |
if(paths.length > 0) { |
||||||
JTree tree = this.comboBox.getTree(); |
setAndScrollSelectionPath(paths[0]); |
||||||
if(tree != null){ |
} else { |
||||||
scrollPane = new UIScrollPane(tree); |
setSelectionPath(); |
||||||
scrollPane.setBorder(BorderFactory.createEmptyBorder(0,2,0,0)); |
|
||||||
add(scrollPane, BorderLayout.CENTER); |
|
||||||
} |
} |
||||||
|
return paths; |
||||||
} |
} |
||||||
|
|
||||||
public void show() { |
|
||||||
updatePopup(); |
|
||||||
show(comboBox, 0, comboBox.getHeight()); |
|
||||||
comboBox.getTree().requestFocus(); |
|
||||||
} |
|
||||||
|
|
||||||
public void hide(){ |
private void setSelectionPath(){ |
||||||
setVisible(false); |
|
||||||
comboBox.firePropertyChange("popupVisible", true, false); |
|
||||||
} |
|
||||||
|
|
||||||
protected JList list = new JList(); |
/** |
||||||
public JList getList(){ |
* 不让传null参数,所以只有自己定义 |
||||||
return list; |
*/ |
||||||
|
super.setSelectionPath(null); |
||||||
|
clearSelection(); |
||||||
} |
} |
||||||
|
|
||||||
public MouseMotionListener getMouseMotionListener(){ |
private void searchFormRoot(XLayoutContainer container, ArrayList<XCreator> searchList, String text) { |
||||||
if(mouseMotionListener == null){ |
if (StringUtils.isEmpty(text)) { |
||||||
mouseMotionListener = new MouseMotionAdapter(){}; |
return; |
||||||
|
} |
||||||
|
for (int i = 0, size = container.getXCreatorCount(); i < size; i++) { |
||||||
|
XCreator creator = container.getXCreator(i); |
||||||
|
String xName = creator.toData().getWidgetName(); |
||||||
|
if (xName.toLowerCase().contains(text)) { |
||||||
|
searchList.add(creator); |
||||||
|
} |
||||||
|
if (creator instanceof XLayoutContainer) { |
||||||
|
searchFormRoot((XLayoutContainer) creator, searchList, text); |
||||||
|
} |
||||||
} |
} |
||||||
return mouseMotionListener; |
|
||||||
} |
|
||||||
|
|
||||||
public KeyListener getKeyListener(){ |
|
||||||
return null; |
|
||||||
} |
} |
||||||
|
|
||||||
public void uninstallingUI(){} |
|
||||||
|
|
||||||
/** |
/** |
||||||
* Implementation of ComboPopup.getMouseListener(). |
* 触发 |
||||||
* |
|
||||||
* @return a <code>MouseListener</code> or null |
|
||||||
* @see ComboPopup#getMouseListener |
|
||||||
*/ |
*/ |
||||||
public MouseListener getMouseListener(){ |
public void fireTreeChanged() { |
||||||
if(mouseListener == null){ |
designer.refreshDesignerUI(); |
||||||
mouseListener = new InvocationMouseHandler(); |
|
||||||
} |
|
||||||
return mouseListener; |
|
||||||
} |
|
||||||
|
|
||||||
protected void togglePopup(){ |
|
||||||
if(isVisible()){ |
|
||||||
hide(); |
|
||||||
} else{ |
|
||||||
show(); |
|
||||||
} |
|
||||||
} |
|
||||||
protected void updatePopup(){ |
|
||||||
setPreferredSize(new Dimension(comboBox.getSize().width, 200)); |
|
||||||
Object selectedObj = comboBox.getSelectedItem(); |
|
||||||
if(selectedObj != null){ |
|
||||||
TreePath tp = (TreePath)selectedObj; |
|
||||||
((UITreeComboBox)comboBox).getTree().setSelectionPath(tp); |
|
||||||
} |
|
||||||
} |
} |
||||||
|
|
||||||
protected class InvocationMouseHandler extends MouseAdapter{ |
/** |
||||||
public void mousePressed(MouseEvent e){ |
* 刷新 |
||||||
if(!SwingUtilities.isLeftMouseButton(e) || !comboBox.isEnabled()){ |
*/ |
||||||
return; |
public void refreshTreeRoot() { |
||||||
} |
model = new ComponentTreeModel(designer, designer.getTopContainer()); |
||||||
if(comboBox.isEditable()){ |
setModel(model); |
||||||
Component comp = comboBox.getEditor().getEditorComponent(); |
setDragEnabled(false); |
||||||
if((!(comp instanceof JComponent)) || |
setDropMode(DropMode.ON_OR_INSERT); |
||||||
((JComponent)comp).isRequestFocusEnabled()){ |
setTransferHandler(new TreeTransferHandler()); |
||||||
comp.requestFocus(); |
repaint(); |
||||||
} |
} |
||||||
} else if(comboBox.isRequestFocusEnabled()){ |
|
||||||
comboBox.requestFocus(); |
private TreePath buildTreePath(Component comp) { |
||||||
|
ArrayList<Component> path = new ArrayList<Component>(); |
||||||
|
Component parent = comp; |
||||||
|
|
||||||
|
while (parent != null) { |
||||||
|
XCreator creator = (XCreator) parent; |
||||||
|
path.add(0, parent); |
||||||
|
if (creator != comp ) { |
||||||
|
creator.notShowInComponentTree(path); |
||||||
} |
} |
||||||
togglePopup(); |
//绝对布局作为body的时候不显示自适应布局父层
|
||||||
} |
if (((XCreator) parent).acceptType(XWAbsoluteBodyLayout.class) |
||||||
|
&& (parent.getParent() != null) |
||||||
public void mouseClicked (MouseEvent e){ |
&& ((XCreator)parent.getParent()).acceptType(XWFitLayout.class)){ |
||||||
if (e.isMetaDown()) { |
parent = parent.getParent().getParent(); |
||||||
popupMenu(e); |
continue; |
||||||
} else { |
|
||||||
return; |
|
||||||
} |
} |
||||||
|
parent = parent.getParent(); |
||||||
} |
} |
||||||
|
Object[] components = path.toArray(); |
||||||
|
return new TreePath(components); |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
} |
|
Loading…
Reference in new issue