package com.vci.client.oq.ui; import java.awt.AlphaComposite; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceDragEvent; import java.awt.dnd.DragSourceDropEvent; import java.awt.dnd.DragSourceEvent; import java.awt.dnd.DragSourceListener; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.Timer; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableColumn; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; import org.jdesktop.swingx.JXTable; import org.jdesktop.swingx.decorator.HighlighterFactory; import com.vci.corba.omd.atm.AttribItem; import com.vci.corba.omd.ltm.LinkType; import com.vci.corba.omd.qtm.QTD; import com.vci.omd.constants.SystemAttribute; import com.vci.omd.objects.OtherInfo; import com.vci.client.omd.attribpool.ui.APClient; import com.vci.client.omd.provider.BtmProvider; import com.vci.client.omd.provider.LinkTypeProvider; import com.vci.client.ui.swing.VCISwingUtil; import com.vci.client.ui.table.CheckBoxEditor; import com.vci.client.ui.table.CheckBoxRenderer; import com.vci.common.qt.object.QTConstants; import com.vci.corba.common.VCIError; class QTDTree extends JTree implements DragGestureListener, DragSourceListener, DropTargetListener { /** * 查询模板定义 */ private QTD qtd; /** * */ private static final long serialVersionUID = 1L; BufferedImage ghostImage; private Rectangle2D ghostRect = new Rectangle2D.Float(); private Point ptOffset = new Point(); private Point lastPoint = new Point(); private TreePath lastPath; private Timer hoverTimer; DefaultMutableTreeNode sourceNode; private final String BTM = "btm"; private String direction = null; JPopupMenu menu = new JPopupMenu(); JMenuItem menuItem = new JMenuItem("添加系统属性"); DefaultMutableTreeNode sNode = null; public QTDTree(QTD qtd, String direction) { this.qtd = qtd; this.direction = direction; DragSource dragSource = DragSource.getDefaultDragSource(); dragSource.createDefaultDragGestureRecognizer(this, // component where // drag originates DnDConstants.ACTION_COPY_OR_MOVE, // actions this); // drag gesture recognizer menu.add(menuItem); setModel(createTreeModel()); addTreeExpansionListener(new TreeExpansionListener() { public void treeCollapsed(TreeExpansionEvent e) { } public void treeExpanded(TreeExpansionEvent e) { TreePath path = e.getPath(); if (path != null) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); } } }); this.setCellRenderer(new DefaultTreeCellRenderer() { public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); TreePath tp = tree.getPathForRow(row); if (tp != null) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) tp.getLastPathComponent(); if (node.isLeaf()) setIcon(VCISwingUtil.createImageIcon("attribute.png")); } return this; } }); this.addMouseListener(new MouseListener() { @Override public void mouseReleased(MouseEvent e) { Object sObj = getThis().getLastSelectedPathComponent(); if(sObj != null && sObj instanceof DefaultMutableTreeNode){ sNode = (DefaultMutableTreeNode)sObj; if(e.getButton() == MouseEvent.BUTTON3 && e.getClickCount() == 1){ if(!sNode.isRoot() && !sNode.isLeaf() ){ menu.show(e.getComponent(), e.getX(), e.getY()); } } } } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub } }); menuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { List list = getChildrenNames(sNode); List oppList = getOppSysAttNames(list); RefAttribDialog dialog = new RefAttribDialog(oppList); dialog.setVisible(true); if(dialog.closeByOK()){ List selAtts = dialog.getSelAtts(); String pName = (String)sNode.getLastLeaf().getUserObject(); pName = pName.substring(0, pName.indexOf(".")); for(String att : selAtts){ sNode.add(new DefaultMutableTreeNode(pName + "." + att)); } getThis().updateUI(); } } }); super.setScrollsOnExpand(true); // Set up a hover timer, so that a node will be automatically expanded // or collapsed // if the user lingers on it for more than a short time hoverTimer = new Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent e) { if (lastPath == null) { return; } if (getRowForPath(lastPath) == 0) return; // Do nothing if we are hovering over the root node if (isExpanded(lastPath)) collapsePath(lastPath); else expandPath(lastPath); } }); hoverTimer.setRepeats(false); // Set timer to one-shot mode this.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { int code = e.getKeyCode(); int modifiers = e.getModifiers(); if (code == 'v' || code == 'V') { System.out.println("find v"); System.out.println("modifiers:" + modifiers + "\t" + ((modifiers & KeyEvent.CTRL_MASK) != 0)); } if ((modifiers & KeyEvent.CTRL_MASK) != 0 && (code == 'v' || code == 'V')) { Transferable tr = Toolkit.getDefaultToolkit() .getSystemClipboard().getContents(null); TreePath path = getSelectionPath(); if (path == null) { return; } FileNode node = (FileNode) path.getLastPathComponent(); if (node.isDirectory()) { System.out.println("file cp"); try { List list = (List) (tr .getTransferData(DataFlavor.javaFileListFlavor)); Iterator iterator = list.iterator(); File parent = node.getFile(); while (iterator.hasNext()) { File f = (File) iterator.next(); cp(f, new File(parent, f.getName())); } node.reexplore(); } catch (Exception ioe) { ioe.printStackTrace(); } updateUI(); } } } }); } public void dragGestureRecognized(DragGestureEvent e) { // drag anything ... TreePath path = getLeadSelectionPath(); if (path == null) return; DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); sourceNode = node; // Work out the offset of the drag point from the TreePath bounding // rectangle origin Rectangle raPath = getPathBounds(path); Point ptDragOrigin = e.getDragOrigin(); ptOffset.setLocation(ptDragOrigin.x - raPath.x, ptDragOrigin.y - raPath.y); // Get the cell renderer (which is a JLabel) for the path being dragged int row = this.getRowForLocation(ptDragOrigin.x, ptDragOrigin.y); JLabel lbl = (JLabel) getCellRenderer().getTreeCellRendererComponent( this, // tree path.getLastPathComponent(), // value false, // isSelected (dont want a colored background) isExpanded(path), // isExpanded getModel().isLeaf(path.getLastPathComponent()), // isLeaf row, // row (not important for rendering) false // hasFocus (dont want a focus rectangle) ); lbl.setSize((int) raPath.getWidth(), (int) raPath.getHeight()); // <-- // The // layout // manager // would // normally // do // this // Get a buffered image of the selection for dragging a ghost image this.ghostImage = new BufferedImage((int) raPath.getWidth(), (int) raPath.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); Graphics2D g2 = ghostImage.createGraphics(); // Ask the cell renderer to paint itself into the BufferedImage g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.5f)); // Make the image ghostlike lbl.paint(g2); g2.dispose(); // this.getGraphics().drawImage(ghostImage, e.getDragOrigin().x, // e.getDragOrigin().y, this); e.startDrag(DragSource.DefaultMoveDrop, getFilename(), this); } public void dragDropEnd(DragSourceDropEvent e) { ghostImage = null; sourceNode = null; } public void dragEnter(DragSourceDragEvent e) { } public void dragExit(DragSourceEvent e) { if (!DragSource.isDragImageSupported()) { repaint(ghostRect.getBounds()); } } public void dragOver(DragSourceDragEvent e) { } public void dropActionChanged(DragSourceDragEvent e) { } public MTransferable getFilename() { TreePath path = getLeadSelectionPath(); DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); String abName = (String) node.getUserObject(); MTransferable mt = new MTransferable(abName); return mt; } private DefaultTreeModel createTreeModel(){ String[] abNames = qtd.abNames; DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(qtd.name); DefaultTreeModel treeModel = new DefaultTreeModel(rootNode); for(int i = 0; i < abNames.length; i++){ //TODO String abName = abNames[i]; if(direction != null){ if(direction.equals(QTConstants.DIRECTION_POSITIVE)){ abName = "T_OID." + abName; }else if(direction.equals(QTConstants.DIRECTION_OPPOSITE)){ abName = "F_OID." + abName; } } DefaultMutableTreeNode node = new DefaultMutableTreeNode(abName); addNode(rootNode, node); } return treeModel; } private void addNode(DefaultMutableTreeNode pNode, DefaultMutableTreeNode node){ if(pNode.getPath().length >= 4){ return; } pNode.add(node); if(node.getPath().length >= 4){ return; } String abName = (String) node.getUserObject(); //取node上的最后一个属性名 if(abName.contains(".")){ abName = abName.substring(abName.lastIndexOf(".") + 1); } if(SystemAttribute.sysAttList().contains(abName.toUpperCase())){ return; } AttribItem abItem = null; try { abItem = APClient.getService().getAttribItemByName(abName); String other = abItem.other; // String btmName = ApProvider.getInstance().getOtherValueByType(other, BTM); OtherInfo otherInfo = OtherInfo.getOtherInfoByText(other); int refFlag = otherInfo.getRefFlag(); String refTypeName = otherInfo.getRefTypeName(); if(refFlag != -1){ //参照业务类型 if(refFlag == 0){ //pName: 为参照属性名加上路径 String pName = node.getUserObject() + "."; String[] abNames = BtmProvider.getInstance().getAbNames(refTypeName); for(int i = 0; i < abNames.length; i++){ String abName_ = abNames[i]; DefaultMutableTreeNode node_ = new DefaultMutableTreeNode(pName + abName_); addNode(node, node_); } //系统属性ID,NAME,DESCRIPTION for (int i = 0; i < SystemAttribute.bosysAttList().size(); i++) { addNode(node, new DefaultMutableTreeNode(pName + SystemAttribute.bosysAttList().get(i))); } //参照链接类型 }else if(refFlag == 1){ //pName: 为参照属性名加上路径 String pName = node.getUserObject() + "."; LinkType link = null; try { link = LinkTypeProvider.getInstance().getLinkTypeByName(refTypeName); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } if(link != null){ String[] abNames = LinkTypeProvider.getInstance().getAbNames(link ); for(int i = 0; i < abNames.length; i++){ String abName_ = abNames[i]; DefaultMutableTreeNode node_ = new DefaultMutableTreeNode(pName + abName_); addNode(node, node_); } //系统属性ID,NAME,DESCRIPTION for (int i = 0; i < SystemAttribute.losysAttList().size(); i++) { addNode(node, new DefaultMutableTreeNode(pName + SystemAttribute.losysAttList().get(i))); } } } } } catch (VCIError e) { e.printStackTrace(); } } public void dragEnter(DropTargetDragEvent dtde) { } public void dragOver(DropTargetDragEvent dtde) { Point pt = dtde.getLocation(); if (pt.equals(lastPoint)) { return; } if (ghostImage != null) { Graphics2D g2 = (Graphics2D) getGraphics(); // If a drag image is not supported by the platform, then draw my // own drag image if (!DragSource.isDragImageSupported()) { paintImmediately(ghostRect.getBounds()); // Rub out the last // ghost image and cue // line // And remember where we are about to draw the new ghost image ghostRect.setRect(pt.x - ptOffset.x, pt.y - ptOffset.y, ghostImage.getWidth(), ghostImage.getHeight()); g2.drawImage((ghostImage), AffineTransform .getTranslateInstance(ghostRect.getX(), ghostRect.getY()), null); } } TreePath path = getClosestPathForLocation(pt.x, pt.y); if (!(path == lastPath)) { lastPath = path; hoverTimer.restart(); } } public void dropActionChanged(DropTargetDragEvent dtde) { } public void drop(DropTargetDropEvent e) { try { DataFlavor stringFlavor = DataFlavor.stringFlavor; Transferable tr = e.getTransferable(); TreePath path = this.getPathForLocation(e.getLocation().x, e.getLocation().y); if (path == null) { e.rejectDrop(); return; } FileNode node = (FileNode) path.getLastPathComponent(); if (e.isDataFlavorSupported(DataFlavor.javaFileListFlavor) && node.isDirectory()) { e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); System.out.println("file cp"); List list = (List) (e.getTransferable() .getTransferData(DataFlavor.javaFileListFlavor)); Iterator iterator = list.iterator(); File parent = node.getFile(); while (iterator.hasNext()) { File f = (File) iterator.next(); cp(f, new File(parent, f.getName())); } node.reexplore(); e.dropComplete(true); this.updateUI(); } else if (e.isDataFlavorSupported(stringFlavor) && node.isDirectory()) { String filename = (String) tr.getTransferData(stringFlavor); if (filename.endsWith(".txt") || filename.endsWith(".java") || filename.endsWith(".jsp") || filename.endsWith(".html") || filename.endsWith(".htm")) { e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); File f = new File(filename); if (f.exists()) { f.renameTo(new File(node.getFile(), f.getName())); node.reexplore(); ((FileNode) sourceNode.getParent()).remove(sourceNode); e.dropComplete(true); this.updateUI(); } else { e.rejectDrop(); } } else { e.rejectDrop(); } } else { e.rejectDrop(); } } catch (IOException ioe) { ioe.printStackTrace(); } catch (UnsupportedFlavorException ufe) { ufe.printStackTrace(); } finally { ghostImage = null; this.repaint(); } } private void cp(File src, File dest) throws IOException { if (src.isDirectory()) { if (!dest.exists()) { boolean ret = dest.mkdir(); if (ret == false) return; } File[] fs = src.listFiles(); for (int i = 0; i < fs.length; i++) { cp(fs[i], new File(dest, fs[i].getName())); } return; } byte[] buf = new byte[1024]; FileInputStream in = new FileInputStream(src); FileOutputStream out = new FileOutputStream(dest); int len; try { while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } } finally { in.close(); out.close(); } } public void dragExit(DropTargetEvent dte) { } private QTDTree getThis(){ return this; } /** * 获取选择节点的子节点名集合 * @param sNode2 * @return */ private List getChildrenNames(DefaultMutableTreeNode sNode2) { List list = new ArrayList(); Enumeration children = sNode2.children(); while(children.hasMoreElements()){ DefaultMutableTreeNode n = (DefaultMutableTreeNode) children.nextElement(); String attName = (String)n.getUserObject(); list.add(attName.substring(attName.lastIndexOf(".") + 1)); } return list; } /** * 获取不在list中的系统属性 */ private List getOppSysAttNames(List list){ List list_ = new ArrayList(); String[] sysAtts = BtmProvider.getInstance().getSysAttributes(); for(String sysAtt : sysAtts){ if(!list.contains(sysAtt.toUpperCase())){ list_.add(sysAtt.toUpperCase()); } } return list_; } } class FileNode extends DefaultMutableTreeNode { private boolean explored = false; public FileNode(File file) { setUserObject(file); } public boolean getAllowsChildren() { return isDirectory(); } public boolean isLeaf() { return !isDirectory(); } public File getFile() { return (File) getUserObject(); } public boolean isExplored() { return explored; } public boolean isDirectory() { File file = getFile(); return file.isDirectory(); } public String toString() { File file = (File) getUserObject(); String filename = file.toString(); int index = filename.lastIndexOf(File.separator); return (index != -1 && index != filename.length() - 1) ? filename .substring(index + 1) : filename; } public void explore() { if (!isDirectory()) return; if (!isExplored()) { File file = getFile(); File[] children = file.listFiles(); for (int i = 0; i < children.length; ++i) { if (children[i].isDirectory()) add(new FileNode(children[i])); } for (int i = 0; i < children.length; ++i) { if (!children[i].isDirectory()) add(new FileNode(children[i])); } explored = true; } } public void reexplore() { this.removeAllChildren(); explored = false; explore(); } } /** * 选择参照的系统属性 * @author zhouhui * */ class RefAttribDialog extends JDialog{ /** * */ private static final long serialVersionUID = 8368196568148843089L; private static final int ROW_HEIGHT = 30; private static final int TABLE_HEADER_HEIGHT = 25; private String[] tableHeader = new String[]{"","属性名"}; private List list = null; private JPanel northPanel; private JPanel centerPanel; private JPanel southPanel; private JScrollPane scrollPane; private TableModel_ tableModel; private JXTable table; private JButton btnOK; private JButton btnCancel; private boolean closeByOK = false; public RefAttribDialog(List list_){ this.list = list_; initUI(); initTable(); addListener(); } private void initUI(){ this.setTitle("查询结果"); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); this.setSize(screenSize.width/2, screenSize.height/2); this.setModal(true); this.setLocationRelativeTo(null); this.setResizable(false); this.setLayout(new BorderLayout(0, 0)); northPanel = new JPanel(); centerPanel = new JPanel(); southPanel = new JPanel(); this.add(northPanel, BorderLayout.NORTH); this.add(centerPanel, BorderLayout.CENTER); this.add(southPanel, BorderLayout.SOUTH); centerPanel.setLayout(new BorderLayout(5, 5)); scrollPane = new JScrollPane(); centerPanel.add(scrollPane, BorderLayout.CENTER); tableModel = new TableModel_(); tableModel.setColumnIdentifiers(tableHeader); table = new JXTable(tableModel); TableColumn column = table.getColumn(0); column.setCellEditor(new CheckBoxEditor(new JCheckBox())); column.setCellRenderer(new CheckBoxRenderer()); table.setRowHeight(ROW_HEIGHT); table.setHorizontalScrollEnabled(true); table.setHighlighters(HighlighterFactory.createAlternateStriping()); //排序后,引起其他页面的数据不显示 table.setSortable(true); //设置表头高度 JTableHeader tableHeader = table.getTableHeader(); Dimension size = tableHeader.getPreferredSize(); size.height = TABLE_HEADER_HEIGHT; tableHeader.setPreferredSize(size); scrollPane.setViewportView(table); southPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); btnOK = new JButton("确定"); btnCancel = new JButton("取消"); southPanel.add(btnOK); southPanel.add(btnCancel); } private void initTable(){ table.setEditable(true); table.removeAll(); tableModel.setRowCount(list.size()); //重新设置table的Cell的可编辑性 tableModel.setInitFlag(false); int i; for(i = 0; i < table.getRowCount(); i++){ table.setValueAt(new JCheckBox(), i, 0); table.setValueAt(list.get(i), i, 1); } //重新设置table的Cell的可编辑性 tableModel.setInitFlag(true); } private void addListener() { btnOK.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { closeByOK = true; dispose(); } }); btnCancel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { dispose(); } }); } public List getSelAtts(){ List list_ = new ArrayList(); int i; for(i = 0; i < table.getRowCount(); i++){ if(((JCheckBox)table.getValueAt(i, 0)).isSelected()){ list_.add((String) table.getValueAt(i, 1)); } } return list_; } public boolean closeByOK(){ return closeByOK ; } /** * 特殊设置checkbox的可编辑性 * @author zhouhui * */ class TableModel_ extends DefaultTableModel{ /** * */ private static final long serialVersionUID = -7123910865180265533L; public boolean initedFlag = false; /** * 初始table的每一个表格都是可以编辑的; * 但当数据设置后, 只留下checkBox还可以编辑 */ public boolean isCellEditable(int row, int column){ if(initedFlag){ if(column == 0){ return true; }else{ return false; } } return true; } /** * @param flag */ public void setInitFlag(boolean flag){ this.initedFlag = flag; } } }