From 0ebd6831eb0ebcb1a1734b8700c843b63cf6e8e3 Mon Sep 17 00:00:00 2001 From: "yaoh.wu" Date: Fri, 18 May 2018 20:21:32 +0800 Subject: [PATCH] file tree --- .../design/remote/ui/AuthorityEditorPane.java | 15 +++- .../tree/FileAuthorityTreeCellRenderer.java | 83 +++++++++++++++++++ .../ui/tree/FileAuthorityTreeLabel.java | 69 +++++++++++++++ .../remote/ui/tree/FileAuthorityTreeNode.java | 23 +++-- ...ileAuthorityTreeNodeSelectionListener.java | 27 ++++++ 5 files changed, 208 insertions(+), 9 deletions(-) create mode 100644 designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeCellRenderer.java create mode 100644 designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeLabel.java create mode 100644 designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeNodeSelectionListener.java diff --git a/designer-base/src/com/fr/design/remote/ui/AuthorityEditorPane.java b/designer-base/src/com/fr/design/remote/ui/AuthorityEditorPane.java index 9c83da4d2..b61f9250c 100644 --- a/designer-base/src/com/fr/design/remote/ui/AuthorityEditorPane.java +++ b/designer-base/src/com/fr/design/remote/ui/AuthorityEditorPane.java @@ -1,9 +1,13 @@ package com.fr.design.remote.ui; +import com.fr.base.FRContext; import com.fr.design.beans.BasicBeanPane; +import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.remote.RemoteDesignAuthority; +import com.fr.design.remote.ui.tree.FileAuthorityTree; +import com.fr.file.filetree.IOFileNodeFilter; import javax.swing.BorderFactory; import java.awt.BorderLayout; @@ -12,10 +16,17 @@ public class AuthorityEditorPane extends BasicBeanPane { private UILabel label = new UILabel(); + private FileAuthorityTree tree = new FileAuthorityTree(); + + public AuthorityEditorPane() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); this.setBorder(BorderFactory.createEmptyBorder()); - this.add(label, BorderLayout.CENTER); + this.add(label, BorderLayout.NORTH); + IOFileNodeFilter filter = new IOFileNodeFilter(new String[]{".cpt", ".class", ".frm", ".form"}); + tree.setFileNodeFilter(filter); + this.add(new UIScrollPane(tree), BorderLayout.CENTER); + tree.refreshEnv(FRContext.getCurrentEnv()); } @Override @@ -26,10 +37,12 @@ public class AuthorityEditorPane extends BasicBeanPane { @Override public void populateBean(RemoteDesignAuthority ob) { label.setText(ob.getName()); + // todo 选中树的结点 } @Override public RemoteDesignAuthority updateBean() { + // todo 更新权限信息 return new RemoteDesignAuthority(); } } diff --git a/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeCellRenderer.java b/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeCellRenderer.java new file mode 100644 index 000000000..84ed6c723 --- /dev/null +++ b/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeCellRenderer.java @@ -0,0 +1,83 @@ +package com.fr.design.remote.ui.tree; + + +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import javax.swing.JTree; +import javax.swing.UIManager; +import javax.swing.plaf.ColorUIResource; +import javax.swing.tree.TreeCellRenderer; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; + +public class FileAuthorityTreeCellRenderer extends JPanel implements TreeCellRenderer { + + + protected JCheckBox check; + protected FileAuthorityTreeLabel label; + + public FileAuthorityTreeCellRenderer() { + setLayout(null); + add(check = new JCheckBox()); + add(label = new FileAuthorityTreeLabel()); + check.setBackground(UIManager.getColor("Tree.textBackground")); + label.setForeground(UIManager.getColor("Tree.textForeground")); + } + + /** + * 返回的是一个JPanel对象,该对象中包含一个JCheckBox对象 + * 和一个JLabel对象。并且根据每个结点是否被选中来决定JCheckBox + * 是否被选中。 + */ + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, + boolean selected, boolean expanded, boolean leaf, int row, + boolean hasFocus) { + String stringValue = tree.convertValueToText(value, selected, expanded, leaf, row, hasFocus); + setEnabled(tree.isEnabled()); + check.setSelected(((FileAuthorityTreeNode) value).isSelected()); + label.setFont(tree.getFont()); + label.setText(stringValue); + label.setSelected(selected); + label.setFocus(hasFocus); + if (leaf) + label.setIcon(UIManager.getIcon("Tree.leafIcon")); + else if (expanded) + label.setIcon(UIManager.getIcon("Tree.openIcon")); + else + label.setIcon(UIManager.getIcon("Tree.closedIcon")); + + return this; + } + + @Override + public Dimension getPreferredSize() { + Dimension dCheck = check.getPreferredSize(); + Dimension dLabel = label.getPreferredSize(); + return new Dimension(dCheck.width + dLabel.width, dCheck.height < dLabel.height ? dLabel.height : dCheck.height); + } + + @Override + public void doLayout() { + Dimension dCheck = check.getPreferredSize(); + Dimension dLabel = label.getPreferredSize(); + int yCheck = 0; + int yLabel = 0; + if (dCheck.height < dLabel.height) + yCheck = (dLabel.height - dCheck.height) / 2; + else + yLabel = (dCheck.height - dLabel.height) / 2; + check.setLocation(0, yCheck); + check.setBounds(0, yCheck, dCheck.width, dCheck.height); + label.setLocation(dCheck.width, yLabel); + label.setBounds(dCheck.width, yLabel, dLabel.width, dLabel.height); + } + + @Override + public void setBackground(Color color) { + if (color instanceof ColorUIResource) + color = null; + super.setBackground(color); + } +} diff --git a/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeLabel.java b/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeLabel.java new file mode 100644 index 000000000..de4e8cf2d --- /dev/null +++ b/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeLabel.java @@ -0,0 +1,69 @@ +package com.fr.design.remote.ui.tree; + + +import javax.swing.Icon; +import javax.swing.JLabel; +import javax.swing.UIManager; +import javax.swing.plaf.ColorUIResource; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; + +public class FileAuthorityTreeLabel extends JLabel { + private boolean isSelected; + private boolean hasFocus; + + public FileAuthorityTreeLabel() { + } + + @Override + public void setBackground(Color color) { + if (color instanceof ColorUIResource) { + color = null; + } + super.setBackground(color); + } + + @Override + public void paint(Graphics g) { + String str; + if ((str = getText()) != null) { + if (0 < str.length()) { + if (isSelected) { + g.setColor(UIManager.getColor("Tree.selectionBackground")); + } else { + g.setColor(UIManager.getColor("Tree.textBackground")); + } + Dimension d = getPreferredSize(); + int imageOffset = 0; + Icon currentIcon = getIcon(); + if (currentIcon != null) { + imageOffset = currentIcon.getIconWidth() + Math.max(0, getIconTextGap() - 1); + } + g.fillRect(imageOffset, 0, d.width - 1 - imageOffset, d.height); + if (hasFocus) { + g.setColor(UIManager.getColor("Tree.selectionBorderColor")); + g.drawRect(imageOffset, 0, d.width - 1 - imageOffset, d.height - 1); + } + } + } + super.paint(g); + } + + @Override + public Dimension getPreferredSize() { + Dimension retDimension = super.getPreferredSize(); + if (retDimension != null) { + retDimension = new Dimension(retDimension.width + 3, retDimension.height); + } + return retDimension; + } + + public void setSelected(boolean isSelected) { + this.isSelected = isSelected; + } + + public void setFocus(boolean hasFocus) { + this.hasFocus = hasFocus; + } +} diff --git a/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeNode.java b/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeNode.java index aed486730..ddd8ed22b 100644 --- a/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeNode.java +++ b/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeNode.java @@ -48,10 +48,12 @@ public class FileAuthorityTreeNode extends DefaultMutableTreeNode { setStatus(selected ? Status.SELECTED : Status.UNSELECTED); } + public void setStatus(Status status) { this.status = status; switch (status) { case SELECTED: + // 标记为选中 // 向下 // 如果选中,则所有的子结点都要选中 if (children != null) { @@ -88,6 +90,7 @@ public class FileAuthorityTreeNode extends DefaultMutableTreeNode { } break; case UNSELECTED: + //标记为未被选中 // 向下 // 子结点都要取消选中 if (children != null) { @@ -125,17 +128,21 @@ public class FileAuthorityTreeNode extends DefaultMutableTreeNode { } break; case INDETERMINATE: - // todo 标记为未知 - - + // 标记为未知 + // 向下 + // 不做改动 + // 向上 + // 需要将父结点标记为未知 + if (parent != null) { + FileAuthorityTreeNode pNode = (FileAuthorityTreeNode) parent; + if (!pNode.isIndeterminate()) { + pNode.setStatus(Status.INDETERMINATE); + } + } break; - - default: break; } } -} - - +} \ No newline at end of file diff --git a/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeNodeSelectionListener.java b/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeNodeSelectionListener.java new file mode 100644 index 000000000..e3b9a89f4 --- /dev/null +++ b/designer-base/src/com/fr/design/remote/ui/tree/FileAuthorityTreeNodeSelectionListener.java @@ -0,0 +1,27 @@ +package com.fr.design.remote.ui.tree; + + +import javax.swing.JTree; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class FileAuthorityTreeNodeSelectionListener extends MouseAdapter { + @Override + public void mouseClicked(MouseEvent event) { + JTree tree = (JTree) event.getSource(); + int x = event.getX(); + int y = event.getY(); + int row = tree.getRowForLocation(x, y); + TreePath path = tree.getPathForRow(row); + if (path != null) { + FileAuthorityTreeNode node = (FileAuthorityTreeNode) path.getLastPathComponent(); + if (node != null) { + boolean isSelected = !node.isSelected(); + node.setSelected(isSelected); + ((DefaultTreeModel) tree.getModel()).nodeStructureChanged(node); + } + } + } +}