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